diff --git a/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/InitialDataController.kt b/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/InitialDataController.kt index 74aa31efb9..7922c402d1 100644 --- a/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/InitialDataController.kt +++ b/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/InitialDataController.kt @@ -6,6 +6,7 @@ import io.tolgee.api.EeSubscriptionProvider import io.tolgee.component.PreferredOrganizationFacade import io.tolgee.hateoas.InitialDataModel import io.tolgee.hateoas.ee.IEeSubscriptionModelAssembler +import io.tolgee.notifications.UserNotificationService import io.tolgee.openApiDocs.OpenApiHideFromPublicDocs import io.tolgee.security.authentication.AuthenticationFacade import io.tolgee.service.security.UserPreferencesService @@ -32,6 +33,7 @@ class InitialDataController( private val eeSubscriptionModelAssembler: IEeSubscriptionModelAssembler, private val eeSubscriptionProvider: EeSubscriptionProvider, private val announcementController: AnnouncementController, + private val userNotificationService: UserNotificationService, ) : IController { @GetMapping(value = [""]) @Operation(summary = "Get initial data", description = "Returns initial data required by the UI to load") @@ -53,6 +55,7 @@ class InitialDataController( data.preferredOrganization = preferredOrganizationFacade.getPreferred() data.languageTag = userPreferencesService.find(userAccount.id)?.language data.announcement = announcementController.getLatest() + data.unreadNotifications = userNotificationService.getUnreadNotificationsCount(userAccount.id) } return data diff --git a/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/notifications/NotificationPreferencesController.kt b/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/notifications/NotificationPreferencesController.kt new file mode 100644 index 0000000000..53c75fe6ff --- /dev/null +++ b/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/notifications/NotificationPreferencesController.kt @@ -0,0 +1,128 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.api.v2.controllers.notifications + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import io.tolgee.notifications.NotificationPreferencesService +import io.tolgee.notifications.dto.NotificationPreferencesDto +import io.tolgee.security.authentication.AuthenticationFacade +import org.springframework.http.HttpHeaders +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.validation.annotation.Validated +import org.springframework.web.bind.annotation.DeleteMapping +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping(value = ["/v2/notifications/preferences"]) +@Tag(name = "Notification preferences") +class NotificationPreferencesController( + private val authenticationFacade: AuthenticationFacade, + private val notificationPreferencesService: NotificationPreferencesService, +) { + @GetMapping("") + @Operation(summary = "Fetch the global preferences and all overrides of the current user") + fun getAllPreferences(): Map { + return notificationPreferencesService.getAllPreferences(authenticationFacade.authenticatedUser.id) + } + + @GetMapping("/global") + @Operation(summary = "Fetch the global preferences for the current user") + fun getGlobalPreferences(): NotificationPreferencesDto { + return notificationPreferencesService.getGlobalPreferences(authenticationFacade.authenticatedUser.id) + } + + @PutMapping("/global") + @Operation(summary = "Update the global notification preferences of the current user") + fun updateGlobalPreferences( + @RequestBody @Validated preferencesDto: NotificationPreferencesDto, + ): NotificationPreferencesDto { + val updated = + notificationPreferencesService.setPreferencesOfUser( + authenticationFacade.authenticatedUser.id, + preferencesDto, + ) + + return NotificationPreferencesDto.fromEntity(updated) + } + + @GetMapping("/project/{id}") + @Operation(summary = "Fetch the notification preferences of the current user for a specific project") + fun getPerProjectPreferences( + @PathVariable("id") id: Long, + ): NotificationPreferencesDto { + return notificationPreferencesService.getProjectPreferences( + authenticationFacade.authenticatedUser.id, + id, + ) + } + + @PutMapping("/project/{id}") + @Operation(summary = "Update the notification preferences of the current user for a specific project") + fun updatePerProjectPreferences( + @PathVariable("id") id: Long, + @RequestBody @Validated preferencesDto: NotificationPreferencesDto, + ): NotificationPreferencesDto { + val updated = + notificationPreferencesService.setProjectPreferencesOfUser( + authenticationFacade.authenticatedUser.id, + id, + preferencesDto, + ) + + return NotificationPreferencesDto.fromEntity(updated) + } + + @DeleteMapping("/project/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Delete the notification preferences of the current user for a specific project") + fun deletePerProjectPreferences( + @PathVariable("id") id: Long, + ) { + notificationPreferencesService.deleteProjectPreferencesOfUser( + authenticationFacade.authenticatedUser.id, + id, + ) + } + + @PostMapping("/project/{id}/subscribe") + @Operation(summary = "Subscribe to notifications for a given project") + fun subscribeToProject( + @PathVariable("id") id: Long, + ): ResponseEntity { + return ResponseEntity( + "Coming soon! Please see https://github.com/tolgee/tolgee-platform/issues/1360 for progress on this. :D", + HttpHeaders().also { + @Suppress("UastIncorrectHttpHeaderInspection") + it.add( + "x-hey-curious-reader", + "oh hey there, didn't expect you here... " + + "if you're here, might as well join us! https://tolgee.io/career", + ) + }, + HttpStatus.NOT_IMPLEMENTED, + ) + } +} diff --git a/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/notifications/NotificationsController.kt b/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/notifications/NotificationsController.kt new file mode 100644 index 0000000000..426f651835 --- /dev/null +++ b/backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/notifications/NotificationsController.kt @@ -0,0 +1,122 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.api.v2.controllers.notifications + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import io.tolgee.hateoas.notifications.UserNotificationModel +import io.tolgee.hateoas.notifications.UserNotificationModelAssembler +import io.tolgee.notifications.NotificationStatus +import io.tolgee.notifications.UserNotificationService +import io.tolgee.security.authentication.AuthenticationFacade +import org.springdoc.core.annotations.ParameterObject +import org.springframework.data.domain.Pageable +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping(value = ["/v2/notifications"]) +@Tag(name = "Notifications") +class NotificationsController( + private val authenticationFacade: AuthenticationFacade, + private val userNotificationService: UserNotificationService, + private val userNotificationModelAssembler: UserNotificationModelAssembler, +) { + @GetMapping("") + @Operation(summary = "Fetch the current user's notifications") + fun getNotifications( + @RequestParam("status", defaultValue = "UNREAD,READ") status: Set, + @ParameterObject pageable: Pageable, + ): List { + val notifications = + userNotificationService.findNotificationsOfUserFilteredPaged( + authenticationFacade.authenticatedUser.id, + status, + pageable, + ) + + return notifications.map { userNotificationModelAssembler.toModel(it) } + } + + @PostMapping("/mark-as-read") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Marks a given set of notifications as read.") + fun markNotificationsAsRead( + @RequestBody notifications: List, + ) { + userNotificationService.markAsRead( + authenticationFacade.authenticatedUser.id, + notifications, + ) + } + + @PostMapping("/mark-as-read/all") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Marks all notifications as read.") + fun markAllNotificationsAsRead() { + userNotificationService.markAllAsRead(authenticationFacade.authenticatedUser.id) + } + + @PostMapping("/mark-as-unread") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Marks a given set of notifications as unread.") + fun markNotificationsAsUnread( + @RequestBody notifications: List, + ) { + userNotificationService.markAsUnread( + authenticationFacade.authenticatedUser.id, + notifications, + ) + } + + @PostMapping("/mark-as-done") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Marks a given set of notifications as done.") + fun markNotificationsAsDone( + @RequestBody notifications: List, + ) { + userNotificationService.markAsDone( + authenticationFacade.authenticatedUser.id, + notifications, + ) + } + + @PostMapping("/mark-as-done/all") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Marks all notifications as done.") + fun markAllNotificationsAsDone() { + userNotificationService.markAllAsDone(authenticationFacade.authenticatedUser.id) + } + + @PostMapping("/unmark-as-done") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "Un-marks a given set of notifications as done.") + fun unmarkNotificationsAsDone( + @RequestBody notifications: Collection, + ) { + userNotificationService.unmarkAsDone( + authenticationFacade.authenticatedUser.id, + notifications, + ) + } +} diff --git a/backend/api/src/main/kotlin/io/tolgee/hateoas/InitialDataModel.kt b/backend/api/src/main/kotlin/io/tolgee/hateoas/InitialDataModel.kt index 42af2c8457..84db86ef53 100644 --- a/backend/api/src/main/kotlin/io/tolgee/hateoas/InitialDataModel.kt +++ b/backend/api/src/main/kotlin/io/tolgee/hateoas/InitialDataModel.kt @@ -6,11 +6,13 @@ import io.tolgee.hateoas.ee.eeSubscription.EeSubscriptionModel import io.tolgee.hateoas.organization.PrivateOrganizationModel import io.tolgee.hateoas.userAccount.PrivateUserAccountModel -class InitialDataModel( +@Suppress("unused") +data class InitialDataModel( val serverConfiguration: PublicConfigurationDTO, var userInfo: PrivateUserAccountModel? = null, var preferredOrganization: PrivateOrganizationModel? = null, var languageTag: String? = null, val eeSubscription: EeSubscriptionModel? = null, var announcement: AnnouncementDto? = null, + var unreadNotifications: Int? = null, ) diff --git a/backend/api/src/main/kotlin/io/tolgee/hateoas/notifications/UserNotificationModel.kt b/backend/api/src/main/kotlin/io/tolgee/hateoas/notifications/UserNotificationModel.kt new file mode 100644 index 0000000000..141050165e --- /dev/null +++ b/backend/api/src/main/kotlin/io/tolgee/hateoas/notifications/UserNotificationModel.kt @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.hateoas.notifications + +import io.tolgee.hateoas.batch.BatchJobModel +import io.tolgee.hateoas.project.SimpleProjectModel +import io.tolgee.model.views.activity.SimpleModifiedEntityView +import io.tolgee.notifications.NotificationType +import org.springframework.hateoas.RepresentationModel +import java.io.Serializable +import java.util.* + +@Suppress("unused") +class UserNotificationModel( + val id: Long, + val type: NotificationType, + val project: SimpleProjectModel?, + val batchJob: BatchJobModel?, + val modifiedEntities: List?, + val unread: Boolean, + val markedDoneAt: Date?, + val lastUpdated: Date, +) : RepresentationModel(), Serializable diff --git a/backend/api/src/main/kotlin/io/tolgee/hateoas/notifications/UserNotificationModelAssembler.kt b/backend/api/src/main/kotlin/io/tolgee/hateoas/notifications/UserNotificationModelAssembler.kt new file mode 100644 index 0000000000..1502f11f10 --- /dev/null +++ b/backend/api/src/main/kotlin/io/tolgee/hateoas/notifications/UserNotificationModelAssembler.kt @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.hateoas.notifications + +import io.tolgee.activity.views.ModifiedEntitiesViewProvider +import io.tolgee.api.v2.controllers.notifications.NotificationsController +import io.tolgee.batch.BatchJobService +import io.tolgee.hateoas.batch.BatchJobModelAssembler +import io.tolgee.hateoas.project.SimpleProjectModelAssembler +import io.tolgee.model.activity.ActivityModifiedEntity +import io.tolgee.model.notifications.UserNotification +import io.tolgee.model.views.activity.SimpleModifiedEntityView +import org.springframework.context.ApplicationContext +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport +import org.springframework.stereotype.Component + +@Component +class UserNotificationModelAssembler( + private val batchJobService: BatchJobService, + private val simpleProjectModelAssembler: SimpleProjectModelAssembler, + private val batchJobModelAssembler: BatchJobModelAssembler, + private val applicationContext: ApplicationContext, +) : RepresentationModelAssemblerSupport( + NotificationsController::class.java, + UserNotificationModel::class.java, + ) { + override fun toModel(entity: UserNotification): UserNotificationModel { + val project = entity.project?.let { simpleProjectModelAssembler.toModel(it) } + val modifiedEntities = assembleEntityChanges(entity.modifiedEntities).ifEmpty { null } + val batchJob = + entity.batchJob?.let { + val view = batchJobService.getView(it) + batchJobModelAssembler.toModel(view) + } + + return UserNotificationModel( + id = entity.id, + type = entity.type, + project = project, + batchJob = batchJob, + modifiedEntities = modifiedEntities, + unread = entity.unread, + markedDoneAt = entity.markedDoneAt, + lastUpdated = entity.lastUpdated, + ) + } + + private fun assembleEntityChanges(modifiedEntities: List): List { + val provider = + ModifiedEntitiesViewProvider( + applicationContext, + modifiedEntities, + ) + + return provider.getSimple() + } +} diff --git a/backend/api/src/main/kotlin/io/tolgee/websocket/ActivityWebsocketListener.kt b/backend/api/src/main/kotlin/io/tolgee/websocket/ActivityWebsocketListener.kt index 33a29574f0..ec9594ee1d 100644 --- a/backend/api/src/main/kotlin/io/tolgee/websocket/ActivityWebsocketListener.kt +++ b/backend/api/src/main/kotlin/io/tolgee/websocket/ActivityWebsocketListener.kt @@ -1,6 +1,6 @@ package io.tolgee.websocket -import io.tolgee.activity.projectActivityView.RelationDescriptionExtractor +import io.tolgee.activity.views.RelationDescriptionExtractor import io.tolgee.batch.OnBatchJobCompleted import io.tolgee.batch.WebsocketProgressInfo import io.tolgee.batch.events.OnBatchJobCancelled diff --git a/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresDockerRunner.kt b/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresDockerRunner.kt index 90470a780f..d4955d31cb 100644 --- a/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresDockerRunner.kt +++ b/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresDockerRunner.kt @@ -53,6 +53,7 @@ class PostgresDockerRunner( get() = instance?.containerExisted != true || postgresAutostartProperties.stop override val datasourceUrl by lazy { - "jdbc:postgresql://localhost:${postgresAutostartProperties.port}/${postgresAutostartProperties.databaseName}" + "jdbc:postgresql://localhost:${postgresAutostartProperties.port}/${postgresAutostartProperties.databaseName}" + + "?reWriteBatchedInserts=true" } } diff --git a/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresEmbeddedRunner.kt b/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresEmbeddedRunner.kt index 6638c97da3..81ddc1659b 100644 --- a/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresEmbeddedRunner.kt +++ b/backend/app/src/main/kotlin/io/tolgee/postgresRunners/PostgresEmbeddedRunner.kt @@ -86,7 +86,7 @@ class PostgresEmbeddedRunner( override val datasourceUrl by lazy { // It's not that easy to change port in embedded version, since there is no env prop for that - "jdbc:postgresql://localhost:$POSTGRES_PORT/${postgresAutostartProperties.databaseName}" + "jdbc:postgresql://localhost:$POSTGRES_PORT/${postgresAutostartProperties.databaseName}?reWriteBatchedInserts=true" } private fun isPostgresUp(): Boolean { diff --git a/backend/app/src/main/resources/application.yaml b/backend/app/src/main/resources/application.yaml index 2174f1b769..4ab12cc349 100644 --- a/backend/app/src/main/resources/application.yaml +++ b/backend/app/src/main/resources/application.yaml @@ -16,7 +16,8 @@ spring: order_by: default_null_ordering: first jdbc: - batch_size: 1000 + batch_size: 50 + batch_versioned_data: true order_inserts: true order_updates: true dialect: io.tolgee.dialects.postgres.CustomPostgreSQLDialect @@ -31,6 +32,8 @@ spring: enabled: false jdbc: initialize-schema: always + datasource: + auto-commit: false tolgee: authentication: enabled: false diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/V2UserControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/V2UserControllerTest.kt index 2011eef4bd..1998be3142 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/V2UserControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/V2UserControllerTest.kt @@ -16,6 +16,7 @@ import io.tolgee.testing.AuthorizedControllerTest import io.tolgee.testing.ContextRecreatingTest import io.tolgee.testing.assert import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.assertj.core.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -23,7 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.test.web.servlet.result.MockMvcResultMatchers -import java.util.* @ContextRecreatingTest @SpringBootTest( diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/contentDelivery/ContentDeliveryConfigControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/contentDelivery/ContentDeliveryConfigControllerTest.kt index 2ee31ba14a..773c80b510 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/contentDelivery/ContentDeliveryConfigControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/contentDelivery/ContentDeliveryConfigControllerTest.kt @@ -21,6 +21,7 @@ import io.tolgee.service.contentDelivery.ContentDeliveryConfigService import io.tolgee.testing.ContextRecreatingTest import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod import io.tolgee.testing.assert +import io.tolgee.testing.satisfies import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerInvitingTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerInvitingTest.kt index d188069a90..5c3e107ed5 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerInvitingTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerInvitingTest.kt @@ -17,6 +17,7 @@ import io.tolgee.model.enums.OrganizationRoleType import io.tolgee.testing.AuthorizedControllerTest import io.tolgee.testing.assertions.Assertions.assertThat import io.tolgee.testing.assertions.Assertions.assertThatThrownBy +import io.tolgee.testing.satisfies import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerTest.kt index 7ae6542fe2..c583d553be 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerTest.kt @@ -3,12 +3,22 @@ package io.tolgee.api.v2.controllers.organizationController import io.tolgee.development.testDataBuilder.data.OrganizationTestData import io.tolgee.dtos.request.organization.OrganizationDto import io.tolgee.dtos.request.organization.SetOrganizationRoleDto -import io.tolgee.fixtures.* +import io.tolgee.fixtures.andAssertError +import io.tolgee.fixtures.andAssertThatJson +import io.tolgee.fixtures.andIsBadRequest +import io.tolgee.fixtures.andIsCreated +import io.tolgee.fixtures.andIsForbidden +import io.tolgee.fixtures.andIsNotFound +import io.tolgee.fixtures.andIsOk +import io.tolgee.fixtures.andPrettyPrint +import io.tolgee.fixtures.isPermissionScopes +import io.tolgee.fixtures.node import io.tolgee.model.Organization import io.tolgee.model.enums.OrganizationRoleType import io.tolgee.model.enums.ProjectPermissionType import io.tolgee.testing.assert import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfiesIf import org.junit.jupiter.api.Test import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest @@ -171,7 +181,7 @@ class OrganizationControllerTest : BaseOrganizationControllerTest() { node("name").isEqualTo("Test org") node("slug").isEqualTo("test-org") node("_links.self.href").isEqualTo("http://localhost/v2/organizations/test-org") - node("id").isNumber.satisfies { + node("id").isNumber.satisfiesIf { organizationService.find(it.toLong()) is Organization } } diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerCursorTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerCursorTest.kt index ecfb0b8dab..f0d01db4c1 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerCursorTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerCursorTest.kt @@ -8,6 +8,7 @@ import io.tolgee.fixtures.andIsOk import io.tolgee.fixtures.andPrettyPrint import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerModificationTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerModificationTest.kt index 92d490c44d..654ba2e16f 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerModificationTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/translations/v2TranslationsController/TranslationsControllerModificationTest.kt @@ -17,6 +17,7 @@ import io.tolgee.testing.annotations.ProjectApiKeyAuthTestMethod import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod import io.tolgee.testing.assert import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/SecuredV2ImageUploadControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/SecuredV2ImageUploadControllerTest.kt index d27a75e50b..0f01a5071b 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/SecuredV2ImageUploadControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/SecuredV2ImageUploadControllerTest.kt @@ -4,18 +4,23 @@ package io.tolgee.api.v2.controllers.v2ImageUploadController -import io.tolgee.fixtures.* +import io.tolgee.fixtures.andAssertThatJson +import io.tolgee.fixtures.andIsCreated +import io.tolgee.fixtures.andIsNotFound +import io.tolgee.fixtures.andIsOk +import io.tolgee.fixtures.andIsUnauthorized +import io.tolgee.fixtures.andPrettyPrint import io.tolgee.security.authentication.JwtService import io.tolgee.testing.ContextRecreatingTest import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.assertj.core.data.Offset import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.springframework.boot.test.context.SpringBootTest import java.time.Duration -import java.util.* @TestInstance(TestInstance.Lifecycle.PER_CLASS) @ContextRecreatingTest diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/V2ImageUploadControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/V2ImageUploadControllerTest.kt index a9905114c0..e84850b669 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/V2ImageUploadControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ImageUploadController/V2ImageUploadControllerTest.kt @@ -13,6 +13,7 @@ import io.tolgee.fixtures.andIsOk import io.tolgee.fixtures.andPrettyPrint import io.tolgee.testing.assert import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.assertj.core.data.Offset import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeAll diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2KeyController/KeyControllerCreationTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2KeyController/KeyControllerCreationTest.kt index 3207ac7ddf..19fe9a3e0a 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2KeyController/KeyControllerCreationTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2KeyController/KeyControllerCreationTest.kt @@ -24,6 +24,7 @@ import io.tolgee.testing.annotations.ProjectApiKeyAuthTestMethod import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod import io.tolgee.testing.assert import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import io.tolgee.util.generateImage import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerCreateTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerCreateTest.kt index 5151156059..623f246814 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerCreateTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerCreateTest.kt @@ -11,6 +11,7 @@ import io.tolgee.fixtures.andIsOk import io.tolgee.fixtures.andPrettyPrint import io.tolgee.testing.AuthorizedControllerTest import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerInvitationTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerInvitationTest.kt index 4e59309d6a..ab006abcec 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerInvitationTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerInvitationTest.kt @@ -83,9 +83,12 @@ class ProjectsControllerInvitationTest : ProjectAuthControllerTest("/v2/projects type = ProjectPermissionType.TRANSLATE languages = setOf(getLang("en")) }.andIsOk - val invitation = invitationTestUtil.getInvitation(result) - invitation.permission?.translateLanguages!!.map { it.tag }.assert.contains("en") // stores - invitation.permission?.viewLanguages!!.map { it.tag }.assert.contains() // ads also to view + + executeInNewTransaction { + val invitation = invitationTestUtil.getInvitation(result) + invitation.permission?.translateLanguages!!.map { it.tag }.assert.contains("en") // stores + invitation.permission?.viewLanguages!!.map { it.tag }.assert.contains() // ads also to view + } } @Test @@ -97,9 +100,12 @@ class ProjectsControllerInvitationTest : ProjectAuthControllerTest("/v2/projects translateLanguages = setOf(getLang("en")) stateChangeLanguages = setOf(getLang("en")) }.andIsOk - val invitation = invitationTestUtil.getInvitation(result) - invitation.permission?.stateChangeLanguages!!.map { it.tag }.assert.contains("en") // stores - invitation.permission?.viewLanguages!!.map { it.tag }.assert.contains() // ads also to view + + executeInNewTransaction { + val invitation = invitationTestUtil.getInvitation(result) + invitation.permission?.stateChangeLanguages!!.map { it.tag }.assert.contains("en") // stores + invitation.permission?.viewLanguages!!.map { it.tag }.assert.contains() // ads also to view + } } @Test diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerTest.kt index fb0edd44ab..4856f13322 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ProjectsController/ProjectsControllerTest.kt @@ -83,24 +83,26 @@ class ProjectsControllerTest : ProjectAuthControllerTest("/v2/projects/") { node("[0].organizationOwner.name").isEqualTo("test_username") node("[0].directPermission.scopes").isPermissionScopes(ProjectPermissionType.MANAGE) node("[0].computedPermission.scopes").isPermissionScopes(ProjectPermissionType.MANAGE) - node("[0].stats.translationStatePercentages").isEqualTo( - """ - { - "UNTRANSLATED": 100.0, - "TRANSLATED": 0, - "REVIEWED": 0 - } - """, - ) - node("[1].stats.translationStatePercentages").isEqualTo( - """ - { - "UNTRANSLATED": 25.0, - "TRANSLATED": 75.0, - "REVIEWED": 0.0 - } - """, - ) + node("[0].stats.translationStatePercentages") + .isEqualTo( + """ + { + "UNTRANSLATED": 100.0, + "TRANSLATED": 0, + "REVIEWED": 0 + } + """, + ) + node("[1].stats.translationStatePercentages") + .isEqualTo( + """ + { + "UNTRANSLATED": 25.0, + "TRANSLATED": 75.0, + "REVIEWED": 0 + } + """, + ) } } } diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/KeyScreenshotControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/KeyScreenshotControllerTest.kt index 4b5365e7af..6fc7974b8b 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/KeyScreenshotControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/KeyScreenshotControllerTest.kt @@ -13,6 +13,7 @@ import io.tolgee.fixtures.andPrettyPrint import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod import io.tolgee.testing.assert import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import io.tolgee.util.InMemoryFileStorage import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeAll diff --git a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/SecuredKeyScreenshotControllerTest.kt b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/SecuredKeyScreenshotControllerTest.kt index 77284d42fc..7067e80a3f 100644 --- a/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/SecuredKeyScreenshotControllerTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/v2ScreenshotController/SecuredKeyScreenshotControllerTest.kt @@ -5,20 +5,25 @@ package io.tolgee.api.v2.controllers.v2ScreenshotController import io.tolgee.dtos.request.key.CreateKeyDto -import io.tolgee.fixtures.* +import io.tolgee.fixtures.andAssertThatJson +import io.tolgee.fixtures.andIsCreated +import io.tolgee.fixtures.andIsNotFound +import io.tolgee.fixtures.andIsOk +import io.tolgee.fixtures.andIsUnauthorized +import io.tolgee.fixtures.generateUniqueString import io.tolgee.model.Permission import io.tolgee.model.enums.Scope import io.tolgee.security.authentication.JwtService import io.tolgee.testing.ContextRecreatingTest import io.tolgee.testing.annotations.ProjectJWTAuthTestMethod import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.assertj.core.data.Offset import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.springframework.boot.test.context.SpringBootTest import java.time.Duration -import java.util.* @ContextRecreatingTest @SpringBootTest( diff --git a/backend/app/src/test/kotlin/io/tolgee/cache/AbstractCacheTest.kt b/backend/app/src/test/kotlin/io/tolgee/cache/AbstractCacheTest.kt index 93fc711fbb..32a63e5a62 100644 --- a/backend/app/src/test/kotlin/io/tolgee/cache/AbstractCacheTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/cache/AbstractCacheTest.kt @@ -122,7 +122,7 @@ abstract class AbstractCacheTest : AbstractSpringTest() { fun `caches permission by project and user`() { val permission = Permission(id = 1) whenever(permissionRepository.findOneByProjectIdAndUserIdAndOrganizationId(1, 1)) - .then { permission } + .then { Permission.PermissionWithLanguageIdsWrapper(permission, null, null, null) } permissionService.find(1, 1) Mockito.verify(permissionRepository, times(1)) .findOneByProjectIdAndUserIdAndOrganizationId(1, 1) @@ -137,7 +137,7 @@ abstract class AbstractCacheTest : AbstractSpringTest() { whenever( permissionRepository .findOneByProjectIdAndUserIdAndOrganizationId(null, null, organizationId = 1), - ).then { permission } + ).then { Permission.PermissionWithLanguageIdsWrapper(permission, null, null, null) } permissionService.find(organizationId = 1) Mockito.verify(permissionRepository, times(1)) diff --git a/backend/app/src/test/kotlin/io/tolgee/initialUserCreation/LegacyMigrationTest.kt b/backend/app/src/test/kotlin/io/tolgee/initialUserCreation/LegacyMigrationTest.kt index 25480726cf..97821db8dd 100644 --- a/backend/app/src/test/kotlin/io/tolgee/initialUserCreation/LegacyMigrationTest.kt +++ b/backend/app/src/test/kotlin/io/tolgee/initialUserCreation/LegacyMigrationTest.kt @@ -16,6 +16,7 @@ import io.tolgee.repository.UserAccountRepository import io.tolgee.service.security.SecurityService import io.tolgee.testing.ContextRecreatingTest import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.satisfies import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.assertDoesNotThrow diff --git a/backend/app/src/test/kotlin/io/tolgee/notifications/AbstractNotificationTest.kt b/backend/app/src/test/kotlin/io/tolgee/notifications/AbstractNotificationTest.kt new file mode 100644 index 0000000000..67714651cf --- /dev/null +++ b/backend/app/src/test/kotlin/io/tolgee/notifications/AbstractNotificationTest.kt @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.repository.notifications.UserNotificationRepository +import io.tolgee.testing.AuthorizedControllerTest +import io.tolgee.testing.assert +import io.tolgee.util.addMilliseconds +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.mockito.Mockito +import org.mockito.kotlin.any +import org.mockito.kotlin.doAnswer +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.mock.mockito.SpyBean +import org.springframework.scheduling.TaskScheduler +import java.util.* +import java.util.concurrent.Semaphore +import java.util.concurrent.TimeUnit + +abstract class AbstractNotificationTest : AuthorizedControllerTest() { + @Autowired + lateinit var userNotificationService: UserNotificationService + + @Autowired + lateinit var taskScheduler: TaskScheduler + + @SpyBean + @Autowired + lateinit var userNotificationRepository: UserNotificationRepository + + lateinit var semaphore: Semaphore + + @BeforeEach + fun setupTests() { + semaphore = Semaphore(0) + + doAnswer { + entityManager.persist(it.arguments[0]) + entityManager.flush() + + // Wait a bit to make sure everything's *actually* persisted + // Kind of an ugly way to synchronize everything, but it is what it is + taskScheduler.schedule( + { semaphore.release() }, + Date().addMilliseconds(100).toInstant(), + ) + + it.arguments[0] + }.`when`(userNotificationRepository).save(any()) + + doAnswer { + val list = it.arguments[0] as List<*> + for (entity in list) entityManager.persist(entity) + entityManager.flush() + + for (entity in it.arguments[0] as List<*>) entityManager.refresh(entity) + + // Wait a bit to make sure everything's *actually* persisted + // Kind of an ugly way to synchronize everything, but it is what it is + taskScheduler.schedule( + { semaphore.release(list.size) }, + Date().addMilliseconds(100).toInstant(), + ) + + it.arguments[0] + }.`when`(userNotificationRepository).saveAll(Mockito.anyList()) + } + + @AfterEach + fun clearWatcher() { + Mockito.reset(userNotificationRepository) + } + + fun waitUntilUserNotificationDispatch(count: Int = 1) { + val dispatched = semaphore.tryAcquire(count, 1L, TimeUnit.SECONDS) + dispatched.assert + .withFailMessage("Expected at least $count notification(s) to be dispatched.") + .isTrue() + } + + fun ensureNoUserNotificationDispatch() { + val dispatched = semaphore.tryAcquire(1L, TimeUnit.SECONDS) + dispatched.assert + .withFailMessage("Expected no notifications to be dispatched.") + .isFalse() + } +} diff --git a/backend/app/src/test/kotlin/io/tolgee/notifications/RemappedNotificationsTest.kt b/backend/app/src/test/kotlin/io/tolgee/notifications/RemappedNotificationsTest.kt new file mode 100644 index 0000000000..e11f111477 --- /dev/null +++ b/backend/app/src/test/kotlin/io/tolgee/notifications/RemappedNotificationsTest.kt @@ -0,0 +1,235 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.development.testDataBuilder.data.NotificationsTestData +import io.tolgee.dtos.request.key.ComplexEditKeyDto +import io.tolgee.dtos.request.key.KeyScreenshotDto +import io.tolgee.fixtures.andGetContentAsJsonMap +import io.tolgee.fixtures.andIsCreated +import io.tolgee.fixtures.andIsOk +import io.tolgee.testing.assert +import io.tolgee.util.generateImage +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.mock.web.MockMultipartFile + +class RemappedNotificationsTest : AbstractNotificationTest() { + lateinit var testData: NotificationsTestData + + @BeforeEach + override fun setupTests() { + testData = NotificationsTestData() + testDataService.saveTestData(testData.root) + + super.setupTests() + } + + @Test + fun `it does properly remap imports to key and translation notifications`() { + performAuthMultipart( + url = "/v2/projects/${testData.project1.id}/import", + files = + listOf( + MockMultipartFile( + "files", + "en.json", + "application/json", + """{"new-key1": "New string 1", "new-key2": "New string 2"}""".toByteArray(), + ), + MockMultipartFile( + "files", + "fr.json", + "application/json", + """{"some-key": "Updated", "new-key1": "New FR string 1", "new-key2": "New FR string 2"}""".toByteArray(), + ), + MockMultipartFile( + "files", + "cs.json", + "application/json", + """{"new-key1": "New CZ string 1", "new-key2": "New CZ string 2"}""".toByteArray(), + ), + ), + ).andIsOk + + performAuthPut("/v2/projects/${testData.project1.id}/import/apply?forceMode=OVERRIDE", null).andIsOk + + waitUntilUserNotificationDispatch(12) + val acmeChiefNotifications = userNotificationRepository.findAllByRecipient(testData.orgAdmin) + val projectManagerNotifications = userNotificationRepository.findAllByRecipient(testData.projectManager) + val frenchTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.frenchTranslator) + val czechTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.czechTranslator) + val germanTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.germanTranslator) + val frenchCzechTranslatorNotifications = + userNotificationRepository.findAllByRecipient(testData.frenchCzechTranslator) + val bobNotifications = userNotificationRepository.findAllByRecipient(testData.bob) + + acmeChiefNotifications.assert.hasSize(2) + projectManagerNotifications.assert.hasSize(2) + frenchTranslatorNotifications.assert.hasSize(2) + czechTranslatorNotifications.assert.hasSize(1) + germanTranslatorNotifications.assert.hasSize(1) + frenchCzechTranslatorNotifications.assert.hasSize(2) + bobNotifications.assert.hasSize(2) + + acmeChiefNotifications.assert + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_CREATED) + it.modifiedEntities.assert.hasSize(8) // 2 keys + 6 translations + } + + projectManagerNotifications.assert + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_CREATED) + it.modifiedEntities.assert.hasSize(8) // 2 keys + 6 translations + } + + frenchTranslatorNotifications.assert + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_CREATED) + it.modifiedEntities.assert.hasSize(6) // 2 keys + 4 translations + } + + czechTranslatorNotifications.assert + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_CREATED) + it.modifiedEntities.assert.hasSize(6) // 2 keys + 4 translations + } + + germanTranslatorNotifications.assert + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_CREATED) + it.modifiedEntities.assert.hasSize(4) // 2 keys + 2 translations + } + + frenchCzechTranslatorNotifications.assert + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_CREATED) + it.modifiedEntities.assert.hasSize(8) // 2 keys + 6 translations + } + + bobNotifications.assert + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_CREATED) + it.modifiedEntities.assert.hasSize(8) // 2 keys + 6 translations + } + + ensureNoUserNotificationDispatch() + } + + @Test + fun `it does remap complex key edits to relevant notification types`() { + val screenshotId = + performAuthMultipart( + url = "/v2/image-upload", + files = + listOf( + MockMultipartFile( + "image", + "image.png", + "image/png", + generateImage(100, 100).inputStream.readAllBytes(), + ), + ), + ).andIsCreated.andGetContentAsJsonMap["id"].let { (it as Int).toLong() } + + performAuthPut( + "/v2/projects/${testData.project1.id}/keys/${testData.keyProject1.id}/complex-update", + ComplexEditKeyDto( + name = "new-name", + namespace = "new-namespace", + translations = mapOf("en" to "New EN string", "fr" to "New FR string"), + screenshotsToAdd = + listOf( + KeyScreenshotDto(uploadedImageId = screenshotId), + ), + ), + ).andIsOk + + waitUntilUserNotificationDispatch(25) + val acmeChiefNotifications = userNotificationRepository.findAllByRecipient(testData.orgAdmin) + val czechTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.czechTranslator) + val bobNotifications = userNotificationRepository.findAllByRecipient(testData.bob) + + bobNotifications.assert + .hasSize(3) + .noneSatisfy { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_SCREENSHOTS_UPLOADED) + } + + acmeChiefNotifications.assert + .hasSize(4) + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_UPDATED) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_SCREENSHOTS_UPLOADED) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + + czechTranslatorNotifications.assert + .hasSize(3) + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_UPDATED) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_KEYS_SCREENSHOTS_UPLOADED) + } + .satisfiesOnlyOnce { + it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) + it.modifiedEntities.assert.hasSize(1) + } + + ensureNoUserNotificationDispatch() + } +} diff --git a/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationDebounceTest.kt b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationDebounceTest.kt new file mode 100644 index 0000000000..24eb7466ec --- /dev/null +++ b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationDebounceTest.kt @@ -0,0 +1,129 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.development.testDataBuilder.data.NotificationsTestData +import io.tolgee.dtos.request.LanguageRequest +import io.tolgee.dtos.request.key.CreateKeyDto +import io.tolgee.dtos.request.translation.comment.TranslationCommentWithLangKeyDto +import io.tolgee.fixtures.andIsCreated +import io.tolgee.fixtures.andIsOk +import io.tolgee.testing.assert +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class UserNotificationDebounceTest : AbstractNotificationTest() { + lateinit var testData: NotificationsTestData + + @BeforeEach + override fun setupTests() { + testData = NotificationsTestData() + testDataService.saveTestData(testData.root) + + super.setupTests() + } + + @Test + fun `it debounces notifications of the same type`() { + performAuthPost( + "/v2/projects/${testData.calmProject.id}/keys/create", + CreateKeyDto(name = "test-key-1"), + ).andIsCreated + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(1) + + performAuthPost( + "/v2/projects/${testData.calmProject.id}/keys/create", + CreateKeyDto(name = "test-key-2"), + ).andIsCreated + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(1) + + performAuthPost( + url = "/v2/projects/${testData.calmProject.id}/languages", + content = + LanguageRequest( + name = "Meow", + originalName = "meow", + tag = "meow-en", + ), + ).andIsOk + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(2) + } + + @Test + fun `it only debounces notifications within the same project`() { + performAuthPost( + "/v2/projects/${testData.calmProject.id}/keys/create", + CreateKeyDto(name = "test-key-1"), + ).andIsCreated + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(1) + + performAuthPost( + "/v2/projects/${testData.project2.id}/keys/create", + CreateKeyDto(name = "test-key-2"), + ).andIsCreated + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(2) + } + + @Test + fun `it debounces comments only when they are under the same translation`() { + performAuthPost( + "/v2/projects/${testData.calmProject.id}/translations/create-comment", + TranslationCommentWithLangKeyDto( + keyId = testData.keyCalmProject.id, + languageId = testData.keyCalmEnTranslation.language.id, + text = "This is a test", + ), + ).andIsCreated + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(1) + + performAuthPost( + "/v2/projects/${testData.calmProject.id}/translations/create-comment", + TranslationCommentWithLangKeyDto( + keyId = testData.keyCalmProject.id, + languageId = testData.keyCalmEnTranslation.language.id, + text = "This is a test 2", + ), + ).andIsCreated + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(1) + + performAuthPost( + "/v2/projects/${testData.calmProject.id}/translations/create-comment", + TranslationCommentWithLangKeyDto( + keyId = testData.keyCalmProject.id, + languageId = testData.calmProjectFr.id, + text = "This is a test", + ), + ).andIsCreated + + waitUntilUserNotificationDispatch() + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(2) + } +} diff --git a/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationDispatchTest.kt b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationDispatchTest.kt new file mode 100644 index 0000000000..e6a4296de0 --- /dev/null +++ b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationDispatchTest.kt @@ -0,0 +1,218 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.development.testDataBuilder.data.NotificationsTestData +import io.tolgee.dtos.request.key.CreateKeyDto +import io.tolgee.dtos.request.translation.SetTranslationsWithKeyDto +import io.tolgee.fixtures.andIsCreated +import io.tolgee.fixtures.andIsOk +import io.tolgee.testing.assert +import io.tolgee.util.generateImage +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.mock.web.MockMultipartFile + +class UserNotificationDispatchTest : AbstractNotificationTest() { + lateinit var testData: NotificationsTestData + + @BeforeEach + override fun setupTests() { + testData = NotificationsTestData() + testDataService.saveTestData(testData.root) + + super.setupTests() + } + + @Test + fun `it dispatches notifications to everyone in project`() { + performAuthPost( + "/v2/projects/${testData.project1.id}/keys/create", + CreateKeyDto(name = "test-key"), + ).andIsCreated + + waitUntilUserNotificationDispatch(7) + val adminNotifications = userNotificationRepository.findAllByRecipient(testData.admin) + val acmeChiefNotifications = userNotificationRepository.findAllByRecipient(testData.orgAdmin) + val projectManagerNotifications = userNotificationRepository.findAllByRecipient(testData.projectManager) + val frenchTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.frenchTranslator) + val czechTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.czechTranslator) + val germanTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.germanTranslator) + val frenchCzechTranslatorNotifications = + userNotificationRepository.findAllByRecipient(testData.frenchCzechTranslator) + val bobNotifications = userNotificationRepository.findAllByRecipient(testData.bob) + val aliceNotifications = userNotificationRepository.findAllByRecipient(testData.alice) + + adminNotifications.assert.hasSize(0) + acmeChiefNotifications.assert.hasSize(1) + projectManagerNotifications.assert.hasSize(1) + frenchTranslatorNotifications.assert.hasSize(1) + czechTranslatorNotifications.assert.hasSize(1) + germanTranslatorNotifications.assert.hasSize(1) + frenchCzechTranslatorNotifications.assert.hasSize(1) + bobNotifications.assert.hasSize(1) + aliceNotifications.assert.hasSize(0) + + ensureNoUserNotificationDispatch() + } + + @Test + fun `it does not dispatch notifications to people without the permission to see the change`() { + performAuthMultipart( + url = "/v2/projects/${testData.project1.id}/keys/${testData.keyProject1.id}/screenshots", + files = + listOf( + MockMultipartFile( + "screenshot", + "originalShot.png", + "image/png", + generateImage(100, 100).inputStream.readAllBytes(), + ), + ), + ).andIsCreated + + waitUntilUserNotificationDispatch(6) + val acmeChiefNotifications = userNotificationRepository.findAllByRecipient(testData.orgAdmin) + val projectManagerNotifications = userNotificationRepository.findAllByRecipient(testData.projectManager) + val frenchTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.frenchTranslator) + val czechTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.czechTranslator) + val germanTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.germanTranslator) + val frenchCzechTranslatorNotifications = + userNotificationRepository.findAllByRecipient(testData.frenchCzechTranslator) + val bobNotifications = userNotificationRepository.findAllByRecipient(testData.bob) + + acmeChiefNotifications.assert.hasSize(1) + projectManagerNotifications.assert.hasSize(1) + frenchTranslatorNotifications.assert.hasSize(1) + czechTranslatorNotifications.assert.hasSize(1) + germanTranslatorNotifications.assert.hasSize(1) + frenchCzechTranslatorNotifications.assert.hasSize(1) + bobNotifications.assert.hasSize(0) + + ensureNoUserNotificationDispatch() + } + + @Test + fun `it does not dispatch notifications to people without the permission to see the target language`() { + performAuthPut( + url = "/v2/projects/${testData.project1.id}/translations", + content = + SetTranslationsWithKeyDto( + key = testData.keyProject1.name, + translations = mapOf("fr" to "Superb French translation!"), + ), + ).andIsOk + + waitUntilUserNotificationDispatch(5) + val acmeChiefNotifications = userNotificationRepository.findAllByRecipient(testData.orgAdmin) + val projectManagerNotifications = userNotificationRepository.findAllByRecipient(testData.projectManager) + val frenchTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.frenchTranslator) + val czechTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.czechTranslator) + val germanTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.germanTranslator) + val frenchCzechTranslatorNotifications = + userNotificationRepository.findAllByRecipient(testData.frenchCzechTranslator) + val bobNotifications = userNotificationRepository.findAllByRecipient(testData.bob) + + acmeChiefNotifications.assert.hasSize(1) + projectManagerNotifications.assert.hasSize(1) + frenchTranslatorNotifications.assert.hasSize(1) + czechTranslatorNotifications.assert.hasSize(0) + germanTranslatorNotifications.assert.hasSize(0) + frenchCzechTranslatorNotifications.assert.hasSize(1) + bobNotifications.assert.hasSize(1) + + ensureNoUserNotificationDispatch() + } + + @Test + fun `it does dispatch notifications with trimmed data to people who can only see part of the changes`() { + performAuthPut( + url = "/v2/projects/${testData.project1.id}/translations", + content = + SetTranslationsWithKeyDto( + key = testData.keyProject1.name, + translations = mapOf("fr" to "Superb French translation!", "cs" to "Superb Czech translation!"), + ), + ).andIsOk + + waitUntilUserNotificationDispatch(6) + val acmeChiefNotifications = userNotificationRepository.findAllByRecipient(testData.orgAdmin) + val projectManagerNotifications = userNotificationRepository.findAllByRecipient(testData.projectManager) + val frenchTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.frenchTranslator) + val czechTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.czechTranslator) + val germanTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.germanTranslator) + val frenchCzechTranslatorNotifications = + userNotificationRepository.findAllByRecipient(testData.frenchCzechTranslator) + val bobNotifications = userNotificationRepository.findAllByRecipient(testData.bob) + + acmeChiefNotifications.assert.hasSize(1) + projectManagerNotifications.assert.hasSize(1) + frenchTranslatorNotifications.assert.hasSize(1) + czechTranslatorNotifications.assert.hasSize(1) + germanTranslatorNotifications.assert.hasSize(0) + frenchCzechTranslatorNotifications.assert.hasSize(1) + bobNotifications.assert.hasSize(1) + + acmeChiefNotifications[0].modifiedEntities.assert.hasSize(2) + projectManagerNotifications[0].modifiedEntities.assert.hasSize(2) + frenchTranslatorNotifications[0].modifiedEntities.assert.hasSize(1) + czechTranslatorNotifications[0].modifiedEntities.assert.hasSize(1) + frenchCzechTranslatorNotifications[0].modifiedEntities.assert.hasSize(2) + bobNotifications[0].modifiedEntities.assert.hasSize(2) + + frenchTranslatorNotifications[0].modifiedEntities.first() + .entityId.assert.isEqualTo(testData.key1FrTranslation.id) + + czechTranslatorNotifications[0].modifiedEntities.first() + .entityId.assert.isEqualTo(testData.key1CzTranslation.id) + + ensureNoUserNotificationDispatch() + } + + @Test + fun `it does not dispatch modifications to the responsible user`() { + loginAsUser(testData.projectManager) + performAuthPost( + "/v2/projects/${testData.project1.id}/keys/create", + CreateKeyDto(name = "test-key"), + ).andIsCreated + + waitUntilUserNotificationDispatch(6) + val adminNotifications = userNotificationRepository.findAllByRecipient(testData.admin) + val acmeChiefNotifications = userNotificationRepository.findAllByRecipient(testData.orgAdmin) + val projectManagerNotifications = userNotificationRepository.findAllByRecipient(testData.projectManager) + val frenchTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.frenchTranslator) + val czechTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.czechTranslator) + val germanTranslatorNotifications = userNotificationRepository.findAllByRecipient(testData.germanTranslator) + val frenchCzechTranslatorNotifications = + userNotificationRepository.findAllByRecipient(testData.frenchCzechTranslator) + val bobNotifications = userNotificationRepository.findAllByRecipient(testData.bob) + val aliceNotifications = userNotificationRepository.findAllByRecipient(testData.alice) + + adminNotifications.assert.hasSize(0) + acmeChiefNotifications.assert.hasSize(1) + projectManagerNotifications.assert.hasSize(0) + frenchTranslatorNotifications.assert.hasSize(1) + czechTranslatorNotifications.assert.hasSize(1) + germanTranslatorNotifications.assert.hasSize(1) + frenchCzechTranslatorNotifications.assert.hasSize(1) + bobNotifications.assert.hasSize(1) + aliceNotifications.assert.hasSize(0) + + ensureNoUserNotificationDispatch() + } +} diff --git a/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationSubscriptionTest.kt b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationSubscriptionTest.kt new file mode 100644 index 0000000000..31c18c34e2 --- /dev/null +++ b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationSubscriptionTest.kt @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.development.testDataBuilder.data.NotificationSubscriptionTestData +import io.tolgee.dtos.request.key.CreateKeyDto +import io.tolgee.fixtures.andIsCreated +import io.tolgee.testing.assert +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class UserNotificationSubscriptionTest : AbstractNotificationTest() { + lateinit var testData: NotificationSubscriptionTestData + + @BeforeEach + override fun setupTests() { + testData = NotificationSubscriptionTestData() + testDataService.saveTestData(testData.root) + + super.setupTests() + } + + @Test + fun `it respects global notification subscription settings`() { + performAuthPost( + "/v2/projects/${testData.project1.id}/keys/create", + CreateKeyDto(name = "test-key"), + ).andIsCreated + + waitUntilUserNotificationDispatch(1) + val notifications1 = userNotificationRepository.findAllByRecipient(testData.user1) + val notifications2 = userNotificationRepository.findAllByRecipient(testData.user2) + + notifications1.assert.hasSize(1) + notifications2.assert.hasSize(0) + ensureNoUserNotificationDispatch() + } + + @Test + fun `it respects project-level notification subscription settings`() { + performAuthPost( + "/v2/projects/${testData.project2.id}/keys/create", + CreateKeyDto(name = "test-key"), + ).andIsCreated + + waitUntilUserNotificationDispatch(1) + val notifications1 = userNotificationRepository.findAllByRecipient(testData.user1) + val notifications2 = userNotificationRepository.findAllByRecipient(testData.user2) + + notifications1.assert.hasSize(0) + notifications2.assert.hasSize(1) + ensureNoUserNotificationDispatch() + } +} diff --git a/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationTranslationTest.kt b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationTranslationTest.kt new file mode 100644 index 0000000000..d7a6b222e2 --- /dev/null +++ b/backend/app/src/test/kotlin/io/tolgee/notifications/UserNotificationTranslationTest.kt @@ -0,0 +1,112 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.development.testDataBuilder.data.NotificationsTestData +import io.tolgee.dtos.request.key.CreateKeyDto +import io.tolgee.dtos.request.translation.SetTranslationsWithKeyDto +import io.tolgee.fixtures.andIsCreated +import io.tolgee.fixtures.andIsOk +import io.tolgee.testing.assert +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class UserNotificationTranslationTest : AbstractNotificationTest() { + lateinit var testData: NotificationsTestData + + @BeforeEach + override fun setupTests() { + testData = NotificationsTestData() + testDataService.saveTestData(testData.root) + + super.setupTests() + } + + @Test + fun `it does not dispatch the same type of notification for source strings and translated strings`() { + performAuthPut( + url = "/v2/projects/${testData.calmProject.id}/translations", + content = + SetTranslationsWithKeyDto( + key = testData.keyCalmProject.name, + translations = mapOf("en" to "Superb English translation!"), + ), + ).andIsOk + + waitUntilUserNotificationDispatch() + + userNotificationRepository.findAllByRecipient(testData.alice).assert + .satisfiesOnlyOnce { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .noneSatisfy { it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) } + + performAuthPut( + url = "/v2/projects/${testData.calmProject.id}/translations", + content = + SetTranslationsWithKeyDto( + key = testData.keyCalmProject.name, + translations = mapOf("fr" to "Superb French translation!"), + ), + ).andIsOk + + waitUntilUserNotificationDispatch() + + userNotificationRepository.findAllByRecipient(testData.alice).assert + .satisfiesOnlyOnce { it.type.assert.isEqualTo(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED) } + .satisfiesOnlyOnce { it.type.assert.isEqualTo(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED) } + } + + @Test + fun `it does debounce key creation and setting strings as a single notification`() { + performAuthPost( + "/v2/projects/${testData.calmProject.id}/keys/create", + CreateKeyDto(name = "test-key"), + ).andIsCreated + + waitUntilUserNotificationDispatch() + + performAuthPut( + url = "/v2/projects/${testData.calmProject.id}/translations", + content = + SetTranslationsWithKeyDto( + key = "test-key", + translations = mapOf("en" to "Superb English translation!", "fr" to "Superb French translation!"), + ), + ).andIsOk + + waitUntilUserNotificationDispatch() + + userNotificationRepository.findAllByRecipient(testData.alice).assert.hasSize(1) + } + + @Test + fun `it does not dispatch outdated notifications if it was not done manually`() { + performAuthPut( + url = "/v2/projects/${testData.calmProject.id}/translations", + content = + SetTranslationsWithKeyDto( + key = testData.keyCalmProject.name, + translations = mapOf("en" to "Superb English translation!"), + ), + ).andIsOk + + waitUntilUserNotificationDispatch() + + userNotificationRepository.findAllByRecipient(testData.alice).assert + .noneMatch { it.type == NotificationType.ACTIVITY_TRANSLATION_OUTDATED } + .noneMatch { it.type == NotificationType.ACTIVITY_TRANSLATIONS_UPDATED } + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/activity/ActivityService.kt b/backend/data/src/main/kotlin/io/tolgee/activity/ActivityService.kt index 5befbcbe88..71c2406fd9 100644 --- a/backend/data/src/main/kotlin/io/tolgee/activity/ActivityService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/activity/ActivityService.kt @@ -3,8 +3,8 @@ package io.tolgee.activity import com.fasterxml.jackson.databind.ObjectMapper import io.tolgee.activity.data.ActivityType import io.tolgee.activity.data.RevisionType -import io.tolgee.activity.projectActivityView.ProjectActivityViewByPageableProvider -import io.tolgee.activity.projectActivityView.ProjectActivityViewByRevisionProvider +import io.tolgee.activity.views.ProjectActivityViewByPageableProvider +import io.tolgee.activity.views.ProjectActivityViewByRevisionProvider import io.tolgee.dtos.queryResults.TranslationHistoryView import io.tolgee.events.OnProjectActivityStoredEvent import io.tolgee.model.activity.ActivityModifiedEntity diff --git a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ActivityViewByRevisionsProvider.kt b/backend/data/src/main/kotlin/io/tolgee/activity/views/ActivityViewByRevisionsProvider.kt similarity index 53% rename from backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ActivityViewByRevisionsProvider.kt rename to backend/data/src/main/kotlin/io/tolgee/activity/views/ActivityViewByRevisionsProvider.kt index 1d134f262e..f33ff4dc4d 100644 --- a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ActivityViewByRevisionsProvider.kt +++ b/backend/data/src/main/kotlin/io/tolgee/activity/views/ActivityViewByRevisionsProvider.kt @@ -1,12 +1,7 @@ -package io.tolgee.activity.projectActivityView +package io.tolgee.activity.views -import io.sentry.Sentry -import io.tolgee.activity.annotation.ActivityReturnsExistence import io.tolgee.activity.data.ActivityType -import io.tolgee.activity.data.EntityDescriptionRef -import io.tolgee.activity.data.ExistenceEntityDescription import io.tolgee.model.UserAccount -import io.tolgee.model.activity.ActivityDescribingEntity import io.tolgee.model.activity.ActivityModifiedEntity import io.tolgee.model.activity.ActivityModifiedEntity_ import io.tolgee.model.activity.ActivityRevision @@ -15,7 +10,6 @@ import io.tolgee.model.views.activity.ModifiedEntityView import io.tolgee.model.views.activity.ProjectActivityView import io.tolgee.repository.activity.ActivityRevisionRepository import io.tolgee.service.security.UserAccountService -import io.tolgee.util.EntityUtil import jakarta.persistence.EntityManager import jakarta.persistence.criteria.Predicate import org.springframework.context.ApplicationContext @@ -33,17 +27,12 @@ class ActivityViewByRevisionsProvider( private val entityManager: EntityManager = applicationContext.getBean(EntityManager::class.java) - private val entityUtil: EntityUtil = - applicationContext.getBean(EntityUtil::class.java) - private lateinit var authors: Map private lateinit var modifiedEntities: Map> private lateinit var revisionIds: MutableList private lateinit var counts: MutableMap> private lateinit var allDataReturningEventTypes: List - private lateinit var allRelationData: Map> private lateinit var rawModifiedEntities: List - private lateinit var entityExistences: Map, Boolean> private lateinit var params: Map fun get(): List { @@ -73,13 +62,17 @@ class ActivityViewByRevisionsProvider( allDataReturningEventTypes = ActivityType.entries.filter { !it.onlyCountsInList } - allRelationData = getAllowedRevisionRelations(revisionIds, allDataReturningEventTypes) - rawModifiedEntities = getModifiedEntitiesRaw() - entityExistences = getEntityExistences() + val modifiedEntitiesViewProvider = + ModifiedEntitiesViewProvider( + applicationContext, + rawModifiedEntities, + ) - modifiedEntities = this.getModifiedEntities() + modifiedEntities = + modifiedEntitiesViewProvider.get() + .groupBy { it.activityRevision.id } params = getParams() @@ -123,68 +116,6 @@ class ActivityViewByRevisionsProvider( revisions.mapNotNull { it.authorId }.toSet(), ).associateBy { it.id } - private fun getAllowedRevisionRelations( - revisionIds: List, - allowedTypes: Collection, - ): Map> { - return activityRevisionRepository.getRelationsForRevisions(revisionIds, allowedTypes) - .groupBy { it.activityRevision.id } - } - - private fun getModifiedEntities(): Map> { - return rawModifiedEntities.map { modifiedEntity -> - val relations = - modifiedEntity.describingRelations - ?.mapNotNull relationsOfEntityMap@{ relationEntry -> - relationEntry.key to - extractCompressedRef( - relationEntry.value, - allRelationData[modifiedEntity.activityRevision.id] ?: let { - Sentry.captureException( - IllegalStateException("No relation data for revision ${modifiedEntity.activityRevision.id}"), - ) - return@relationsOfEntityMap null - }, - ) - }?.toMap() - ModifiedEntityView( - activityRevision = modifiedEntity.activityRevision, - entityClass = modifiedEntity.entityClass, - entityId = modifiedEntity.entityId, - exists = entityExistences[modifiedEntity.entityClass to modifiedEntity.entityId], - modifications = modifiedEntity.modifications, - description = modifiedEntity.describingData, - describingRelations = relations, - ) - }.groupBy { it.activityRevision.id } - } - - private fun getEntityExistences(): Map, Boolean> { - val modifiedEntityClassIdPairs = rawModifiedEntities.map { it.entityClass to it.entityId } - val relationsClassIdPairs = allRelationData.flatMap { (_, data) -> data.map { it.entityClass to it.entityId } } - val entities = (modifiedEntityClassIdPairs + relationsClassIdPairs).toHashSet() - - return entities - .groupBy { (entityClass, _) -> entityClass } - .mapNotNull { (entityClassName, classIdPairs) -> - val entityClass = entityUtil.getRealEntityClass(entityClassName) - val annotation = entityClass?.getAnnotation(ActivityReturnsExistence::class.java) - if (annotation != null) { - val cb = entityManager.criteriaBuilder - val query = cb.createQuery(Long::class.java) - val root = query.from(entityClass) - val ids = classIdPairs.map { it.second } - query.select(root.get("id")) - query.where(root.get("id").`in`(ids)) - val existingIds = entityManager.createQuery(query).resultList - return@mapNotNull (entityClassName to ids.map { it to existingIds.contains(it) }) - } - return@mapNotNull null - } - .flatMap { (entityClassName, existingIds) -> existingIds.map { (entityClassName to it.first) to it.second } } - .toMap() - } - private fun getModifiedEntitiesRaw(): List { val cb = entityManager.criteriaBuilder val query = cb.createQuery(ActivityModifiedEntity::class.java) @@ -209,24 +140,4 @@ class ActivityViewByRevisionsProvider( query.where(cb.and(*whereConditions.toTypedArray())) return entityManager.createQuery(query).resultList } - - private fun extractCompressedRef( - value: EntityDescriptionRef, - describingEntities: List, - ): ExistenceEntityDescription { - val entity = describingEntities.find { it.entityClass == value.entityClass && it.entityId == value.entityId } - - val relations = - entity?.describingRelations - ?.map { it.key to extractCompressedRef(it.value, describingEntities) } - ?.toMap() - - return ExistenceEntityDescription( - entityClass = value.entityClass, - entityId = value.entityId, - exists = entityExistences[value.entityClass to value.entityId], - data = entity?.data ?: mapOf(), - relations = relations ?: mapOf(), - ) - } } diff --git a/backend/data/src/main/kotlin/io/tolgee/activity/views/ModifiedEntitiesViewProvider.kt b/backend/data/src/main/kotlin/io/tolgee/activity/views/ModifiedEntitiesViewProvider.kt new file mode 100644 index 0000000000..f23b378d7e --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/activity/views/ModifiedEntitiesViewProvider.kt @@ -0,0 +1,154 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.activity.views + +import io.sentry.Sentry +import io.tolgee.activity.annotation.ActivityReturnsExistence +import io.tolgee.activity.data.ActivityType +import io.tolgee.activity.data.EntityDescriptionRef +import io.tolgee.activity.data.ExistenceEntityDescription +import io.tolgee.model.activity.ActivityDescribingEntity +import io.tolgee.model.activity.ActivityModifiedEntity +import io.tolgee.model.views.activity.ModifiedEntityView +import io.tolgee.model.views.activity.SimpleModifiedEntityView +import io.tolgee.repository.activity.ActivityRevisionRepository +import io.tolgee.service.security.UserAccountService +import io.tolgee.util.EntityUtil +import jakarta.persistence.EntityManager +import org.springframework.context.ApplicationContext + +class ModifiedEntitiesViewProvider( + applicationContext: ApplicationContext, + private val modifiedEntities: Collection, +) { + val userAccountService: UserAccountService = + applicationContext.getBean(UserAccountService::class.java) + + private val activityRevisionRepository: ActivityRevisionRepository = + applicationContext.getBean(ActivityRevisionRepository::class.java) + + private val entityManager: EntityManager = + applicationContext.getBean(EntityManager::class.java) + + private val entityUtil: EntityUtil = + applicationContext.getBean(EntityUtil::class.java) + + private val describingEntities: Map> by lazy { fetchAllowedRevisionRelations() } + + private val entityExistences: Map, Boolean> by lazy { fetchEntityExistences() } + + fun get(): List { + return modifiedEntities.map entities@{ entity -> + val relations = getRelations(entity) + ModifiedEntityView( + activityRevision = entity.activityRevision, + entityClass = entity.entityClass, + entityId = entity.entityId, + exists = entityExistences[entity.entityClass to entity.entityId], + modifications = entity.modifications, + description = entity.describingData, + describingRelations = relations, + ) + } + } + + fun getSimple(): List { + return modifiedEntities.map entities@{ entity -> + val relations = getRelations(entity) + SimpleModifiedEntityView( + entityClass = entity.entityClass, + entityId = entity.entityId, + exists = entityExistences[entity.entityClass to entity.entityId], + modifications = entity.modifications, + description = entity.describingData, + describingRelations = relations, + ) + } + } + + private fun getRelations(entity: ActivityModifiedEntity): Map? { + return entity.describingRelations + ?.mapNotNull { + Pair( + it.key, + extractCompressedRef( + it.value, + describingEntities[entity.activityRevision.id] ?: let { _ -> + Sentry.captureException( + IllegalStateException("No relation data for revision ${entity.activityRevision.id}"), + ) + return@mapNotNull null + }, + ), + ) + } + ?.toMap() + } + + private fun fetchAllowedRevisionRelations(): Map> { + val revisionIds = modifiedEntities.map { it.activityRevision.id } + val allowedTypes = ActivityType.entries.filter { !it.onlyCountsInList } + return activityRevisionRepository.getRelationsForRevisions(revisionIds, allowedTypes) + .groupBy { it.activityRevision.id } + } + + private fun fetchEntityExistences(): Map, Boolean> { + val modifiedEntityClassIdPairs = modifiedEntities.map { it.entityClass to it.entityId } + val relationsClassIdPairs = describingEntities.flatMap { (_, data) -> data.map { it.entityClass to it.entityId } } + val entities = (modifiedEntityClassIdPairs + relationsClassIdPairs).toHashSet() + + return entities + .groupBy { (entityClass, _) -> entityClass } + .mapNotNull { (entityClassName, classIdPairs) -> + val entityClass = entityUtil.getRealEntityClass(entityClassName) + val annotation = entityClass?.getAnnotation(ActivityReturnsExistence::class.java) + if (annotation != null) { + val cb = entityManager.criteriaBuilder + val query = cb.createQuery(Long::class.java) + val root = query.from(entityClass) + val ids = classIdPairs.map { it.second } + query.select(root.get("id")) + query.where(root.get("id").`in`(ids)) + val existingIds = entityManager.createQuery(query).resultList + return@mapNotNull (entityClassName to ids.map { it to existingIds.contains(it) }) + } + return@mapNotNull null + } + .flatMap { (entityClassName, existingIds) -> existingIds.map { (entityClassName to it.first) to it.second } } + .toMap() + } + + private fun extractCompressedRef( + value: EntityDescriptionRef, + describingEntities: List, + ): ExistenceEntityDescription { + val entity = describingEntities.find { it.entityClass == value.entityClass && it.entityId == value.entityId } + + val relations = + entity?.describingRelations + ?.map { it.key to extractCompressedRef(it.value, describingEntities) } + ?.toMap() + + return ExistenceEntityDescription( + entityClass = value.entityClass, + entityId = value.entityId, + exists = entityExistences[value.entityClass to value.entityId], + data = entity?.data ?: mapOf(), + relations = relations ?: mapOf(), + ) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ProjectActivityViewByPageableProvider.kt b/backend/data/src/main/kotlin/io/tolgee/activity/views/ProjectActivityViewByPageableProvider.kt similarity index 91% rename from backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ProjectActivityViewByPageableProvider.kt rename to backend/data/src/main/kotlin/io/tolgee/activity/views/ProjectActivityViewByPageableProvider.kt index 7eecf61b7b..7fcdc75ef8 100644 --- a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ProjectActivityViewByPageableProvider.kt +++ b/backend/data/src/main/kotlin/io/tolgee/activity/views/ProjectActivityViewByPageableProvider.kt @@ -1,4 +1,4 @@ -package io.tolgee.activity.projectActivityView +package io.tolgee.activity.views import io.tolgee.activity.data.ActivityType import io.tolgee.model.activity.ActivityRevision @@ -24,7 +24,7 @@ class ProjectActivityViewByPageableProvider( projectId: Long, pageable: Pageable, ): Page { - val types = ActivityType.values().filter { !it.hideInList } + val types = ActivityType.entries.filter { !it.hideInList } return activityRevisionRepository.getForProject(projectId, pageable, types) } diff --git a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ProjectActivityViewByRevisionProvider.kt b/backend/data/src/main/kotlin/io/tolgee/activity/views/ProjectActivityViewByRevisionProvider.kt similarity index 95% rename from backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ProjectActivityViewByRevisionProvider.kt rename to backend/data/src/main/kotlin/io/tolgee/activity/views/ProjectActivityViewByRevisionProvider.kt index db61322206..3b70728e27 100644 --- a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/ProjectActivityViewByRevisionProvider.kt +++ b/backend/data/src/main/kotlin/io/tolgee/activity/views/ProjectActivityViewByRevisionProvider.kt @@ -1,4 +1,4 @@ -package io.tolgee.activity.projectActivityView +package io.tolgee.activity.views import io.tolgee.model.activity.ActivityRevision import io.tolgee.model.views.activity.ProjectActivityView diff --git a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/RelationDescriptionExtractor.kt b/backend/data/src/main/kotlin/io/tolgee/activity/views/RelationDescriptionExtractor.kt similarity index 94% rename from backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/RelationDescriptionExtractor.kt rename to backend/data/src/main/kotlin/io/tolgee/activity/views/RelationDescriptionExtractor.kt index 0572fdea18..0bcff5a1c5 100644 --- a/backend/data/src/main/kotlin/io/tolgee/activity/projectActivityView/RelationDescriptionExtractor.kt +++ b/backend/data/src/main/kotlin/io/tolgee/activity/views/RelationDescriptionExtractor.kt @@ -1,4 +1,4 @@ -package io.tolgee.activity.projectActivityView +package io.tolgee.activity.views import io.tolgee.activity.data.EntityDescriptionRef import io.tolgee.activity.data.EntityDescriptionWithRelations diff --git a/backend/data/src/main/kotlin/io/tolgee/batch/BatchJobActionService.kt b/backend/data/src/main/kotlin/io/tolgee/batch/BatchJobActionService.kt index 168712a90f..61ac9bcca1 100644 --- a/backend/data/src/main/kotlin/io/tolgee/batch/BatchJobActionService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/batch/BatchJobActionService.kt @@ -55,7 +55,6 @@ class BatchJobActionService( @EventListener(ApplicationReadyEvent::class) fun run() { - println("Application ready") concurrentExecutionLauncher.run { executionItem, coroutineContext -> var retryExecution: BatchJobChunkExecution? = null try { diff --git a/backend/data/src/main/kotlin/io/tolgee/batch/ProgressManager.kt b/backend/data/src/main/kotlin/io/tolgee/batch/ProgressManager.kt index f712347cc0..cc27c24c93 100644 --- a/backend/data/src/main/kotlin/io/tolgee/batch/ProgressManager.kt +++ b/backend/data/src/main/kotlin/io/tolgee/batch/ProgressManager.kt @@ -4,7 +4,7 @@ import io.tolgee.batch.data.BatchJobDto import io.tolgee.batch.events.OnBatchJobCancelled import io.tolgee.batch.events.OnBatchJobFailed import io.tolgee.batch.events.OnBatchJobProgress -import io.tolgee.batch.events.OnBatchJobStatusUpdated +import io.tolgee.batch.events.OnBatchJobStarted import io.tolgee.batch.events.OnBatchJobSucceeded import io.tolgee.batch.state.BatchJobStateProvider import io.tolgee.batch.state.ExecutionState @@ -130,7 +130,6 @@ class ProgressManager( } fun onJobCompletedCommitted(batchJob: BatchJobDto) { - eventPublisher.publishEvent(OnBatchJobStatusUpdated(batchJob.id, batchJob.projectId, batchJob.status)) cachingBatchJobService.evictJobCache(batchJob.id) batchJobProjectLockingManager.unlockJobForProject(batchJob.projectId, batchJob.id) batchJobStateProvider.removeJobState(batchJob.id) @@ -200,6 +199,7 @@ class ProgressManager( if (job.status == BatchJobStatus.PENDING) { logger.debug { """Updating job state to running ${job.id}""" } cachingBatchJobService.setRunningState(job.id) + eventPublisher.publishEvent(OnBatchJobStarted(job)) } } } diff --git a/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobFinalized.kt b/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobFinalized.kt deleted file mode 100644 index f73554f866..0000000000 --- a/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobFinalized.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.tolgee.batch.events - -import io.tolgee.batch.OnBatchJobCompleted -import io.tolgee.batch.data.BatchJobDto - -data class OnBatchJobFinalized( - override val job: BatchJobDto, -) : OnBatchJobCompleted diff --git a/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobStarted.kt b/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobStarted.kt new file mode 100644 index 0000000000..b12f8a0443 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobStarted.kt @@ -0,0 +1,21 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.batch.events + +import io.tolgee.batch.data.BatchJobDto + +data class OnBatchJobStarted(val job: BatchJobDto) diff --git a/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobStatusUpdated.kt b/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobStatusUpdated.kt deleted file mode 100644 index 1ff05fde54..0000000000 --- a/backend/data/src/main/kotlin/io/tolgee/batch/events/OnBatchJobStatusUpdated.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.tolgee.batch.events - -import io.tolgee.model.batch.BatchJobStatus - -class OnBatchJobStatusUpdated( - val jobId: Long, - val projectId: Long, - val status: BatchJobStatus, -) diff --git a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt index 2751bfd20d..eaa70cebc1 100644 --- a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt @@ -110,6 +110,14 @@ class TestDataService( executeInNewTransaction(transactionManager) { saveProjectData(builder) + + // These depend on users and projects, so they must be stored only after all the projects have been stored. + builder.data.userAccounts.forEach { + it.data.notificationPreferences.forEach { entityBuilder -> + entityManager.persist(entityBuilder.self) + } + } + finalize() } @@ -351,7 +359,7 @@ class TestDataService( } private fun saveAllKeyDependants(keyBuilders: List) { - val metas = keyBuilders.map { it.data.meta?.self }.filterNotNull() + val metas = keyBuilders.mapNotNull { it.data.meta?.self } tagService.saveAll(metas.flatMap { it.tags }) keyMetaService.saveAll(metas) } diff --git a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/builders/NotificationPreferencesBuilder.kt b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/builders/NotificationPreferencesBuilder.kt new file mode 100644 index 0000000000..d9281301aa --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/builders/NotificationPreferencesBuilder.kt @@ -0,0 +1,11 @@ +package io.tolgee.development.testDataBuilder.builders + +import io.tolgee.development.testDataBuilder.EntityDataBuilder +import io.tolgee.model.notifications.NotificationPreferences + +class NotificationPreferencesBuilder( + val userAccountBuilder: UserAccountBuilder, +) : EntityDataBuilder { + override var self: NotificationPreferences = + NotificationPreferences(userAccountBuilder.self, null, emptyArray()) +} diff --git a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/builders/UserAccountBuilder.kt b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/builders/UserAccountBuilder.kt index 6adf059fc7..02c434d073 100644 --- a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/builders/UserAccountBuilder.kt +++ b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/builders/UserAccountBuilder.kt @@ -4,6 +4,7 @@ import io.tolgee.development.testDataBuilder.FT import io.tolgee.model.Pat import io.tolgee.model.UserAccount import io.tolgee.model.UserPreferences +import io.tolgee.model.notifications.NotificationPreferences import org.springframework.core.io.ClassPathResource class UserAccountBuilder( @@ -17,6 +18,7 @@ class UserAccountBuilder( var avatarFile: ClassPathResource? = null var userPreferences: UserPreferencesBuilder? = null var pats: MutableList = mutableListOf() + var notificationPreferences: MutableList = mutableListOf() } var data = DATA() @@ -32,4 +34,6 @@ class UserAccountBuilder( } fun addPat(ft: FT) = addOperation(data.pats, ft) + + fun addNotificationPreferences(ft: FT) = addOperation(data.notificationPreferences, ft) } diff --git a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/NotificationSubscriptionTestData.kt b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/NotificationSubscriptionTestData.kt new file mode 100644 index 0000000000..5210ae8307 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/NotificationSubscriptionTestData.kt @@ -0,0 +1,109 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.development.testDataBuilder.data + +import io.tolgee.development.testDataBuilder.builders.TestDataBuilder +import io.tolgee.model.Organization +import io.tolgee.model.Project +import io.tolgee.model.UserAccount +import io.tolgee.model.enums.OrganizationRoleType +import io.tolgee.notifications.NotificationType + +class NotificationSubscriptionTestData { + lateinit var user1: UserAccount + lateinit var user2: UserAccount + + lateinit var organization: Organization + + lateinit var project1: Project + lateinit var project2: Project + + val root: TestDataBuilder = TestDataBuilder() + + init { + root.apply { + addUserAccount { + username = "admin" + role = UserAccount.Role.ADMIN + } + + val user1Builder = + addUserAccountWithoutOrganization { + name = "User 1" + username = "user1" + user1 = this + } + + val user2Builder = + addUserAccountWithoutOrganization { + name = "User 2" + username = "user2" + user2 = this + } + + addOrganization { + name = "Test org" + slug = "test-org" + + organization = this + + addProject { + name = "Test project 1" + slug = "project1" + organizationOwner = organization + + project1 = this + } + + addProject { + name = "Test project 2" + slug = "project2" + organizationOwner = organization + + project2 = this + } + }.build { + addRole { + user = user1 + type = OrganizationRoleType.OWNER + } + + addRole { + user = user2 + type = OrganizationRoleType.OWNER + } + } + + user1Builder.build { + addNotificationPreferences { + project = project2 + disabledNotifications = arrayOf(NotificationType.ACTIVITY_KEYS_CREATED) + } + } + + user2Builder.build { + addNotificationPreferences { + disabledNotifications = arrayOf(NotificationType.ACTIVITY_KEYS_CREATED) + } + + addNotificationPreferences { + project = project2 + } + } + } + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/NotificationsTestData.kt b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/NotificationsTestData.kt new file mode 100644 index 0000000000..833e5f2df2 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/NotificationsTestData.kt @@ -0,0 +1,331 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.development.testDataBuilder.data + +import io.tolgee.development.testDataBuilder.builders.TestDataBuilder +import io.tolgee.model.Language +import io.tolgee.model.Organization +import io.tolgee.model.Project +import io.tolgee.model.UserAccount +import io.tolgee.model.enums.OrganizationRoleType +import io.tolgee.model.enums.ProjectPermissionType +import io.tolgee.model.enums.Scope +import io.tolgee.model.enums.TranslationState +import io.tolgee.model.key.Key +import io.tolgee.model.translation.Translation + +class NotificationsTestData { + lateinit var admin: UserAccount + + lateinit var orgAdmin: UserAccount + lateinit var projectManager: UserAccount + lateinit var frenchTranslator: UserAccount + lateinit var czechTranslator: UserAccount + lateinit var germanTranslator: UserAccount + lateinit var frenchCzechTranslator: UserAccount + + lateinit var bob: UserAccount + lateinit var alice: UserAccount + + lateinit var acme: Organization + + lateinit var project1: Project + lateinit var project2: Project + lateinit var calmProject: Project // A project with only Alice in it for less notification noise + + lateinit var keyProject1: Key + lateinit var key1EnTranslation: Translation + lateinit var key1FrTranslation: Translation + lateinit var key1CzTranslation: Translation + + lateinit var keyProject2: Key + lateinit var key2EnTranslation: Translation + + lateinit var keyCalmProject: Key + lateinit var keyCalmEnTranslation: Translation + + lateinit var calmProjectFr: Language + + val root: TestDataBuilder = TestDataBuilder() + + init { + root.apply { + addUserAccount { + name = "Admin" + username = "admin" + isInitialUser = true + role = UserAccount.Role.ADMIN + + admin = this + } + + addUserAccountWithoutOrganization { + name = "Acme 1 chief" + username = "chief-acme-1" + + orgAdmin = this + } + + addUserAccountWithoutOrganization { + name = "Project manager" + username = "project-manager" + + projectManager = this + } + + addUserAccountWithoutOrganization { + name = "Translator (french)" + username = "french-translator" + + frenchTranslator = this + } + + addUserAccountWithoutOrganization { + name = "Translator (czech)" + username = "czech-translator" + + czechTranslator = this + } + + addUserAccountWithoutOrganization { + name = "Translator (german)" + username = "german-translator" + + germanTranslator = this + } + + addUserAccountWithoutOrganization { + name = "Translator (french and czech)" + username = "french-czech-translator" + + frenchCzechTranslator = this + } + + addUserAccount { + name = "Bob" + username = "bob" + + bob = this + } + + addUserAccount { + name = "Alice" + username = "alice" + + alice = this + }.build { + defaultOrganizationBuilder.let { + addProject { + name = "Calm project" + slug = "keep-it-cool" + organizationOwner = it.self + + calmProject = this + }.build { + val en = addEnglish() + calmProjectFr = addFrench().self + + val key = + addKey { + name = "some-key" + + this@NotificationsTestData.keyCalmProject = this@addKey + } + + addTranslation { + this.key = key.self + language = en.self + text = "Some translation" + + this@NotificationsTestData.keyCalmEnTranslation = this@addTranslation + } + } + } + } + + addOrganization { + name = "ACME Corporation" + slug = "acme" + + this@NotificationsTestData.acme = this@addOrganization + }.build { + addRole { + user = orgAdmin + type = OrganizationRoleType.OWNER + } + + addRole { + user = projectManager + type = OrganizationRoleType.MEMBER + } + + addRole { + user = frenchTranslator + type = OrganizationRoleType.MEMBER + } + + addRole { + user = czechTranslator + type = OrganizationRoleType.MEMBER + } + + addRole { + user = germanTranslator + type = OrganizationRoleType.MEMBER + } + + addRole { + user = frenchCzechTranslator + type = OrganizationRoleType.MEMBER + } + + addProject { + name = "Explosive Type-Checker" + slug = "explosive-type-checker" + organizationOwner = acme + + project1 = this + }.build { + val en = addEnglish() + val fr = addFrench() + val cz = addCzech() + val de = addGerman() + + val key = + addKey { + name = "some-key" + + this@NotificationsTestData.keyProject1 = this@addKey + } + + addTranslation { + this.key = key.self + language = en.self + text = "Some translation" + state = TranslationState.REVIEWED + + this@NotificationsTestData.key1EnTranslation = this@addTranslation + } + + addTranslation { + this.key = key.self + language = fr.self + text = "Some french translation" + state = TranslationState.REVIEWED + + this@NotificationsTestData.key1FrTranslation = this@addTranslation + } + + addTranslation { + this.key = key.self + language = cz.self + text = "Some czech translation" + + this@NotificationsTestData.key1CzTranslation = this@addTranslation + } + + // --- --- --- + addPermission { + user = projectManager + type = ProjectPermissionType.MANAGE + } + + addPermission { + user = frenchTranslator + type = ProjectPermissionType.EDIT + viewLanguages.add(en.self) + viewLanguages.add(fr.self) + translateLanguages.add(en.self) + translateLanguages.add(fr.self) + stateChangeLanguages.add(en.self) + stateChangeLanguages.add(fr.self) + } + + addPermission { + user = czechTranslator + type = ProjectPermissionType.EDIT + viewLanguages.add(en.self) + viewLanguages.add(cz.self) + translateLanguages.add(en.self) + translateLanguages.add(cz.self) + stateChangeLanguages.add(en.self) + stateChangeLanguages.add(cz.self) + } + + addPermission { + user = germanTranslator + type = ProjectPermissionType.EDIT + viewLanguages.add(en.self) + viewLanguages.add(de.self) + translateLanguages.add(en.self) + translateLanguages.add(de.self) + stateChangeLanguages.add(en.self) + stateChangeLanguages.add(de.self) + } + + addPermission { + user = frenchCzechTranslator + type = ProjectPermissionType.EDIT + viewLanguages.add(en.self) + viewLanguages.add(fr.self) + viewLanguages.add(cz.self) + translateLanguages.add(en.self) + translateLanguages.add(fr.self) + translateLanguages.add(cz.self) + stateChangeLanguages.add(en.self) + stateChangeLanguages.add(fr.self) + stateChangeLanguages.add(cz.self) + } + + addPermission { + user = bob + scopes = arrayOf(Scope.TRANSLATIONS_EDIT) + } + } + + addProject { + name = "Rocket-Powered Office Chair Controller" + slug = "rpocc" + organizationOwner = acme + + project2 = this + }.build { + val en = addEnglish() + val key = + addKey { + name = "some-key" + + this@NotificationsTestData.keyProject2 = this@addKey + } + + addTranslation { + this.key = key.self + language = en.self + text = "Some translation" + + this@NotificationsTestData.key2EnTranslation = this@addTranslation + } + + addPermission { + user = alice + scopes = arrayOf(Scope.TRANSLATIONS_EDIT, Scope.SCREENSHOTS_UPLOAD) + } + } + } + } + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/dtos/ComputedPermissionDto.kt b/backend/data/src/main/kotlin/io/tolgee/dtos/ComputedPermissionDto.kt index 8c75654358..107e6cda4c 100644 --- a/backend/data/src/main/kotlin/io/tolgee/dtos/ComputedPermissionDto.kt +++ b/backend/data/src/main/kotlin/io/tolgee/dtos/ComputedPermissionDto.kt @@ -77,9 +77,9 @@ class ComputedPermissionDto( ) companion object { - private fun getEmptyPermission( + fun getEmptyPermission( scopes: Array, - type: ProjectPermissionType, + type: ProjectPermissionType?, ): IPermission { return object : IPermission { override val scopes: Array @@ -94,7 +94,7 @@ class ComputedPermissionDto( get() = null override val stateChangeLanguageIds: Set? get() = null - override val type: ProjectPermissionType + override val type: ProjectPermissionType? get() = type override val granular: Boolean? get() = null diff --git a/backend/data/src/main/kotlin/io/tolgee/dtos/request/key/KeyScreenshotDto.kt b/backend/data/src/main/kotlin/io/tolgee/dtos/request/key/KeyScreenshotDto.kt index f890f042c5..878fdaed7b 100644 --- a/backend/data/src/main/kotlin/io/tolgee/dtos/request/key/KeyScreenshotDto.kt +++ b/backend/data/src/main/kotlin/io/tolgee/dtos/request/key/KeyScreenshotDto.kt @@ -3,10 +3,9 @@ package io.tolgee.dtos.request.key import io.swagger.v3.oas.annotations.media.Schema import io.tolgee.dtos.request.KeyInScreenshotPositionDto -class KeyScreenshotDto { - var text: String? = null - +data class KeyScreenshotDto( + var text: String? = null, @Schema(description = "Ids of screenshot uploaded with /v2/image-upload endpoint") - var uploadedImageId: Long = 0 - var positions: List? = null -} + var uploadedImageId: Long = 0, + var positions: List? = null, +) diff --git a/backend/data/src/main/kotlin/io/tolgee/model/EmailVerification.kt b/backend/data/src/main/kotlin/io/tolgee/model/EmailVerification.kt index 3c0cd8b330..f975d38499 100644 --- a/backend/data/src/main/kotlin/io/tolgee/model/EmailVerification.kt +++ b/backend/data/src/main/kotlin/io/tolgee/model/EmailVerification.kt @@ -20,7 +20,6 @@ data class EmailVerification( @Email var newEmail: String? = null, ) : AuditModel() { - @Suppress("JoinDeclarationAndAssignment") @OneToOne(optional = false) lateinit var userAccount: UserAccount diff --git a/backend/data/src/main/kotlin/io/tolgee/model/Permission.kt b/backend/data/src/main/kotlin/io/tolgee/model/Permission.kt index 97a950bb52..7041442e60 100644 --- a/backend/data/src/main/kotlin/io/tolgee/model/Permission.kt +++ b/backend/data/src/main/kotlin/io/tolgee/model/Permission.kt @@ -21,6 +21,7 @@ import jakarta.persistence.ManyToOne import jakarta.persistence.OneToOne import jakarta.persistence.PrePersist import jakarta.persistence.PreUpdate +import org.hibernate.Hibernate import org.hibernate.annotations.Parameter import org.hibernate.annotations.Type @@ -79,7 +80,7 @@ class Permission( * Languages for TRANSLATIONS_EDIT scope. * When specified, user is restricted to edit specific language translations. */ - @ManyToMany(fetch = FetchType.EAGER) + @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "permission_languages", inverseJoinColumns = [JoinColumn(name = "languages_id")]) var translateLanguages: MutableSet = mutableSetOf() @@ -87,14 +88,14 @@ class Permission( * Languages for TRANSLATIONS_EDIT scope. * When specified, user is restricted to edit specific language translations. */ - @ManyToMany(fetch = FetchType.EAGER) + @ManyToMany(fetch = FetchType.LAZY) var viewLanguages: MutableSet = mutableSetOf() /** * Languages for TRANSLATIONS_EDIT scope. * When specified, user is restricted to edit specific language translations. */ - @ManyToMany(fetch = FetchType.EAGER) + @ManyToMany(fetch = FetchType.LAZY) var stateChangeLanguages: MutableSet = mutableSetOf() constructor( @@ -132,14 +133,42 @@ class Permission( get() = this.project?.id override val organizationId: Long? get() = this.organization?.id - override val translateLanguageIds: Set? - get() = this.translateLanguages.map { it.id }.toSet() + + @Transient + private var fetchedViewLanguageIds: Set? = null + + @Transient + private var fetchedTranslateLanguageIds: Set? = null + + @Transient + private var fetchedStateChangeLanguageIds: Set? = null override val viewLanguageIds: Set? - get() = this.viewLanguages.map { it.id }.toSet() + get() { + if (fetchedViewLanguageIds == null || Hibernate.isInitialized(this.viewLanguages)) { + return this.viewLanguages.map { it.id }.toSet() + } + + return fetchedViewLanguageIds + } + + override val translateLanguageIds: Set? + get() { + if (fetchedTranslateLanguageIds == null || Hibernate.isInitialized(this.translateLanguages)) { + return this.translateLanguages.map { it.id }.toSet() + } + + return fetchedTranslateLanguageIds + } override val stateChangeLanguageIds: Set? - get() = this.stateChangeLanguages.map { it.id }.toSet() + get() { + if (fetchedStateChangeLanguageIds == null || Hibernate.isInitialized(this.stateChangeLanguages)) { + return this.stateChangeLanguages.map { it.id }.toSet() + } + + return fetchedStateChangeLanguageIds + } companion object { class PermissionListeners { @@ -163,4 +192,31 @@ class Permission( } } } + + class PermissionWithLanguageIdsWrapper( + val permission: Permission, + fetchedViewLanguageIds: Any?, + fetchedTranslateLanguageIds: Any?, + fetchedStateChangeLanguageIds: Any?, + ) { + init { + permission.fetchedViewLanguageIds = (fetchedViewLanguageIds as? String) + ?.split(',') + ?.map { e -> e.toLong() } + ?.toSet() + ?: emptySet() + + permission.fetchedTranslateLanguageIds = (fetchedTranslateLanguageIds as? String) + ?.split(',') + ?.map { e -> e.toLong() } + ?.toSet() + ?: emptySet() + + permission.fetchedStateChangeLanguageIds = (fetchedStateChangeLanguageIds as? String) + ?.split(',') + ?.map { e -> e.toLong() } + ?.toSet() + ?: emptySet() + } + } } diff --git a/backend/data/src/main/kotlin/io/tolgee/model/Project.kt b/backend/data/src/main/kotlin/io/tolgee/model/Project.kt index 7c6203a28f..36a4372b25 100644 --- a/backend/data/src/main/kotlin/io/tolgee/model/Project.kt +++ b/backend/data/src/main/kotlin/io/tolgee/model/Project.kt @@ -78,7 +78,6 @@ class Project( @OneToMany(fetch = FetchType.LAZY, mappedBy = "project") var apiKeys: MutableSet = LinkedHashSet() - @Suppress("SetterBackingFieldAssignment") @ManyToOne(optional = true, fetch = FetchType.LAZY) @Deprecated(message = "Project can be owned only by organization") var userOwner: UserAccount? = null @@ -109,16 +108,16 @@ class Project( @Transient override var disableActivityLogging = false - @OneToMany(orphanRemoval = true, mappedBy = "project") + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "project") var automations: MutableList = mutableListOf() - @OneToMany(orphanRemoval = true, mappedBy = "project") + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "project") var contentDeliveryConfigs: MutableList = mutableListOf() - @OneToMany(orphanRemoval = true, mappedBy = "project") + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "project") var contentStorages: MutableList = mutableListOf() - @OneToMany(orphanRemoval = true, mappedBy = "project") + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "project") var webhookConfigs: MutableList = mutableListOf() @ColumnDefault("true") diff --git a/backend/data/src/main/kotlin/io/tolgee/model/UserAccount.kt b/backend/data/src/main/kotlin/io/tolgee/model/UserAccount.kt index 6631236051..c5960ca44c 100644 --- a/backend/data/src/main/kotlin/io/tolgee/model/UserAccount.kt +++ b/backend/data/src/main/kotlin/io/tolgee/model/UserAccount.kt @@ -2,6 +2,8 @@ package io.tolgee.model import io.hypersistence.utils.hibernate.type.array.ListArrayType import io.tolgee.api.IUserAccount +import io.tolgee.model.notifications.NotificationPreferences +import io.tolgee.model.notifications.UserNotification import jakarta.persistence.CascadeType import jakarta.persistence.Column import jakarta.persistence.Entity @@ -17,6 +19,7 @@ import jakarta.persistence.OrderBy import jakarta.validation.constraints.NotBlank import org.hibernate.annotations.ColumnDefault import org.hibernate.annotations.Type +import org.hibernate.annotations.Where import java.util.* @Entity @@ -88,25 +91,19 @@ data class UserAccount( @ColumnDefault("true") var passwordChanged: Boolean = true - constructor( - id: Long?, - username: String?, - password: String?, - name: String?, - permissions: MutableSet, - role: Role = Role.USER, - accountType: AccountType = AccountType.LOCAL, - thirdPartyAuthType: String?, - thirdPartyAuthId: String?, - resetPasswordCode: String?, - ) : this(id = 0L, username = "", password, name = "") { - this.permissions = permissions - this.role = role - this.accountType = accountType - this.thirdPartyAuthType = thirdPartyAuthType - this.thirdPartyAuthId = thirdPartyAuthId - this.resetPasswordCode = resetPasswordCode - } + @OneToMany(fetch = FetchType.LAZY, cascade = [CascadeType.REMOVE], orphanRemoval = true, mappedBy = "recipient") + var userNotifications: MutableList = mutableListOf() + + @Where(clause = "project_id IS NOT NULL") + @OneToMany(fetch = FetchType.LAZY, cascade = [CascadeType.REMOVE], orphanRemoval = true, mappedBy = "userAccount") + var projectNotificationPreferences: MutableList = mutableListOf() + + @Where(clause = "project_id IS NULL") + @OneToMany(fetch = FetchType.LAZY, cascade = [CascadeType.REMOVE], orphanRemoval = true, mappedBy = "userAccount") + private var _globalNotificationPreferences: MutableList = mutableListOf() + + val globalNotificationPreferences: NotificationPreferences? + get() = _globalNotificationPreferences.firstOrNull() enum class Role { USER, diff --git a/backend/data/src/main/kotlin/io/tolgee/model/contentDelivery/S3ContentStorageConfig.kt b/backend/data/src/main/kotlin/io/tolgee/model/contentDelivery/S3ContentStorageConfig.kt index 8611958ead..3ff25ffbd6 100644 --- a/backend/data/src/main/kotlin/io/tolgee/model/contentDelivery/S3ContentStorageConfig.kt +++ b/backend/data/src/main/kotlin/io/tolgee/model/contentDelivery/S3ContentStorageConfig.kt @@ -9,7 +9,7 @@ import jakarta.persistence.MapsId import jakarta.persistence.OneToOne import jakarta.validation.constraints.NotBlank -@Entity() +@Entity class S3ContentStorageConfig( @MapsId @JoinColumn(name = "content_storage_id") diff --git a/backend/data/src/main/kotlin/io/tolgee/model/notifications/NotificationPreferences.kt b/backend/data/src/main/kotlin/io/tolgee/model/notifications/NotificationPreferences.kt new file mode 100644 index 0000000000..4770be5717 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/model/notifications/NotificationPreferences.kt @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.model.notifications + +import io.hypersistence.utils.hibernate.type.array.EnumArrayType +import io.tolgee.model.Project +import io.tolgee.model.UserAccount +import io.tolgee.notifications.NotificationType +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType +import jakarta.persistence.Id +import jakarta.persistence.Index +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.Table +import org.hibernate.annotations.Parameter +import org.hibernate.annotations.Type + +@Entity +@Table( + indexes = [ + Index( + name = "notification_preferences_user_project", + columnList = "user_account_id, project_id", + unique = true, + ), + Index( + name = "notification_preferences_user", + columnList = "user_account_id", + ), + Index( + name = "notification_preferences_project", + columnList = "project_id", + ), + ], +) +class NotificationPreferences( + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false) + val userAccount: UserAccount, + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = true) + var project: Project?, + @Type(EnumArrayType::class, parameters = [Parameter(name = EnumArrayType.SQL_ARRAY_TYPE, value = "varchar")]) + @Column(nullable = false, columnDefinition = "varchar[]") + var disabledNotifications: Array, +) { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long = 0L +} diff --git a/backend/data/src/main/kotlin/io/tolgee/model/notifications/UserNotification.kt b/backend/data/src/main/kotlin/io/tolgee/model/notifications/UserNotification.kt new file mode 100644 index 0000000000..7e531c5c7a --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/model/notifications/UserNotification.kt @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.model.notifications + +import io.tolgee.model.Project +import io.tolgee.model.UserAccount +import io.tolgee.model.activity.ActivityModifiedEntity +import io.tolgee.model.batch.BatchJob +import io.tolgee.notifications.NotificationType +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated +import jakarta.persistence.FetchType +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType +import jakarta.persistence.Id +import jakarta.persistence.JoinColumn +import jakarta.persistence.JoinTable +import jakarta.persistence.ManyToMany +import jakarta.persistence.ManyToOne +import jakarta.persistence.OrderBy +import jakarta.persistence.SequenceGenerator +import jakarta.persistence.Temporal +import jakarta.persistence.TemporalType +import org.hibernate.annotations.ColumnDefault +import org.hibernate.annotations.UpdateTimestamp +import java.util.* + +@Entity +class UserNotification( + @Column(nullable = false) + @Enumerated(EnumType.STRING) + val type: NotificationType, + // This data is very likely to be useless when consuming the entity: lazy + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false) + val recipient: UserAccount, + // We most definitely need this to show the notification: eager + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(nullable = true) + val project: Project?, + // We most definitely need this to show the notification: eager + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "user_notification_modified_entities") + val modifiedEntities: MutableList = mutableListOf(), + // We most definitely need this to show the notification: eager + @ManyToOne(fetch = FetchType.EAGER) + val batchJob: BatchJob? = null, +) { + @Id + @SequenceGenerator(name = "notification_seq", sequenceName = "sequence_notifications") + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "notification_seq") + val id: Long = 0 + + @Column(nullable = false) + @ColumnDefault("true") + var unread: Boolean = true + + @Temporal(TemporalType.TIMESTAMP) + var markedDoneAt: Date? = null + + @OrderBy + @UpdateTimestamp + @Temporal(TemporalType.TIMESTAMP) + val lastUpdated: Date = Date() +} diff --git a/backend/data/src/main/kotlin/io/tolgee/model/views/UserAccountProjectPermissionsNotificationPreferencesDataView.kt b/backend/data/src/main/kotlin/io/tolgee/model/views/UserAccountProjectPermissionsNotificationPreferencesDataView.kt new file mode 100644 index 0000000000..7d1252e8c1 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/model/views/UserAccountProjectPermissionsNotificationPreferencesDataView.kt @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.model.views + +import io.tolgee.model.OrganizationRole +import io.tolgee.model.Permission +import io.tolgee.model.enums.OrganizationRoleType +import io.tolgee.model.enums.ProjectPermissionType +import io.tolgee.model.enums.Scope +import io.tolgee.model.notifications.NotificationPreferences +import jakarta.persistence.Id +import jakarta.persistence.OneToMany + +data class UserProjectMetadata( + @Id + val id: Long, + @Id + val projectId: Long, + @OneToMany + val organizationRole: OrganizationRole?, + @OneToMany + val basePermissions: Permission?, + @OneToMany + val permissions: Permission?, + @OneToMany + val globalNotificationPreferences: NotificationPreferences?, + @OneToMany + val projectNotificationPreferences: NotificationPreferences?, +) { + val notificationPreferences + get() = projectNotificationPreferences ?: globalNotificationPreferences +} + +class UserAccountProjectPermissionsNotificationPreferencesDataView(data: Map) { + init { + println(data["permittedViewLanguages"]) + } + + val id = data["id"] as? Long ?: throw IllegalArgumentException() + + val projectId = data["projectId"] as? Long ?: throw IllegalArgumentException() + + val organizationRole = data["organizationRole"] as? OrganizationRoleType + + val basePermissionsBasic = data["basePermissionsBasic"] as? ProjectPermissionType + + val basePermissionsGranular = + (data["basePermissionsGranular"] as? Array<*>) + ?.map { enumValueOf((it as? Enum<*>)?.name ?: throw IllegalArgumentException()) } + + val permissionsBasic = data["permissionsBasic"] as? ProjectPermissionType + + val permissionsGranular = + (data["permissionsGranular"] as? Array<*>) + ?.map { enumValueOf((it as? Enum<*>)?.name ?: throw IllegalArgumentException()) } + + val permittedViewLanguages = + (data["permittedViewLanguages"] as? Array<*>) + ?.map { (it as? String)?.toLong() ?: throw IllegalArgumentException() } + + val notificationPreferences = + (data["projectNotificationPreferences"] ?: data["globalNotificationPreferences"]) + as? NotificationPreferences +} diff --git a/backend/data/src/main/kotlin/io/tolgee/model/views/UserProjectMetadataView.kt b/backend/data/src/main/kotlin/io/tolgee/model/views/UserProjectMetadataView.kt new file mode 100644 index 0000000000..51b99f231c --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/model/views/UserProjectMetadataView.kt @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.model.views + +import io.tolgee.model.Permission +import io.tolgee.model.enums.OrganizationRoleType +import io.tolgee.model.notifications.NotificationPreferences + +class UserProjectMetadataView( + val userAccountId: Long, + val projectId: Long, + val organizationRole: OrganizationRoleType?, + basePermissions: Permission?, + fetchedBaseViewLanguages: Any?, + permissions: Permission?, + fetchedViewLanguages: Any?, + globalNotificationPreferences: NotificationPreferences?, + projectNotificationPreferences: NotificationPreferences?, +) { + val notificationPreferences = projectNotificationPreferences ?: globalNotificationPreferences + + val basePermissions = + basePermissions?.let { + println(basePermissions) + Permission.PermissionWithLanguageIdsWrapper( + basePermissions, + fetchedBaseViewLanguages, + null, + null, + ) + }?.permission + + val permissions = + permissions?.let { + Permission.PermissionWithLanguageIdsWrapper( + permissions, + fetchedViewLanguages, + null, + null, + ) + }?.permission +} diff --git a/backend/data/src/main/kotlin/io/tolgee/model/views/activity/SimpleModifiedEntityView.kt b/backend/data/src/main/kotlin/io/tolgee/model/views/activity/SimpleModifiedEntityView.kt new file mode 100644 index 0000000000..b04287a8df --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/model/views/activity/SimpleModifiedEntityView.kt @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.model.views.activity + +import io.tolgee.activity.data.ExistenceEntityDescription +import io.tolgee.activity.data.PropertyModification + +data class SimpleModifiedEntityView( + val entityClass: String, + val entityId: Long, + val exists: Boolean?, + var modifications: Map = mutableMapOf(), + var description: Map? = null, + var describingRelations: Map? = null, +) diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationPreferencesService.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationPreferencesService.kt new file mode 100644 index 0000000000..031cd92ebf --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationPreferencesService.kt @@ -0,0 +1,138 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.exceptions.NotFoundException +import io.tolgee.model.Project +import io.tolgee.model.UserAccount +import io.tolgee.model.notifications.NotificationPreferences +import io.tolgee.notifications.dto.NotificationPreferencesDto +import io.tolgee.repository.notifications.NotificationPreferencesRepository +import io.tolgee.service.security.SecurityService +import jakarta.persistence.EntityManager +import org.springframework.stereotype.Service + +@Service +class NotificationPreferencesService( + private val entityManager: EntityManager, + private val notificationPreferencesRepository: NotificationPreferencesRepository, + private val securityService: SecurityService, +) { + fun getAllPreferences(user: Long): Map { + return notificationPreferencesRepository.findAllByUserAccountId(user) + .associate { + val key = it.project?.id?.toString() ?: "global" + val dto = NotificationPreferencesDto.fromEntity(it) + Pair(key, dto) + } + } + + fun getGlobalPreferences(user: Long): NotificationPreferencesDto { + val entity = + notificationPreferencesRepository.findByUserAccountIdAndProjectId(user, null) + ?: return NotificationPreferencesDto.createBlank() + + return NotificationPreferencesDto.fromEntity(entity) + } + + fun getProjectPreferences( + user: Long, + project: Long, + ): NotificationPreferencesDto { + // If the user cannot see the project, the project "does not exist". + val scopes = securityService.getProjectPermissionScopesNoApiKey(project, user) ?: emptyArray() + if (scopes.isEmpty()) throw NotFoundException() + + val entity = + notificationPreferencesRepository.findByUserAccountIdAndProjectId(user, null) + ?: throw NotFoundException() + + return NotificationPreferencesDto.fromEntity(entity) + } + + fun setPreferencesOfUser( + user: Long, + dto: NotificationPreferencesDto, + ): NotificationPreferences { + return setPreferencesOfUser( + entityManager.getReference(UserAccount::class.java, user), + dto, + ) + } + + fun setPreferencesOfUser( + user: UserAccount, + dto: NotificationPreferencesDto, + ): NotificationPreferences { + return doSetPreferencesOfUser(user, null, dto) + } + + fun setProjectPreferencesOfUser( + user: Long, + project: Long, + dto: NotificationPreferencesDto, + ): NotificationPreferences { + return setProjectPreferencesOfUser( + entityManager.getReference(UserAccount::class.java, user), + entityManager.getReference(Project::class.java, project), + dto, + ) + } + + fun setProjectPreferencesOfUser( + user: UserAccount, + project: Project, + dto: NotificationPreferencesDto, + ): NotificationPreferences { + // If the user cannot see the project, the project "does not exist". + val scopes = securityService.getProjectPermissionScopesNoApiKey(project.id, user.id) ?: emptyArray() + if (scopes.isEmpty()) throw NotFoundException() + + return doSetPreferencesOfUser(user, project, dto) + } + + private fun doSetPreferencesOfUser( + user: UserAccount, + project: Project?, + dto: NotificationPreferencesDto, + ): NotificationPreferences { + // Hidden as a private function as the fact global prefs and project overrides are the "same" is an implementation + // detail that should not be relied on by consumer of this service. + return notificationPreferencesRepository.save( + NotificationPreferences( + user, + project, + dto.disabledNotifications.toTypedArray(), + ), + ) + } + + fun deleteProjectPreferencesOfUser( + user: Long, + project: Long, + ) { + notificationPreferencesRepository.deleteByUserAccountIdAndProjectId(user, project) + } + + fun deleteAllByUserId(userId: Long) { + notificationPreferencesRepository.deleteAllByUserId(userId) + } + + fun deleteAllByProjectId(projectId: Long) { + notificationPreferencesRepository.deleteAllByProjectId(projectId) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationStatus.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationStatus.kt new file mode 100644 index 0000000000..d80da10164 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationStatus.kt @@ -0,0 +1,23 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +enum class NotificationStatus { + UNREAD, + READ, + DONE, +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationType.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationType.kt new file mode 100644 index 0000000000..cf66b8fffc --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/NotificationType.kt @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import java.util.* + +enum class NotificationType { + ACTIVITY_LANGUAGES_CREATED, + ACTIVITY_KEYS_CREATED, + ACTIVITY_KEYS_UPDATED, + ACTIVITY_KEYS_SCREENSHOTS_UPLOADED, + ACTIVITY_SOURCE_STRINGS_UPDATED, + ACTIVITY_TRANSLATIONS_UPDATED, + ACTIVITY_TRANSLATION_OUTDATED, + ACTIVITY_TRANSLATION_REVIEWED, + ACTIVITY_TRANSLATION_UNREVIEWED, + ACTIVITY_NEW_COMMENTS, + ACTIVITY_COMMENTS_MENTION, + + BATCH_JOB_ERRORED, + ; + + companion object { + val ACTIVITY_NOTIFICATIONS: EnumSet = + EnumSet.of( + ACTIVITY_LANGUAGES_CREATED, + ACTIVITY_KEYS_CREATED, + ACTIVITY_KEYS_UPDATED, + ACTIVITY_KEYS_SCREENSHOTS_UPLOADED, + ACTIVITY_SOURCE_STRINGS_UPDATED, + ACTIVITY_TRANSLATIONS_UPDATED, + ACTIVITY_TRANSLATION_OUTDATED, + ACTIVITY_TRANSLATION_REVIEWED, + ACTIVITY_TRANSLATION_UNREVIEWED, + ACTIVITY_NEW_COMMENTS, + ACTIVITY_COMMENTS_MENTION, + ) + + val BATCH_JOB_NOTIFICATIONS: EnumSet = + EnumSet.of( + BATCH_JOB_ERRORED, + ) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/UserNotificationDebouncer.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/UserNotificationDebouncer.kt new file mode 100644 index 0000000000..b3e7fa399c --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/UserNotificationDebouncer.kt @@ -0,0 +1,158 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.model.UserAccount +import io.tolgee.model.activity.ActivityModifiedEntity +import io.tolgee.model.notifications.UserNotification +import io.tolgee.model.translation.Translation +import io.tolgee.model.translation.TranslationComment +import io.tolgee.notifications.dto.NotificationCreateDto +import io.tolgee.notifications.dto.UserNotificationParamsDto +import io.tolgee.repository.notifications.UserNotificationRepository +import org.springframework.stereotype.Component +import java.util.* + +typealias UserNotificationDebounceResult = Pair, List> + +/** + * Component responsible for debouncing notifications based on existing notifications for a given user. + */ +@Component +class UserNotificationDebouncer( + private val userNotificationRepository: UserNotificationRepository, +) { + /** + * Updates existing notifications when possible according to the debouncing policy. + * + * @return A pair of the notifications which have been updated, and the remaining notifications to process. + */ + fun debounce( + notificationDto: NotificationCreateDto, + params: List, + ): UserNotificationDebounceResult { + if (NotificationType.ACTIVITY_NOTIFICATIONS.contains(notificationDto.type)) { + return debounceActivityNotification(notificationDto, params) + } + + return Pair(emptyList(), params) + } + + // -- + // Activity-related notifications + // -- + private fun debounceActivityNotification( + notificationDto: NotificationCreateDto, + params: List, + ): UserNotificationDebounceResult { + val debouncedUserNotifications = mutableListOf() + val notificationsToProcess = mutableListOf() + val notifications = fetchRelevantActivityNotifications(notificationDto, params.map { it.recipient }) + + params.forEach { + if (notifications.containsKey(it.recipient.id)) { + val notification = notifications[it.recipient.id]!! + notificationDto.mergeIntoUserNotificationEntity(notification, it) + debouncedUserNotifications.add(notification) + } else { + notificationsToProcess.add(it) + } + } + + return Pair(debouncedUserNotifications, notificationsToProcess) + } + + private fun fetchRelevantActivityNotifications( + notificationDto: NotificationCreateDto, + recipients: List, + ): Map { + val notifications = + when { + translationUpdateNotificationTypes.contains(notificationDto.type) -> + findCandidatesForTranslationUpdateNotificationDebouncing( + notificationDto.type, + notificationDto.projectId, + recipients, + notificationDto.modifiedEntities, + ) + + commentNotificationTypes.contains(notificationDto.type) -> + findCandidatesForCommentNotificationDebouncing( + notificationDto.projectId, + recipients, + notificationDto.modifiedEntities, + ) + + else -> + userNotificationRepository.findCandidatesForNotificationDebouncing( + notificationDto.type, + notificationDto.projectId, + recipients, + ) + } + + return notifications.associateBy { it.recipient.id } + } + + private fun findCandidatesForTranslationUpdateNotificationDebouncing( + type: NotificationType, + projectId: Long, + recipients: List, + entities: List?, + ): List { + val keyId = + entities?.find { it.entityClass == Translation::class.simpleName } + ?.describingRelations?.get("key")?.entityId ?: 0L + + return userNotificationRepository.findCandidatesForTranslationUpdateNotificationDebouncing( + type, + projectId, + recipients, + keyId, + ) + } + + private fun findCandidatesForCommentNotificationDebouncing( + projectId: Long, + recipients: List, + entities: List?, + ): List { + val translationId = + entities?.find { it.entityClass == TranslationComment::class.simpleName } + ?.describingRelations?.get("translation")?.entityId ?: 0L + + return userNotificationRepository.findCandidatesForCommentNotificationDebouncing( + projectId, + recipients, + translationId, + ) + } + + companion object { + val translationUpdateNotificationTypes: EnumSet = + EnumSet.of( + NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED, + NotificationType.ACTIVITY_TRANSLATIONS_UPDATED, + ) + + val commentNotificationTypes: EnumSet = + EnumSet.of( + NotificationType.ACTIVITY_NEW_COMMENTS, + NotificationType.ACTIVITY_COMMENTS_MENTION, + ) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/UserNotificationService.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/UserNotificationService.kt new file mode 100644 index 0000000000..976439015e --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/UserNotificationService.kt @@ -0,0 +1,141 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications + +import io.tolgee.model.notifications.UserNotification +import io.tolgee.notifications.dto.NotificationCreateDto +import io.tolgee.notifications.dto.UserNotificationParamsDto +import io.tolgee.notifications.events.UserNotificationPushEvent +import io.tolgee.repository.notifications.UserNotificationRepository +import jakarta.persistence.EntityManager +import org.springframework.context.ApplicationEventPublisher +import org.springframework.data.domain.Pageable +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class UserNotificationService( + private val entityManager: EntityManager, + private val userNotificationRepository: UserNotificationRepository, + private val applicationEventPublisher: ApplicationEventPublisher, + private val userNotificationDebouncer: UserNotificationDebouncer, +) { + @Transactional + fun dispatchNotification( + notificationDto: NotificationCreateDto, + params: UserNotificationParamsDto, + ) { + return dispatchNotifications(notificationDto, listOf(params)) + } + + @Transactional + fun dispatchNotifications( + notificationDto: NotificationCreateDto, + params: List, + ) { + val createdUserNotificationObjects = mutableSetOf() + val updatedUserNotificationObjects = mutableSetOf() + + val (processed, remaining) = userNotificationDebouncer.debounce(notificationDto, params) + updatedUserNotificationObjects.addAll( + userNotificationRepository.saveAll(processed), + ) + + remaining.forEach { + val notification = notificationDto.toUserNotificationEntity(it, entityManager) + createdUserNotificationObjects.add( + userNotificationRepository.save(notification), + ) + } + + // Dispatch event + applicationEventPublisher.publishEvent( + UserNotificationPushEvent( + createdUserNotificationObjects, + updatedUserNotificationObjects, + ), + ) + } + + fun findNotificationsOfUserFilteredPaged( + user: Long, + status: Set, + pageable: Pageable, + ): List { + return userNotificationRepository.findNotificationsOfUserFilteredPaged( + user, + status.map { it.toString() }, + pageable, + ) + } + + fun getUnreadNotificationsCount(user: Long): Int { + return userNotificationRepository.countNotificationsByRecipientIdAndUnreadTrue(user) + } + + @Transactional + fun markAsRead( + user: Long, + notifications: Collection, + ) { + return userNotificationRepository.markAsRead(user, notifications) + } + + @Transactional + fun markAllAsRead(user: Long) { + return userNotificationRepository.markAllAsRead(user) + } + + @Transactional + fun markAsUnread( + user: Long, + notifications: Collection, + ) { + return userNotificationRepository.markAsUnread(user, notifications) + } + + @Transactional + fun markAsDone( + user: Long, + notifications: Collection, + ) { + return userNotificationRepository.markAsDone(user, notifications) + } + + @Transactional + fun markAllAsDone(user: Long) { + return userNotificationRepository.markAllAsDone(user) + } + + @Transactional + fun unmarkAsDone( + user: Long, + notifications: Collection, + ) { + return userNotificationRepository.unmarkAsDone(user, notifications) + } + + @Transactional + fun deleteAllByUserId(userId: Long) { + userNotificationRepository.deleteAllByUserId(userId) + } + + @Transactional + fun deleteAllByProjectId(projectId: Long) { + userNotificationRepository.deleteAllByProjectId(projectId) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/dispatchers/UserNotificationDispatch.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/dispatchers/UserNotificationDispatch.kt new file mode 100644 index 0000000000..53f371f36f --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/dispatchers/UserNotificationDispatch.kt @@ -0,0 +1,158 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.dispatchers + +import io.tolgee.dtos.ComputedPermissionDto +import io.tolgee.model.Screenshot +import io.tolgee.model.UserAccount +import io.tolgee.model.activity.ActivityModifiedEntity +import io.tolgee.model.enums.Scope +import io.tolgee.model.translation.Translation +import io.tolgee.model.views.UserProjectMetadataView +import io.tolgee.notifications.NotificationType +import io.tolgee.notifications.UserNotificationService +import io.tolgee.notifications.dto.UserNotificationParamsDto +import io.tolgee.notifications.events.NotificationCreateEvent +import io.tolgee.service.LanguageService +import io.tolgee.service.security.PermissionService +import io.tolgee.service.security.UserAccountService +import io.tolgee.util.Logging +import io.tolgee.util.logger +import jakarta.persistence.EntityManager +import org.springframework.context.event.EventListener +import org.springframework.scheduling.annotation.Async +import org.springframework.scheduling.annotation.EnableAsync +import org.springframework.stereotype.Component + +@Component +@EnableAsync(proxyTargetClass = true) +class UserNotificationDispatch( + private val userAccountService: UserAccountService, + private val permissionService: PermissionService, + private val languageService: LanguageService, + private val userNotificationService: UserNotificationService, + private val entityManager: EntityManager, +) : Logging { + @Async + @EventListener + fun onNotificationCreate(e: NotificationCreateEvent) { + logger.trace("Received notification creation event {}", e) + + when { + NotificationType.ACTIVITY_NOTIFICATIONS.contains(e.notification.type) -> + handleActivityNotification(e) + NotificationType.BATCH_JOB_NOTIFICATIONS.contains(e.notification.type) -> + handleBatchJobNotification(e) + else -> + throw IllegalStateException("Encountered invalid notification type ${e.notification.type}") + } + } + + private fun handleActivityNotification(e: NotificationCreateEvent) { + val users = + userAccountService.getAllConnectedUserProjectMetadataViews(e.notification.projectId) + .filter { + it.notificationPreferences?.disabledNotifications?.contains(e.notification.type) != true && + it.userAccountId != e.responsibleUserId + } + + val translationToLanguageMap = + e.notification.modifiedEntities!! + .filter { it.entityClass == Translation::class.simpleName } + .map { it.entityId } + .let { if (it.isEmpty()) emptyMap() else languageService.findLanguageIdsOfTranslations(it) } + + val notifications = + users.mapNotNull { + handleActivityNotificationForUser(e, translationToLanguageMap, it) + } + + userNotificationService.dispatchNotifications(e.notification, notifications) + } + + private fun handleBatchJobNotification(e: NotificationCreateEvent) { + // Only send a full notification for job failures. + if (e.notification.type != NotificationType.BATCH_JOB_ERRORED) return + + val batchJob = e.notification.batchJob!! + val author = batchJob.author ?: return + userNotificationService.dispatchNotification( + e.notification, + UserNotificationParamsDto(author), + ) + } + + private fun handleActivityNotificationForUser( + e: NotificationCreateEvent, + translationToLanguageMap: Map, + userProjectMetadataView: UserProjectMetadataView, + ): UserNotificationParamsDto? { + val permissions = + permissionService.computeProjectPermission( + userProjectMetadataView.organizationRole, + userProjectMetadataView.basePermissions, + userProjectMetadataView.permissions, + ) + + // Filter the entities the user is allowed to see + val filteredModifiedEntities = + filterModifiedEntities( + e.notification.modifiedEntities!!, + permissions, + translationToLanguageMap, + ) + + if (filteredModifiedEntities.isEmpty()) return null + + return UserNotificationParamsDto( + recipient = entityManager.getReference(UserAccount::class.java, userProjectMetadataView.userAccountId), + modifiedEntities = filteredModifiedEntities.toSet(), + ) + } + + private fun filterModifiedEntities( + modifiedEntities: List, + permissions: ComputedPermissionDto, + translationToLanguageMap: Map, + ): Set { + return modifiedEntities + .filter { + when (it.entityClass) { + Screenshot::class.simpleName -> + isUserAllowedToSeeScreenshot(permissions) + Translation::class.simpleName -> + isUserAllowedToSeeTranslation(it, permissions, translationToLanguageMap) + else -> true + } + }.toSet() + } + + private fun isUserAllowedToSeeScreenshot(permissions: ComputedPermissionDto): Boolean { + return permissions.expandedScopes.contains(Scope.SCREENSHOTS_VIEW) + } + + private fun isUserAllowedToSeeTranslation( + entity: ActivityModifiedEntity, + permissions: ComputedPermissionDto, + translationToLanguageMap: Map, + ): Boolean { + if (!permissions.expandedScopes.contains(Scope.TRANSLATIONS_VIEW)) return false + + val language = translationToLanguageMap[entity.entityId] ?: return false + return permissions.viewLanguageIds.isNullOrEmpty() || permissions.viewLanguageIds.contains(language) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/dto/NotificationCreateDto.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/dto/NotificationCreateDto.kt new file mode 100644 index 0000000000..96e4745a59 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/dto/NotificationCreateDto.kt @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.dto + +import io.tolgee.model.Project +import io.tolgee.model.activity.ActivityModifiedEntity +import io.tolgee.model.batch.BatchJob +import io.tolgee.model.notifications.UserNotification +import io.tolgee.notifications.NotificationType +import jakarta.persistence.EntityManager + +data class NotificationCreateDto( + val type: NotificationType, + val projectId: Long, + val modifiedEntities: MutableList? = null, + val batchJob: BatchJob? = null, +) { + fun toUserNotificationEntity( + params: UserNotificationParamsDto, + em: EntityManager, + ): UserNotification { + return UserNotification( + type = type, + recipient = params.recipient, + project = em.getReference(Project::class.java, projectId), + modifiedEntities = params.modifiedEntities.toMutableList(), + ) + } + + fun mergeIntoUserNotificationEntity( + userNotification: UserNotification, + params: UserNotificationParamsDto, + ) { + when { + NotificationType.ACTIVITY_NOTIFICATIONS.contains(userNotification.type) -> + mergeIntoNotificationEntityActivity(userNotification, params) + + else -> + throw IllegalArgumentException("Cannot merge notifications of type ${userNotification.type}") + } + } + + private fun mergeIntoNotificationEntityActivity( + userNotification: UserNotification, + params: UserNotificationParamsDto, + ) { + userNotification.modifiedEntities.addAll(params.modifiedEntities) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/dto/NotificationPreferencesDto.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/dto/NotificationPreferencesDto.kt new file mode 100644 index 0000000000..6b1051d5c6 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/dto/NotificationPreferencesDto.kt @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.dto + +import io.swagger.v3.oas.annotations.media.Schema +import io.tolgee.model.notifications.NotificationPreferences +import io.tolgee.notifications.NotificationType + +data class NotificationPreferencesDto( + @Schema(description = "List of notification types the user does not want to receive.") + val disabledNotifications: List, +) { + companion object { + fun fromEntity(notificationPreferences: NotificationPreferences): NotificationPreferencesDto { + return NotificationPreferencesDto( + notificationPreferences.disabledNotifications.toList(), + ) + } + + fun createBlank(): NotificationPreferencesDto { + return NotificationPreferencesDto(emptyList()) + } + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/dto/UserNotificationParamsDto.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/dto/UserNotificationParamsDto.kt new file mode 100644 index 0000000000..5637526046 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/dto/UserNotificationParamsDto.kt @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.dto + +import io.tolgee.model.UserAccount +import io.tolgee.model.activity.ActivityModifiedEntity + +data class UserNotificationParamsDto( + val recipient: UserAccount, + val modifiedEntities: Set = emptySet(), +) diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/events/NotificationCreateEvent.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/events/NotificationCreateEvent.kt new file mode 100644 index 0000000000..ecb6874973 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/events/NotificationCreateEvent.kt @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.events + +import io.tolgee.notifications.dto.NotificationCreateDto + +data class NotificationCreateEvent( + val notification: NotificationCreateDto, + val responsibleUserId: Long?, + val source: Any? = null, +) diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/events/UserNotificationPushEvent.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/events/UserNotificationPushEvent.kt new file mode 100644 index 0000000000..980aeec1b5 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/events/UserNotificationPushEvent.kt @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.events + +import io.tolgee.model.notifications.UserNotification + +/** + * Event sent when a set of users received a new notification. + */ +data class UserNotificationPushEvent( + val createdNotifications: Set, + val updatedNotifications: Set, +) diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/listeners/ActivityEventListener.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/listeners/ActivityEventListener.kt new file mode 100644 index 0000000000..77e5ce4d0c --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/listeners/ActivityEventListener.kt @@ -0,0 +1,355 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.listeners + +import io.tolgee.activity.data.ActivityType +import io.tolgee.activity.data.RevisionType +import io.tolgee.events.OnProjectActivityStoredEvent +import io.tolgee.model.Screenshot +import io.tolgee.model.activity.ActivityModifiedEntity +import io.tolgee.model.enums.TranslationState +import io.tolgee.model.key.Key +import io.tolgee.model.key.KeyMeta +import io.tolgee.model.translation.Translation +import io.tolgee.notifications.NotificationType +import io.tolgee.notifications.dto.NotificationCreateDto +import io.tolgee.notifications.events.NotificationCreateEvent +import io.tolgee.service.LanguageService +import io.tolgee.util.Logging +import io.tolgee.util.logger +import org.springframework.context.ApplicationEventPublisher +import org.springframework.context.event.EventListener +import org.springframework.stereotype.Component +import org.springframework.transaction.annotation.Transactional + +private typealias SortedTranslations = List>> + +@Component +class ActivityEventListener( + private val applicationEventPublisher: ApplicationEventPublisher, + private val languageService: LanguageService, +) : Logging { + @EventListener + @Transactional + fun onActivityRevision(e: OnProjectActivityStoredEvent) { + // Using the Stored variant so `modifiedEntities` is populated. + + logger.trace( + "Received project activity event - {} on proj#{} ({} entities modified)", + e.activityRevision.type, + e.activityRevision.projectId, + e.activityRevision.modifiedEntities.size, + ) + + val projectId = e.activityRevision.projectId ?: return + val responsibleUserId = e.activityRevision.authorId + + when (e.activityRevision.type) { + // ACTIVITY_LANGUAGES_CREATED + ActivityType.CREATE_LANGUAGE -> + processSimpleActivity(NotificationType.ACTIVITY_LANGUAGES_CREATED, projectId, responsibleUserId, e) + + // ACTIVITY_KEYS_CREATED + ActivityType.CREATE_KEY -> + processSimpleActivity(NotificationType.ACTIVITY_KEYS_CREATED, projectId, responsibleUserId, e) + + // ACTIVITY_KEYS_UPDATED + ActivityType.KEY_TAGS_EDIT, + ActivityType.KEY_NAME_EDIT, + ActivityType.BATCH_TAG_KEYS, + ActivityType.BATCH_UNTAG_KEYS, + ActivityType.BATCH_SET_KEYS_NAMESPACE, + -> + processSimpleActivity(NotificationType.ACTIVITY_KEYS_UPDATED, projectId, responsibleUserId, e) + + // ACTIVITY_KEYS_UPDATED, ACTIVITY_KEYS_SCREENSHOTS_UPLOADED, ACTIVITY_TRANSLATIONS_* + ActivityType.COMPLEX_EDIT -> + processComplexEdit(projectId, responsibleUserId, e) + + // ACTIVITY_KEYS_SCREENSHOTS_UPLOADED + ActivityType.SCREENSHOT_ADD -> + processScreenshotUpdate(projectId, responsibleUserId, e) + + // ACTIVITY_TRANSLATIONS_* + ActivityType.SET_TRANSLATIONS, + ActivityType.SET_TRANSLATION_STATE, + ActivityType.BATCH_PRE_TRANSLATE_BY_TM, + ActivityType.BATCH_MACHINE_TRANSLATE, + ActivityType.AUTO_TRANSLATE, + ActivityType.BATCH_CLEAR_TRANSLATIONS, + ActivityType.BATCH_COPY_TRANSLATIONS, + ActivityType.BATCH_SET_TRANSLATION_STATE, + -> + processSetTranslations(projectId, responsibleUserId, e) + + ActivityType.SET_OUTDATED_FLAG -> + processOutdatedFlagUpdate(projectId, responsibleUserId, e) + + // ACTIVITY_NEW_COMMENTS (ACTIVITY_COMMENTS_MENTION is user-specific and not computed here) + ActivityType.TRANSLATION_COMMENT_ADD -> + processSimpleActivity(NotificationType.ACTIVITY_NEW_COMMENTS, projectId, responsibleUserId, e) + + // ACTIVITY_KEYS_CREATED, ACTIVITY_TRANSLATIONS_* + ActivityType.IMPORT -> + processImport(projectId, responsibleUserId, e) + + // We don't care about those, ignore them. + // They're explicitly not written as a single `else` branch, + // so it causes a compile error when new activities are added + // and ensures the notification policy is adjusted accordingly. + ActivityType.UNKNOWN, + ActivityType.DISMISS_AUTO_TRANSLATED_STATE, + ActivityType.TRANSLATION_COMMENT_DELETE, + ActivityType.TRANSLATION_COMMENT_EDIT, + ActivityType.TRANSLATION_COMMENT_SET_STATE, + ActivityType.SCREENSHOT_DELETE, + ActivityType.KEY_DELETE, + ActivityType.EDIT_LANGUAGE, + ActivityType.DELETE_LANGUAGE, + ActivityType.CREATE_PROJECT, + ActivityType.EDIT_PROJECT, + ActivityType.NAMESPACE_EDIT, + ActivityType.AUTOMATION, + ActivityType.CONTENT_DELIVERY_CONFIG_CREATE, + ActivityType.CONTENT_DELIVERY_CONFIG_UPDATE, + ActivityType.CONTENT_DELIVERY_CONFIG_DELETE, + ActivityType.CONTENT_STORAGE_CREATE, + ActivityType.CONTENT_STORAGE_UPDATE, + ActivityType.CONTENT_STORAGE_DELETE, + ActivityType.WEBHOOK_CONFIG_CREATE, + ActivityType.WEBHOOK_CONFIG_UPDATE, + ActivityType.WEBHOOK_CONFIG_DELETE, + null, + -> {} + } + } + + /** + * Handles activities that can be simply mapped to a corresponding notification without extra processing. + */ + private fun processSimpleActivity( + type: NotificationType, + projectId: Long, + responsibleUserId: Long?, + e: OnProjectActivityStoredEvent, + ) { + applicationEventPublisher.publishEvent( + NotificationCreateEvent( + NotificationCreateDto(type, projectId, e.activityRevision.modifiedEntities), + responsibleUserId, + source = e, + ), + ) + } + + /** + * Emits multiple notification create events depending on the details of the complex edition. + */ + private fun processComplexEdit( + projectId: Long, + responsibleUserId: Long?, + e: OnProjectActivityStoredEvent, + ) { + processComplexEditKeyUpdate(projectId, responsibleUserId, e) + processScreenshotUpdate(projectId, responsibleUserId, e) + processSetTranslations(projectId, responsibleUserId, e) + } + + private fun processComplexEditKeyUpdate( + projectId: Long, + responsibleUserId: Long?, + e: OnProjectActivityStoredEvent, + ) { + // The key was updated if: + // The entity is a Key and its name or namespace was modified; + // The entity is a KeyMeta and its tags were modified. + val relevantEntities = + e.activityRevision.modifiedEntities.filter { + ( + it.entityClass == Key::class.simpleName && + (it.modifications.containsKey("name") || it.modifications.containsKey("namespace")) + ) || + ( + it.entityClass == KeyMeta::class.simpleName && + it.modifications.containsKey("tags") + ) + } + + if (relevantEntities.isNotEmpty()) { + applicationEventPublisher.publishEvent( + NotificationCreateEvent( + NotificationCreateDto(NotificationType.ACTIVITY_KEYS_UPDATED, projectId, relevantEntities.toMutableList()), + responsibleUserId, + source = e, + ), + ) + } + } + + /** + * Emits notifications based on whether a translation was added, updated or removed. + * + * Refer to the Hacking Documentation, Notifications, Activity Notifications - User Dispatch, §2.2.2. + */ + private fun processSetTranslations( + projectId: Long, + responsibleUserId: Long?, + e: OnProjectActivityStoredEvent, + modifiedEntities: List = e.activityRevision.modifiedEntities, + ) { + val baseLanguageId = languageService.getBaseLanguageForProjectId(projectId) + val sortedTranslations = + sortTranslations( + modifiedEntities, + baseLanguage = baseLanguageId ?: 0L, + ) + + for ((type, translations) in sortedTranslations) { + if (translations.isNotEmpty()) { + applicationEventPublisher.publishEvent( + NotificationCreateEvent( + NotificationCreateDto(type, projectId, translations), + responsibleUserId, + source = e, + ), + ) + } + } + } + + private fun sortTranslations( + entities: List, + baseLanguage: Long, + ): SortedTranslations { + val updatedSourceTranslations = mutableListOf() + val updatedTranslations = mutableListOf() + val reviewedTranslations = mutableListOf() + val unreviewedTranslations = mutableListOf() + + entities.forEach { + if (it.entityClass != Translation::class.simpleName) return@forEach + + val text = it.modifications["text"] + val state = it.modifications["state"] + + if (text != null) { + val languageId = it.describingRelations?.get("language")?.entityId + if (languageId == baseLanguage) { + updatedSourceTranslations.add(it) + } else { + updatedTranslations.add(it) + } + } + + if (state?.new == TranslationState.REVIEWED.name) { + reviewedTranslations.add(it) + } + if (state?.new == TranslationState.TRANSLATED.name && state.old == TranslationState.REVIEWED.name) { + unreviewedTranslations.add(it) + } + } + + return listOf( + Pair(NotificationType.ACTIVITY_SOURCE_STRINGS_UPDATED, updatedSourceTranslations), + Pair(NotificationType.ACTIVITY_TRANSLATIONS_UPDATED, updatedTranslations), + Pair(NotificationType.ACTIVITY_TRANSLATION_REVIEWED, reviewedTranslations), + Pair(NotificationType.ACTIVITY_TRANSLATION_UNREVIEWED, unreviewedTranslations), + ) + } + + private fun processOutdatedFlagUpdate( + projectId: Long, + responsibleUserId: Long?, + e: OnProjectActivityStoredEvent, + ) { + val outdatedTranslations = + e.activityRevision.modifiedEntities + .filter { it.modifications["outdated"]?.new == true } + + if (outdatedTranslations.isNotEmpty()) { + applicationEventPublisher.publishEvent( + NotificationCreateEvent( + NotificationCreateDto( + type = NotificationType.ACTIVITY_TRANSLATION_OUTDATED, + projectId = projectId, + modifiedEntities = outdatedTranslations.toMutableList(), + ), + responsibleUserId, + source = e, + ), + ) + } + } + + private fun processScreenshotUpdate( + projectId: Long, + responsibleUserId: Long?, + e: OnProjectActivityStoredEvent, + ) { + val addedScreenshots = + e.activityRevision.modifiedEntities + .filter { it.entityClass == Screenshot::class.simpleName && it.revisionType == RevisionType.ADD } + + if (addedScreenshots.isNotEmpty()) { + applicationEventPublisher.publishEvent( + NotificationCreateEvent( + NotificationCreateDto( + type = NotificationType.ACTIVITY_KEYS_SCREENSHOTS_UPLOADED, + projectId = projectId, + modifiedEntities = addedScreenshots.toMutableList(), + ), + responsibleUserId, + source = e, + ), + ) + } + } + + private fun processImport( + projectId: Long, + responsibleUserId: Long?, + e: OnProjectActivityStoredEvent, + ) { + val createdKeys = + e.activityRevision.modifiedEntities + .filter { it.entityClass == Key::class.simpleName && it.revisionType == RevisionType.ADD } + .toMutableList() + + val keyIds = createdKeys.map { it.entityId }.toSet() + val updatedTranslations = + e.activityRevision.modifiedEntities + .filter { + val isFromNewKey = keyIds.contains(it.describingRelations?.get("key")?.entityId ?: 0L) + if (isFromNewKey) createdKeys.add(it) + !isFromNewKey + } + + if (createdKeys.isNotEmpty()) { + applicationEventPublisher.publishEvent( + NotificationCreateEvent( + NotificationCreateDto(NotificationType.ACTIVITY_KEYS_CREATED, projectId, createdKeys.toMutableList()), + responsibleUserId, + source = e, + ), + ) + } + + if (updatedTranslations.isNotEmpty()) { + processSetTranslations(projectId, responsibleUserId, e, updatedTranslations) + } + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/notifications/listeners/BatchJobListener.kt b/backend/data/src/main/kotlin/io/tolgee/notifications/listeners/BatchJobListener.kt new file mode 100644 index 0000000000..be85de420f --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/notifications/listeners/BatchJobListener.kt @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.notifications.listeners + +import io.tolgee.batch.events.OnBatchJobFailed +import io.tolgee.model.batch.BatchJob +import io.tolgee.notifications.NotificationType +import io.tolgee.notifications.dto.NotificationCreateDto +import io.tolgee.notifications.events.NotificationCreateEvent +import io.tolgee.util.Logging +import io.tolgee.util.logger +import jakarta.persistence.EntityManager +import org.springframework.context.ApplicationEventPublisher +import org.springframework.context.event.EventListener +import org.springframework.stereotype.Component + +@Component +class BatchJobListener( + private val applicationEventPublisher: ApplicationEventPublisher, + private val entityManager: EntityManager, +) : Logging { + @EventListener + fun onBatchJobError(e: OnBatchJobFailed) { + logger.trace( + "Received batch job failure event - job#{} on proj#{}", + e.job.id, + e.job.projectId, + ) + + val job = entityManager.getReference(BatchJob::class.java, e.job.id) + applicationEventPublisher.publishEvent( + NotificationCreateEvent( + NotificationCreateDto( + type = NotificationType.BATCH_JOB_ERRORED, + projectId = e.job.projectId, + batchJob = job, + ), + source = e, + responsibleUserId = null, + ), + ) + } +} diff --git a/backend/data/src/main/kotlin/io/tolgee/repository/LanguageRepository.kt b/backend/data/src/main/kotlin/io/tolgee/repository/LanguageRepository.kt index 7262f537ed..b88552afcd 100644 --- a/backend/data/src/main/kotlin/io/tolgee/repository/LanguageRepository.kt +++ b/backend/data/src/main/kotlin/io/tolgee/repository/LanguageRepository.kt @@ -2,6 +2,7 @@ package io.tolgee.repository import io.tolgee.dtos.cacheable.LanguageDto import io.tolgee.model.Language +import io.tolgee.model.Project import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository @@ -13,7 +14,7 @@ import java.util.* interface LanguageRepository : JpaRepository { fun findByNameAndProject( name: String?, - project: io.tolgee.model.Project, + project: Project, ): Optional fun findAllByProjectId(projectId: Long?): Set @@ -77,4 +78,16 @@ interface LanguageRepository : JpaRepository { """, ) fun findAllDtosByProjectId(projectId: Long): List + + @Query( + """ + SELECT new map(t.id as translationId, t.language.id as languageId) + FROM Translation t + WHERE t.id IN :translationIds + """, + ) + fun findLanguageIdsOfTranslations(translationIds: List): List> + + @Query("SELECT l.id FROM Language l, Project p WHERE p.id = :projectId AND l = p.baseLanguage") + fun getBaseLanguageForProjectId(projectId: Long): Long? } diff --git a/backend/data/src/main/kotlin/io/tolgee/repository/PermissionRepository.kt b/backend/data/src/main/kotlin/io/tolgee/repository/PermissionRepository.kt index 828de80567..a6cf7d6358 100644 --- a/backend/data/src/main/kotlin/io/tolgee/repository/PermissionRepository.kt +++ b/backend/data/src/main/kotlin/io/tolgee/repository/PermissionRepository.kt @@ -10,18 +10,28 @@ import org.springframework.stereotype.Repository interface PermissionRepository : JpaRepository { @Query( """ - from Permission p - where + SELECT DISTINCT new io.tolgee.model.Permission${'$'}PermissionWithLanguageIdsWrapper( + p, + listagg(str(vl.id), ','), + listagg(str(tl.id), ','), + listagg(str(sl.id), ',') + ) + FROM Permission p + LEFT JOIN p.viewLanguages vl + LEFT JOIN p.translateLanguages tl + LEFT JOIN p.stateChangeLanguages sl + WHERE ((:projectId is null and p.project.id is null) or p.project.id = :projectId) and ((:userId is null and p.user.id is null) or p.user.id = :userId) and ((:organizationId is null and p.organization.id is null) or p.organization.id = :organizationId) + GROUP BY p """, ) fun findOneByProjectIdAndUserIdAndOrganizationId( projectId: Long?, userId: Long?, organizationId: Long? = null, - ): Permission? + ): Permission.PermissionWithLanguageIdsWrapper? fun getAllByProjectAndUserNotNull(project: io.tolgee.model.Project?): Set diff --git a/backend/data/src/main/kotlin/io/tolgee/repository/UserAccountRepository.kt b/backend/data/src/main/kotlin/io/tolgee/repository/UserAccountRepository.kt index d04c4edd5a..c2af76c5c4 100644 --- a/backend/data/src/main/kotlin/io/tolgee/repository/UserAccountRepository.kt +++ b/backend/data/src/main/kotlin/io/tolgee/repository/UserAccountRepository.kt @@ -4,6 +4,7 @@ import io.tolgee.dtos.queryResults.UserAccountView import io.tolgee.model.UserAccount import io.tolgee.model.views.UserAccountInProjectView import io.tolgee.model.views.UserAccountWithOrganizationRoleView +import io.tolgee.model.views.UserProjectMetadataView import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository @@ -162,7 +163,7 @@ interface UserAccountRepository : JpaRepository { @Query( value = """ - select ua from UserAccount ua where id in (:ids) + select ua from UserAccount ua where ua.id in (:ids) """, ) fun getAllByIdsIncludingDeleted(ids: Set): MutableList @@ -200,4 +201,43 @@ interface UserAccountRepository : JpaRepository { """, ) fun findActiveWithFetchedDataByUserNames(usernames: List): List + + @Query( + """ + SELECT DISTINCT new io.tolgee.model.views.UserProjectMetadataView( + ua.id, + p.id, + org_r.type, + perm_org, + listagg(str(vl_org.id), ','), + perm, + listagg(str(vl.id), ','), + np_global, + np_project + ) + FROM UserAccount ua + LEFT JOIN Project p ON p.id = :projectId + LEFT JOIN OrganizationRole org_r ON + org_r.user = ua AND + org_r.organization = p.organizationOwner + LEFT JOIN FETCH Permission perm ON + perm.user = ua AND + perm.project = p + LEFT JOIN perm.viewLanguages vl + LEFT JOIN FETCH Permission perm_org ON + org_r.user = ua AND + org_r.organization = p.organizationOwner AND + perm_org.organization = p.organizationOwner + LEFT JOIN perm_org.viewLanguages vl_org + LEFT JOIN FETCH NotificationPreferences np_global ON np_global.userAccount = ua AND np_global.project IS NULL + LEFT JOIN FETCH NotificationPreferences np_project ON np_project.userAccount = ua AND np_project.project = p + WHERE + ua.deletedAt IS NULL AND ( + (perm._scopes IS NOT NULL AND cast(perm._scopes as string) != '{}') OR perm.type IS NOT NULL OR + (perm_org._scopes IS NOT NULL AND cast(perm_org._scopes as string) != '{}') OR perm_org.type IS NOT NULL + ) + GROUP BY ua.id, p.id, org_r.type, perm_org, perm, np_global, np_project + """, + ) + fun findAllUserProjectMetadataViews(projectId: Long): List } diff --git a/backend/data/src/main/kotlin/io/tolgee/repository/notifications/NotificationPreferencesRepository.kt b/backend/data/src/main/kotlin/io/tolgee/repository/notifications/NotificationPreferencesRepository.kt new file mode 100644 index 0000000000..a3b5b3883b --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/repository/notifications/NotificationPreferencesRepository.kt @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.repository.notifications + +import io.tolgee.model.notifications.NotificationPreferences +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Modifying +import org.springframework.data.jpa.repository.Query +import org.springframework.stereotype.Repository + +@Repository +interface NotificationPreferencesRepository : JpaRepository { + fun findAllByUserAccountId(user: Long): List + + fun findByUserAccountIdAndProjectId( + user: Long, + project: Long?, + ): NotificationPreferences? + + fun deleteByUserAccountIdAndProjectId( + user: Long, + project: Long, + ) + + @Modifying + @Query("DELETE FROM NotificationPreferences WHERE userAccount.id = :userId") + fun deleteAllByUserId(userId: Long) + + @Modifying + @Query("DELETE FROM NotificationPreferences WHERE project.id = :projectId") + fun deleteAllByProjectId(projectId: Long) +} diff --git a/backend/data/src/main/kotlin/io/tolgee/repository/notifications/UserNotificationRepository.kt b/backend/data/src/main/kotlin/io/tolgee/repository/notifications/UserNotificationRepository.kt new file mode 100644 index 0000000000..dd90944a98 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/repository/notifications/UserNotificationRepository.kt @@ -0,0 +1,175 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.repository.notifications + +import io.tolgee.model.UserAccount +import io.tolgee.model.notifications.UserNotification +import io.tolgee.notifications.NotificationType +import org.springframework.data.domain.Pageable +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Modifying +import org.springframework.data.jpa.repository.Query +import org.springframework.stereotype.Repository + +@Repository +interface UserNotificationRepository : JpaRepository { + fun findAllByRecipient(recipient: UserAccount): List + + fun countNotificationsByRecipientIdAndUnreadTrue(recipient: Long): Int + + @Query( + """ + FROM UserNotification un WHERE + un.recipient.id = :recipient AND ( + ('UNREAD' IN :status AND un.unread = true AND un.markedDoneAt IS NULL) OR + ('READ' IN :status AND un.unread = false AND un.markedDoneAt IS NULL) OR + ('DONE' IN :status AND un.markedDoneAt IS NOT NULL) + ) + """, + ) + fun findNotificationsOfUserFilteredPaged( + recipient: Long, + status: List, + pageable: Pageable, + ): List + + @Query( + """ + FROM UserNotification un + WHERE + un.unread = true AND + un.type = :type AND + un.project.id = :projectId AND + un.recipient IN :recipients + """, + ) + fun findCandidatesForNotificationDebouncing( + type: NotificationType, + projectId: Long, + recipients: Collection, + ): List + + @Query( + """ + SELECT un + FROM UserNotification un + INNER JOIN un.modifiedEntities me + WHERE + un.unread = true AND + un.project.id = :projectId AND + un.recipient IN :recipients AND ( + un.type = :type OR ( + un.type = io.tolgee.notifications.NotificationType.ACTIVITY_KEYS_CREATED AND + me.entityClass = 'Key' AND + me.entityId = :keyId + ) + ) + ORDER BY un.type DESC + """, + ) + fun findCandidatesForTranslationUpdateNotificationDebouncing( + type: NotificationType, + projectId: Long, + recipients: Collection, + keyId: Long, + ): List + + @Query( + """ + SELECT un + FROM UserNotification un + INNER JOIN un.modifiedEntities me + INNER JOIN ActivityDescribingEntity de ON de.activityRevision = me.activityRevision + WHERE + un.unread = true AND + me.entityClass = 'TranslationComment' AND + de.entityClass = 'Translation' AND + de.entityId = :translationId AND + un.project.id = :projectId AND + un.recipient IN :recipients AND + un.type IN ( + io.tolgee.notifications.NotificationType.ACTIVITY_NEW_COMMENTS, + io.tolgee.notifications.NotificationType.ACTIVITY_COMMENTS_MENTION + ) + """, + ) + fun findCandidatesForCommentNotificationDebouncing( + projectId: Long, + recipients: Collection, + translationId: Long, + ): List + + @Modifying + @Query("UPDATE UserNotification un SET un.unread = false WHERE un.recipient.id = ?1 AND un.id IN ?2") + fun markAsRead( + recipient: Long, + notifications: Collection, + ) + + @Modifying + @Query("UPDATE UserNotification un SET un.unread = false WHERE un.recipient.id = ?1") + fun markAllAsRead(recipient: Long) + + @Modifying + @Query("UPDATE UserNotification un SET un.unread = true WHERE un.recipient.id = ?1 AND un.id IN ?2") + fun markAsUnread( + recipient: Long, + notifications: Collection, + ) + + @Modifying + @Query( + """ + UPDATE UserNotification un + SET un.unread = false, un.markedDoneAt = CURRENT_TIMESTAMP() + WHERE un.recipient.id = ?1 AND un.id IN ?2 + """, + ) + fun markAsDone( + recipient: Long, + notifications: Collection, + ) + + @Modifying + @Query( + """ + UPDATE UserNotification un + SET un.unread = false, un.markedDoneAt = CURRENT_TIMESTAMP() + WHERE un.recipient.id = ?1 + """, + ) + fun markAllAsDone(recipient: Long) + + @Modifying + @Query("UPDATE UserNotification un SET un.markedDoneAt = null WHERE un.recipient.id = ?1 AND un.id IN ?2") + fun unmarkAsDone( + recipient: Long, + notifications: Collection, + ) + + @Modifying + @Query("DELETE FROM user_notification WHERE marked_done_at < NOW() - INTERVAL '90 DAY'", nativeQuery = true) + fun pruneOldNotifications() // Native query since HQL can't do "INTERVAL" + + @Modifying + @Query("DELETE FROM UserNotification WHERE recipient.id = :userId") + fun deleteAllByUserId(userId: Long) + + @Modifying + @Query("DELETE FROM UserNotification WHERE project.id = :projectId") + fun deleteAllByProjectId(projectId: Long) +} diff --git a/backend/data/src/main/kotlin/io/tolgee/service/CachedPermissionService.kt b/backend/data/src/main/kotlin/io/tolgee/service/CachedPermissionService.kt index 9cf66c7ff4..e9285cd627 100644 --- a/backend/data/src/main/kotlin/io/tolgee/service/CachedPermissionService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/service/CachedPermissionService.kt @@ -51,7 +51,7 @@ class CachedPermissionService( projectId = projectId, userId = userId, organizationId = organizationId, - )?.let { permission -> + )?.permission?.let { permission -> PermissionDto( id = permission.id, userId = permission.user?.id, diff --git a/backend/data/src/main/kotlin/io/tolgee/service/LanguageService.kt b/backend/data/src/main/kotlin/io/tolgee/service/LanguageService.kt index e5a2c10098..dcb23b0913 100644 --- a/backend/data/src/main/kotlin/io/tolgee/service/LanguageService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/service/LanguageService.kt @@ -259,6 +259,16 @@ class LanguageService( return languageRepository.findByNameAndProject(name, project) } + fun findLanguageIdsOfTranslations(translationIds: List): Map { + val maps = languageRepository.findLanguageIdsOfTranslations(translationIds) + if (maps.isEmpty()) return emptyMap() + + return maps + .map { mapOf(it["translationId"]!! to it["languageId"]!!) } + .reduce { acc, map -> acc.plus(map) } + } + + @Transactional fun deleteAllByProject(projectId: Long) { translationService.deleteAllByProject(projectId) autoTranslationService.deleteConfigsByProject(projectId) @@ -408,4 +418,8 @@ class LanguageService( language.project = entityManager.getReference(Project::class.java, projectId) return languageRepository.save(language) } + + fun getBaseLanguageForProjectId(projectId: Long): Long? { + return languageRepository.getBaseLanguageForProjectId(projectId) + } } diff --git a/backend/data/src/main/kotlin/io/tolgee/service/project/ProjectService.kt b/backend/data/src/main/kotlin/io/tolgee/service/project/ProjectService.kt index 227bcae729..c83004a0f2 100644 --- a/backend/data/src/main/kotlin/io/tolgee/service/project/ProjectService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/service/project/ProjectService.kt @@ -21,6 +21,8 @@ import io.tolgee.model.Project import io.tolgee.model.UserAccount import io.tolgee.model.views.ProjectView import io.tolgee.model.views.ProjectWithLanguagesView +import io.tolgee.notifications.NotificationPreferencesService +import io.tolgee.notifications.UserNotificationService import io.tolgee.repository.ProjectRepository import io.tolgee.security.ProjectHolder import io.tolgee.security.ProjectNotSelectedException @@ -62,10 +64,10 @@ class ProjectService( private val slugGenerator: SlugGenerator, private val avatarService: AvatarService, private val activityHolder: ActivityHolder, - @Lazy - private val projectHolder: ProjectHolder, - @Lazy - private val batchJobService: BatchJobService, + @Lazy private val projectHolder: ProjectHolder, + @Lazy private val batchJobService: BatchJobService, + @Lazy private val userNotificationService: UserNotificationService, + @Lazy private val notificationPreferencesService: NotificationPreferencesService, private val currentDateProvider: CurrentDateProvider, ) : Logging { @set:Autowired @@ -309,12 +311,16 @@ class ProjectService( avatarService.unlinkAvatarFiles(project) batchJobService.deleteAllByProjectId(project.id) bigMetaService.deleteAllByProjectId(project.id) + + userNotificationService.deleteAllByProjectId(project.id) + notificationPreferencesService.deleteAllByProjectId(project.id) + projectRepository.delete(project) } } /** - * If base language is missing on project it selects language with lowest id + * If base language is missing on project it selects the language with the lowest id * It saves updated project and returns project's new baseLanguage */ @CacheEvict(cacheNames = [Caches.PROJECTS], key = "#projectId") diff --git a/backend/data/src/main/kotlin/io/tolgee/service/security/PermissionService.kt b/backend/data/src/main/kotlin/io/tolgee/service/security/PermissionService.kt index 16b1562a63..2a9652d583 100644 --- a/backend/data/src/main/kotlin/io/tolgee/service/security/PermissionService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/service/security/PermissionService.kt @@ -22,6 +22,7 @@ import io.tolgee.model.UserAccount import io.tolgee.model.enums.OrganizationRoleType import io.tolgee.model.enums.ProjectPermissionType import io.tolgee.model.enums.Scope +import io.tolgee.model.views.UserProjectMetadataView import io.tolgee.repository.PermissionRepository import io.tolgee.service.CachedPermissionService import io.tolgee.service.LanguageService @@ -194,7 +195,7 @@ class PermissionService( fun computeProjectPermission( organizationRole: OrganizationRoleType?, - organizationBasePermission: IPermission, + organizationBasePermission: IPermission?, directPermission: IPermission?, userRole: UserAccount.Role? = null, ): ComputedPermissionDto { @@ -202,7 +203,7 @@ class PermissionService( when { organizationRole == OrganizationRoleType.OWNER -> ComputedPermissionDto.ORGANIZATION_OWNER directPermission != null -> ComputedPermissionDto(directPermission, ComputedPermissionOrigin.DIRECT) - organizationRole == OrganizationRoleType.MEMBER -> + organizationRole == OrganizationRoleType.MEMBER && organizationBasePermission != null -> ComputedPermissionDto( organizationBasePermission, ComputedPermissionOrigin.ORGANIZATION_BASE, @@ -216,6 +217,14 @@ class PermissionService( } ?: computed } + fun computeProjectPermission(userProjectMetadataView: UserProjectMetadataView): ComputedPermissionDto { + return computeProjectPermission( + userProjectMetadataView.organizationRole, + userProjectMetadataView.basePermissions, + userProjectMetadataView.permissions, + ) + } + fun createForInvitation( invitation: Invitation, params: CreateProjectInvitationParams, diff --git a/backend/data/src/main/kotlin/io/tolgee/service/security/UserAccountService.kt b/backend/data/src/main/kotlin/io/tolgee/service/security/UserAccountService.kt index 04f125a902..88602f9b8d 100644 --- a/backend/data/src/main/kotlin/io/tolgee/service/security/UserAccountService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/service/security/UserAccountService.kt @@ -20,6 +20,9 @@ import io.tolgee.model.UserAccount import io.tolgee.model.views.ExtendedUserAccountInProject import io.tolgee.model.views.UserAccountInProjectView import io.tolgee.model.views.UserAccountWithOrganizationRoleView +import io.tolgee.model.views.UserProjectMetadataView +import io.tolgee.notifications.NotificationPreferencesService +import io.tolgee.notifications.UserNotificationService import io.tolgee.repository.UserAccountRepository import io.tolgee.service.AvatarService import io.tolgee.service.EmailVerificationService @@ -53,6 +56,8 @@ class UserAccountService( private val organizationService: OrganizationService, private val entityManager: EntityManager, private val currentDateProvider: CurrentDateProvider, + @Lazy private val userNotificationService: UserNotificationService, + @Lazy private val notificationPreferencesService: NotificationPreferencesService, private val cacheManager: CacheManager, @Suppress("SelfReferenceConstructorParameter") @Lazy @@ -162,6 +167,10 @@ class UserAccountService( toDelete.organizationRoles.forEach { entityManager.remove(it) } + + userNotificationService.deleteAllByUserId(toDelete.id) + notificationPreferencesService.deleteAllByUserId(toDelete.id) + userAccountRepository.softDeleteUser(toDelete, currentDateProvider.date) applicationEventPublisher.publishEvent(OnUserCountChanged(decrease = true, this)) } @@ -333,6 +342,11 @@ class UserAccountService( } } + fun getAllConnectedUserProjectMetadataViews(projectId: Long): List { + userAccountRepository.findAllUserProjectMetadataViews(projectId).forEach { println(it.userAccountId) } + return userAccountRepository.findAllUserProjectMetadataViews(projectId) + } + @Transactional @CacheEvict(cacheNames = [Caches.USER_ACCOUNTS], key = "#result.id") fun update( diff --git a/backend/data/src/main/kotlin/io/tolgee/util/dateExt.kt b/backend/data/src/main/kotlin/io/tolgee/util/dateExt.kt index f22821dccc..25526c2f40 100644 --- a/backend/data/src/main/kotlin/io/tolgee/util/dateExt.kt +++ b/backend/data/src/main/kotlin/io/tolgee/util/dateExt.kt @@ -28,6 +28,12 @@ fun Date.addSeconds(seconds: Int): Date { return calendar.time } +fun Date.addMilliseconds(milliseconds: Int): Date { + val calendar = toUtcCalendar() + calendar.add(Calendar.MILLISECOND, milliseconds) + return calendar.time +} + private fun Date.toUtcCalendar(): Calendar { val calendar = getUtcCalendar() calendar.time = this diff --git a/backend/data/src/main/resources/db/changelog/schema.xml b/backend/data/src/main/resources/db/changelog/schema.xml index 8cb52f1006..c997527883 100644 --- a/backend/data/src/main/resources/db/changelog/schema.xml +++ b/backend/data/src/main/resources/db/changelog/schema.xml @@ -3224,4 +3224,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/data/src/main/resources/hibernate-types.properties b/backend/data/src/main/resources/hypersistence-utils.properties similarity index 100% rename from backend/data/src/main/resources/hibernate-types.properties rename to backend/data/src/main/resources/hypersistence-utils.properties diff --git a/backend/development/src/main/kotlin/io/tolgee/controllers/internal/e2eData/NotificationsE2eDataController.kt b/backend/development/src/main/kotlin/io/tolgee/controllers/internal/e2eData/NotificationsE2eDataController.kt new file mode 100644 index 0000000000..0a5bcdb11f --- /dev/null +++ b/backend/development/src/main/kotlin/io/tolgee/controllers/internal/e2eData/NotificationsE2eDataController.kt @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.controllers.internal.e2eData + +import io.swagger.v3.oas.annotations.Hidden +import io.tolgee.development.testDataBuilder.builders.TestDataBuilder +import io.tolgee.development.testDataBuilder.data.NotificationsTestData +import io.tolgee.repository.UserAccountRepository +import io.tolgee.service.security.UserAccountService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.transaction.annotation.Transactional +import org.springframework.web.bind.annotation.CrossOrigin +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@CrossOrigin(origins = ["*"]) +@Hidden +@RequestMapping(value = ["internal/e2e-data/notifications"]) +class NotificationsE2eDataController : AbstractE2eDataController() { + @Autowired + lateinit var userAccountRepository: UserAccountRepository + + @Autowired + lateinit var userAccountService: UserAccountService + + @GetMapping(value = ["/generate"]) + @Transactional + fun generateBasicTestData() { + userAccountService.findActive("admin")?.let { + userAccountService.delete(it) + userAccountRepository.delete(it) + } + + testDataService.saveTestData(testData) + } + + override val testData: TestDataBuilder + get() = NotificationsTestData().root +} diff --git a/backend/testing/build.gradle b/backend/testing/build.gradle index fae4d407ea..8902fdef40 100644 --- a/backend/testing/build.gradle +++ b/backend/testing/build.gradle @@ -76,8 +76,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-validation" implementation("org.springframework.boot:spring-boot-starter-security") implementation 'org.springframework.boot:spring-boot-starter-mail' - implementation('org.springframework.boot:spring-boot-starter-test') { - } + implementation('org.springframework.boot:spring-boot-starter-test') kapt "org.springframework.boot:spring-boot-configuration-processor" implementation "org.springframework.boot:spring-boot-configuration-processor" api "org.springframework.boot:spring-boot-starter-actuator" diff --git a/backend/testing/src/main/kotlin/io/tolgee/fixtures/EmailTestUtil.kt b/backend/testing/src/main/kotlin/io/tolgee/fixtures/EmailTestUtil.kt index 6a0f40ea20..199b8551be 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/fixtures/EmailTestUtil.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/fixtures/EmailTestUtil.kt @@ -55,7 +55,6 @@ class EmailTestUtil() { val assertEmailTo: AbstractStringAssert<*> get() { - @Suppress("CAST_NEVER_SUCCEEDS") return Assertions.assertThat(messageArgumentCaptor.firstValue.getHeader("To")[0] as String) } } diff --git a/backend/testing/src/main/kotlin/io/tolgee/fixtures/ProjectApiKeyAuthRequestPerformer.kt b/backend/testing/src/main/kotlin/io/tolgee/fixtures/ProjectApiKeyAuthRequestPerformer.kt index bb825d9bfd..28a5fba3fe 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/fixtures/ProjectApiKeyAuthRequestPerformer.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/fixtures/ProjectApiKeyAuthRequestPerformer.kt @@ -12,7 +12,6 @@ import org.springframework.stereotype.Component import org.springframework.test.web.servlet.ResultActions import org.springframework.test.web.servlet.request.MockMvcRequestBuilders -@Suppress("SpringJavaInjectionPointsAutowiringInspection") @Component @org.springframework.context.annotation.Scope("prototype") class ProjectApiKeyAuthRequestPerformer( diff --git a/backend/testing/src/main/kotlin/io/tolgee/fixtures/scopeAssert.kt b/backend/testing/src/main/kotlin/io/tolgee/fixtures/scopeAssert.kt index e462cd84a2..7f5ad0c3a5 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/fixtures/scopeAssert.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/fixtures/scopeAssert.kt @@ -4,9 +4,10 @@ import io.tolgee.model.enums.ProjectPermissionType import io.tolgee.model.enums.Scope import io.tolgee.model.enums.unpack import io.tolgee.testing.assertions.Assertions +import io.tolgee.testing.satisfies import org.assertj.core.api.ObjectArrayAssert -fun ObjectArrayAssert.equalsPermissionType(permissionType: ProjectPermissionType): ObjectArrayAssert? { +fun ObjectArrayAssert.equalsPermissionType(permissionType: ProjectPermissionType): ObjectArrayAssert { return this.satisfies { Assertions.assertThat(it.unpack()).containsExactlyInAnyOrder(*permissionType.availableScopes.unpack()) } diff --git a/backend/testing/src/main/kotlin/io/tolgee/fixtures/statusExpectations.kt b/backend/testing/src/main/kotlin/io/tolgee/fixtures/statusExpectations.kt index fd41a6932b..46202e0c94 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/fixtures/statusExpectations.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/fixtures/statusExpectations.kt @@ -6,6 +6,7 @@ import io.tolgee.constants.Message import io.tolgee.model.enums.ProjectPermissionType import io.tolgee.model.enums.Scope import io.tolgee.testing.assertions.Assertions.assertThat +import io.tolgee.testing.assertions.ErrorResponseAssert import io.tolgee.testing.assertions.MvcResultAssert import net.javacrumbs.jsonunit.assertj.JsonAssert import net.javacrumbs.jsonunit.assertj.assertThatJson @@ -57,7 +58,18 @@ val ResultActions.andAssertThatJson: JsonAssert.ConfigurableJsonAssert fun ResultActions.andAssertThatJson(jsonAssert: JsonAssert.ConfigurableJsonAssert.() -> Unit): ResultActions { tryPrettyPrinting { - jsonAssert(assertThatJson(this.andGetContentAsString)) + jsonAssert( + assertThatJson(this.andGetContentAsString) + // https://github.com/lukas-krecan/JsonUnit?tab=readme-ov-file#numerical-comparison + // We only care about the numeric value, not the precision. Not the business of doing physics (...yet)! :p + .withConfiguration { + it.withNumberComparator { a, b, tolerance -> + val diff = if (a > b) a - b else b - a + diff <= (tolerance ?: BigDecimal.ZERO) + } + }, + ) + this } return this @@ -77,16 +89,20 @@ fun ResultActions.tryPrettyPrinting(fn: ResultActions.() -> ResultActions): Resu } } -val ResultActions.andGetContentAsString +val ResultActions.andGetContentAsString: String get() = this.andReturn().response.getContentAsString(StandardCharsets.UTF_8) -val ResultActions.andAssertError +val ResultActions.andGetContentAsJsonMap + @Suppress("UNCHECKED_CAST") + get() = jacksonObjectMapper().readValue(andGetContentAsString, MutableMap::class.java) as MutableMap + +val ResultActions.andAssertError: ErrorResponseAssert get() = assertThat(this.andReturn()).error() val ResultActions.andPrettyPrint: ResultActions get() = jacksonObjectMapper().let { mapper -> - val parsed = mapper.readValue(this.andGetContentAsString) + val parsed = mapper.readValue(andGetContentAsString) println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(parsed)) return this } diff --git a/backend/testing/src/main/kotlin/io/tolgee/testing/satisfies.kt b/backend/testing/src/main/kotlin/io/tolgee/testing/satisfies.kt new file mode 100644 index 0000000000..977e902946 --- /dev/null +++ b/backend/testing/src/main/kotlin/io/tolgee/testing/satisfies.kt @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2023 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.tolgee.testing + +import org.assertj.core.api.AbstractAssert +import org.assertj.core.api.Condition +import org.assertj.core.api.ThrowingConsumer + +// https://github.com/assertj/assertj/issues/2357 +fun , E> AbstractAssert.satisfies(fn: (actual: E) -> Unit): S { + return satisfies(ThrowingConsumer { fn(it) }) +} + +fun , E> AbstractAssert.satisfiesIf(fn: (actual: E) -> Boolean): S { + return satisfies( + object : Condition() { + override fun matches(value: E): Boolean = fn(value) + }, + ) +} diff --git a/e2e/cypress/support/dataCyType.d.ts b/e2e/cypress/support/dataCyType.d.ts index 46ed004576..71adee6076 100644 --- a/e2e/cypress/support/dataCyType.d.ts +++ b/e2e/cypress/support/dataCyType.d.ts @@ -186,6 +186,8 @@ declare namespace DataCy { "global-list-pagination" | "global-list-search" | "global-loading" | + "global-notifications-button" | + "global-notifications-count" | "global-paginated-list" | "global-plus-button" | "global-search-field" | diff --git a/ee/backend/tests/src/test/kotlin/io/tolgee/ee/api/v2/controllers/V2ProjectsInvitationControllerEeTest.kt b/ee/backend/tests/src/test/kotlin/io/tolgee/ee/api/v2/controllers/V2ProjectsInvitationControllerEeTest.kt index fbbdede5ad..2b470e044f 100644 --- a/ee/backend/tests/src/test/kotlin/io/tolgee/ee/api/v2/controllers/V2ProjectsInvitationControllerEeTest.kt +++ b/ee/backend/tests/src/test/kotlin/io/tolgee/ee/api/v2/controllers/V2ProjectsInvitationControllerEeTest.kt @@ -59,8 +59,10 @@ class V2ProjectsInvitationControllerEeTest : ProjectAuthControllerTest("/v2/proj translateLanguages = setOf(getLang("en")) }.andIsOk - val invitation = invitationTestUtil.getInvitation(result) - invitation.permission!!.translateLanguages.map { it.tag }.assert.containsExactlyInAnyOrder("en") + executeInNewTransaction { + val invitation = invitationTestUtil.getInvitation(result) + invitation.permission!!.translateLanguages.map { it.tag }.assert.containsExactlyInAnyOrder("en") + } } @Test diff --git a/gradle.properties b/gradle.properties index 37bb8ca15e..b51bc75c3f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,10 +1,10 @@ kotlinVersion=1.9.21 -springBootVersion=3.1.5 +springBootVersion=3.2.5 springDocVersion=2.2.0 jjwtVersion=0.11.2 -hibernateVersion=6.4.1.Final +hibernateVersion=6.5.0.Final amazonAwsSdkVersion=2.20.8 springDependencyManagementVersion=1.0.11.RELEASE -org.gradle.jvmargs=-Xmx6g -Dkotlin.daemon.jvm.options=-Xmx6g +org.gradle.jvmargs=-Xmx2g -Dkotlin.daemon.jvm.options=-Xmx2g org.gradle.parallel=true jacksonVersion=2.13.5 diff --git a/settings.gradle b/settings.gradle index 33a44e013b..7ef8cb7d50 100644 --- a/settings.gradle +++ b/settings.gradle @@ -51,12 +51,12 @@ dependencyResolutionManagement { library('jjwtApi', 'io.jsonwebtoken', 'jjwt-api').version(jjwtVersion) library('jjwtImpl', 'io.jsonwebtoken', 'jjwt-impl').version(jjwtVersion) library('jjwtJackson', 'io.jsonwebtoken', 'jjwt-jackson').version(jjwtVersion) - library('assertJCore', 'org.assertj:assertj-core:3.19.0') + library('assertJCore', 'org.assertj:assertj-core:3.24.2') library('springmockk', 'com.ninja-squad:springmockk:3.0.1') library('mockito', 'org.mockito.kotlin:mockito-kotlin:5.0.0') library('commonsCodec', 'commons-codec:commons-codec:1.15') library('icu4j', 'com.ibm.icu:icu4j:74.2') - library('jsonUnitAssert', 'net.javacrumbs.json-unit:json-unit-assertj:2.28.0') + library('jsonUnitAssert', 'net.javacrumbs.json-unit:json-unit-assertj:2.38.0') library('amazonS3', "software.amazon.awssdk:s3:$amazonAwsSdkVersion") library('amazonSTS', "software.amazon.awssdk:sts:$amazonAwsSdkVersion") library('amazonTranslate', "software.amazon.awssdk:translate:$amazonAwsSdkVersion") @@ -64,7 +64,7 @@ dependencyResolutionManagement { library('liquibaseCore', "org.liquibase:liquibase-core:4.26.0") library('liquibaseHibernate', "org.liquibase.ext:liquibase-hibernate6:4.26.0") library('liquibasePicoli', "info.picocli:picocli:4.6.3") - library('hibernateTypes', "io.hypersistence:hypersistence-utils-hibernate-63:3.7.0") + library('hibernateTypes', "io.hypersistence:hypersistence-utils-hibernate-63:3.7.4") library('redissonSpringBootStarter', "org.redisson:redisson-spring-boot-starter:3.26.0") library('postHog', 'com.posthog.java:posthog:1.1.1') library('micrometerPrometheus', "io.micrometer:micrometer-registry-prometheus:1.9.12") diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 45c763c0ec..3140c5cab6 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -9,18 +9,16 @@ "version": "0.1.0", "dependencies": { "@codemirror/lang-json": "6.0.0", - "@dicebear/avatars": "4.10.2", - "@dicebear/avatars-identicon-sprites": "4.10.2", - "@dicebear/avatars-initials-sprites": "4.10.2", - "@emotion/react": "^11.11.1", + "@dicebear/core": "^7.0.4", + "@dicebear/identicon": "^7.0.4", + "@dicebear/initials": "^7.0.4", + "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@formatjs/icu-messageformat-parser": "^2.0.8", - "@mdx-js/rollup": "^3.0.0", - "@mui/icons-material": "^5.5.1", - "@mui/lab": "^5.0.0-alpha.75", - "@mui/material": "^5.5.3", - "@mui/x-date-pickers": "5.0.0-beta.6", - "@openreplay/tracker": "^3.5.4", + "@mui/icons-material": "^5.15.7", + "@mui/lab": "^5.0.0-alpha.163", + "@mui/material": "^5.15.7", + "@mui/x-date-pickers": "^5.0.20", "@sentry/browser": "^7.80.0", "@stomp/stompjs": "^6.1.2", "@tginternal/editor": "^1.15.1", @@ -36,15 +34,11 @@ "dotenv-flow": "4.0.1", "formik": "^2.2.9", "intl-messageformat": "^9.8.1", - "node-fetch": "3.3.0", "notistack": "^2.0.4", "posthog-js": "^1.96.1", - "prism-react-renderer": "1.2.1", - "prism-svelte": "0.4.7", + "prism-react-renderer": "^2.3.1", "react": "^17.0.1", - "react-cropper": "2.1.8", - "react-dnd": "^14.0.2", - "react-dnd-html5-backend": "^14.0.0", + "react-cropper": "^2.3.3", "react-dom": "^17.0.2", "react-draggable": "^4.4.3", "react-google-recaptcha-v3": "1.9.5", @@ -55,7 +49,7 @@ "react-qr-code": "^2.0.7", "react-query": "^3.39.2", "react-router-dom": "^5.2.0", - "recharts": "2.1.9", + "recharts": "^2.11.0", "reflect-metadata": "^0.1.13", "regenerator-runtime": "^0.13.9", "sockjs-client": "^1.6.1", @@ -69,7 +63,8 @@ "zxcvbn": "^4.4.2" }, "devDependencies": { - "@mdx-js/loader": "1.6.22", + "@mdx-js/rollup": "^3.0.0", + "@redux-devtools/extension": "^3.3.0", "@sentry/types": "^6.5.1", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", @@ -93,11 +88,10 @@ "eslint-plugin-react": "^7.24.0", "openapi-typescript": "^4.0.2", "prettier": "^2.3.1", - "redux-devtools-extension": "^2.13.9", "rehype-highlight": "^7.0.0", "ts-unused-exports": "^9.0.4", "typescript": "^5.3.3", - "vite-plugin-node-polyfills": "^0.19.0", + "vite": "^5.0.12", "vite-plugin-static-copy": "^1.0.0", "vite-plugin-svgr": "^4.2.0", "vite-tsconfig-paths": "^4.2.3" @@ -142,6 +136,70 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", @@ -151,26 +209,25 @@ } }, "node_modules/@babel/core": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", - "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", + "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.9", + "@babel/parser": "^7.23.9", + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -180,6 +237,19 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/generator": { "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", @@ -209,14 +279,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -225,11 +287,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", @@ -370,69 +427,79 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "bin": { - "parser": "bin/babel-parser.js" + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=4" } }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", - "dev": true, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=4" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "dev": true, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "color-name": "1.1.3" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "dev": true, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "bin": { + "parser": "bin/babel-parser.js" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.0.0" } }, "node_modules/@babel/plugin-transform-react-jsx-self": { @@ -526,9 +593,9 @@ } }, "node_modules/@codemirror/autocomplete": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.12.0.tgz", - "integrity": "sha512-r4IjdYFthwbCQyvqnSlx0WBHRHi8nBvU+WjJxFUij81qsBfhNudf/XKKmmC2j3m0LaOYUQTf3qiEK1J8lO1sdg==", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.16.0.tgz", + "integrity": "sha512-P/LeCTtZHRTCU4xQsa89vSKWecYv1ZqwzOd5topheGRf+qtacFgBeIMQi3eL8Kt/BUNvxUWkx+5qP2jlGoARrg==", "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", @@ -543,9 +610,9 @@ } }, "node_modules/@codemirror/commands": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz", - "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.5.0.tgz", + "integrity": "sha512-rK+sj4fCAN/QfcY9BEzYMgp4wwL/q5aj/VfNSoH1RWPF9XS/dUwBkvlL3hpWgEjOqlpdN1uLC9UkjJ4tmyjJYg==", "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.4.0", @@ -563,9 +630,9 @@ } }, "node_modules/@codemirror/language": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.0.tgz", - "integrity": "sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz", + "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==", "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", @@ -601,9 +668,9 @@ "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" }, "node_modules/@codemirror/view": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.24.1.tgz", - "integrity": "sha512-sBfP4rniPBRQzNakwuQEqjEuiJDWJyF2kqLLqij4WXRoVwPPJfjx966Eq3F7+OPQxDtMt/Q9MWLoZLWjeveBlg==", + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.3.tgz", + "integrity": "sha512-gmqxkPALZjkgSxIeeweY/wGQXBfwTUaLs8h7OKtSwfbj9Ct3L11lD+u1sS7XHppxFQoMDiMDp07P9f3I2jWOHw==", "dependencies": { "@codemirror/state": "^6.4.0", "style-mod": "^4.1.0", @@ -679,36 +746,66 @@ } } }, - "node_modules/@dicebear/avatars": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/@dicebear/avatars/-/avatars-4.10.2.tgz", - "integrity": "sha512-7Qd4Mmq9jeMkWtPZgY89GxFZmu1ERSTSTSEbeNfgVzqxZ0M2NHKcc/uynFMpU13w2BGesCDGT3ulmKyCoYbMGA==", - "deprecated": "This package is deprecated. Use '@dicebear/core' instead. Read more: https://dicebear.com/how-to-use/js-library", + "node_modules/@dicebear/converter": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@dicebear/converter/-/converter-7.0.4.tgz", + "integrity": "sha512-oiA2Oc5izWf6ipPtHYCi2c9W565VzyryObtSL6xB36V9MHRD8wvH5mYr9AvbViDGEOOeNE3EtIELQIMdNtB7Rg==", + "dependencies": { + "@types/json-schema": "^7.0.11", + "tmp-promise": "^3.0.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@resvg/resvg-js": "^2.4.1", + "exiftool-vendored": "^23.0.0", + "sharp": "^0.32.6" + }, + "peerDependenciesMeta": { + "@resvg/resvg-js": { + "optional": true + }, + "exiftool-vendored": { + "optional": true + }, + "sharp": { + "optional": true + } + } + }, + "node_modules/@dicebear/core": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@dicebear/core/-/core-7.0.4.tgz", + "integrity": "sha512-Xi8Au8K4pWj61jKMKqlhqmg83DvMAG6PfDuDbp7F75ZNvrGGh0BkJt9keSHe4WpHs+BbXDXSMOivSS10QB20fA==", "dependencies": { - "@types/json-schema": "^7.0.7", - "pure-color": "^1.3.0", - "svgson": "^5.2.1" + "@dicebear/converter": "7.0.4", + "@types/json-schema": "^7.0.11" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@dicebear/avatars-identicon-sprites": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/@dicebear/avatars-identicon-sprites/-/avatars-identicon-sprites-4.10.2.tgz", - "integrity": "sha512-EI8CL9w3VCZp0KhxFzHh3iuvGR6CZT6CWjxao8urvwNUKEFBBhwI8C1/1bKYG+zWDtMPHkakmlvn/BCSNRl7Qg==", - "deprecated": "This package is deprecated. Use '@dicebear/identicon' instead. Read more: https://dicebear.com/styles/identicon", + "node_modules/@dicebear/identicon": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@dicebear/identicon/-/identicon-7.0.4.tgz", + "integrity": "sha512-Q68lP7dqqt0fMx9SONPJSi94aieNveTyrCgv/kuU3F9upeQyesmdAeQ+e2QOojOOMrEuM+ujFuPInvwwkaZF7w==", + "engines": { + "node": ">=16.0.0" + }, "peerDependencies": { - "@dicebear/avatars": "^4.6.0" + "@dicebear/core": "^7.0.0" } }, - "node_modules/@dicebear/avatars-initials-sprites": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/@dicebear/avatars-initials-sprites/-/avatars-initials-sprites-4.10.2.tgz", - "integrity": "sha512-/i0fnPOV8jideYUz8Dhgrh76pu7f7gATrX1LjbCgMuGyoXj9VwX+F9jJagFxpcqxWANHGd8JvNaA44yno/vysA==", - "deprecated": "This package is deprecated. Use '@dicebear/initials' instead. Read more: https://dicebear.com/styles/initials", - "dependencies": { - "initials": "^3.0.1" + "node_modules/@dicebear/initials": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@dicebear/initials/-/initials-7.0.4.tgz", + "integrity": "sha512-cNkuG/3cPbF4UScmLk+2nYF2LaB9N1k3Pw1gmd3PST+oUsdlkNIM6e4Wym/0fgDLGPWyxbiGsbhe371ACWJVNQ==", + "engines": { + "node": ">=16.0.0" }, "peerDependencies": { - "@dicebear/avatars": "^4.6.0" + "@dicebear/core": "^7.0.0" } }, "node_modules/@emotion/babel-plugin": { @@ -855,7 +952,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=12" } @@ -871,7 +967,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -887,7 +982,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -903,7 +997,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -919,7 +1012,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -935,7 +1027,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -951,7 +1042,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -967,7 +1057,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -983,7 +1072,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -999,7 +1087,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1015,7 +1102,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1031,7 +1117,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1047,7 +1132,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1063,7 +1147,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1079,7 +1162,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1095,7 +1177,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1111,7 +1192,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1127,7 +1207,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -1143,7 +1222,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -1159,7 +1237,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=12" } @@ -1175,7 +1252,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -1191,7 +1267,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -1207,7 +1282,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -1534,93 +1608,23 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dependencies": { - "color-convert": "^2.0.1" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6.0.0" } }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "engines": { "node": ">=6.0.0" } @@ -1678,87 +1682,11 @@ "@lezer/common": "^1.0.0" } }, - "node_modules/@mdx-js/loader": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.22.tgz", - "integrity": "sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==", - "dev": true, - "dependencies": { - "@mdx-js/mdx": "1.6.22", - "@mdx-js/react": "1.6.22", - "loader-utils": "2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/@mdx-js/mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", - "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", - "dev": true, - "dependencies": { - "@babel/core": "7.12.9", - "@babel/plugin-syntax-jsx": "7.12.1", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "1.6.22", - "babel-plugin-apply-mdx-type-prop": "1.6.22", - "babel-plugin-extract-import-names": "1.6.22", - "camelcase-css": "2.0.1", - "detab": "2.0.4", - "hast-util-raw": "6.0.1", - "lodash.uniq": "4.5.0", - "mdast-util-to-hast": "10.0.1", - "remark-footnotes": "2.0.0", - "remark-mdx": "1.6.22", - "remark-parse": "8.0.3", - "remark-squeeze-paragraphs": "4.0.0", - "style-to-object": "0.3.0", - "unified": "9.2.0", - "unist-builder": "2.0.3", - "unist-util-visit": "2.0.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" - } - }, - "node_modules/@mdx-js/rollup": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mdx-js/rollup/-/rollup-3.0.0.tgz", - "integrity": "sha512-ITvGiwPGEBW+D7CCnpSA9brzAosIWHAi4y+Air8wgfLnez8aWue50avHtWMfnFLCp7vt+JQ9UM8nwfuQuuydxw==", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@rollup/pluginutils": "^5.0.0", - "source-map": "^0.7.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "rollup": ">=2" - } - }, - "node_modules/@mdx-js/rollup/node_modules/@mdx-js/mdx": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", @@ -1789,281 +1717,100 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/@mdx-js/rollup/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@mdx-js/rollup/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@mdx-js/rollup/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/@mdx-js/rollup/node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@mdx-js/rollup/node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@mdx-js/rollup/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/@mdx-js/rollup/node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "node_modules/@mdx-js/mdx/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8" } }, - "node_modules/@mdx-js/rollup/node_modules/mdast-util-to-hast": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", - "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", + "node_modules/@mdx-js/rollup": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@mdx-js/rollup/-/rollup-3.0.0.tgz", + "integrity": "sha512-ITvGiwPGEBW+D7CCnpSA9brzAosIWHAi4y+Air8wgfLnez8aWue50avHtWMfnFLCp7vt+JQ9UM8nwfuQuuydxw==", + "dev": true, "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", + "@mdx-js/mdx": "^3.0.0", + "@rollup/pluginutils": "^5.0.0", + "source-map": "^0.7.0", "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/rollup/node_modules/remark-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", - "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "peerDependencies": { + "rollup": ">=2" } }, - "node_modules/@mdx-js/rollup/node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/@mdx-js/rollup/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" } }, - "node_modules/@mdx-js/rollup/node_modules/remark-rehype": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "node_modules/@mui/base": { + "version": "5.0.0-beta.34", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.34.tgz", + "integrity": "sha512-e2mbTGTtReD/y5RFwnhkl1Tgl3XwgJhY040IlfkTVaU9f5LWrVhEnpRsYXu3B1CtLrwiWs4cu7aMHV9yRd4jpw==", "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.7", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@mdx-js/rollup/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "node_modules/@mui/base/node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", "engines": { - "node": ">= 8" + "node": ">=6" } }, - "node_modules/@mdx-js/rollup/node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "node_modules/@mui/core-downloads-tracker": { + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.7.tgz", + "integrity": "sha512-AuF+Wo2Mp/edaO6vJnWjg+gj4tzEz5ChMZnAQpc22DXpSvM8ddgGcZvM7D7F99pIBoSv8ub+Iz0viL+yuGVmhg==", "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/mui-org" } }, - "node_modules/@mdx-js/rollup/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "node_modules/@mui/icons-material": { + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.7.tgz", + "integrity": "sha512-EDAc8TVJGIA/imAvR3u4nANl2W5h3QeHieu2gK7Ypez/nIA55p08tHjf8UrMXEpxCAvfZO6piY9S9uaxETdicA==", "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/rollup/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/rollup/node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/rollup/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/rollup/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/util": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", - "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.33", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.33.tgz", - "integrity": "sha512-WcSpoJUw/UYHXpvgtl4HyMar2Ar97illUpqiS/X1gtSBp6sdDW6kB2BJ9OlVQ+Kk/RL2GDp/WHA9sbjAYV35ow==", - "dependencies": { - "@babel/runtime": "^7.23.8", - "@floating-ui/react-dom": "^2.0.6", - "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.6", - "@popperjs/core": "^2.11.8", - "clsx": "^2.1.0", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/base/node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.6.tgz", - "integrity": "sha512-0aoWS4qvk1uzm9JBs83oQmIMIQeTBUeqqu8u+3uo2tMznrB5fIKqQVCbCgq+4Tm4jG+5F7dIvnjvQ2aV7UKtdw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - } - }, - "node_modules/@mui/icons-material": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.6.tgz", - "integrity": "sha512-GnkxMtlhs+8ieHLmCytg00ew0vMOiXGFCw8Ra9nxMsBjBqnrOI5gmXqUm+sGggeEU/HG8HyeqC1MX/IxOBJHzA==", - "dependencies": { - "@babel/runtime": "^7.23.8" - }, - "engines": { - "node": ">=12.0.0" + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" }, "funding": { "type": "opencollective", @@ -2081,15 +1828,15 @@ } }, "node_modules/@mui/lab": { - "version": "5.0.0-alpha.162", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.162.tgz", - "integrity": "sha512-nSdlhq1YVozKXn6mtItWmnU9b/gQ708RSWG6C+M/Y096MlQ7Mz1gdNWOEwcGw2HaNoNgDvuG0+0HKARAMIMaLg==", + "version": "5.0.0-alpha.163", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.163.tgz", + "integrity": "sha512-ieOX3LFBln78jgNsBca0JUX+zAC2p6/u2P9b7rU9eZIr0AK44b5Qr8gDOWI1JfJtib4kxLGd1Msasrbxy5cMSQ==", "dependencies": { - "@babel/runtime": "^7.23.8", - "@mui/base": "5.0.0-beta.33", - "@mui/system": "^5.15.6", + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.34", + "@mui/system": "^5.15.7", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.6", + "@mui/utils": "^5.15.7", "clsx": "^2.1.0", "prop-types": "^15.8.1" }, @@ -2129,16 +1876,16 @@ } }, "node_modules/@mui/material": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.6.tgz", - "integrity": "sha512-rw7bDdpi2kzfmcDN78lHp8swArJ5sBCKsn+4G3IpGfu44ycyWAWX0VdlvkjcR9Yrws2KIm7c+8niXpWHUDbWoA==", - "dependencies": { - "@babel/runtime": "^7.23.8", - "@mui/base": "5.0.0-beta.33", - "@mui/core-downloads-tracker": "^5.15.6", - "@mui/system": "^5.15.6", + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.7.tgz", + "integrity": "sha512-l6+AiKZH3iOJmZCnlpel8ghYQe9Lq0BEuKP8fGj3g5xz4arO9GydqYAtLPMvuHKtArj8lJGNuT2yHYxmejincA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.34", + "@mui/core-downloads-tracker": "^5.15.7", + "@mui/system": "^5.15.7", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.6", + "@mui/utils": "^5.15.7", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.2", @@ -2181,12 +1928,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.6.tgz", - "integrity": "sha512-ZBX9E6VNUSscUOtU8uU462VvpvBS7eFl5VfxAzTRVQBHflzL+5KtnGrebgf6Nd6cdvxa1o0OomiaxSKoN2XDmg==", + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.7.tgz", + "integrity": "sha512-bcEeeXm7GyQCQvN9dwo8htGv8/6tP05p0i02Z7GXm5EoDPlBcqTNGugsjNLoGq6B0SsdyanjJGw0Jw00o1yAOA==", "dependencies": { - "@babel/runtime": "^7.23.8", - "@mui/utils": "^5.15.6", + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.7", "prop-types": "^15.8.1" }, "engines": { @@ -2207,11 +1954,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.6.tgz", - "integrity": "sha512-KAn8P8xP/WigFKMlEYUpU9z2o7jJnv0BG28Qu1dhNQVutsLVIFdRf5Nb+0ijp2qgtcmygQ0FtfRuXv5LYetZTg==", + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.7.tgz", + "integrity": "sha512-ixSdslOjK1kzdGcxqj7O3d14By/LPQ7EWknsViQ8RaeT863EAQemS+zvUJDTcOpkfJh6q6gPnYMIb2TJCs9eWA==", "dependencies": { - "@babel/runtime": "^7.23.8", + "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -2238,15 +1985,15 @@ } }, "node_modules/@mui/system": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.6.tgz", - "integrity": "sha512-J01D//u8IfXvaEHMBQX5aO2l7Q+P15nt96c4NskX7yp5/+UuZP8XCQJhtBtLuj+M2LLyXHYGmCPeblsmmscP2Q==", + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.7.tgz", + "integrity": "sha512-9alZ4/dLxsTwUOdqakgzxiL5YW6ntqj0CfzWImgWnBMTZhgGcPsbYpBLniNkkk7/jptma4/bykWXHwju/ls/pg==", "dependencies": { - "@babel/runtime": "^7.23.8", - "@mui/private-theming": "^5.15.6", - "@mui/styled-engine": "^5.15.6", + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.7", + "@mui/styled-engine": "^5.15.7", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.6", + "@mui/utils": "^5.15.7", "clsx": "^2.1.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -2298,11 +2045,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.6.tgz", - "integrity": "sha512-qfEhf+zfU9aQdbzo1qrSWlbPQhH1nCgeYgwhOVnj9Bn39shJQitEnXpSQpSNag8+uty5Od6PxmlNKPTnPySRKA==", + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.7.tgz", + "integrity": "sha512-8qhsxQRNV6aEOjjSk6YQIYJxkF5klhj8oG1FEEU4z6HV78TjNqRxMP08QGcdsibEbez+nihAaz6vu83b4XqbAg==", "dependencies": { - "@babel/runtime": "^7.23.8", + "@babel/runtime": "^7.23.9", "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" @@ -2325,17 +2072,17 @@ } }, "node_modules/@mui/x-date-pickers": { - "version": "5.0.0-beta.6", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.0-beta.6.tgz", - "integrity": "sha512-8NS3s1uslmmZLl1KVCJ6eu9Wnago0EUdRb4NTCmJOwphE2w7cdI4LP+ZGRH7uWtkb6dQEmum1oumBAB3g4Ix+A==", + "version": "5.0.20", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.20.tgz", + "integrity": "sha512-ERukSeHIoNLbI1C2XRhF9wRhqfsr+Q4B1SAw2ZlU7CWgcG8UBOxgqRKDEOVAIoSWL+DWT6GRuQjOKvj6UXZceA==", "dependencies": { - "@babel/runtime": "^7.18.6", + "@babel/runtime": "^7.18.9", "@date-io/core": "^2.15.0", "@date-io/date-fns": "^2.15.0", "@date-io/dayjs": "^2.15.0", "@date-io/luxon": "^2.15.0", "@date-io/moment": "^2.15.0", - "@mui/utils": "^5.4.1", + "@mui/utils": "^5.10.3", "@types/react-transition-group": "^4.4.5", "clsx": "^1.2.1", "prop-types": "^15.7.2", @@ -2417,17 +2164,6 @@ "node": ">= 8" } }, - "node_modules/@openreplay/tracker": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/@openreplay/tracker/-/tracker-3.6.6.tgz", - "integrity": "sha512-mM1s/D+v+oyD+xlwF/GP5JsHrSXziIZvF4e85WMDa/zaboVgEg1m0VpJtCd3SiDCESaXcZA20iDXcfWPVmRPAw==", - "dependencies": { - "error-stack-parser": "^2.0.6" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -2447,47 +2183,24 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@react-dnd/asap": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.1.tgz", - "integrity": "sha512-kLy0PJDDwvwwTXxqTFNAAllPHD73AycE9ypWeln/IguoGBEbvFcPDbCV03G52bEcC5E+YgupBE0VzHGdC8SIXg==" - }, - "node_modules/@react-dnd/invariant": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz", - "integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==" - }, - "node_modules/@react-dnd/shallowequal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", - "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" - }, - "node_modules/@rollup/plugin-inject": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", - "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", + "node_modules/@redux-devtools/extension": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/extension/-/extension-3.3.0.tgz", + "integrity": "sha512-X34S/rC8S/M1BIrkYD1mJ5f8vlH0BDqxXrs96cvxSBo4FhMdbhU+GUGsmNYov1xjSyLMHgo8NYrUG8bNX7525g==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" + "@babel/runtime": "^7.23.2", + "immutable": "^4.3.4" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "redux": "^3.1.0 || ^4.0.0 || ^5.0.0" } }, "node_modules/@rollup/pluginutils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -2505,302 +2218,139 @@ } } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", - "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", - "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", - "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", - "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", - "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", - "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", - "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", - "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", - "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", - "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", - "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", - "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", - "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true }, "node_modules/@sentry-internal/feedback": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.98.0.tgz", - "integrity": "sha512-t/mATvwkLcQLKRlx8SO5vlUjaadF6sT3lfR0PdWYyBy8qglbMTHDW4KP6JKh1gdzTVQGnwMByy+/4h9gy4AVzw==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.99.0.tgz", + "integrity": "sha512-exIO1o+bE0MW4z30FxC0cYzJ4ZHSMlDPMHCBDPzU+MWGQc/fb8s58QUrx5Dnm6HTh9G3H+YlroCxIo9u0GSwGQ==", "dependencies": { - "@sentry/core": "7.98.0", - "@sentry/types": "7.98.0", - "@sentry/utils": "7.98.0" + "@sentry/core": "7.99.0", + "@sentry/types": "7.99.0", + "@sentry/utils": "7.99.0" }, "engines": { "node": ">=12" } }, "node_modules/@sentry-internal/feedback/node_modules/@sentry/types": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.98.0.tgz", - "integrity": "sha512-pc034ziM0VTETue4bfBcBqTWGy4w0okidtoZJjGVrYAfE95ObZnUGVj/XYIQ3FeCYWIa7NFN2MvdsCS0buwivQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz", + "integrity": "sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==", "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.98.0.tgz", - "integrity": "sha512-vAR6KIycyazaY9HwxG5UONrPTe8jeKtZr6k04svPC8OvcoI0xF+l1jMEYcarffuzKpZlPfssYb5ChHtKuXCB+Q==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.99.0.tgz", + "integrity": "sha512-PoIkfusToDq0snfl2M6HJx/1KJYtXxYhQplrn11kYadO04SdG0XGXf4h7wBTMEQ7LDEAtQyvsOu4nEQtTO3YjQ==", "dependencies": { - "@sentry/core": "7.98.0", - "@sentry/replay": "7.98.0", - "@sentry/types": "7.98.0", - "@sentry/utils": "7.98.0" + "@sentry/core": "7.99.0", + "@sentry/replay": "7.99.0", + "@sentry/types": "7.99.0", + "@sentry/utils": "7.99.0" }, "engines": { "node": ">=12" } }, "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/types": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.98.0.tgz", - "integrity": "sha512-pc034ziM0VTETue4bfBcBqTWGy4w0okidtoZJjGVrYAfE95ObZnUGVj/XYIQ3FeCYWIa7NFN2MvdsCS0buwivQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz", + "integrity": "sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==", "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.98.0.tgz", - "integrity": "sha512-FnhD2uMLIAJvv4XsYPv3qsTTtxrImyLxiZacudJyaWFhxoeVQ8bKKbWJ/Ar68FAwqTtjXMeY5evnEBbRMcQlaA==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.99.0.tgz", + "integrity": "sha512-z3JQhHjoM1KdM20qrHwRClKJrNLr2CcKtCluq7xevLtXHJWNAQQbafnWD+Aoj85EWXBzKt9yJMv2ltcXJ+at+w==", "dependencies": { - "@sentry/core": "7.98.0", - "@sentry/types": "7.98.0", - "@sentry/utils": "7.98.0" + "@sentry/core": "7.99.0", + "@sentry/types": "7.99.0", + "@sentry/utils": "7.99.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry-internal/tracing/node_modules/@sentry/types": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.98.0.tgz", - "integrity": "sha512-pc034ziM0VTETue4bfBcBqTWGy4w0okidtoZJjGVrYAfE95ObZnUGVj/XYIQ3FeCYWIa7NFN2MvdsCS0buwivQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz", + "integrity": "sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==", "engines": { "node": ">=8" } }, "node_modules/@sentry/browser": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.98.0.tgz", - "integrity": "sha512-/MzTS31N2iM6Qwyh4PSpHihgmkVD5xdfE5qi1mTlwQZz5Yz8t7MdMriX8bEDPlLB8sNxl7+D6/+KUJO8akX0nQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.99.0.tgz", + "integrity": "sha512-bgfoUv3wkwwLgN5YUOe0ibB3y268ZCnamZh6nLFqnY/UBKC1+FXWFdvzVON/XKUm62LF8wlpCybOf08ebNj2yg==", "dependencies": { - "@sentry-internal/feedback": "7.98.0", - "@sentry-internal/replay-canvas": "7.98.0", - "@sentry-internal/tracing": "7.98.0", - "@sentry/core": "7.98.0", - "@sentry/replay": "7.98.0", - "@sentry/types": "7.98.0", - "@sentry/utils": "7.98.0" + "@sentry-internal/feedback": "7.99.0", + "@sentry-internal/replay-canvas": "7.99.0", + "@sentry-internal/tracing": "7.99.0", + "@sentry/core": "7.99.0", + "@sentry/replay": "7.99.0", + "@sentry/types": "7.99.0", + "@sentry/utils": "7.99.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/browser/node_modules/@sentry/types": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.98.0.tgz", - "integrity": "sha512-pc034ziM0VTETue4bfBcBqTWGy4w0okidtoZJjGVrYAfE95ObZnUGVj/XYIQ3FeCYWIa7NFN2MvdsCS0buwivQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz", + "integrity": "sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==", "engines": { "node": ">=8" } }, "node_modules/@sentry/core": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.98.0.tgz", - "integrity": "sha512-baRUcpCNGyk7cApQHMfqEZJkXdvAKK+z/dVWiMqWc5T5uhzMnPE8/gjP1JZsMtJSQ8g5nHimBdI5TwOyZtxPaA==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.99.0.tgz", + "integrity": "sha512-vOAtzcAXEUtS/oW7wi3wMkZ3hsb5Ch96gKyrrj/mXdOp2zrcwdNV6N9/pawq2E9P/7Pw8AXw4CeDZztZrjQLuA==", "dependencies": { - "@sentry/types": "7.98.0", - "@sentry/utils": "7.98.0" + "@sentry/types": "7.99.0", + "@sentry/utils": "7.99.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/core/node_modules/@sentry/types": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.98.0.tgz", - "integrity": "sha512-pc034ziM0VTETue4bfBcBqTWGy4w0okidtoZJjGVrYAfE95ObZnUGVj/XYIQ3FeCYWIa7NFN2MvdsCS0buwivQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz", + "integrity": "sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==", "engines": { "node": ">=8" } }, "node_modules/@sentry/replay": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.98.0.tgz", - "integrity": "sha512-CQabv/3KnpMkpc2TzIquPu5krpjeMRAaDIO0OpTj5SQeH2RqSq3fVWNZkHa8tLsADxcfLFINxqOg2jd1NxvwxA==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.99.0.tgz", + "integrity": "sha512-gyN/I2WpQrLAZDT+rScB/0jnFL2knEVBo8U8/OVt8gNP20Pq8T/rDZKO/TG0cBfvULDUbJj2P4CJryn2p/O2rA==", "dependencies": { - "@sentry-internal/tracing": "7.98.0", - "@sentry/core": "7.98.0", - "@sentry/types": "7.98.0", - "@sentry/utils": "7.98.0" + "@sentry-internal/tracing": "7.99.0", + "@sentry/core": "7.99.0", + "@sentry/types": "7.99.0", + "@sentry/utils": "7.99.0" }, "engines": { "node": ">=12" } }, "node_modules/@sentry/replay/node_modules/@sentry/types": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.98.0.tgz", - "integrity": "sha512-pc034ziM0VTETue4bfBcBqTWGy4w0okidtoZJjGVrYAfE95ObZnUGVj/XYIQ3FeCYWIa7NFN2MvdsCS0buwivQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz", + "integrity": "sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==", "engines": { "node": ">=8" } @@ -2815,20 +2365,20 @@ } }, "node_modules/@sentry/utils": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.98.0.tgz", - "integrity": "sha512-0/LY+kpHxItVRY0xPDXPXVsKRb95cXsGSQf8sVMtfSjz++0bLL1U4k7PFz1c5s2/Vk0B8hS6duRrgMv6dMIZDw==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.99.0.tgz", + "integrity": "sha512-cYZy5WNTkWs5GgggGnjfGqC44CWir0pAv4GVVSx0fsup4D4pMKBJPrtub15f9uC+QkUf3vVkqwpBqeFxtmJQTQ==", "dependencies": { - "@sentry/types": "7.98.0" + "@sentry/types": "7.99.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/utils/node_modules/@sentry/types": { - "version": "7.98.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.98.0.tgz", - "integrity": "sha512-pc034ziM0VTETue4bfBcBqTWGy4w0okidtoZJjGVrYAfE95ObZnUGVj/XYIQ3FeCYWIa7NFN2MvdsCS0buwivQ==", + "version": "7.99.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz", + "integrity": "sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA==", "engines": { "node": ">=8" } @@ -3012,36 +2562,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@svgr/core/node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, "node_modules/@svgr/core/node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -3054,21 +2574,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@svgr/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@svgr/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", @@ -3108,51 +2613,6 @@ "@svgr/core": "*" } }, - "node_modules/@svgr/plugin-jsx/node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@svgr/plugin-jsx/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@svgr/plugin-jsx/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@testing-library/dom": { "version": "9.3.4", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", @@ -3173,82 +2633,6 @@ "node": ">=14" } }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.17.0", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", @@ -3271,21 +2655,6 @@ "yarn": ">=1" } }, - "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/@testing-library/jest-dom/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -3299,45 +2668,6 @@ "node": ">=8" } }, - "node_modules/@testing-library/jest-dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@testing-library/jest-dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/react": { "version": "12.1.5", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", @@ -3375,110 +2705,40 @@ "node": ">=12" } }, - "node_modules/@testing-library/react/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@babel/runtime": "^7.12.5" }, "engines": { - "node": ">=8" + "node": ">=10", + "npm": ">=6" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" } }, - "node_modules/@testing-library/react/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node_modules/@tginternal/editor": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@tginternal/editor/-/editor-1.15.1.tgz", + "integrity": "sha512-pdsz7e6L8TRJBYs5KTQnI4JJ3O19NTfRaciLZtzN67fPEqucNFNVAWfpKg92vvpG/roHIMj+Qjw0OiqYIc0nDA==", + "peerDependencies": { + "@codemirror/lint": "^6.4.2", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.23.1" } }, - "node_modules/@testing-library/react/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@tginternal/language-util": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@tginternal/language-util/-/language-util-1.1.1.tgz", + "integrity": "sha512-DRkEf72TDfHVsT46mFLr7qaYcwdvIgQWprJsOEUHSiTFeBmE3wY1gwlESD/gEgZYP7P5jjcp1m8mrTeQH3NKVw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@testing-library/react/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, - "node_modules/@tginternal/editor": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@tginternal/editor/-/editor-1.15.1.tgz", - "integrity": "sha512-pdsz7e6L8TRJBYs5KTQnI4JJ3O19NTfRaciLZtzN67fPEqucNFNVAWfpKg92vvpG/roHIMj+Qjw0OiqYIc0nDA==", - "peerDependencies": { - "@codemirror/lint": "^6.4.2", - "@codemirror/state": "^6.4.0", - "@codemirror/view": "^6.23.1" - } - }, - "node_modules/@tginternal/language-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@tginternal/language-util/-/language-util-1.1.1.tgz", - "integrity": "sha512-DRkEf72TDfHVsT46mFLr7qaYcwdvIgQWprJsOEUHSiTFeBmE3wY1gwlESD/gEgZYP7P5jjcp1m8mrTeQH3NKVw==", - "dev": true, - "dependencies": { - "@formatjs/intl-getcanonicallocales": "^1.7.0", - "latinize": "^0.5.0" + "@formatjs/intl-getcanonicallocales": "^1.7.0", + "latinize": "^0.5.0" } }, "node_modules/@tolgee/cli": { @@ -3508,38 +2768,39 @@ } }, "node_modules/@tolgee/core": { - "version": "5.20.3", - "resolved": "https://registry.npmjs.org/@tolgee/core/-/core-5.20.3.tgz", - "integrity": "sha512-QVnf2bAkdIhhl3PXRSrVb4sNCFwug9rtjEB/ouu1bdX9fOe5A8J/reSvIdx2rrVAipPAz3aW6tMzjOEW0xBifg==" + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@tolgee/core/-/core-5.25.0.tgz", + "integrity": "sha512-/gS7uf5QpCQDcF5xXMY9e63Ejbcr70Mm3ZIHdCXHwiVqnTFnjXO9AUPo8vkZlScpjfM1xrk0X68uOAaIX12Spw==" }, "node_modules/@tolgee/format-icu": { - "version": "5.20.3", - "resolved": "https://registry.npmjs.org/@tolgee/format-icu/-/format-icu-5.20.3.tgz", - "integrity": "sha512-PfCzwJ1UykoPu2OCF5aDwhydzwBWbCiA1Pq53RLSo5qZaU7S4dDt5uLLASe5eQNRYJmfVJWxFX/Fh6wEirL05A==" + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@tolgee/format-icu/-/format-icu-5.25.0.tgz", + "integrity": "sha512-2FcIHfObos30BXrT8k3WYWHYchbs+Pj9gf7N4MEQUyVttHzAvgvkHM4jJ4AeAb7jSPh5QuRMU3vi8n3IPLwGdA==" }, "node_modules/@tolgee/react": { - "version": "5.20.3", - "resolved": "https://registry.npmjs.org/@tolgee/react/-/react-5.20.3.tgz", - "integrity": "sha512-LWNubZA6E2oo1V5hzziKeqteTbQe/9wZmPP0GDHLsq4hDhe14r3hStG0ac0Teq2oScyMXr8L08qmxc7rW+z/3g==", + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@tolgee/react/-/react-5.25.0.tgz", + "integrity": "sha512-DV2nXEqgVz2lIaXz28UHaGIw7e1c5bMJdH/lorAyWh0NovQWFjgmQ1DMQV7JMNUTWC7KPZUM6V39meASgkb04Q==", "dependencies": { - "@tolgee/web": "5.20.3" + "@tolgee/web": "5.25.0" }, "peerDependencies": { "react": "^16.14.0 || ^17.0.1 || ^18.1.0" } }, "node_modules/@tolgee/web": { - "version": "5.20.3", - "resolved": "https://registry.npmjs.org/@tolgee/web/-/web-5.20.3.tgz", - "integrity": "sha512-yOWwfn8MwQ2uwHOWP2aWaTmeHaLNzTkyeb8mJs9mxUVuJDsuKlDv80cJMDvDWbprx3M63c8JCtBcVSmNY1W1ig==", + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@tolgee/web/-/web-5.25.0.tgz", + "integrity": "sha512-xsdkKUG9eo0VKtZNNGwZo+H5EEmtwDs9IDyNk+5cD0c910TamwxT69G5UKsYTobf96HqWsUucBuLRig0gMst5Q==", "dependencies": { - "@tolgee/core": "5.20.3" + "@tolgee/core": "5.25.0" } }, "node_modules/@types/acorn": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dev": true, "dependencies": { "@types/estree": "*" } @@ -3587,44 +2848,59 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, "node_modules/@types/d3-color": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.6.tgz", - "integrity": "sha512-tbaFGDmJWHqnenvk3QGSvD3RVwr631BjKRD7Sc7VLRgrdX5mk5hTyoeBL6rXZaeoXzmZwIl1D2HPogEdt1rHBg==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" }, "node_modules/@types/d3-interpolate": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.5.tgz", - "integrity": "sha512-UINE41RDaUMbulp+bxQMDnhOi51rh5lA2dG+dWZU0UY/IwQiG/u2x8TfnWYU9+xwGdXsJoAvrBYUEQl0r91atg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", "dependencies": { - "@types/d3-color": "^2" + "@types/d3-color": "*" } }, "node_modules/@types/d3-path": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.4.tgz", - "integrity": "sha512-jjZVLBjEX4q6xneKMmv62UocaFJFOTQSb/1aTzs3m3ICTOFoVaqGBHpNLm/4dVi0/FTltfBKgmOK1ECj3/gGjA==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.2.tgz", + "integrity": "sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA==" }, "node_modules/@types/d3-scale": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.5.tgz", - "integrity": "sha512-YOpKj0kIEusRf7ofeJcSZQsvKbnTwpe1DUF+P2qsotqG53kEsjm7EzzliqQxMkAWdkZcHrg5rRhB4JiDOQPX+A==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", "dependencies": { - "@types/d3-time": "^2" + "@types/d3-time": "*" } }, "node_modules/@types/d3-shape": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.7.tgz", - "integrity": "sha512-HedHlfGHdwzKqX9+PiQVXZrdmGlwo7naoefJP7kCNk4Y7qcpQt1tUaoRa6qn0kbTdlaIHGO7111qLtb/6J8uuw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", "dependencies": { - "@types/d3-path": "^2" + "@types/d3-path": "*" } }, "node_modules/@types/d3-time": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.4.tgz", - "integrity": "sha512-BTfLsxTeo7yFxI/haOOf1ZwJ6xKgQLT9dCp+EcmQv87Gox6X+oKl4mLKfO6fnWm3P22+A6DknMNEZany8ql2Rw==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" }, "node_modules/@types/debug": { "version": "4.1.12", @@ -3646,19 +2922,21 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/estree-jsx": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", - "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.4.tgz", + "integrity": "sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==", + "dev": true, "dependencies": { "@types/estree": "*" } }, "node_modules/@types/hast": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.9.tgz", - "integrity": "sha512-pTHyNlaMD/oKJmS+ZZUyFUcsZeBZpC0lmGquw98CqRVNgAdJZJeD7GoeLiT6Xbx5rU9VCjSt0RwEvDgzh4obFw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, "dependencies": { - "@types/unist": "^2" + "@types/unist": "*" } }, "node_modules/@types/history": { @@ -3710,39 +2988,6 @@ "pretty-format": "^26.0.0" } }, - "node_modules/@types/jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@types/jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/@types/jest/node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", @@ -3781,17 +3026,19 @@ "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==" }, "node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", + "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "dev": true, "dependencies": { - "@types/unist": "^2" + "@types/unist": "*" } }, "node_modules/@types/mdx": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", - "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.11.tgz", + "integrity": "sha512-HM5bwOaIQJIQbAYfax35HCKxx7a3KrK3nBtIqJgSOitivTD1y3oW9P3rxY9RkXYPUk7y/AjAohfHKmFpGE79zw==", + "dev": true }, "node_modules/@types/minimist": { "version": "1.2.5", @@ -3805,9 +3052,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "18.19.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.10.tgz", - "integrity": "sha512-IZD8kAM02AW1HRDTPOlz3npFava678pr8Ie9Vp8uRhBROXAv8MXT2pCnGZZAKYdromsNQLHQcfWQ6EOatVLtqA==", + "version": "18.19.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.14.tgz", + "integrity": "sha512-EnQ4Us2rmOS64nHDWr0XqAD8DsO6f3XR6lf9UIIrZQpUzPVdN/oPuEzfDWNHSyXLvoGgjuEm/sPwFGSSs35Wtg==", "devOptional": true, "dependencies": { "undici-types": "~5.26.4" @@ -3824,11 +3071,10 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, - "node_modules/@types/parse5": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", - "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==", - "dev": true + "node_modules/@types/prismjs": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", + "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" }, "node_modules/@types/prop-types": { "version": "15.7.11", @@ -3904,11 +3150,6 @@ "@types/react": "*" } }, - "node_modules/@types/resize-observer-browser": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", - "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==" - }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", @@ -3930,9 +3171,10 @@ } }, "node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", + "dev": true }, "node_modules/@types/yargs": { "version": "15.0.19", @@ -3962,16 +3204,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz", - "integrity": "sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/type-utils": "6.19.1", - "@typescript-eslint/utils": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -3996,31 +3238,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.1.tgz", - "integrity": "sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4" }, "engines": { @@ -4040,13 +3267,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4057,13 +3284,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz", - "integrity": "sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/utils": "6.19.1", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -4084,9 +3311,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4097,13 +3324,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4124,33 +3351,18 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "engines": { @@ -4164,28 +3376,13 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -4199,7 +3396,8 @@ "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true }, "node_modules/@vitejs/plugin-react": { "version": "4.2.1", @@ -4219,52 +3417,11 @@ "vite": "^4.2.0 || ^5.0.0" } }, - "node_modules/@vitejs/plugin-react/node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@vitejs/plugin-react/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/@vitejs/plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -4276,6 +3433,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -4315,14 +3473,18 @@ } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { @@ -4354,13 +3516,16 @@ } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4431,30 +3596,31 @@ } }, "node_modules/array.prototype.tosorted": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", - "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" }, "engines": { @@ -4473,37 +3639,6 @@ "node": ">=0.10.0" } }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -4517,6 +3652,7 @@ "version": "1.8.6", "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "dev": true, "bin": { "astring": "bin/astring" } @@ -4537,9 +3673,9 @@ "dev": true }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", + "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", "dev": true, "engines": { "node": ">= 0.4" @@ -4548,48 +3684,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/babel-plugin-apply-mdx-type-prop": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", - "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "7.10.4", - "@mdx-js/util": "1.6.22" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@babel/core": "^7.11.6" - } - }, - "node_modules/babel-plugin-apply-mdx-type-prop/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, - "node_modules/babel-plugin-extract-import-names": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", - "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "7.10.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/babel-plugin-extract-import-names/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -4620,10 +3714,9 @@ } }, "node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "dev": true, + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4640,26 +3733,6 @@ "integrity": "sha512-KNWUX/R7wKenwE/G/qFMzGScOgVntOmbE27vvc6GrniDGYb6a5+qWcuoXl8WIOQL7q0TpK7nZDm1Y04Yi3Yn5g==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", @@ -4668,15 +3741,6 @@ "node": ">=0.6" } }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -4686,12 +3750,6 @@ "node": ">=8" } }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -4728,97 +3786,6 @@ "unload": "2.2.0" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "dev": true, - "dependencies": { - "resolve": "^1.17.0" - } - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } - }, "node_modules/browserslist": { "version": "4.22.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", @@ -4850,30 +3817,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -4883,18 +3826,6 @@ "node": "*" } }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", @@ -4926,15 +3857,6 @@ "node": ">=6" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", @@ -4953,9 +3875,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001581", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz", - "integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==", + "version": "1.0.30001584", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001584.tgz", + "integrity": "sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==", "funding": [ { "type": "opencollective", @@ -4972,9 +3894,9 @@ ] }, "node_modules/ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "dev": true, "funding": { "type": "github", @@ -4982,31 +3904,25 @@ } }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true, + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5016,15 +3932,16 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", "dev": true, "funding": { "type": "github", @@ -5032,9 +3949,9 @@ } }, "node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", "dev": true, "funding": { "type": "github", @@ -5068,21 +3985,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" - }, "node_modules/clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -5106,9 +4008,9 @@ } }, "node_modules/collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", "dev": true, "funding": { "type": "github", @@ -5116,17 +4018,22 @@ } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -5141,10 +4048,9 @@ } }, "node_modules/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", - "dev": true, + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5164,18 +4070,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -5223,55 +4117,6 @@ "node": ">=10.0.0" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", @@ -5296,33 +4141,6 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/css-unit-converter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", - "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" - }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -5335,78 +4153,113 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", "dependencies": { - "internmap": "^1.0.0" + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" } }, "node_modules/d3-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", - "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } }, "node_modules/d3-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", - "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } }, "node_modules/d3-interpolate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", - "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "dependencies": { - "d3-color": "1 - 2" + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" } }, "node_modules/d3-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", - "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } }, "node_modules/d3-scale": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", - "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", "dependencies": { - "d3-array": "^2.3.0", - "d3-format": "1 - 2", - "d3-interpolate": "1.2.0 - 2", - "d3-time": "^2.1.1", - "d3-time-format": "2 - 3" + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" } }, "node_modules/d3-shape": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", - "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", "dependencies": { - "d3-path": "1 - 2" + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/d3-time": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", - "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", "dependencies": { - "d3-array": "2" + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" } }, "node_modules/d3-time-format": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", - "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", "dependencies": { - "d3-time": "1 - 2" + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", "engines": { - "node": ">= 12" + "node": ">=12" } }, "node_modules/date-fns": { @@ -5488,15 +4341,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/decode-named-character-reference/node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/deep-equal": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", @@ -5535,34 +4379,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/deep-rename-keys": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz", - "integrity": "sha512-RHd9ABw4Fvk+gYDWqwOftG849x0bYOySl/RgX0tLI9i27ZIeSO91mLZJEp7oPHOMFqHvpgu21YptmDt0FYD/0A==", - "dependencies": { - "kind-of": "^3.0.2", - "rename-keys": "^1.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-rename-keys/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/deep-rename-keys/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/deepmerge": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", @@ -5619,29 +4435,6 @@ "node": ">=6" } }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/detab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", - "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", - "dev": true, - "dependencies": { - "repeat-string": "^1.5.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -5651,6 +4444,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, "dependencies": { "dequal": "^2.0.0" }, @@ -5676,23 +4470,6 @@ "node": ">= 10.14.2" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -5705,16 +4482,6 @@ "node": ">=8" } }, - "node_modules/dnd-core": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-14.0.1.tgz", - "integrity": "sha512-+PVS2VPTgKFPYWo3vAFEA8WPbTf7/xo43TifH9G8S1KqnrQu0o77A3unrF5yOugy4mIz7K5wAVFHUcha7wsz6A==", - "dependencies": { - "@react-dnd/asap": "^4.0.0", - "@react-dnd/invariant": "^2.0.0", - "redux": "^4.1.1" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -5742,18 +4509,6 @@ "csstype": "^3.0.2" } }, - "node_modules/domain-browser": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", - "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" - } - }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -5793,30 +4548,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.648", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz", - "integrity": "sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg==" - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "version": "1.4.656", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.656.tgz", + "integrity": "sha512-9AQB5eFTHyR3Gvt2t/NwR0le2jBSUNwCnMbUCejFWHD+so4tH40/dRLgoE+jxlPeWS43XJewyvCv+I8LPMl49Q==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -5824,15 +4558,6 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", @@ -5866,14 +4591,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "dependencies": { - "stackframe": "^1.3.4" - } - }, "node_modules/es-abstract": { "version": "1.22.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", @@ -5927,6 +4644,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-get-iterator": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", @@ -6014,7 +4740,6 @@ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "hasInstallScript": true, - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -6048,9 +4773,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "engines": { "node": ">=6" } @@ -6301,21 +5026,6 @@ "@babel/highlight": "^7.10.4" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/eslint/node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -6335,40 +5045,6 @@ "concat-map": "0.0.1" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", @@ -6393,15 +5069,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/eslint/node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -6436,33 +5103,6 @@ "node": "*" } }, - "node_modules/eslint/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -6548,6 +5188,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0" }, @@ -6560,6 +5201,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", @@ -6571,18 +5213,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/estree-util-build-jsx/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, "node_modules/estree-util-is-identifier-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -6592,6 +5227,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", @@ -6606,6 +5242,7 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, "engines": { "node": ">= 8" } @@ -6614,6 +5251,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" @@ -6623,15 +5261,14 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/estree-util-visit/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } }, "node_modules/esutils": { "version": "2.0.3", @@ -6647,15 +5284,6 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, "node_modules/eventsource": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", @@ -6664,16 +5292,6 @@ "node": ">=12.0.0" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -6682,7 +5300,8 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-diff": { "version": "1.3.0", @@ -6727,9 +5346,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", - "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -6755,28 +5374,6 @@ "pend": "~1.2.0" } }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, "node_modules/fflate": { "version": "0.4.8", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", @@ -6883,17 +5480,6 @@ "node": ">= 6" } }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/formik": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.5.tgz", @@ -7000,16 +5586,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.3.tgz", + "integrity": "sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==", "dev": true, "dependencies": { + "es-errors": "^1.0.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7162,11 +5752,12 @@ } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { @@ -7206,12 +5797,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -7220,30 +5811,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -7255,86 +5822,6 @@ "node": ">= 0.4" } }, - "node_modules/hast-to-hyperscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", - "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.3", - "comma-separated-tokens": "^1.0.0", - "property-information": "^5.3.0", - "space-separated-tokens": "^1.0.0", - "style-to-object": "^0.3.0", - "unist-util-is": "^4.0.0", - "web-namespaces": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", - "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", - "dev": true, - "dependencies": { - "@types/parse5": "^5.0.0", - "hastscript": "^6.0.0", - "property-information": "^5.0.0", - "vfile": "^4.0.0", - "vfile-location": "^3.2.0", - "web-namespaces": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-is-element": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", @@ -7348,94 +5835,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-is-element/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dev": true, - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", - "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", - "dev": true, - "dependencies": { - "@types/hast": "^2.0.0", - "hast-util-from-parse5": "^6.0.0", - "hast-util-to-parse5": "^6.0.0", - "html-void-elements": "^1.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^3.0.0", - "vfile": "^4.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-to-estree": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", @@ -7459,91 +5863,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-estree/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/hast-util-to-estree/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-to-estree/node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-to-estree/node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree/node_modules/property-information": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", - "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-to-estree/node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-to-estree/node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/hast-util-to-estree/node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree/node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", @@ -7566,98 +5890,19 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-jsx-runtime/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", - "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/property-information": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", - "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==", + "dev": true }, "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", - "dependencies": { - "inline-style-parser": "0.2.2" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", - "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", "dev": true, "dependencies": { - "hast-to-hyperscript": "^9.0.0", - "property-information": "^5.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "inline-style-parser": "0.2.2" } }, "node_modules/hast-util-to-text": { @@ -7676,41 +5921,13 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-text/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dev": true, - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/hast-util-to-text/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true - }, "node_modules/hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "dev": true, "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" + "@types/hast": "^3.0.0" }, "funding": { "type": "opencollective", @@ -7739,17 +5956,6 @@ "value-equal": "^1.0.1" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -7775,56 +5981,44 @@ "node": ">=10" } }, - "node_modules/html-void-elements": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", - "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, + "node_modules/hosted-git-info/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", + "dev": true + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -7872,11 +6066,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/initials": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/initials/-/initials-3.1.2.tgz", - "integrity": "sha512-Sltg35nx8+GX1w4U86rmbxFEmqFiSuMJviS6cB2KChB+jcT2/8Td+nlImXD74HkqpZF5PMv8hN57AyrA/7ltXw==" - }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", @@ -7897,9 +6086,12 @@ } }, "node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } }, "node_modules/intl-messageformat": { "version": "9.13.0", @@ -7949,9 +6141,9 @@ } }, "node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "dev": true, "funding": { "type": "github", @@ -7959,13 +6151,13 @@ } }, "node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "dev": true, "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" }, "funding": { "type": "github", @@ -7989,14 +6181,16 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8062,28 +6256,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -8123,9 +6295,9 @@ } }, "node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "dev": true, "funding": { "type": "github", @@ -8190,9 +6362,9 @@ } }, "node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", "dev": true, "funding": { "type": "github", @@ -8208,22 +6380,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -8273,6 +6429,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dev": true, "dependencies": { "@types/estree": "*" } @@ -8345,12 +6502,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -8393,26 +6550,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -8425,15 +6562,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/isomorphic-timers-promises": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-timers-promises/-/isomorphic-timers-promises-1.0.1.tgz", - "integrity": "sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -8480,64 +6608,6 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff/node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", @@ -8559,18 +6629,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", @@ -8724,20 +6782,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, - "node_modules/loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -8777,16 +6821,11 @@ "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8827,25 +6866,12 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/lowlight/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dev": true, - "dependencies": { - "@types/unist": "*" - } - }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/lz-string": { @@ -8857,22 +6883,10 @@ "lz-string": "bin/bin.js" } }, - "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, "engines": { "node": ">=8" @@ -8881,20 +6895,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/markdown-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "dev": true, "engines": { "node": ">=16" }, @@ -8911,37 +6916,66 @@ "remove-accents": "0.5.0" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, + "node_modules/mdast-util-definitions": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", + "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-squeeze-paragraphs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", - "dev": true, + "node_modules/mdast-util-definitions/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-definitions/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", "dependencies": { - "unist-util-remove": "^2.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-definitions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", - "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", - "dev": true, + "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", "dependencies": { - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" }, "funding": { "type": "opencollective", @@ -8952,6 +6986,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "dev": true, "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -8971,23 +7006,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-from-markdown/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, "node_modules/mdast-util-mdx": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dev": true, "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx-expression": "^2.0.0", @@ -9004,6 +7027,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -9017,26 +7041,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdx-expression/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, "node_modules/mdast-util-mdx-jsx": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", + "dev": true, "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -9057,376 +7066,92 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdx-jsx/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-mdx-jsx/node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/is-alphanumerical": { + "node_modules/mdast-util-mdxjs-esm": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dev": true, "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdx-jsx/node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdx-jsx/node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "node_modules/mdast-util-to-hast": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", + "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", + "dev": true, "dependencies": { - "@types/unist": "^3.0.0" + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dev": true, "dependencies": { + "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" + "@types/mdast": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", - "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-phrasing/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-phrasing/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", - "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", - "dev": true, - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-definitions": "^4.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^2.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-to-markdown/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string/node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, "node_modules/meow": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", @@ -9466,6 +7191,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9500,6 +7226,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9533,6 +7260,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9558,6 +7286,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "dev": true, "dependencies": { "@types/acorn": "^4.0.0", "@types/estree": "^1.0.0", @@ -9579,6 +7308,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dev": true, "dependencies": { "micromark-util-types": "^2.0.0" }, @@ -9591,6 +7321,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dev": true, "dependencies": { "acorn": "^8.0.0", "acorn-jsx": "^5.0.0", @@ -9610,6 +7341,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", @@ -9630,6 +7362,7 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -9641,6 +7374,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9661,6 +7395,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9682,6 +7417,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9707,6 +7443,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9726,6 +7463,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9747,6 +7485,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9768,6 +7507,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9787,6 +7527,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9805,6 +7546,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9825,6 +7567,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9844,6 +7587,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9862,6 +7606,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9883,6 +7628,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9898,6 +7644,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9919,15 +7666,11 @@ "vfile-message": "^4.0.0" } }, - "node_modules/micromark-util-events-to-acorn/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, "node_modules/micromark-util-html-tag-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9943,6 +7686,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9961,6 +7705,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9979,6 +7724,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -9999,6 +7745,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -10020,6 +7767,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -10035,6 +7783,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -10064,25 +7813,6 @@ "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", @@ -10125,18 +7855,6 @@ "node": ">=4" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, "node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -10220,7 +7938,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10244,39 +7961,24 @@ "tslib": "^2.0.3" } }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, "node_modules/node-fetch": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz", - "integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" + "whatwg-url": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "4.x || >=6.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, "node_modules/node-releases": { @@ -10284,50 +7986,6 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, - "node_modules/node-stdlib-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/node-stdlib-browser/-/node-stdlib-browser-1.2.0.tgz", - "integrity": "sha512-VSjFxUhRhkyed8AtLwSCkMrJRfQ3e2lGtG3sP6FEgaLKBBbxM/dLfjRe1+iLhjvyLFW3tBQ8+c0pcOtXGbAZJg==", - "dev": true, - "dependencies": { - "assert": "^2.0.0", - "browser-resolve": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^5.7.1", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "create-require": "^1.1.1", - "crypto-browserify": "^3.11.0", - "domain-browser": "^4.22.0", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "isomorphic-timers-promises": "^1.0.1", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "pkg-dir": "^5.0.0", - "process": "^0.11.10", - "punycode": "^1.4.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.6.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.1", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-stdlib-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -10355,21 +8013,24 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/normalize-package-data/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, + "node_modules/normalize-package-data/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -10565,26 +8226,6 @@ "npm": ">= 7.0.0" } }, - "node_modules/openapi-typescript/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -10602,12 +8243,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -10644,12 +8279,6 @@ "node": ">=6" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10661,37 +8290,32 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, "node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", "dev": true, "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -10709,18 +8333,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -10798,22 +8410,6 @@ "node": ">=8" } }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -10824,20 +8420,13 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", "is-reference": "^3.0.0" } }, - "node_modules/periscopic/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -10847,6 +8436,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -10854,79 +8444,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/postcss": { "version": "8.4.33", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", @@ -10945,7 +8462,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", @@ -10955,15 +8471,10 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/posthog-js": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.103.1.tgz", - "integrity": "sha512-cFXFU4Z4kl/+RUUV4ju1DlfM7dwCGi6H9xWsfhljIhGcBbT8UfS4JGgZGXl9ABQDdgDPb9xciqnysFSsUQshTA==", + "version": "1.104.4", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.104.4.tgz", + "integrity": "sha512-eZyNh0mhyfC129udFh5ln1QnUy67cPnRITVFvcOK4hdniM1v+T+cPxAkQK+4CjdHvvLM8hjh6OhiMWfppYqUzA==", "dependencies": { "fflate": "^0.4.8", "preact": "^10.19.3" @@ -11047,25 +8558,23 @@ "dev": true }, "node_modules/prism-react-renderer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz", - "integrity": "sha512-w23ch4f75V1Tnz8DajsYKvY5lF7H1+WvzvLUcF0paFxkTHSp42RS0H5CttdN2Q8RR3DRGZ9v5xD/h3n8C8kGmg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", + "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, "peerDependencies": { - "react": ">=0.14.9" + "react": ">=16.0.0" } }, - "node_modules/prism-svelte": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz", - "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==" - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, + "node_modules/prism-react-renderer/node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", "engines": { - "node": ">= 0.6.0" + "node": ">=6" } }, "node_modules/progress": { @@ -11098,38 +8607,14 @@ "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" }, "node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dev": true, - "dependencies": { - "xtend": "^4.0.0" - }, + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", + "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -11139,40 +8624,11 @@ "node": ">=6" } }, - "node_modules/pure-color": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz", - "integrity": "sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==" - }, "node_modules/qr.js": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==" }, - "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -11207,25 +8663,6 @@ "node": ">=8" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -11239,51 +8676,14 @@ } }, "node_modules/react-cropper": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/react-cropper/-/react-cropper-2.1.8.tgz", - "integrity": "sha512-QEj6CE9et/gMRqpaKMgZQdBgtzLjjq+zj1pmHwtoWG6GqscDl4QpTwoEElWN2pieYxkwFaZa0lPiD2b9nwqLKQ==", - "dependencies": { - "cropperjs": "^1.5.12" - }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/react-dnd": { - "version": "14.0.5", - "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-14.0.5.tgz", - "integrity": "sha512-9i1jSgbyVw0ELlEVt/NkCUkxy1hmhJOkePoCH713u75vzHGyXhPDm28oLfc2NMSBjZRM1Y+wRjHXJT3sPrTy+A==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/react-cropper/-/react-cropper-2.3.3.tgz", + "integrity": "sha512-zghiEYkUb41kqtu+2jpX2Ntigf+Jj1dF9ew4lAobPzI2adaPE31z0p+5TcWngK6TvmWQUwK3lj4G+NDh1PDQ1w==", "dependencies": { - "@react-dnd/invariant": "^2.0.0", - "@react-dnd/shallowequal": "^2.0.0", - "dnd-core": "14.0.1", - "fast-deep-equal": "^3.1.3", - "hoist-non-react-statics": "^3.3.2" + "cropperjs": "^1.5.13" }, "peerDependencies": { - "@types/hoist-non-react-statics": ">= 3.3.1", - "@types/node": ">= 12", - "@types/react": ">= 16", - "react": ">= 16.14" - }, - "peerDependenciesMeta": { - "@types/hoist-non-react-statics": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-dnd-html5-backend": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-14.1.0.tgz", - "integrity": "sha512-6ONeqEC3XKVf4eVmMTe0oPds+c5B9Foyj8p/ZKLb7kL2qh9COYxiBHv3szd6gztqi/efkmriywLUVlPotqoJyw==", - "dependencies": { - "dnd-core": "14.0.1" + "react": ">=17.0.2" } }, "node_modules/react-dom": { @@ -11413,43 +8813,77 @@ "react": ">=16" } }, - "node_modules/react-markdown/node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/react-markdown/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dependencies": { + "@types/unist": "^2" } }, - "node_modules/react-markdown/node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/react-markdown/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" } }, - "node_modules/react-markdown/node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "engines": { - "node": ">=12" - }, + "node_modules/react-markdown/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/react-markdown/node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/react-markdown/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", + "node_modules/react-markdown/node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/react-markdown/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-markdown/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", "mdast-util-to-string": "^3.1.0", "micromark": "^3.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", @@ -11465,6 +8899,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/react-markdown/node_modules/mdast-util-to-hast": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", + "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-definitions": "^5.0.0", + "micromark-util-sanitize-uri": "^1.1.0", + "trim-lines": "^3.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/react-markdown/node_modules/mdast-util-to-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", @@ -11898,15 +9351,6 @@ } ] }, - "node_modules/react-markdown/node_modules/property-information": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", - "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/react-markdown/node_modules/remark-parse": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", @@ -11921,30 +9365,19 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/react-markdown/node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/react-markdown/node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "node_modules/react-markdown/node_modules/remark-rehype": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", + "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/react-markdown/node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-to-hast": "^12.1.0", + "unified": "^10.0.0" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, "node_modules/react-markdown/node_modules/unified": { @@ -11977,6 +9410,18 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/react-markdown/node_modules/unist-util-position": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/react-markdown/node_modules/unist-util-stringify-position": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", @@ -12095,20 +9540,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-resize-detector": { - "version": "6.7.8", - "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz", - "integrity": "sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw==", - "dependencies": { - "@types/resize-observer-browser": "^0.1.6", - "lodash": "^4.17.21", - "resize-observer-polyfill": "^1.5.1" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0", - "react-dom": "^16.0.0 || ^17.0.0" - } - }, "node_modules/react-router": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", @@ -12269,605 +9700,220 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recharts": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.1.9.tgz", - "integrity": "sha512-VozH5uznUvGqD7n224FGj7cmMAenlS0HPCs+7r2HeeHiQK6un6z0CTZfWVAB860xbcr4m+BN/EGMPZmYWd34Rg==", - "dependencies": { - "@types/d3-interpolate": "^2.0.0", - "@types/d3-scale": "^3.0.0", - "@types/d3-shape": "^2.0.0", - "classnames": "^2.2.5", - "d3-interpolate": "^2.0.0", - "d3-scale": "^3.0.0", - "d3-shape": "^2.0.0", - "eventemitter3": "^4.0.1", - "lodash": "^4.17.19", - "react-is": "^16.10.2", - "react-resize-detector": "^6.6.3", - "react-smooth": "^2.0.0", - "recharts-scale": "^0.4.4", - "reduce-css-calc": "^2.1.8" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0", - "react-dom": "^16.0.0 || ^17.0.0" - } - }, - "node_modules/recharts-scale": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", - "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", - "dependencies": { - "decimal.js-light": "^2.4.1" - } - }, - "node_modules/recharts/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reduce-css-calc": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", - "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", - "dependencies": { - "css-unit-converter": "^1.1.1", - "postcss-value-parser": "^3.3.0" - } - }, - "node_modules/redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "dependencies": { - "@babel/runtime": "^7.9.2" - } - }, - "node_modules/redux-devtools-extension": { - "version": "2.13.9", - "resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.9.tgz", - "integrity": "sha512-cNJ8Q/EtjhQaZ71c8I9+BPySIBVEKssbPpskBfsXqb8HJ002A3KRVHfeRzwRo6mGPqsm7XuHTqNSNeS1Khig0A==", - "deprecated": "Package moved to @redux-devtools/extension.", - "dev": true, - "peerDependencies": { - "redux": "^3.1.0 || ^4.0.0" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", - "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/rehype-highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.0.tgz", - "integrity": "sha512-QtobgRgYoQaK6p1eSr2SD1i61f7bjF2kZHAQHxeCHAuJf7ZUDMvQ7owDq9YTkmar5m5TSUol+2D3bp3KfJf/oA==", - "dev": true, - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-text": "^4.0.0", - "lowlight": "^3.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-highlight/node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dev": true, - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/rehype-highlight/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true - }, - "node_modules/rehype-highlight/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-highlight/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-highlight/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-footnotes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", - "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", - "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "dependencies": { - "@babel/core": "7.12.9", - "@babel/helper-plugin-utils": "7.10.4", - "@babel/plugin-proposal-object-rest-spread": "7.12.1", - "@babel/plugin-syntax-jsx": "7.12.1", - "@mdx-js/util": "1.6.22", - "is-alphabetical": "1.0.4", - "remark-parse": "8.0.3", - "unified": "9.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, - "node_modules/remark-parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", - "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", - "dev": true, - "dependencies": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", - "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-to-hast": "^12.1.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-rehype/node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/remark-rehype/node_modules/mdast-util-definitions": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", - "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/mdast-util-to-hast": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", - "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-definitions": "^5.0.0", - "micromark-util-sanitize-uri": "^1.1.0", - "trim-lines": "^3.0.0", - "unist-util-generated": "^2.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-rehype/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/remark-rehype/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "bin": { + "semver": "bin/semver" } }, - "node_modules/remark-rehype/node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/remark-rehype/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/remark-rehype/node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "node_modules/remark-rehype/node_modules/unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "node_modules/recharts": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.11.0.tgz", + "integrity": "sha512-5s+u1m5Hwxb2nh0LABkE3TS/lFqFHyWl7FnPbQhHobbQQia4ih1t3o3+ikPYr31Ns+kYe4FASIthKeKi/YYvMg==", "dependencies": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.19", + "react-is": "^16.10.2", + "react-smooth": "^2.0.5", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/remark-rehype/node_modules/unist-util-generated": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", - "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" } }, - "node_modules/remark-rehype/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "node_modules/recharts/node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/recharts/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=8" } }, - "node_modules/remark-rehype/node_modules/unist-util-position": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", - "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0" + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/reflect-metadata": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", + "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "get-intrinsic": "^1.2.3", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/remark-rehype/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/remark-rehype/node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/remark-rehype/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "node_modules/rehype-highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.0.tgz", + "integrity": "sha512-QtobgRgYoQaK6p1eSr2SD1i61f7bjF2kZHAQHxeCHAuJf7ZUDMvQ7owDq9YTkmar5m5TSUol+2D3bp3KfJf/oA==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" + "@types/hast": "^3.0.0", + "hast-util-to-text": "^4.0.0", + "lowlight": "^3.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-rehype/node_modules/vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "node_modules/remark-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", + "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-rehype/node_modules/vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-squeeze-paragraphs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", + "node_modules/remark-rehype": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", + "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", "dev": true, "dependencies": { - "mdast-squeeze-paragraphs": "^4.0.0" + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", @@ -12879,23 +9925,6 @@ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" }, - "node_modules/rename-keys": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz", - "integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -12910,11 +9939,6 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, - "node_modules/resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -13015,21 +10039,11 @@ "node": "*" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "node_modules/rollup": { + "name": "@rollup/wasm-node", "version": "4.9.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", - "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", - "peer": true, + "resolved": "https://registry.npmjs.org/@rollup/wasm-node/-/wasm-node-4.9.6.tgz", + "integrity": "sha512-B3FpAkroTE6q+MRHzv8XLBgPbxdjJiy5UnduZNQ/4lxeF1JT2O/OAr0JPpXeRG/7zpKm/kdqU/4m6AULhmnSqw==", "dependencies": { "@types/estree": "1.0.5" }, @@ -13041,19 +10055,6 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.6", - "@rollup/rollup-android-arm64": "4.9.6", - "@rollup/rollup-darwin-arm64": "4.9.6", - "@rollup/rollup-darwin-x64": "4.9.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", - "@rollup/rollup-linux-arm64-gnu": "4.9.6", - "@rollup/rollup-linux-arm64-musl": "4.9.6", - "@rollup/rollup-linux-riscv64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-musl": "4.9.6", - "@rollup/rollup-win32-arm64-msvc": "4.9.6", - "@rollup/rollup-win32-ia32-msvc": "4.9.6", - "@rollup/rollup-win32-x64-msvc": "4.9.6", "fsevents": "~2.3.2" } }, @@ -13145,12 +10146,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -13161,13 +10156,38 @@ } }, "node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/set-function-length": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", @@ -13198,25 +10218,6 @@ "node": ">= 0.4" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -13290,39 +10291,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", @@ -13371,16 +10339,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", - "dev": true, + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -13424,21 +10390,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" - }, - "node_modules/state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -13451,37 +10402,6 @@ "node": ">= 0.4" } }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -13616,6 +10536,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "dev": true, "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -13625,15 +10546,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/stringify-entities/node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -13693,15 +10605,14 @@ } }, "node_modules/style-mod": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.0.tgz", - "integrity": "sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==" + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" }, "node_modules/style-to-object": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", - "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", - "dev": true, + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", "dependencies": { "inline-style-parser": "0.1.1" } @@ -13712,14 +10623,15 @@ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -13739,15 +10651,6 @@ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", "dev": true }, - "node_modules/svgson": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/svgson/-/svgson-5.3.1.tgz", - "integrity": "sha512-qdPgvUNWb40gWktBJnbJRelWcPzkLed/ShhnRsjbayXz8OtdPOzbil9jtiZdrYvSDumAz/VNQr6JaNfPx/gvPA==", - "dependencies": { - "deep-rename-keys": "^0.2.1", - "xml-reader": "2.4.3" - } - }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -13812,18 +10715,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", @@ -13844,6 +10735,25 @@ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dependencies": { + "tmp": "^0.2.0" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -13880,13 +10790,6 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, - "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "deprecated": "Use String.prototype.trim() instead", - "dev": true - }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -13905,33 +10808,22 @@ "node": ">=8" } }, - "node_modules/trim-trailing-lines": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.0.tgz", + "integrity": "sha512-d+3WxW4r8WQy2cZWpNRPPGExX8ffOLGcIhheUANKbL5Sqjbhkneki76fRAWeXkaslV2etTb4tSJBSxOsH5+CJw==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=18" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -13961,76 +10853,6 @@ } } }, - "node_modules/ts-unused-exports/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ts-unused-exports/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ts-unused-exports/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ts-unused-exports/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ts-unused-exports/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-unused-exports/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/tsconfck": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.1.tgz", @@ -14080,12 +10902,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14183,136 +10999,73 @@ "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "5.28.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", - "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==", - "dev": true, - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true - }, - "node_modules/unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/unified": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", - "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", - "dev": true, - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unified/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, + }, "engines": { - "node": ">=8" + "node": ">=14.17" } }, - "node_modules/unified/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { - "@types/unist": "^2.0.2" + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unified/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "node_modules/undici": { + "version": "5.28.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", + "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" + "@fastify/busboy": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=14.0" } }, - "node_modules/unified/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "devOptional": true + }, + "node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-builder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", - "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==", + "node_modules/unified/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, + "engines": { + "node": ">=12" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/unist-util-find-after": { @@ -14329,50 +11082,36 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-find-after/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true - }, - "node_modules/unist-util-find-after/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-generated": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", - "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", + "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -14382,26 +11121,9 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/unist-util-remove": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.1.0.tgz", - "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", "dev": true, "dependencies": { - "unist-util-is": "^4.0.0" + "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", @@ -14409,12 +11131,13 @@ } }, "node_modules/unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", "dev": true, "dependencies": { - "unist-util-visit": "^2.0.0" + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" }, "funding": { "type": "opencollective", @@ -14425,6 +11148,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, "dependencies": { "@types/unist": "^3.0.0" }, @@ -14433,20 +11157,15 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-stringify-position/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, "node_modules/unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", @@ -14454,13 +11173,13 @@ } }, "node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", @@ -14523,16 +11242,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -14542,12 +11251,6 @@ "requires-port": "^1.0.0" } }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, "node_modules/use-context-selector": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/use-context-selector/-/use-context-selector-1.4.1.tgz", @@ -14587,9 +11290,9 @@ } }, "node_modules/usehooks-ts": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-3.0.2.tgz", - "integrity": "sha512-qJScCj8YOxa8RV3Iz2T+2IsydLG0EID5FouTGE7aNFEpFlCXmRrnJiPCESDArKr1FLTaUQSfDQ43UDn7yMLExw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-3.1.0.tgz", + "integrity": "sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw==", "dependencies": { "lodash.debounce": "^4.0.8" }, @@ -14600,25 +11303,6 @@ "react": "^16.8.0 || ^17 || ^18" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, "node_modules/uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", @@ -14669,6 +11353,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dev": true, "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0", @@ -14679,20 +11364,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-location": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", - "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -14702,21 +11378,31 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-message/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/vfile/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/victory-vendor": { + "version": "36.9.0", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.0.tgz", + "integrity": "sha512-n1A0J1xgwHb5nh56M0d8XlQabMCeTktvEqqr5WNAHspWEsVVGGaaaRg0TcQUtyC1akX0Cox1lMZdIv0Jl7o0ew==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } }, "node_modules/vite": { "version": "5.0.12", "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz", "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==", - "peer": true, "dependencies": { "esbuild": "^0.19.3", "postcss": "^8.4.32", @@ -14767,22 +11453,6 @@ } } }, - "node_modules/vite-plugin-node-polyfills": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.19.0.tgz", - "integrity": "sha512-AhdVxAmVnd1doUlIRGUGV6ZRPfB9BvIwDF10oCOmL742IsvsFIAV4tSMxSfu5e0Px0QeJLgWVOSbtHIvblzqMw==", - "dev": true, - "dependencies": { - "@rollup/plugin-inject": "^5.0.5", - "node-stdlib-browser": "^1.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/davidmyersdev" - }, - "peerDependencies": { - "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" - } - }, "node_modules/vite-plugin-static-copy": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.1.tgz", @@ -14834,12 +11504,6 @@ } } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -14857,24 +11521,6 @@ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" }, - "node_modules/web-namespaces": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", - "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", - "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", - "engines": { - "node": ">= 8" - } - }, "node_modules/web-vitals": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", @@ -14990,16 +11636,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -15043,39 +11689,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -15140,33 +11753,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/xml-lexer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz", - "integrity": "sha512-G0i98epIwiUEiKmMcavmVdhtymW+pCAohMRgybyIME9ygfVu8QheIi+YoQh3ngiThsT0SQzJT4R0sKDEv8Ou0w==", - "dependencies": { - "eventemitter3": "^2.0.0" - } - }, - "node_modules/xml-lexer/node_modules/eventemitter3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", - "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" - }, - "node_modules/xml-reader": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz", - "integrity": "sha512-xWldrIxjeAMAu6+HSf9t50ot1uL5M+BtOidRCWHXIeewvSeIpscWCsp4Zxjk8kHHhdqFBrfK8U0EJeCcnyQ/gA==", - "dependencies": { - "eventemitter3": "^2.0.0", - "xml-lexer": "^0.2.2" - } - }, - "node_modules/xml-reader/node_modules/eventemitter3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", - "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" - }, "node_modules/xstate": { "version": "4.38.3", "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.38.3.tgz", @@ -15177,20 +11763,10 @@ "url": "https://opencollective.com/xstate" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { "version": "1.10.2", @@ -15219,18 +11795,6 @@ "fd-slicer": "~1.1.0" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/yup": { "version": "0.32.11", "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", @@ -15272,9 +11836,9 @@ } }, "node_modules/zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "dev": true, "funding": { "type": "github", diff --git a/webapp/package.json b/webapp/package.json index 5cab7b3b61..a815c35b57 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -5,18 +5,16 @@ "type": "module", "dependencies": { "@codemirror/lang-json": "6.0.0", - "@dicebear/avatars": "4.10.2", - "@dicebear/avatars-identicon-sprites": "4.10.2", - "@dicebear/avatars-initials-sprites": "4.10.2", - "@emotion/react": "^11.11.1", + "@dicebear/core": "^7.0.4", + "@dicebear/identicon": "^7.0.4", + "@dicebear/initials": "^7.0.4", + "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@formatjs/icu-messageformat-parser": "^2.0.8", - "@mdx-js/rollup": "^3.0.0", - "@mui/icons-material": "^5.5.1", - "@mui/lab": "^5.0.0-alpha.75", - "@mui/material": "^5.5.3", - "@mui/x-date-pickers": "5.0.0-beta.6", - "@openreplay/tracker": "^3.5.4", + "@mui/icons-material": "^5.15.7", + "@mui/lab": "^5.0.0-alpha.163", + "@mui/material": "^5.15.7", + "@mui/x-date-pickers": "^5.0.20", "@sentry/browser": "^7.80.0", "@stomp/stompjs": "^6.1.2", "@tginternal/editor": "^1.15.1", @@ -32,15 +30,11 @@ "dotenv-flow": "4.0.1", "formik": "^2.2.9", "intl-messageformat": "^9.8.1", - "node-fetch": "3.3.0", "notistack": "^2.0.4", "posthog-js": "^1.96.1", - "prism-react-renderer": "1.2.1", - "prism-svelte": "0.4.7", + "prism-react-renderer": "^2.3.1", "react": "^17.0.1", - "react-cropper": "2.1.8", - "react-dnd": "^14.0.2", - "react-dnd-html5-backend": "^14.0.0", + "react-cropper": "^2.3.3", "react-dom": "^17.0.2", "react-draggable": "^4.4.3", "react-google-recaptcha-v3": "1.9.5", @@ -51,7 +45,7 @@ "react-qr-code": "^2.0.7", "react-query": "^3.39.2", "react-router-dom": "^5.2.0", - "recharts": "2.1.9", + "recharts": "^2.11.0", "reflect-metadata": "^0.1.13", "regenerator-runtime": "^0.13.9", "sockjs-client": "^1.6.1", @@ -99,7 +93,7 @@ ] }, "devDependencies": { - "@mdx-js/loader": "1.6.22", + "@mdx-js/rollup": "^3.0.0", "@sentry/types": "^6.5.1", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", @@ -123,13 +117,21 @@ "eslint-plugin-react": "^7.24.0", "openapi-typescript": "^4.0.2", "prettier": "^2.3.1", - "redux-devtools-extension": "^2.13.9", + "@redux-devtools/extension": "^3.3.0", "rehype-highlight": "^7.0.0", "ts-unused-exports": "^9.0.4", "typescript": "^5.3.3", - "vite-plugin-node-polyfills": "^0.19.0", + "vite": "^5.0.12", "vite-plugin-static-copy": "^1.0.0", "vite-plugin-svgr": "^4.2.0", "vite-tsconfig-paths": "^4.2.3" + }, + "overrides": { + "vite": { + "rollup": "npm:@rollup/wasm-node" + }, + "@mdx-js/rollup": { + "rollup": "npm:@rollup/wasm-node" + } } } diff --git a/webapp/src/component/RootRouter.tsx b/webapp/src/component/RootRouter.tsx index c5bacedcd0..1658c52272 100644 --- a/webapp/src/component/RootRouter.tsx +++ b/webapp/src/component/RootRouter.tsx @@ -1,6 +1,7 @@ import { Redirect, Route, Switch } from 'react-router-dom'; import { LINKS } from 'tg.constants/links'; import { PrivateRoute } from './common/PrivateRoute'; +import { NotificationsRouter } from 'tg.views/notifications/NotificationsRouter'; import { ProjectsRouter } from 'tg.views/projects/ProjectsRouter'; import { UserSettingsRouter } from 'tg.views/userSettings/UserSettingsRouter'; import { OrganizationsRouter } from 'tg.views/organizations/OrganizationsRouter'; @@ -13,33 +14,17 @@ import { RequirePreferredOrganization } from '../RequirePreferredOrganization'; import { HelpMenu } from './HelpMenu'; import { PublicOnlyRoute } from './common/PublicOnlyRoute'; -const LoginRouter = React.lazy( - () => import(/* webpackChunkName: "login" */ './security/Login/LoginRouter') -); -const SignUpView = React.lazy( - () => - import( - /* webpackChunkName: "sign-up-view" */ './security/SignUp/SignUpView' - ) -); +const LoginRouter = React.lazy(() => import('./security/Login/LoginRouter')); +const SignUpView = React.lazy(() => import('./security/SignUp/SignUpView')); const PasswordResetSetView = React.lazy( - () => - import( - /* webpackChunkName: "reset-password-set-view" */ './security/ResetPasswordSetView' - ) + () => import('./security/ResetPasswordSetView') ); const PasswordResetView = React.lazy( - () => - import( - /* webpackChunkName: "reset-password-view" */ './security/ResetPasswordView' - ) + () => import('./security/ResetPasswordView') ); const AcceptInvitationHandler = React.lazy( - () => - import( - /* webpackChunkName: "accept-invitation-handler" */ './security/AcceptInvitationHandler' - ) + () => import('./security/AcceptInvitationHandler') ); const RecaptchaProvider: FC = (props) => { @@ -86,6 +71,9 @@ export const RootRouter = () => ( + + + diff --git a/webapp/src/component/common/avatar/useAutoAvatarImgSrc.tsx b/webapp/src/component/common/avatar/useAutoAvatarImgSrc.tsx index b43e4c8b42..f14121cec0 100644 --- a/webapp/src/component/common/avatar/useAutoAvatarImgSrc.tsx +++ b/webapp/src/component/common/avatar/useAutoAvatarImgSrc.tsx @@ -1,16 +1,61 @@ import { useEffect, useState } from 'react'; import { AutoAvatarProps } from './AutoAvatar'; +import { colors } from '@mui/material'; + +const COLORS_LIGHT = [ + colors.amber[300], + colors.blue[300], + colors.blueGrey[300], + colors.brown[300], + colors.common[300], + colors.cyan[300], + colors.deepOrange[300], + colors.deepPurple[300], + colors.green[300], + colors.grey[300], + colors.indigo[300], + colors.lightBlue[300], + colors.lightGreen[300], + colors.lime[300], + colors.orange[300], + colors.pink[300], + colors.purple[300], + colors.red[300], + colors.teal[300], +]; + +const COLORS_DARK = [ + colors.amber[700], + colors.blue[700], + colors.blueGrey[700], + colors.brown[700], + colors.common[700], + colors.cyan[700], + colors.deepOrange[700], + colors.deepPurple[700], + colors.green[700], + colors.grey[700], + colors.indigo[700], + colors.lightBlue[700], + colors.lightGreen[700], + colors.lime[700], + colors.orange[700], + colors.pink[700], + colors.purple[700], + colors.red[700], + colors.teal[700], +]; function getInitialsAvatarSvg(ownerName: string, size: number, light: boolean) { return Promise.all([ importCreateAvatarFunction(), - import('@dicebear/avatars-initials-sprites'), + import('@dicebear/initials'), ]).then(([crateAvatar, style]) => { return crateAvatar(style, { seed: ownerName, size, scale: 100, - backgroundColorLevel: light ? 300 : 700, + backgroundColor: light ? COLORS_LIGHT : COLORS_DARK, }); }); } @@ -18,7 +63,7 @@ function getInitialsAvatarSvg(ownerName: string, size: number, light: boolean) { function getIdenticonAvatarSvg(entityId: number | string, size: number) { return Promise.all([ importCreateAvatarFunction(), - import('@dicebear/avatars-identicon-sprites'), + import('@dicebear/identicon'), ]).then(([crateAvatar, style]) => { return crateAvatar(style, { seed: entityId.toString(), @@ -29,7 +74,7 @@ function getIdenticonAvatarSvg(entityId: number | string, size: number) { } export const useAutoAvatarImgSrc = (props: AutoAvatarProps) => { - const [base64, setBase64] = useState(undefined as string | undefined); + const [url, setUrl] = useState(undefined as string | undefined); useEffect(() => { let mounted = true; @@ -42,24 +87,17 @@ export const useAutoAvatarImgSrc = (props: AutoAvatarProps) => { props.ownerType === 'PROJECT' ); - svgStringPromise.then((svgString) => { - const base64 = Buffer.from(svgString).toString('base64'); - if (mounted) { - setBase64(base64); - } + svgStringPromise.then((svg) => { + if (mounted) setUrl(svg.toDataUriSync()); }); return () => { mounted = false; }; }, [props.size, props.entityId, props.ownerName, props.ownerType]); - if (!base64) { - return undefined; - } - - return `data:image/svg+xml;base64,${base64}`; + return url; }; function importCreateAvatarFunction() { - return import('@dicebear/avatars').then((m) => m.createAvatar); + return import('@dicebear/core').then((m) => m.createAvatar); } diff --git a/webapp/src/component/layout/TopBar/NotificationBell.tsx b/webapp/src/component/layout/TopBar/NotificationBell.tsx new file mode 100644 index 0000000000..268a444d39 --- /dev/null +++ b/webapp/src/component/layout/TopBar/NotificationBell.tsx @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2024 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Box, IconButton, styled } from '@mui/material'; +import { Notifications } from '@mui/icons-material'; +import { Link } from 'react-router-dom'; +import { LINKS } from 'tg.constants/links'; + +const StyledIconButton = styled(IconButton)` + width: 40px; + height: 40px; + position: relative; +`; + +const StyledNotificationCount = styled(Box)` + border: 3px ${({ theme }) => theme.palette.navbar.background} solid; + border-radius: 0.6rem; + background-color: ${({ theme }) => theme.palette.error.main}; + color: ${({ theme }) => theme.palette.error.contrastText}; + height: 1.2rem; + min-width: 1.2rem; + padding: 0 2px; + font-size: 0.6rem; + font-weight: bold; + display: flex; + align-items: center; + justify-content: center; + position: absolute; + bottom: 0.2rem; + right: 0.2rem; +`; + +export const NotificationBell: React.FC = () => { + return ( + + + + 1 + + + ); +}; diff --git a/webapp/src/component/layout/TopBar/TopBar.tsx b/webapp/src/component/layout/TopBar/TopBar.tsx index 6aa688927a..46ab0286fe 100644 --- a/webapp/src/component/layout/TopBar/TopBar.tsx +++ b/webapp/src/component/layout/TopBar/TopBar.tsx @@ -12,6 +12,7 @@ import { UserMenu } from '../../security/UserMenu/UserMenu'; import { AdminInfo } from './AdminInfo'; import { QuickStartTopBarButton } from '../QuickStartGuide/QuickStartTopBarButton'; import { LanguageMenu } from 'tg.component/layout/TopBar/LanguageMenu'; +import { NotificationBell } from 'tg.component/layout/TopBar/NotificationBell'; export const TOP_BAR_HEIGHT = 52; @@ -121,7 +122,12 @@ export const TopBar: React.FC = ({ {!user && } - {user && } + {user && ( + <> + + + + )} ); diff --git a/webapp/src/constants/links.tsx b/webapp/src/constants/links.tsx index b5fb07d9c3..7d512bc8c8 100644 --- a/webapp/src/constants/links.tsx +++ b/webapp/src/constants/links.tsx @@ -158,6 +158,18 @@ export class LINKS { 'disable-mfa' ); + /** + * Notifications + */ + + static NOTIFICATIONS = Link.ofRoot('notifications'); + + static NOTIFICATIONS_INBOX = Link.ofParent(LINKS.NOTIFICATIONS, 'inbox'); + + static NOTIFICATIONS_UNREAD = Link.ofParent(LINKS.NOTIFICATIONS, 'unread'); + + static NOTIFICATIONS_DONE = Link.ofParent(LINKS.NOTIFICATIONS, 'done'); + /** * Administration */ diff --git a/webapp/src/custom.d.ts b/webapp/src/custom.d.ts index db8314a9e1..95a115d405 100644 --- a/webapp/src/custom.d.ts +++ b/webapp/src/custom.d.ts @@ -1,4 +1,3 @@ -import API from '@openreplay/tracker'; import { PaletteColor } from '@mui/material/styles'; import { PaletteColorOptions } from '@mui/material'; import { @@ -6,6 +5,7 @@ import { Activity, BillingProgress, Cell, + colors, Editor, Emphasis, ExampleBanner, @@ -23,7 +23,6 @@ declare module '*.svg' { const content: React.FunctionComponent>; export default content; } -import { colors } from './colors'; const all = { ...colors.light, ...colors.dark }; @@ -85,9 +84,10 @@ declare module '@mui/material/Button' { } } -declare global { - interface Window { - openReplayTracker?: API; +declare module '@mui/material/ButtonBase' { + interface ButtonBaseOwnProps> + extends TProps { + component?: T; } } diff --git a/webapp/src/views/notifications/NotificationsRouter.tsx b/webapp/src/views/notifications/NotificationsRouter.tsx new file mode 100644 index 0000000000..8ebc63e082 --- /dev/null +++ b/webapp/src/views/notifications/NotificationsRouter.tsx @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2024 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Switch } from 'react-router-dom'; +import { DashboardPage } from 'tg.component/layout/DashboardPage'; +import { PrivateRoute } from 'tg.component/common/PrivateRoute'; +import { LINKS } from 'tg.constants/links'; +import { NotificationsView } from 'tg.views/notifications/NotificationsView'; +import { useTranslate } from '@tolgee/react'; + +export const NotificationsRouter: React.FC = () => { + const { t } = useTranslate(); + + return ( + + + + + + + + + + + + + + + + ); +}; diff --git a/webapp/src/views/notifications/NotificationsView.tsx b/webapp/src/views/notifications/NotificationsView.tsx new file mode 100644 index 0000000000..061f146f47 --- /dev/null +++ b/webapp/src/views/notifications/NotificationsView.tsx @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2024 Tolgee s.r.o. and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { LINKS } from 'tg.constants/links'; + +import { useTranslate } from '@tolgee/react'; +import { BaseSettingsView } from 'tg.component/layout/BaseSettingsView/BaseSettingsView'; +import { NavigationItem } from 'tg.component/navigation/Navigation'; + +type Props = { + unread?: boolean; + read?: boolean; + done?: boolean; + navigation: NavigationItem; +}; + +export const NotificationsView: React.FC = ({ + navigation, + unread, + read, + done, +}) => { + const { t } = useTranslate(); + + return ( + +

