diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index ff135867f..9439e003e 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -250,3 +250,116 @@ jobs: with: name: e2e-screenshots path: tmp/screenshots/ + + test-search: + name: Testing search + runs-on: ubuntu-latest + + needs: + - build + + services: + postgres: + image: postgres:14-alpine + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + redis: + image: redis:7-alpine + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:7.17.13 + env: + discovery.type: single-node + xpack.security.enabled: false + options: >- + --health-cmd "curl http://localhost:9200/_cluster/health" + --health-interval 10s + --health-timeout 5s + --health-retries 10 + ports: + - 9200:9200 + + env: + DB_HOST: localhost + DB_USER: postgres + DB_PASS: postgres + DISABLE_SIMPLECOV: true + RAILS_ENV: test + BUNDLE_WITH: test + ES_ENABLED: true + ES_HOST: localhost + ES_PORT: 9200 + + strategy: + fail-fast: false + matrix: + ruby-version: + - '3.0' + - '3.1' + - '.ruby-version' + + steps: + - uses: actions/checkout@v3 + + - uses: actions/download-artifact@v3 + with: + path: './public' + name: ${{ github.sha }} + + - name: Update package index + run: sudo apt-get update + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version-file: '.nvmrc' + + - name: Install native Ruby dependencies + run: sudo apt-get install -y libicu-dev libidn11-dev + + - name: Install additional system dependencies + run: sudo apt-get install -y ffmpeg imagemagick + + - name: Set up bundler cache + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version}} + bundler-cache: true + + - run: yarn --frozen-lockfile + + - name: Load database schema + run: './bin/rails db:create db:schema:load db:seed' + + - run: bundle exec rake spec:search + + - name: Archive logs + uses: actions/upload-artifact@v3 + if: failure() + with: + name: test-search-logs-${{ matrix.ruby-version }} + path: log/ + + - name: Archive test screenshots + uses: actions/upload-artifact@v3 + if: failure() + with: + name: test-search-screenshots + path: tmp/screenshots/ diff --git a/.nvmrc b/.nvmrc index 59ea99ee6..541b047dd 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.20 +20.6 diff --git a/Dockerfile b/Dockerfile index b22284bbd..3fe4a62bd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1.4 # This needs to be bookworm-slim because the Ruby image is built on bookworm-slim -ARG NODE_VERSION="16.20-bookworm-slim" +ARG NODE_VERSION="20.6-bookworm-slim" FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.2-slim as ruby FROM node:${NODE_VERSION} as build diff --git a/Gemfile.lock b/Gemfile.lock index 4ba0a0994..9e2fc3be2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -640,7 +640,7 @@ GEM sidekiq (>= 5, < 8) rspec-support (3.12.1) rspec_chunked (0.6) - rubocop (1.56.2) + rubocop (1.56.3) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) diff --git a/Vagrantfile b/Vagrantfile index 1117d62ff..4303f8e06 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -76,7 +76,8 @@ path.logs: /var/log/elasticsearch network.host: 0.0.0.0 http.port: 9200 discovery.seed_hosts: ["localhost"] -cluster.initial_master_nodes: ["node-1"]' > /etc/elasticsearch/elasticsearch.yml +cluster.initial_master_nodes: ["node-1"] +xpack.security.enabled: false' > /etc/elasticsearch/elasticsearch.yml sudo systemctl restart elasticsearch diff --git a/app/controllers/api/v1/directories_controller.rb b/app/controllers/api/v1/directories_controller.rb index 110943550..35c504a7f 100644 --- a/app/controllers/api/v1/directories_controller.rb +++ b/app/controllers/api/v1/directories_controller.rb @@ -16,7 +16,9 @@ class Api::V1::DirectoriesController < Api::BaseController end def set_accounts - @accounts = accounts_scope.offset(params[:offset]).limit(limit_param(DEFAULT_ACCOUNTS_LIMIT)) + with_read_replica do + @accounts = accounts_scope.offset(params[:offset]).limit(limit_param(DEFAULT_ACCOUNTS_LIMIT)) + end end def accounts_scope diff --git a/app/javascript/mastodon/actions/search.js b/app/javascript/mastodon/actions/search.js index 21fd54076..7aea346e6 100644 --- a/app/javascript/mastodon/actions/search.js +++ b/app/javascript/mastodon/actions/search.js @@ -1,3 +1,7 @@ +import { fromJS } from 'immutable'; + +import { searchHistory } from 'mastodon/settings'; + import api from '../api'; import { fetchRelationships } from './accounts'; @@ -15,8 +19,7 @@ export const SEARCH_EXPAND_REQUEST = 'SEARCH_EXPAND_REQUEST'; export const SEARCH_EXPAND_SUCCESS = 'SEARCH_EXPAND_SUCCESS'; export const SEARCH_EXPAND_FAIL = 'SEARCH_EXPAND_FAIL'; -export const SEARCH_RESULT_CLICK = 'SEARCH_RESULT_CLICK'; -export const SEARCH_RESULT_FORGET = 'SEARCH_RESULT_FORGET'; +export const SEARCH_HISTORY_UPDATE = 'SEARCH_HISTORY_UPDATE'; export function changeSearch(value) { return { @@ -170,16 +173,34 @@ export const openURL = (value, history, onFailure) => (dispatch, getState) => { }); }; -export const clickSearchResult = (q, type) => ({ - type: SEARCH_RESULT_CLICK, +export const clickSearchResult = (q, type) => (dispatch, getState) => { + const previous = getState().getIn(['search', 'recent']); + const me = getState().getIn(['meta', 'me']); + const current = previous.add(fromJS({ type, q })).takeLast(4); - result: { - type, - q, - }, + searchHistory.set(me, current.toJS()); + dispatch(updateSearchHistory(current)); +}; + +export const forgetSearchResult = q => (dispatch, getState) => { + const previous = getState().getIn(['search', 'recent']); + const me = getState().getIn(['meta', 'me']); + const current = previous.filterNot(result => result.get('q') === q); + + searchHistory.set(me, current.toJS()); + dispatch(updateSearchHistory(current)); +}; + +export const updateSearchHistory = recent => ({ + type: SEARCH_HISTORY_UPDATE, + recent, }); -export const forgetSearchResult = q => ({ - type: SEARCH_RESULT_FORGET, - q, -}); +export const hydrateSearch = () => (dispatch, getState) => { + const me = getState().getIn(['meta', 'me']); + const history = searchHistory.get(me); + + if (history !== null) { + dispatch(updateSearchHistory(history)); + } +}; \ No newline at end of file diff --git a/app/javascript/mastodon/actions/store.js b/app/javascript/mastodon/actions/store.js index 6b0743439..682b0f5db 100644 --- a/app/javascript/mastodon/actions/store.js +++ b/app/javascript/mastodon/actions/store.js @@ -2,6 +2,7 @@ import { Iterable, fromJS } from 'immutable'; import { hydrateCompose } from './compose'; import { importFetchedAccounts } from './importer'; +import { hydrateSearch } from './search'; export const STORE_HYDRATE = 'STORE_HYDRATE'; export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY'; @@ -20,6 +21,7 @@ export function hydrateStore(rawState) { }); dispatch(hydrateCompose()); + dispatch(hydrateSearch()); dispatch(importFetchedAccounts(Object.values(rawState.accounts))); }; } diff --git a/app/javascript/mastodon/features/audio/index.jsx b/app/javascript/mastodon/features/audio/index.jsx index 3f642bc74..103ef5782 100644 --- a/app/javascript/mastodon/features/audio/index.jsx +++ b/app/javascript/mastodon/features/audio/index.jsx @@ -205,11 +205,11 @@ class Audio extends PureComponent { }; toggleMute = () => { - const muted = !this.state.muted; + const muted = !(this.state.muted || this.state.volume === 0); - this.setState({ muted }, () => { + this.setState((state) => ({ muted, volume: Math.max(state.volume || 0.5, 0.05) }), () => { if (this.gainNode) { - this.gainNode.gain.value = muted ? 0 : this.state.volume; + this.gainNode.gain.value = this.state.muted ? 0 : this.state.volume; } }); }; @@ -287,7 +287,7 @@ class Audio extends PureComponent { const { x } = getPointerPosition(this.volume, e); if(!isNaN(x)) { - this.setState({ volume: x }, () => { + this.setState((state) => ({ volume: x, muted: state.muted && x === 0 }), () => { if (this.gainNode) { this.gainNode.gain.value = this.state.muted ? 0 : x; } @@ -466,8 +466,9 @@ class Audio extends PureComponent { render () { const { src, intl, alt, lang, editable, autoPlay, sensitive, blurhash } = this.props; - const { paused, muted, volume, currentTime, duration, buffer, dragging, revealed } = this.state; + const { paused, volume, currentTime, duration, buffer, dragging, revealed } = this.state; const progress = Math.min((currentTime / duration) * 100, 100); + const muted = this.state.muted || volume === 0; let warning; @@ -557,12 +558,12 @@ class Audio extends PureComponent {
-
+
diff --git a/app/javascript/mastodon/features/compose/components/search.jsx b/app/javascript/mastodon/features/compose/components/search.jsx index 53e1db9d4..7e1d8b760 100644 --- a/app/javascript/mastodon/features/compose/components/search.jsx +++ b/app/javascript/mastodon/features/compose/components/search.jsx @@ -16,6 +16,17 @@ const messages = defineMessages({ placeholderSignedIn: { id: 'search.search_or_paste', defaultMessage: 'Search or paste URL' }, }); +const labelForRecentSearch = search => { + switch(search.get('type')) { + case 'account': + return `@${search.get('q')}`; + case 'hashtag': + return `#${search.get('q')}`; + default: + return search.get('q'); + } +}; + class Search extends PureComponent { static contextTypes = { @@ -187,12 +198,16 @@ class Search extends PureComponent { }; handleRecentSearchClick = search => { + const { onChange } = this.props; const { router } = this.context; if (search.get('type') === 'account') { router.history.push(`/@${search.get('q')}`); } else if (search.get('type') === 'hashtag') { router.history.push(`/tags/${search.get('q')}`); + } else { + onChange(search.get('q')); + this._submit(search.get('type')); } this._unfocus(); @@ -221,11 +236,15 @@ class Search extends PureComponent { } _submit (type) { - const { onSubmit, openInRoute } = this.props; + const { onSubmit, openInRoute, value, onClickSearchResult } = this.props; const { router } = this.context; onSubmit(type); + if (value) { + onClickSearchResult(value, type); + } + if (openInRoute) { router.history.push('/search'); } @@ -243,7 +262,7 @@ class Search extends PureComponent { const { recent } = this.props; return recent.toArray().map(search => ({ - label: search.get('type') === 'account' ? `@${search.get('q')}` : `#${search.get('q')}`, + label: labelForRecentSearch(search), action: () => this.handleRecentSearchClick(search), @@ -359,7 +378,7 @@ class Search extends PureComponent { {searchEnabled ? (
{this.defaultOptions.map(({ key, label, action }, i) => ( - ))} diff --git a/app/javascript/mastodon/features/compose/containers/search_container.js b/app/javascript/mastodon/features/compose/containers/search_container.js index 299a3887e..758b6b07d 100644 --- a/app/javascript/mastodon/features/compose/containers/search_container.js +++ b/app/javascript/mastodon/features/compose/containers/search_container.js @@ -15,7 +15,7 @@ import Search from '../components/search'; const mapStateToProps = state => ({ value: state.getIn(['search', 'value']), submitted: state.getIn(['search', 'submitted']), - recent: state.getIn(['search', 'recent']), + recent: state.getIn(['search', 'recent']).reverse(), }); const mapDispatchToProps = dispatch => ({ diff --git a/app/javascript/mastodon/features/video/index.jsx b/app/javascript/mastodon/features/video/index.jsx index 3f7e0ada1..ec0e7a909 100644 --- a/app/javascript/mastodon/features/video/index.jsx +++ b/app/javascript/mastodon/features/video/index.jsx @@ -217,8 +217,9 @@ class Video extends PureComponent { const { x } = getPointerPosition(this.volume, e); if(!isNaN(x)) { - this.setState({ volume: x }, () => { + this.setState((state) => ({ volume: x, muted: state.muted && x === 0 }), () => { this.video.volume = x; + this.video.muted = this.state.muted; }); } }, 15); @@ -425,10 +426,11 @@ class Video extends PureComponent { }; toggleMute = () => { - const muted = !this.video.muted; + const muted = !(this.video.muted || this.state.volume === 0); - this.setState({ muted }, () => { - this.video.muted = muted; + this.setState((state) => ({ muted, volume: Math.max(state.volume || 0.5, 0.05) }), () => { + this.video.volume = this.state.volume; + this.video.muted = this.state.muted; }); }; @@ -501,8 +503,9 @@ class Video extends PureComponent { render () { const { preview, src, aspectRatio, onOpenVideo, onCloseVideo, intl, alt, lang, detailed, sensitive, editable, blurhash, autoFocus } = this.props; - const { currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state; + const { currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, revealed } = this.state; const progress = Math.min((currentTime / duration) * 100, 100); + const muted = this.state.muted || volume === 0; let preload; @@ -593,12 +596,12 @@ class Video extends PureComponent {
-
+
diff --git a/app/javascript/mastodon/reducers/search.js b/app/javascript/mastodon/reducers/search.js index c81d7ff3c..904e35185 100644 --- a/app/javascript/mastodon/reducers/search.js +++ b/app/javascript/mastodon/reducers/search.js @@ -14,8 +14,7 @@ import { SEARCH_SHOW, SEARCH_EXPAND_REQUEST, SEARCH_EXPAND_SUCCESS, - SEARCH_RESULT_CLICK, - SEARCH_RESULT_FORGET, + SEARCH_HISTORY_UPDATE, } from '../actions/search'; const initialState = ImmutableMap({ @@ -73,10 +72,8 @@ export default function search(state = initialState, action) { case SEARCH_EXPAND_SUCCESS: const results = action.searchType === 'hashtags' ? ImmutableOrderedSet(fromJS(action.results.hashtags)) : action.results[action.searchType].map(item => item.id); return state.updateIn(['results', action.searchType], list => list.union(results)); - case SEARCH_RESULT_CLICK: - return state.update('recent', set => set.add(fromJS(action.result))); - case SEARCH_RESULT_FORGET: - return state.update('recent', set => set.filterNot(result => result.get('q') === action.q)); + case SEARCH_HISTORY_UPDATE: + return state.set('recent', ImmutableOrderedSet(fromJS(action.recent))); default: return state; } diff --git a/app/javascript/mastodon/settings.js b/app/javascript/mastodon/settings.js index 46cfadfa3..aefb8e0e9 100644 --- a/app/javascript/mastodon/settings.js +++ b/app/javascript/mastodon/settings.js @@ -46,3 +46,4 @@ export default class Settings { export const pushNotificationsSetting = new Settings('mastodon_push_notification_data'); export const tagHistory = new Settings('mastodon_tag_history'); export const bannerSettings = new Settings('mastodon_banner_settings'); +export const searchHistory = new Settings('mastodon_search_history'); \ No newline at end of file diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 7bbccd591..66835b65f 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -8877,7 +8877,6 @@ noscript { border-radius: 8px; border: 1px solid $highlight-text-color; background: rgba($highlight-text-color, 0.15); - padding-inline-end: 45px; overflow: hidden; &__background-image { @@ -8940,7 +8939,7 @@ noscript { position: absolute; inset-inline-end: 0; top: 0; - padding: 10px; + padding: 15px 10px; .icon-button { color: $highlight-text-color; diff --git a/app/lib/search_query_parser.rb b/app/lib/search_query_parser.rb index 1c57b9b02..dfe8b9e9d 100644 --- a/app/lib/search_query_parser.rb +++ b/app/lib/search_query_parser.rb @@ -8,7 +8,7 @@ class SearchQueryParser < Parslet::Parser rule(:operator) { (str('+') | str('-')).as(:operator) } rule(:prefix) { term >> colon } rule(:shortcode) { (colon >> term >> colon.maybe).as(:shortcode) } - rule(:phrase) { (quote >> (term >> space.maybe).repeat >> quote).as(:phrase) } + rule(:phrase) { (quote >> (match('[^\s"]').repeat(1).as(:term) >> space.maybe).repeat >> quote).as(:phrase) } rule(:clause) { (operator.maybe >> prefix.maybe.as(:prefix) >> (phrase | term | shortcode)).as(:clause) | prefix.as(:clause) | quote.as(:junk) } rule(:query) { (clause >> space.maybe).repeat.as(:query) } root(:query) diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index 2dc10830d..a45ae3d09 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -121,7 +121,7 @@ class SearchQueryTransformer < Parslet::Transform def to_query if @term.start_with?('#') - { match: { tags: { query: @term } } } + { match: { tags: { query: @term, operator: 'and' } } } else { multi_match: { type: 'most_fields', query: @term, fields: ['text', 'text.stemmed'], operator: 'and' } } end @@ -225,17 +225,16 @@ class SearchQueryTransformer < Parslet::Transform rule(clause: subtree(:clause)) do prefix = clause[:prefix][:term].to_s if clause[:prefix] operator = clause[:operator]&.to_s + term = clause[:phrase] ? clause[:phrase].map { |term| term[:term].to_s }.join(' ') : clause[:term].to_s if clause[:prefix] && SUPPORTED_PREFIXES.include?(prefix) - PrefixClause.new(prefix, operator, clause[:term].to_s, current_account: current_account) + PrefixClause.new(prefix, operator, term, current_account: current_account) elsif clause[:prefix] - TermClause.new(operator, "#{prefix} #{clause[:term]}") + TermClause.new(operator, "#{prefix} #{term}") elsif clause[:term] - TermClause.new(operator, clause[:term].to_s) - elsif clause[:shortcode] - TermClause.new(operator, ":#{clause[:term]}:") + TermClause.new(operator, term) elsif clause[:phrase] - PhraseClause.new(operator, clause[:phrase].is_a?(Array) ? clause[:phrase].map { |p| p[:term].to_s }.join(' ') : clause[:phrase].to_s) + PhraseClause.new(operator, term) else raise "Unexpected clause type: #{clause}" end diff --git a/app/models/account.rb b/app/models/account.rb index 99930c322..d670767da 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -129,10 +129,10 @@ class Account < ApplicationRecord scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) } scope :without_unapproved, -> { left_outer_joins(:user).merge(User.approved.confirmed).or(remote) } scope :searchable, -> { without_unapproved.without_suspended.where(moved_to_account_id: nil) } - scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).left_outer_joins(:account_stat) } + scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).joins(:account_stat) } scope :followable_by, ->(account) { joins(arel_table.join(Follow.arel_table, Arel::Nodes::OuterJoin).on(arel_table[:id].eq(Follow.arel_table[:target_account_id]).and(Follow.arel_table[:account_id].eq(account.id))).join_sources).where(Follow.arel_table[:id].eq(nil)).joins(arel_table.join(FollowRequest.arel_table, Arel::Nodes::OuterJoin).on(arel_table[:id].eq(FollowRequest.arel_table[:target_account_id]).and(FollowRequest.arel_table[:account_id].eq(account.id))).join_sources).where(FollowRequest.arel_table[:id].eq(nil)) } - scope :by_recent_status, -> { order(Arel.sql('(case when account_stats.last_status_at is null then 1 else 0 end) asc, account_stats.last_status_at desc, accounts.id desc')) } - scope :by_recent_sign_in, -> { order(Arel.sql('(case when users.current_sign_in_at is null then 1 else 0 end) asc, users.current_sign_in_at desc, accounts.id desc')) } + scope :by_recent_status, -> { order(Arel.sql('account_stats.last_status_at DESC NULLS LAST')) } + scope :by_recent_sign_in, -> { order(Arel.sql('users.current_sign_in_at DESC NULLS LAST')) } scope :popular, -> { order('account_stats.followers_count desc') } scope :by_domain_and_subdomains, ->(domain) { where(domain: Instance.by_domain_and_subdomains(domain).select(:domain)) } scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) } diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 49063754a..0f1b0edc8 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -171,7 +171,7 @@ class MediaAttachment < ApplicationRecord DEFAULT_STYLES = [:original].freeze GLOBAL_CONVERT_OPTIONS = { - all: '-quality 90 +profile "!icc,*" +set modify-date +set create-date', + all: '-quality 90 +profile "!icc,*" +set modify-date -define jpeg:dct-method=float +set create-date', }.freeze belongs_to :account, inverse_of: :media_attachments, optional: true diff --git a/app/services/statuses_search_service.rb b/app/services/statuses_search_service.rb index e4b38a9da..e2a5f41b1 100644 --- a/app/services/statuses_search_service.rb +++ b/app/services/statuses_search_service.rb @@ -8,6 +8,7 @@ class StatusesSearchService < BaseService @limit = options[:limit].to_i @offset = options[:offset].to_i + convert_deprecated_options! status_search_results end @@ -28,4 +29,25 @@ class StatusesSearchService < BaseService def parsed_query SearchQueryTransformer.new.apply(SearchQueryParser.new.parse(@query), current_account: @account) end + + def convert_deprecated_options! + syntax_options = [] + + if @options[:account_id] + username = Account.select(:username, :domain).find(@options[:account_id]).acct + syntax_options << "from:@#{username}" + end + + if @options[:min_id] + timestamp = Mastodon::Snowflake.to_time(@options[:min_id]) + syntax_options << "after:\"#{timestamp.iso8601}\"" + end + + if @options[:max_id] + timestamp = Mastodon::Snowflake.to_time(@options[:max_id]) + syntax_options << "before:\"#{timestamp.iso8601}\"" + end + + @query = "#{@query} #{syntax_options.join(' ')}".strip if syntax_options.any? + end end diff --git a/config/webpack/production.js b/config/webpack/production.js index 7f1ee4a8f..cec810184 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -4,7 +4,7 @@ const { createHash } = require('crypto'); const { readFileSync } = require('fs'); const { resolve } = require('path'); -const CompressionPlugin = require('compression-webpack-plugin'); +const CompressionPlugin = require('@renchap/compression-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const { merge } = require('webpack-merge'); diff --git a/db/migrate/20230907150100_add_index_account_stats_on_last_status_at_and_account_id.rb b/db/migrate/20230907150100_add_index_account_stats_on_last_status_at_and_account_id.rb new file mode 100644 index 000000000..17ac65547 --- /dev/null +++ b/db/migrate/20230907150100_add_index_account_stats_on_last_status_at_and_account_id.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddIndexAccountStatsOnLastStatusAtAndAccountId < ActiveRecord::Migration[7.0] + disable_ddl_transaction! + + def change + add_index :account_stats, [:last_status_at, :account_id], order: { last_status_at: 'DESC NULLS LAST' }, algorithm: :concurrently + end +end diff --git a/db/schema.rb b/db/schema.rb index 777ccd220..9c7c490bb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_09_04_134623) do +ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -99,6 +99,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_04_134623) do t.datetime "updated_at", precision: nil, null: false t.datetime "last_status_at", precision: nil t.index ["account_id"], name: "index_account_stats_on_account_id", unique: true + t.index ["last_status_at", "account_id"], name: "index_account_stats_on_last_status_at_and_account_id", order: { last_status_at: "DESC NULLS LAST" } end create_table "account_statuses_cleanup_policies", force: :cascade do |t| diff --git a/lib/mastodon/snowflake.rb b/lib/mastodon/snowflake.rb index 8b79541da..0a596b294 100644 --- a/lib/mastodon/snowflake.rb +++ b/lib/mastodon/snowflake.rb @@ -104,6 +104,10 @@ module Mastodon::Snowflake id end + def to_time(id) + Time.at((id >> 16) / 1000).utc + end + private def already_defined? diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake index 8f2cbeea3..ec4cd39bf 100644 --- a/lib/tasks/spec.rake +++ b/lib/tasks/spec.rake @@ -9,3 +9,13 @@ if Rake::Task.task_defined?('spec:system') Rake::Task['spec:system'].enhance ['spec:enable_system_specs'] end + +if Rake::Task.task_defined?('spec:search') + namespace :spec do + task :enable_search_specs do # rubocop:disable Rails/RakeEnvironment + ENV['RUN_SEARCH_SPECS'] = 'true' + end + end + + Rake::Task['spec:search'].enhance ['spec:enable_search_specs'] +end diff --git a/package.json b/package.json index e6d0cd59e..2b26f97a2 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@material-design-icons/svg": "^0.14.10", "@rails/ujs": "^7.0.6", "@reduxjs/toolkit": "^1.9.5", + "@renchap/compression-webpack-plugin": "^6.1.4", "@svgr/webpack": "^5.5.0", "abortcontroller-polyfill": "^1.7.5", "atrament": "0.2.4", @@ -64,7 +65,6 @@ "classnames": "^2.3.2", "cocoon-js-vanilla": "^1.3.0", "color-blend": "^4.0.0", - "compression-webpack-plugin": "^6.1.1", "core-js": "^3.30.2", "cross-env": "^7.0.3", "css-loader": "^5.2.7", @@ -139,7 +139,7 @@ "tiny-queue": "^0.2.1", "twitter-text": "3.1.0", "uuid": "^9.0.0", - "webpack": "^4.46.0", + "webpack": "^4.47.0", "webpack-assets-manifest": "^4.0.6", "webpack-bundle-analyzer": "^4.8.0", "webpack-cli": "^3.3.12", diff --git a/spec/controllers/api/v1/directories_controller_spec.rb b/spec/controllers/api/v1/directories_controller_spec.rb index 5e21802e7..308a8874c 100644 --- a/spec/controllers/api/v1/directories_controller_spec.rb +++ b/spec/controllers/api/v1/directories_controller_spec.rb @@ -15,12 +15,13 @@ describe Api::V1::DirectoriesController do describe 'GET #show' do context 'with no params' do before do - _local_unconfirmed_account = Fabricate( + local_unconfirmed_account = Fabricate( :account, domain: nil, user: Fabricate(:user, confirmed_at: nil, approved: true), username: 'local_unconfirmed' ) + local_unconfirmed_account.create_account_stat! local_unapproved_account = Fabricate( :account, @@ -28,15 +29,17 @@ describe Api::V1::DirectoriesController do user: Fabricate(:user, confirmed_at: 10.days.ago), username: 'local_unapproved' ) + local_unapproved_account.create_account_stat! local_unapproved_account.user.update(approved: false) - _local_undiscoverable_account = Fabricate( + local_undiscoverable_account = Fabricate( :account, domain: nil, user: Fabricate(:user, confirmed_at: 10.days.ago, approved: true), discoverable: false, username: 'local_undiscoverable' ) + local_undiscoverable_account.create_account_stat! excluded_from_timeline_account = Fabricate( :account, @@ -44,18 +47,20 @@ describe Api::V1::DirectoriesController do discoverable: true, username: 'remote_excluded_from_timeline' ) + excluded_from_timeline_account.create_account_stat! Fabricate(:block, account: user.account, target_account: excluded_from_timeline_account) - _domain_blocked_account = Fabricate( + domain_blocked_account = Fabricate( :account, domain: 'test.example', discoverable: true, username: 'remote_domain_blocked' ) + domain_blocked_account.create_account_stat! Fabricate(:account_domain_block, account: user.account, domain: 'test.example') end - it 'returns only the local discoverable account' do + it 'returns the local discoverable account and the remote discoverable account' do local_discoverable_account = Fabricate( :account, domain: nil, @@ -63,6 +68,7 @@ describe Api::V1::DirectoriesController do discoverable: true, username: 'local_discoverable' ) + local_discoverable_account.create_account_stat! eligible_remote_account = Fabricate( :account, @@ -70,13 +76,13 @@ describe Api::V1::DirectoriesController do discoverable: true, username: 'eligible_remote' ) + eligible_remote_account.create_account_stat! get :show expect(response).to have_http_status(200) expect(body_as_json.size).to eq(2) - expect(body_as_json.first[:id]).to include(eligible_remote_account.id.to_s) - expect(body_as_json.second[:id]).to include(local_discoverable_account.id.to_s) + expect(body_as_json.pluck(:id)).to contain_exactly(eligible_remote_account.id.to_s, local_discoverable_account.id.to_s) end end @@ -85,6 +91,8 @@ describe Api::V1::DirectoriesController do user = Fabricate(:user, confirmed_at: 10.days.ago, approved: true) local_account = Fabricate(:account, domain: nil, user: user) remote_account = Fabricate(:account, domain: 'host.example') + local_account.create_account_stat! + remote_account.create_account_stat! get :show, params: { local: '1' } @@ -97,24 +105,23 @@ describe Api::V1::DirectoriesController do context 'when ordered by active' do it 'returns accounts in order of most recent status activity' do - status_old = Fabricate(:status) - travel_to 10.seconds.from_now - status_new = Fabricate(:status) + old_stat = Fabricate(:account_stat, last_status_at: 1.day.ago) + new_stat = Fabricate(:account_stat, last_status_at: 1.minute.ago) get :show, params: { order: 'active' } expect(response).to have_http_status(200) expect(body_as_json.size).to eq(2) - expect(body_as_json.first[:id]).to include(status_new.account.id.to_s) - expect(body_as_json.second[:id]).to include(status_old.account.id.to_s) + expect(body_as_json.first[:id]).to include(new_stat.account_id.to_s) + expect(body_as_json.second[:id]).to include(old_stat.account_id.to_s) end end context 'when ordered by new' do it 'returns accounts in order of creation' do - account_old = Fabricate(:account) + account_old = Fabricate(:account_stat).account travel_to 10.seconds.from_now - account_new = Fabricate(:account) + account_new = Fabricate(:account_stat).account get :show, params: { order: 'new' } diff --git a/spec/lib/search_query_transformer_spec.rb b/spec/lib/search_query_transformer_spec.rb index 4b949b1b8..5817e3d1d 100644 --- a/spec/lib/search_query_transformer_spec.rb +++ b/spec/lib/search_query_transformer_spec.rb @@ -57,4 +57,24 @@ describe SearchQueryTransformer do expect(subject.send(:filter_clauses)).to be_empty end end + + context 'with \'"hello world"\'' do + let(:query) { '"hello world"' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses).map(&:phrase)).to contain_exactly('hello world') + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses)).to be_empty + end + end + + context 'with \'before:"2022-01-01 23:00"\'' do + let(:query) { 'before:"2022-01-01 23:00"' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses)).to be_empty + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses).map(&:term)).to contain_exactly(lt: '2022-01-01 23:00', time_zone: 'UTC') + end + end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index d4ff79c51..7b8dccb6a 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -4,11 +4,17 @@ ENV['RAILS_ENV'] ||= 'test' # This needs to be defined before Rails is initialized RUN_SYSTEM_SPECS = ENV.fetch('RUN_SYSTEM_SPECS', false) +RUN_SEARCH_SPECS = ENV.fetch('RUN_SEARCH_SPECS', false) if RUN_SYSTEM_SPECS STREAMING_PORT = ENV.fetch('TEST_STREAMING_PORT', '4020') ENV['STREAMING_API_BASE_URL'] = "http://localhost:#{STREAMING_PORT}" end + +if RUN_SEARCH_SPECS + # Include any configuration or setups specific to search tests here +end + require File.expand_path('../config/environment', __dir__) abort('The Rails environment is running in production mode!') if Rails.env.production? @@ -30,6 +36,7 @@ Sidekiq.logger = nil # System tests config DatabaseCleaner.strategy = [:deletion] streaming_server_manager = StreamingServerManager.new +search_data_manager = SearchDataManager.new Devise::Test::ControllerHelpers.module_eval do alias_method :original_sign_in, :sign_in @@ -69,7 +76,14 @@ end RSpec.configure do |config| # This is set before running spec:system, see lib/tasks/tests.rake - config.filter_run_excluding type: :system unless RUN_SYSTEM_SPECS + config.filter_run_excluding type: lambda { |type| + case type + when :system + !RUN_SYSTEM_SPECS + when :search + !RUN_SEARCH_SPECS + end + } config.fixture_path = Rails.root.join('spec', 'fixtures') config.use_transactional_fixtures = true config.order = 'random' @@ -113,10 +127,17 @@ RSpec.configure do |config| Webpacker.compile streaming_server_manager.start(port: STREAMING_PORT) end + + if RUN_SEARCH_SPECS + Chewy.strategy(:urgent) + search_data_manager.prepare_test_data + end end config.after :suite do streaming_server_manager.stop + + search_data_manager.cleanup_test_data if RUN_SEARCH_SPECS end config.around :each, type: :system do |example| @@ -137,6 +158,12 @@ RSpec.configure do |config| self.use_transactional_tests = true end + config.around :each, type: :search do |example| + search_data_manager.populate_indexes + example.run + search_data_manager.remove_indexes + end + config.before(:each) do |example| unless example.metadata[:paperclip_processing] allow_any_instance_of(Paperclip::Attachment).to receive(:post_process).and_return(true) # rubocop:disable RSpec/AnyInstance diff --git a/spec/search/models/concerns/account_search_spec.rb b/spec/search/models/concerns/account_search_spec.rb new file mode 100644 index 000000000..65e1e4de1 --- /dev/null +++ b/spec/search/models/concerns/account_search_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountSearch do + describe 'a non-discoverable account becoming discoverable' do + let(:account) { Account.find_by(username: 'search_test_account_1') } + + context 'when picking a non-discoverable account' do + it 'its bio is not in the AccountsIndex' do + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to be_nil + end + end + + context 'when the non-discoverable account becomes discoverable' do + it 'its bio is added to the AccountsIndex' do + account.discoverable = true + account.save! + + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to eq(account.note) + end + end + end + + describe 'a discoverable account becoming non-discoverable' do + let(:account) { Account.find_by(username: 'search_test_account_0') } + + context 'when picking an discoverable account' do + it 'has its bio in the AccountsIndex' do + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to eq(account.note) + end + end + + context 'when the discoverable account becomes non-discoverable' do + it 'its bio is removed from the AccountsIndex' do + account.discoverable = false + account.save! + + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to be_nil + end + end + end +end diff --git a/spec/search/models/concerns/account_statuses_search_spec.rb b/spec/search/models/concerns/account_statuses_search_spec.rb new file mode 100644 index 000000000..d35cfa563 --- /dev/null +++ b/spec/search/models/concerns/account_statuses_search_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountStatusesSearch do + describe 'a non-indexable account becoming indexable' do + let(:account) { Account.find_by(username: 'search_test_account_1') } + + context 'when picking a non-indexable account' do + it 'has no statuses in the PublicStatusesIndex' do + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(0) + end + + it 'has statuses in the StatusesIndex' do + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + + context 'when the non-indexable account becomes indexable' do + it 'adds the public statuses to the PublicStatusesIndex' do + account.indexable = true + account.save! + + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.where(visibility: :public).count) + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + end + + describe 'an indexable account becoming non-indexable' do + let(:account) { Account.find_by(username: 'search_test_account_0') } + + context 'when picking an indexable account' do + it 'has statuses in the PublicStatusesIndex' do + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.where(visibility: :public).count) + end + + it 'has statuses in the StatusesIndex' do + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + + context 'when the indexable account becomes non-indexable' do + it 'removes the statuses from the PublicStatusesIndex' do + account.indexable = false + account.save! + + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(0) + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dcbcad48e..b4c20545f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -129,3 +129,45 @@ class StreamingServerManager @running_thread.join end end + +class SearchDataManager + def prepare_test_data + 4.times do |i| + username = "search_test_account_#{i}" + account = Fabricate.create(:account, username: username, indexable: i.even?, discoverable: i.even?, note: "Lover of #{i}.") + 2.times do |j| + Fabricate.create(:status, account: account, text: "#{username}'s #{j} post", visibility: j.even? ? :public : :private) + end + end + + 3.times do |i| + Fabricate.create(:tag, name: "search_test_tag_#{i}") + end + end + + def indexes + [ + AccountsIndex, + PublicStatusesIndex, + StatusesIndex, + TagsIndex, + ] + end + + def populate_indexes + indexes.each do |index_class| + index_class.purge! + index_class.import! + end + end + + def remove_indexes + indexes.each(&:delete!) + end + + def cleanup_test_data + Status.destroy_all + Account.destroy_all + Tag.destroy_all + end +end diff --git a/yarn.lock b/yarn.lock index 75e956410..4d1d76323 100644 --- a/yarn.lock +++ b/yarn.lock @@ -88,7 +88,7 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/generator@^7.22.5", "@babel/generator@^7.7.2": +"@babel/generator@^7.7.2": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== @@ -262,7 +262,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@^7.22.5", "@babel/helper-split-export-declaration@^7.22.6": +"@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== @@ -320,16 +320,16 @@ chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7": +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.22.5": + version "7.22.16" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95" + integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA== + +"@babel/parser@^7.14.7": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== -"@babel/parser@^7.22.15", "@babel/parser@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.15.tgz#d34592bfe288a32e741aa0663dbc4829fcd55160" - integrity sha512-RWmQ/sklUN9BvGGpCDgSubhHWfAx24XDTDObup4ffvxaYsptOg2P3KG0j+1eWKLxpkX0j0uHxmpq2Z1SP/VhxA== - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" @@ -1112,23 +1112,7 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/traverse@7": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" - integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== - dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" - "@babel/parser" "^7.22.5" - "@babel/types" "^7.22.5" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.22.15": +"@babel/traverse@7", "@babel/traverse@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.15.tgz#75be4d2d6e216e880e93017f4e2389aeb77ef2d9" integrity sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ== @@ -1144,16 +1128,16 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.3.3": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" - integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== +"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.4.4": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.15.tgz#266cb21d2c5fd0b3931e7a91b6dd72d2f617d282" + integrity sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA== dependencies: "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.15" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0-beta.49", "@babel/types@^7.12.11", "@babel/types@^7.12.6": +"@babel/types@^7.0.0-beta.49", "@babel/types@^7.12.6": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== @@ -1162,13 +1146,13 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" -"@babel/types@^7.22.10", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.4.4": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.15.tgz#266cb21d2c5fd0b3931e7a91b6dd72d2f617d282" - integrity sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA== +"@babel/types@^7.3.3": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" + integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== dependencies: "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.15" + "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -1325,10 +1309,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.48.0": - version "8.48.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.48.0.tgz#642633964e217905436033a2bd08bf322849b7fb" - integrity sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw== +"@eslint/js@8.49.0": + version "8.49.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.49.0.tgz#86f79756004a97fa4df866835093f1df3d03c333" + integrity sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w== "@floating-ui/core@^1.3.1": version "1.3.1" @@ -1347,12 +1331,20 @@ resolved "https://registry.yarnpkg.com/@formatjs/cli/-/cli-6.1.3.tgz#b4b95259398e222ec6c06cf5f23f76d987f53e96" integrity sha512-PdTXZTY8LqxwmvFqdifn89gjXnPUpGtGyFs0BnoeLuOuxZFSnBfIs5WQCVMaJnr1+0vNNlXyT0VAIAwjRpf6BA== -"@formatjs/ecma402-abstract@1.17.0": - version "1.17.0" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz#2ce191a3bde4c65c6684e03fa247062a4a294b9e" - integrity sha512-6ueQTeJZtwKjmh23bdkq/DMqH4l4bmfvtQH98blOSbiXv/OUiyijSW6jU22IT8BNM1ujCaEvJfTtyCYVH38EMQ== +"@formatjs/ecma402-abstract@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.1.tgz#6ac7d6a1d1c9c8eff76ab6ed949f2a5cbe424030" + integrity sha512-N2sjSUrmsEoynG8Q61pkrKlJ9PxcUGxJke1x3301aGyprGgl58wHWhgGUnzTfS4OHNNNQDxzjcXVp1t5fGW6yQ== dependencies: - "@formatjs/intl-localematcher" "0.4.0" + "@formatjs/intl-localematcher" "0.4.1" + tslib "^2.4.0" + +"@formatjs/ecma402-abstract@1.17.2": + version "1.17.2" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz#d197c6e26b9fd96ff7ba3b3a0cc2f25f1f2dcac3" + integrity sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg== + dependencies: + "@formatjs/intl-localematcher" "0.4.2" tslib "^2.4.0" "@formatjs/fast-memoize@2.2.0": @@ -1362,76 +1354,113 @@ dependencies: tslib "^2.4.0" -"@formatjs/icu-messageformat-parser@2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.0.tgz#b0d58ce8c8f472969c96b5cd0b3ad5522d3a02b7" - integrity sha512-yT6at0qc0DANw9qM/TU8RZaCtfDXtj4pZM/IC2WnVU80yAcliS3KVDiuUt4jSQAeFL9JS5bc2hARnFmjPdA6qw== +"@formatjs/icu-messageformat-parser@2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.1.tgz#ca497d5a2bff641dc0978bd9b64d1d02597980cb" + integrity sha512-dTDNupwdovxT1xDXC96zzPUua/XrxTQTOulJZSvaJP0pt3rr/cGR/tq4d7BnxY9oqPZpc4fjWBmrRlhcUyBSiw== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/icu-skeleton-parser" "1.6.0" + "@formatjs/ecma402-abstract" "1.17.1" + "@formatjs/icu-skeleton-parser" "1.6.1" tslib "^2.4.0" -"@formatjs/icu-skeleton-parser@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.0.tgz#0728be8b6b3656f1a4b8e6e5b0e02dffffc23c6c" - integrity sha512-eMmxNpoX/J1IPUjPGSZwo0Wh+7CEvdEMddP2Jxg1gQJXfGfht/FdW2D5XDFj3VMbOTUQlDIdZJY7uC6O6gjPoA== +"@formatjs/icu-messageformat-parser@2.6.2": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.2.tgz#9bbb29099416e4ce2c7df50029c48985d4f901b3" + integrity sha512-nF/Iww7sc5h+1MBCDRm68qpHTCG4xvGzYs/x9HFcDETSGScaJ1Fcadk5U/NXjXeCtzD+DhN4BAwKFVclHfKMdA== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/icu-skeleton-parser" "1.6.2" tslib "^2.4.0" -"@formatjs/intl-displaynames@6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.5.0.tgz#32737088e7d943fb3e22140e64bb634e0ba05fcf" - integrity sha512-sg/nR8ILEdUl+2sWu6jc1nQ5s04yucGlH1RVfatW8TSJ5uG3Yy3vgigi8NNC/BuhcncUNPWqSpTCSI1hA+rhiw== +"@formatjs/icu-skeleton-parser@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.1.tgz#3647f41b82e362c08bb80bd9b653c7eb6ff31118" + integrity sha512-/LQ6ovxYd8FQjVLmbV+WmuFy86o+JTc0cIQuWixuLuUMfRRif8eUQw3vPK5hx7C/g1UVmKAaOcYRTEsvyEGz9g== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/intl-localematcher" "0.4.0" + "@formatjs/ecma402-abstract" "1.17.1" tslib "^2.4.0" -"@formatjs/intl-listformat@7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.4.0.tgz#fa8ac535d82fc716f052f2fd60eeaa7331362357" - integrity sha512-ifupb+balZUAF/Oh3QyGRqPRWGSKwWoMPR0cYZEG7r61SimD+m38oFQqVx/3Fp7LfQFF11m7IS+MlxOo2sKINA== +"@formatjs/icu-skeleton-parser@1.6.2": + version "1.6.2" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.2.tgz#00303034dc08583973c8aa67b96534c49c0bad8d" + integrity sha512-VtB9Slo4ZL6QgtDFJ8Injvscf0xiDd4bIV93SOJTBjUF4xe2nAWOoSjLEtqIG+hlIs1sNrVKAaFo3nuTI4r5ZA== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/intl-localematcher" "0.4.0" + "@formatjs/ecma402-abstract" "1.17.2" tslib "^2.4.0" -"@formatjs/intl-localematcher@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.0.tgz#63bbc37a7c3545a1bf1686072e51d9a3aed98d6b" - integrity sha512-bRTd+rKomvfdS4QDlVJ6TA/Jx1F2h/TBVO5LjvhQ7QPPHp19oPNMIum7W2CMEReq/zPxpmCeB31F9+5gl/qtvw== +"@formatjs/intl-displaynames@6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.5.1.tgz#d25d260b81845abf6f35a13dbc87c25b0ec22a33" + integrity sha512-BD+coSUka8fppErGnXbWthd6YxTXdCGvQzGR/rSEdPgiZO5sh+0gVLjp0FgXi6cOf9C2z2axqhGifFsqyTVhkw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.1" + "@formatjs/intl-localematcher" "0.4.1" + tslib "^2.4.0" + +"@formatjs/intl-listformat@7.4.1": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.4.1.tgz#cb6f1399a41b9fd568cc4b4b80fc815d0c5b37ab" + integrity sha512-mWd30ndvYw8JydOIVb5Y1ElK2iwsaDY+ajPR5aWWgEZaH04aL+4hzX/8VXPsilu7CF3DN1IP5ZSwJuj7ZyBIHw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.1" + "@formatjs/intl-localematcher" "0.4.1" + tslib "^2.4.0" + +"@formatjs/intl-localematcher@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.1.tgz#af63e2c065731a33f6fed36dc85058009a7f8062" + integrity sha512-Fs4MhhHlLC0RrspX2u2KP7zlwL9eHrBZsOBxaPOeqrCZYLaOUK4cYXQ1ErpAB0HnGV/GUXNa5smzV/7jCuRzxg== + dependencies: + tslib "^2.4.0" + +"@formatjs/intl-localematcher@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz#7e6e596dbaf2f0c5a7c22da5a01d5c55f4c37e9a" + integrity sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA== dependencies: tslib "^2.4.0" "@formatjs/intl-pluralrules@^5.2.2": - version "5.2.4" - resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.2.4.tgz#b417aa503186c2cbb4715f47114ed65211b4ada9" - integrity sha512-6meo376d8I4zikRFSUxATLnqzGwezmc57SmToP4z1/NQwTHXGe0yIG/ABPbO3QMx7IUkofH/ROP3A4DhtPTpnA== + version "5.2.5" + resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.2.5.tgz#72ff79bec4c3383a46e6b3d6b0af73534e544302" + integrity sha512-od9KJzKB5CF9Hfq3g6CJzWA0rW9yaNrF2hMZK3/26aTuZ4Fm3mPm/JI6QReF9qZSC1qkJyqS1GN0JtTm2sVyGQ== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/intl-localematcher" "0.4.0" + "@formatjs/ecma402-abstract" "1.17.1" + "@formatjs/intl-localematcher" "0.4.1" tslib "^2.4.0" -"@formatjs/intl@2.9.0": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.9.0.tgz#e1335572af3ca8a53e136a78e866f1851a9718c2" - integrity sha512-Ym0trUoC/VO6wQu4YHa0H1VR2tEixFRmwZgADkDLm7nD+vv1Ob+/88mUAoT0pwvirFqYKgUKEwp1tFepqyqvVA== +"@formatjs/intl@2.9.1": + version "2.9.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.9.1.tgz#f224109620b71f48c049bd42df770f202e4b6d29" + integrity sha512-NsDMke+lAiu+c6/9KXrp8aldd7sFeyxgQZqFUJSZIeaKrN+gEoYKqWgsiRa7/mxlWqWNJSGuNQnF1P2ChC/yaA== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/ecma402-abstract" "1.17.1" "@formatjs/fast-memoize" "2.2.0" - "@formatjs/icu-messageformat-parser" "2.6.0" - "@formatjs/intl-displaynames" "6.5.0" - "@formatjs/intl-listformat" "7.4.0" - intl-messageformat "10.5.0" + "@formatjs/icu-messageformat-parser" "2.6.1" + "@formatjs/intl-displaynames" "6.5.1" + "@formatjs/intl-listformat" "7.4.1" + intl-messageformat "10.5.1" tslib "^2.4.0" -"@formatjs/ts-transformer@3.13.3": - version "3.13.3" - resolved "https://registry.yarnpkg.com/@formatjs/ts-transformer/-/ts-transformer-3.13.3.tgz#249f5b5df70c51e651280732536d5504078297ff" - integrity sha512-W6+huH4dLYx8eZfZue6fcreNzLZHoPboreqJSkickYCKIOicI35zC0Txb4xCT6kau/DXAKTpNEln3V2NgX6Igg== +"@formatjs/ts-transformer@3.13.4": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@formatjs/ts-transformer/-/ts-transformer-3.13.4.tgz#586582ab3aee75b7e24d37f7090ab270062a9bf5" + integrity sha512-AOOHpHBJyjcNLkJcT82zeU7IlaogHI4qBjPlFgyeqcSbGwR4b+LGY7Frf7N5eM8Y9yGnTDVIUA/u3gHUA3SHQg== dependencies: - "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/icu-messageformat-parser" "2.6.1" + "@types/json-stable-stringify" "^1.0.32" + "@types/node" "14 || 16 || 17" + chalk "^4.0.0" + json-stable-stringify "^1.0.1" + tslib "^2.4.0" + typescript "^4.7 || 5" + +"@formatjs/ts-transformer@3.13.5": + version "3.13.5" + resolved "https://registry.yarnpkg.com/@formatjs/ts-transformer/-/ts-transformer-3.13.5.tgz#8b4f5dcb02940e3f12b9f6c95b47f52777a9969d" + integrity sha512-dh2mmZqkId0UeM+FQtmwugpMGvyzTBmXj5LjwD4M5OeSm62tcgkScjqeO/1EetaNS/JkTUBbsFBnHzaDzh3yOw== + dependencies: + "@formatjs/icu-messageformat-parser" "2.6.2" "@types/json-stable-stringify" "^1.0.32" "@types/node" "14 || 16 || 17" chalk "^4.0.0" @@ -1454,10 +1483,10 @@ resolved "https://registry.yarnpkg.com/@github/webauthn-json/-/webauthn-json-2.1.1.tgz#648e63fc28050917d2882cc2b27817a88cb420fc" integrity sha512-XrftRn4z75SnaJOmZQbt7Mk+IIjqVHw+glDGOxuHwXkZBZh/MBoRS7MHjSZMDaLhT4RjN2VqiEU7EOYleuJWSQ== -"@humanwhocodes/config-array@^0.11.10": - version "0.11.10" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== +"@humanwhocodes/config-array@^0.11.11": + version "0.11.11" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844" + integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -1725,7 +1754,7 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== @@ -1739,9 +1768,9 @@ "@jridgewell/sourcemap-codec" "^1.4.14" "@material-design-icons/svg@^0.14.10": - version "0.14.11" - resolved "https://registry.yarnpkg.com/@material-design-icons/svg/-/svg-0.14.11.tgz#f90a2c8de801523c3b17e606c89313121c8bb3b4" - integrity sha512-jpAksWZIVLB5/qTAeqANns7pH/faIQR3jgV2yROUNKZkzpJ428h7e1/byJB+rFZNI0hgZpY9nOVMLhc1J41HtA== + version "0.14.12" + resolved "https://registry.yarnpkg.com/@material-design-icons/svg/-/svg-0.14.12.tgz#b3dd27b4c2a93e0310f51acfb311846b0212f987" + integrity sha512-hVEMICFvG26SKDXatPmz+vY5BAqLPCDiyXnw+KN46FXOtY4PcpeAfzFZvwt6D9ywNnVJd4EvmLdlWgLmtOWxbA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1822,6 +1851,17 @@ redux-thunk "^2.4.2" reselect "^4.1.8" +"@renchap/compression-webpack-plugin@^6.1.4": + version "6.1.4" + resolved "https://registry.yarnpkg.com/@renchap/compression-webpack-plugin/-/compression-webpack-plugin-6.1.4.tgz#5ff528ae9edf83de7447b72f5b52a05f860bb899" + integrity sha512-Ij43bj/jhKiMKOZVT9b3DJvr4R+dNs9ZbH7QV3kLfloavt4GhNo4Jw86tVwmP5d+seZtSwTL1NG8/c6dM1V0vw== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + webpack-sources "^1.4.3" + "@restart/hooks@^0.4.7": version "0.4.9" resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.9.tgz#ad858fb39d99e252cccce19416adc18fc3f18fcb" @@ -2118,9 +2158,9 @@ integrity sha512-gaBLT8pdcexFztLSPRtriHeXY/Kn4907uOCZ4Q3lncFBkheAWOuNt53ypsF8szgxbEJ513UeBzcf4utN0EzEwA== "@types/eslint@7 || 8": - version "8.40.2" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.40.2.tgz#2833bc112d809677864a4b0e7d1de4f04d7dac2d" - integrity sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ== + version "8.44.2" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.2.tgz#0d21c505f98a89b8dd4d37fa162b09da6089199a" + integrity sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -2252,9 +2292,9 @@ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/lodash@^4.14.195": - version "4.14.197" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.197.tgz#e95c5ddcc814ec3e84c891910a01e0c8a378c54b" - integrity sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g== + version "4.14.198" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.198.tgz#4d27465257011aedc741a809f1269941fa2c5d4c" + integrity sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg== "@types/mime@*": version "3.0.1" @@ -2277,9 +2317,9 @@ integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "20.5.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.9.tgz#a70ec9d8fa0180a314c3ede0e20ea56ff71aed9a" - integrity sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ== + version "20.6.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.0.tgz#9d7daa855d33d4efec8aea88cd66db1c2f0ebe16" + integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg== "@types/node@14 || 16 || 17": version "17.0.45" @@ -2489,9 +2529,9 @@ integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== "@types/semver@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + version "7.5.1" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367" + integrity sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg== "@types/send@*": version "0.17.1" @@ -2590,15 +2630,15 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^6.0.0": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.1.tgz#bc0c6f000134b53c304ad0bec4ee4753cd3e89d2" - integrity sha512-3F5PtBzUW0dYlq77Lcqo13fv+58KDwUib3BddilE8ajPJT+faGgxmI9Sw+I8ZS22BYwoir9ZhNXcLi+S+I2bkw== + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz#19ba09aa34fd504696445100262e5a9e1b1d7024" + integrity sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.4.1" - "@typescript-eslint/type-utils" "6.4.1" - "@typescript-eslint/utils" "6.4.1" - "@typescript-eslint/visitor-keys" "6.4.1" + "@typescript-eslint/scope-manager" "6.6.0" + "@typescript-eslint/type-utils" "6.6.0" + "@typescript-eslint/utils" "6.6.0" + "@typescript-eslint/visitor-keys" "6.6.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -2607,97 +2647,97 @@ ts-api-utils "^1.0.1" "@typescript-eslint/parser@^6.0.0": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.4.1.tgz#85ad550bf4ac4aa227504f1becb828f8e46c44e3" - integrity sha512-610G6KHymg9V7EqOaNBMtD1GgpAmGROsmfHJPXNLCU9bfIuLrkdOygltK784F6Crboyd5tBFayPB7Sf0McrQwg== + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.6.0.tgz#fe323a7b4eafb6d5ea82b96216561810394a739e" + integrity sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w== dependencies: - "@typescript-eslint/scope-manager" "6.4.1" - "@typescript-eslint/types" "6.4.1" - "@typescript-eslint/typescript-estree" "6.4.1" - "@typescript-eslint/visitor-keys" "6.4.1" + "@typescript-eslint/scope-manager" "6.6.0" + "@typescript-eslint/types" "6.6.0" + "@typescript-eslint/typescript-estree" "6.6.0" + "@typescript-eslint/visitor-keys" "6.6.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.4.1": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz#4b073a30be2dbe603e44e9ae0cff7e1d3ed19278" - integrity sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A== +"@typescript-eslint/scope-manager@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz#57105d4419d6de971f7d2c30a2ff4ac40003f61a" + integrity sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw== dependencies: - "@typescript-eslint/types" "6.4.1" - "@typescript-eslint/visitor-keys" "6.4.1" + "@typescript-eslint/types" "6.6.0" + "@typescript-eslint/visitor-keys" "6.6.0" -"@typescript-eslint/type-utils@6.4.1": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.4.1.tgz#fa21cb13016c8d6f352fe9b2d6c9ab6edc2d1857" - integrity sha512-7ON8M8NXh73SGZ5XvIqWHjgX2f+vvaOarNliGhjrJnv1vdjG0LVIz+ToYfPirOoBi56jxAKLfsLm40+RvxVVXA== +"@typescript-eslint/type-utils@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz#14f651d13b884915c4fca0d27adeb652a4499e86" + integrity sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg== dependencies: - "@typescript-eslint/typescript-estree" "6.4.1" - "@typescript-eslint/utils" "6.4.1" + "@typescript-eslint/typescript-estree" "6.6.0" + "@typescript-eslint/utils" "6.6.0" debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@5.59.0": - version "5.59.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.0.tgz#3fcdac7dbf923ec5251545acdd9f1d42d7c4fe32" - integrity sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/types@6.4.1": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.4.1.tgz#b2c61159f46dda210fed9f117f5d027f65bb5c3b" - integrity sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg== +"@typescript-eslint/types@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.6.0.tgz#95e7ea650a2b28bc5af5ea8907114a48f54618c2" + integrity sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg== -"@typescript-eslint/typescript-estree@5.59.0": - version "5.59.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz#8869156ee1dcfc5a95be3ed0e2809969ea28e965" - integrity sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg== +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: - "@typescript-eslint/types" "5.59.0" - "@typescript-eslint/visitor-keys" "5.59.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@6.4.1": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz#91ff88101c710adb0f70a317f2f65efa9441da45" - integrity sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg== +"@typescript-eslint/typescript-estree@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz#373c420d2e12c28220f4a83352280a04823a91b7" + integrity sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA== dependencies: - "@typescript-eslint/types" "6.4.1" - "@typescript-eslint/visitor-keys" "6.4.1" + "@typescript-eslint/types" "6.6.0" + "@typescript-eslint/visitor-keys" "6.6.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.4.1": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.4.1.tgz#81bf62ff0c3119a26c19fab683582e29450717bc" - integrity sha512-F/6r2RieNeorU0zhqZNv89s9bDZSovv3bZQpUNOmmQK1L80/cV4KEu95YUJWi75u5PhboFoKUJBnZ4FQcoqhDw== +"@typescript-eslint/utils@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.6.0.tgz#2d686c0f0786da6362d909e27a9de1c13ba2e7dc" + integrity sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.4.1" - "@typescript-eslint/types" "6.4.1" - "@typescript-eslint/typescript-estree" "6.4.1" + "@typescript-eslint/scope-manager" "6.6.0" + "@typescript-eslint/types" "6.6.0" + "@typescript-eslint/typescript-estree" "6.6.0" semver "^7.5.4" -"@typescript-eslint/visitor-keys@5.59.0": - version "5.59.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz#a59913f2bf0baeb61b5cfcb6135d3926c3854365" - integrity sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA== +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: - "@typescript-eslint/types" "5.59.0" + "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@6.4.1": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz#e3ccf7b8d42e625946ac5094ed92a405fb4115e0" - integrity sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ== +"@typescript-eslint/visitor-keys@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz#1109088b4346c8b2446f3845db526374d9a3bafc" + integrity sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ== dependencies: - "@typescript-eslint/types" "6.4.1" + "@typescript-eslint/types" "6.6.0" eslint-visitor-keys "^3.4.1" "@webassemblyjs/ast@1.9.0": @@ -3373,17 +3413,17 @@ babel-loader@^8.3.0: schema-utils "^2.6.5" babel-plugin-formatjs@^10.5.1: - version "10.5.3" - resolved "https://registry.yarnpkg.com/babel-plugin-formatjs/-/babel-plugin-formatjs-10.5.3.tgz#718e47f4f3aad663ad4f901274aedd7be0a86380" - integrity sha512-PBeryWyN2HY2VUGNFPQS6+DPNQ/I9zDZ97y38i1+LzIpIyTHBePECq/ehEABE73PvvF2irFiN7TCYBrQQw5+lA== + version "10.5.4" + resolved "https://registry.yarnpkg.com/babel-plugin-formatjs/-/babel-plugin-formatjs-10.5.4.tgz#98837caedcdb64f118048f19e59ad0c94f55b5aa" + integrity sha512-6JSpDS/YVjMu74NzHkuEduWqDsmUbUm1qc6sNeccgknixW9Z3hbQqv3Fvfjrh4opBzJ+CRaAZaUlQQL+xDTQzw== dependencies: "@babel/core" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-jsx" "7" "@babel/traverse" "7" "@babel/types" "^7.12.11" - "@formatjs/icu-messageformat-parser" "2.6.0" - "@formatjs/ts-transformer" "3.13.3" + "@formatjs/icu-messageformat-parser" "2.6.1" + "@formatjs/ts-transformer" "3.13.4" "@types/babel__core" "^7.1.7" "@types/babel__helper-plugin-utils" "^7.10.0" "@types/babel__traverse" "^7.1.7" @@ -3922,9 +3962,9 @@ caniuse-lite@^1.0.30001502: integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== caniuse-lite@^1.0.30001517: - version "1.0.30001525" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz#d2e8fdec6116ffa36284ca2c33ef6d53612fe1c8" - integrity sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q== + version "1.0.30001528" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001528.tgz#479972fc705b996f1114336c0032418a215fd0aa" + integrity sha512-0Db4yyjR9QMNlsxh+kKWzQtkyflkG/snYheSzkjmvdEtEXB1+jt7A2HmSEiO6XIJPIbo92lHNGNySvE5pZcs5Q== caniuse-lite@^1.0.30001520: version "1.0.30001520" @@ -4238,17 +4278,6 @@ compressible@~2.0.16: dependencies: mime-db ">= 1.43.0 < 2" -compression-webpack-plugin@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-6.1.1.tgz#ae8e4b2ffdb7396bb776e66918d751a20d8ccf0e" - integrity sha512-BEHft9M6lwOqVIQFMS/YJGmeCYXVOakC5KzQk05TFpMBlODByh1qNsZCWjUBxCQhUP9x0WfGidxTbGkjbWO/TQ== - dependencies: - cacache "^15.0.5" - find-cache-dir "^3.3.1" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - webpack-sources "^1.4.3" - compression@^1.7.4: version "1.7.4" resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" @@ -4337,9 +4366,9 @@ core-js@^2.5.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.30.2: - version "3.32.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.32.1.tgz#a7d8736a3ed9dd05940c3c4ff32c591bb735be77" - integrity sha512-lqufgNn9NLnESg5mQeYsxQP5w7wrViSj0jr/kv6ECQiByzQkrn1MKvV0L3acttpDqfQrHLwr2KCMgX5b8X+lyQ== + version "3.32.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.32.2.tgz#172fb5949ef468f93b4be7841af6ab1f21992db7" + integrity sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ== core-util-is@~1.0.0: version "1.0.3" @@ -5080,9 +5109,9 @@ electron-to-chromium@^1.4.428: integrity sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA== electron-to-chromium@^1.4.477: - version "1.4.508" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.508.tgz#5641ff2f5ba11df4bd960fe6a2f9f70aa8b9af96" - integrity sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg== + version "1.4.510" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.510.tgz#446c50d7533c1e71a84b00a3b37ab06dd601d890" + integrity sha512-xPfLIPFcN/WLXBpQ/K4UgE98oUBO5Tia6BD4rkSR0wE7ep/PwBVlgvPJQrIBpmJGVAmUzwPKuDbVt9XV6+uC2g== elliptic@^6.5.3: version "6.5.4" @@ -5377,19 +5406,19 @@ eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: debug "^3.2.7" eslint-plugin-formatjs@^4.10.1: - version "4.10.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.10.3.tgz#65882730aebee3c8b6eec06381a4b0a18c0d33bd" - integrity sha512-EHKuEMCmWhAiMdCc8oZU8qBAvnvHPUiJuhGxPqA+GX2Nb7GBsGm2o616KYnSSffDisK+v0E9TDCrS8oJ0QLgcw== + version "4.10.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.10.5.tgz#3b38ce5da1f8e9d135298df777cf87115e4d0818" + integrity sha512-pBPA4idiYHXPQMrIb9/Le+D0snlNa7MFQsw12yIzyva/z9uz0u/4NOK3NkfyENMBNMeTX2tZXtugk9FyqM5SRw== dependencies: - "@formatjs/icu-messageformat-parser" "2.6.0" - "@formatjs/ts-transformer" "3.13.3" + "@formatjs/icu-messageformat-parser" "2.6.2" + "@formatjs/ts-transformer" "3.13.5" "@types/eslint" "7 || 8" "@types/picomatch" "^2.3.0" - "@typescript-eslint/typescript-estree" "5.59.0" + "@typescript-eslint/typescript-estree" "5.62.0" emoji-regex "^10.2.1" magic-string "^0.30.0" picomatch "^2.3.1" - tslib "2.5.0" + tslib "2.6.0" typescript "^4.7 || 5" unicode-emoji-utils "^1.1.1" @@ -5417,9 +5446,9 @@ eslint-plugin-import@~2.28.0: tsconfig-paths "^3.14.2" eslint-plugin-jsdoc@^46.1.0: - version "46.5.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.5.0.tgz#02e7945701a01fab76e7ced850d4d1eea63c23c0" - integrity sha512-aulXdA4I1dyWpzyS1Nh/GNoS6PavzeucxEapnMR4JUERowWvaEk2Y4A5irpHAcdXtBBHLVe8WIhdXNjoAlGQgA== + version "46.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.6.0.tgz#513e41911a3081a15fe6a94490002e8d8f7b71d9" + integrity sha512-T/1gzsvnX45qABzyPEonEhFDttkTn7Igm/X89TXIkTLBOsNl2GYtyBqQPZGXZZ8J5VBzEhiCMvI2P2kXX4dnFw== dependencies: "@es-joy/jsdoccomment" "~0.40.1" are-docs-informative "^0.0.2" @@ -5515,15 +5544,15 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.41.0: - version "8.48.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.48.0.tgz#bf9998ba520063907ba7bfe4c480dc8be03c2155" - integrity sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg== + version "8.49.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.49.0.tgz#09d80a89bdb4edee2efcf6964623af1054bf6d42" + integrity sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.48.0" - "@humanwhocodes/config-array" "^0.11.10" + "@eslint/js" "8.49.0" + "@humanwhocodes/config-array" "^0.11.11" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" ajv "^6.12.4" @@ -6813,14 +6842,14 @@ intersection-observer@^0.12.0: resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.12.2.tgz#4a45349cc0cd91916682b1f44c28d7ec737dc375" integrity sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg== -intl-messageformat@10.5.0, intl-messageformat@^10.3.5: - version "10.5.0" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.0.tgz#86d11b15913ac954075b25253f5e669359f89538" - integrity sha512-AvojYuOaRb6r2veOKfTVpxH9TrmjSdc5iR9R5RgBwrDZYSmAAFVT+QLbW3C4V7Qsg0OguMp67Q/EoUkxZzXRGw== +intl-messageformat@10.5.1, intl-messageformat@^10.3.5: + version "10.5.1" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.1.tgz#40304cbde01c8cb2236e11ac8c827642bed474d0" + integrity sha512-irEmjxHq0f1MHviQr3Q4ToF9EgYbnXDq2/R9MRTTveGKHgy6VZ29hQxswu4trqWaX7T6njKxSoKVG92OSz0U5Q== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/ecma402-abstract" "1.17.1" "@formatjs/fast-memoize" "2.2.0" - "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/icu-messageformat-parser" "2.6.1" tslib "^2.4.0" invariant@^2.2.2, invariant@^2.2.4: @@ -8264,11 +8293,11 @@ magic-string@^0.25.0, magic-string@^0.25.7: sourcemap-codec "^1.4.8" magic-string@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.0.tgz#fd58a4748c5c4547338a424e90fa5dd17f4de529" - integrity sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ== + version "0.30.3" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.3.tgz#403755dfd9d6b398dfa40635d52e96c5ac095b85" + integrity sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw== dependencies: - "@jridgewell/sourcemap-codec" "^1.4.13" + "@jridgewell/sourcemap-codec" "^1.4.15" make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" @@ -10006,19 +10035,19 @@ react-immutable-pure-component@^2.2.2: integrity sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A== react-intl@^6.4.2: - version "6.4.4" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.4.4.tgz#14b45ce046bfbb60c0e6d392d8ddc30e9ead5a4f" - integrity sha512-/C9Sl/5//ohfkNG6AWlJuf4BhTXsbzyk93K62A4zRhSPANyOGpKZ+fWhN+TLfFd5YjDUHy+exU/09y0w1bO4Xw== + version "6.4.5" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.4.5.tgz#d8f61fce2fb3be08ef58deb35d96b964e1ef013a" + integrity sha512-nUO2W57Tmdu6ErhsOFpsgkEtfQ4Lo7hPrXn8gGJQx59NRC0FNUxRc6+Ah3G8j6vqBiYRmxsLJpVZtIhLZjhYLA== dependencies: - "@formatjs/ecma402-abstract" "1.17.0" - "@formatjs/icu-messageformat-parser" "2.6.0" - "@formatjs/intl" "2.9.0" - "@formatjs/intl-displaynames" "6.5.0" - "@formatjs/intl-listformat" "7.4.0" + "@formatjs/ecma402-abstract" "1.17.1" + "@formatjs/icu-messageformat-parser" "2.6.1" + "@formatjs/intl" "2.9.1" + "@formatjs/intl-displaynames" "6.5.1" + "@formatjs/intl-listformat" "7.4.1" "@types/hoist-non-react-statics" "^3.3.1" "@types/react" "16 || 17 || 18" hoist-non-react-statics "^3.3.2" - intl-messageformat "10.5.0" + intl-messageformat "10.5.1" tslib "^2.4.0" "react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0: @@ -10797,14 +10826,14 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.7: +semver@^7.3.2: version "7.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== dependencies: lru-cache "^6.0.0" -semver@^7.3.4, semver@^7.3.5, semver@^7.5.3, semver@^7.5.4: +semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -11405,7 +11434,6 @@ stringz@^2.1.0: char-regex "^1.0.2" "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - name strip-ansi-cjs version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11949,9 +11977,9 @@ trim-newlines@^4.0.2: integrity sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ== ts-api-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.2.tgz#7c094f753b6705ee4faee25c3c684ade52d66d99" - integrity sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ== + version "1.0.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== tsconfig-paths@^3.14.2: version "3.14.2" @@ -11963,10 +11991,10 @@ tsconfig-paths@^3.14.2: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== tslib@^1.8.1: version "1.14.1" @@ -11978,7 +12006,12 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== -tslib@^2.4.0, tslib@^2.5.0: +tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tslib@^2.5.0: version "2.5.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== @@ -12089,12 +12122,7 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -"typescript@^4.7 || 5": - version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" - integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== - -typescript@^5.0.4: +"typescript@^4.7 || 5", typescript@^5.0.4: version "5.2.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== @@ -12571,7 +12599,7 @@ webpack-sources@^1.0, webpack-sources@^1.1.0, webpack-sources@^1.4.1, webpack-so source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.46.0: +webpack@^4.47.0: version "4.47.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.47.0.tgz#8b8a02152d7076aeb03b61b47dad2eeed9810ebc" integrity sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ== @@ -12985,9 +13013,9 @@ ws@^7.3.1: integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== ws@^8.11.0, ws@^8.12.1, ws@^8.13.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + version "8.14.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.1.tgz#4b9586b4f70f9e6534c7bb1d3dc0baa8b8cf01e0" + integrity sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A== xml-name-validator@^4.0.0: version "4.0.0"