test

+
+ ); +}; diff --git a/webapp/vite.config.ts b/webapp/vite.config.ts index ebbd50e0e7..2939619e54 100644 --- a/webapp/vite.config.ts +++ b/webapp/vite.config.ts @@ -2,7 +2,6 @@ import { defineConfig, loadEnv } from 'vite'; import react from '@vitejs/plugin-react'; import viteTsconfigPaths from 'vite-tsconfig-paths'; import svgr from 'vite-plugin-svgr'; -import { nodePolyfills } from 'vite-plugin-node-polyfills'; import mdx from '@mdx-js/rollup'; import { viteStaticCopy } from 'vite-plugin-static-copy'; import { resolve } from 'path'; @@ -21,12 +20,16 @@ export default defineConfig(({ mode }) => { viteTsconfigPaths(), svgr(), mdx({ rehypePlugins: [rehypeHighlight] }), - nodePolyfills(), extractDataCy(), viteStaticCopy({ targets: [ { - src: resolve('node_modules/@tginternal/language-util/flags'), + src: resolve( + 'node_modules', + '@tginternal', + 'language-util', + 'flags' + ), dest: '', }, ], @@ -34,7 +37,7 @@ export default defineConfig(({ mode }) => { ], server: { // this ensures that the browser opens upon server start - open: true, + // open: true, // this sets a default port to 3000 port: Number(process.env.VITE_PORT) || 3000, },