diff --git a/.gitea/workflows/deployStaging.yml b/.gitea/workflows/deployStaging.yml index 3495235b..88de5f30 100644 --- a/.gitea/workflows/deployStaging.yml +++ b/.gitea/workflows/deployStaging.yml @@ -8,10 +8,10 @@ on: jobs: CreateImage: - runs-on: [hubstaging] + runs-on: [skeris] uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/build-image.yml@v1.1.6-p with: - runner: hubstaging + runner: skeris secrets: REGISTRY_USER: ${{ secrets.REGISTRY_USER }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} diff --git a/Containerfile b/Containerfile index d5c502fb..95c38239 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,4 @@ -FROM gitea.pena/penadevops/container-images/node:v20.14.0 as build +FROM gitea.pena/penadevops/container-images/node:main as build WORKDIR /usr/app COPY . . diff --git a/api-docs.html b/api-docs.html new file mode 100644 index 00000000..d8eff4a6 --- /dev/null +++ b/api-docs.html @@ -0,0 +1,577 @@ + + + + + + QUIZ Service API Documentation + + + +
+
+

QUIZ Service API Documentation

+

Version 1.0.0

+
+
+ + + +
+
+

Components

+ +
+

Quiz Model

+
+
{
+  "id": integer,          // Id of created quiz
+  "qid": string,         // string id for customers
+  "deleted": boolean,    // true if quiz deleted
+  "archived": boolean,   // true if quiz archived
+  "fingerprinting": boolean,  // set true for save deviceId
+  "repeatable": boolean,     // set true for allow user to repeat quiz
+  "note_prevented": boolean, // set true for save statistic of incomplete quiz passing
+  "mail_notifications": boolean, // set true for mail notification for each quiz passing
+  "unique_answers": boolean,    // set true for save statistics only for unique quiz passing
+  "name": string,        // name of quiz. max 280 length
+  "description": string, // description of quiz
+  "config": string,      // config of quiz. serialized json for rules of quiz flow
+  "status": string,      // status of quiz. allow only '', 'draft', 'template', 'stop', 'start'
+  "limit": integer,      // limit is count of max quiz passing
+  "due_to": integer,     // last time when quiz is valid. timestamp in seconds
+  "time_of_passing": integer, // seconds to pass quiz
+  "pausable": boolean,   // true if it is allowed for pause quiz
+  "version": integer,    // version of quiz
+  "version_comment": string, // version comment to version of quiz
+  "parent_ids": integer[], // array of previous versions of quiz
+  "created_at": string,  // time of creating
+  "updated_at": string,  // time of last updating
+  "question_cnt": integer, // count of questions
+  "passed_count": integer, // count passings
+  "average_time": integer, // average time of passing
+  "super": boolean,      // set true if squiz realize group functionality
+  "group_id": integer    // group of new quiz
+}
+
+
+ +
+

Question Model

+
+
{
+  "id": integer,         // Id of created question
+  "quiz_id": integer,    // relation to quiz
+  "title": string,       // title of question. max 512 length
+  "description": string, // description of question
+  "type": string,        // status of question. allow only text, select, file, variant, images, varimg, emoji, date, number, page, rating
+  "required": boolean,   // user must pass this question
+  "deleted": boolean,    // true if question is deleted
+  "page": integer,       // page if question
+  "content": string,     // serialized json of created question
+  "version": integer,    // version of quiz
+  "parent_ids": integer[], // array of previous versions of quiz
+  "created_at": string,  // time of creating
+  "updated_at": string   // time of last updating
+}
+
+
+ +
+

Answer Model

+
+
{
+  "Id": integer,         // id ответа
+  "Content": string,     // контент ответа
+  "QuestionId": integer, // id вопроса к которому ответ
+  "QuizId": integer,     // id опроса к которому ответ
+  "Fingerprint": string, // fingerprint
+  "Session": string,     // сессия
+  "Result": boolean,     // true or false?
+  "CreatedAt": string,   // таймшап когда ответ создан
+  "New": boolean,        // новый ответ?
+  "Deleted": boolean     // удален?
+}
+
+
+ +
+

LeadTarget Model

+
+
{
+  "ID": integer,         // primary key
+  "AccountID": string,   // account identifier
+  "Type": string,        // type of target (mail, telegram, whatsapp)
+  "QuizID": integer,     // ID of the quiz
+  "Target": string,      // target address
+  "InviteLink": string,  // invitation link
+  "Deleted": boolean,    // is deleted
+  "CreatedAt": string    // creation timestamp
+}
+
+
+ +
+

TgAccount Model

+
+
{
+  "ID": integer,         // primary key
+  "ApiID": integer,      // Telegram API ID
+  "ApiHash": string,     // Telegram API Hash
+  "PhoneNumber": string, // phone number
+  "Password": string,    // account password
+  "Status": string,      // account status (active, inactive, ban)
+  "Deleted": boolean,    // is deleted
+  "CreatedAt": string    // creation timestamp
+}
+
+
+
+ +
+

Quiz Endpoints

+ +
+

Create Quiz

+ POST + /quiz/create +

Create a new quiz with specified parameters.

+ +
+

Security

+

This endpoint requires authentication.

+
+ +

Request Body:

+
+
{
+  "fingerprinting": boolean,  // set true for save deviceId
+  "repeatable": boolean,     // set true for allow user to repeat quiz
+  "note_prevented": boolean, // set true for save statistic of incomplete quiz passing
+  "mail_notifications": boolean, // set true for mail notification for each quiz passing
+  "unique_answers": boolean,    // set true for save statistics only for unique quiz passing
+  "name": string,        // name of quiz. max 280 length
+  "description": string, // description of quiz
+  "config": string,      // config of quiz. serialized json for rules of quiz flow
+  "status": string,      // status of quiz. allow only '', 'draft', 'template', 'stop', 'start'
+  "limit": integer,      // limit is count of max quiz passing
+  "due_to": integer,     // last time when quiz is valid. timestamp in seconds
+  "time_of_passing": integer, // seconds to pass quiz
+  "pausable": boolean,   // true if it is allowed for pause quiz
+  "question_cnt": integer, // count of questions
+  "super": boolean,      // set true if squiz realize group functionality
+  "group_id": integer    // group of new quiz
+}
+
+ +

Responses:

+
+
201 Created
+

Quiz successfully created. Returns the created quiz object.

+
+
{
+  "id": integer,
+  "qid": string,
+  "name": string,
+  "description": string,
+  // ... other quiz properties
+}
+
+
+ +
+
422 Unprocessable Entity
+

Name field should have less than 280 characters.

+
+ +
+
406 Not Acceptable
+

Status on creating must be only draft, template, stop, start or due to time must be lesser than now.

+
+ Allowed status values: '', 'draft', 'template', 'stop', 'start' +
+
+ +
+
409 Conflict
+

You can pause quiz only if it has deadline for passing.

+
+ +
+
500 Internal Server Error
+

If you get any content string send it to developer.

+
+
+ +
+

Get Quiz List

+ POST + /quiz/getList +

Get paginated list of quizzes with filtering options.

+ +

Request Body:

+
+
{
+  "limit": integer,
+  "offset": integer,
+  "from": integer,
+  "to": integer,
+  "search": string,
+  "status": string,
+  "deleted": boolean,
+  "archived": boolean,
+  "super": boolean,
+  "group_id": integer
+}
+
+ +

Responses:

+
+
200 OK
+

Returns list of quizzes with total count.

+
+
{
+  "count": integer,
+  "items": [
+    {
+      "id": integer,
+      "qid": string,
+      // ... other quiz properties
+    }
+  ]
+}
+
+
+ +
+
406 Not Acceptable
+

Inappropriate status, allowed only '', 'stop', 'start', 'draft', 'template', 'timeout', 'offlimit'.

+
+ +
+
500 Internal Server Error
+

If you get any content string send it to developer.

+
+
+ + +
+ +
+

Question Endpoints

+ +
+

Create Question

+ POST + /question/create +

Create a new question for a quiz.

+
+ + +
+ +
+

Results Endpoints

+ +
+

Get Quiz Results

+ POST + /results/getResults/{quizId} +

Get list of quiz results with pagination.

+ +

Path Parameters:

+
+ quizId - ID of the quiz to get results for +
+ +

Request Body:

+
+
{
+  "to": integer,         // таймштамп времени, до которого выбирать статистику. если 0 или не передано - этого ограничения нет
+  "from": integer,       // таймштамп времени, после которого выбирать статистику. если 0 или не передано - этого ограничения нет
+  "new": boolean,        // флаг, по которому вернутся только новые результаты, ещё не просмотренные пользователем
+  "page": integer,       // номер страницы для пагинации
+  "limit": integer       // размер страницы для пагинации
+}
+
+ +

Responses:

+
+
200 OK
+

Returns paginated list of results.

+
+
{
+  "total_count": integer,  // общее количество элементов удволетворяющее фильтру
+  "results": [
+    {
+      "content": string,   // содержимое ответа
+      "id": integer,       // айдишник ответа
+      "new": boolean,      // статус, был ли просмотрен ответ
+      "created_at": string // время создания этого результата
+    }
+  ]
+}
+
+
+
+ +
+

Export Results

+ POST + /results/{quizID}/export +

Export quiz results to CSV format.

+ +

Path Parameters:

+
+ quizID - ID of the quiz to export results from +
+ +

Request Body:

+
+
{
+  "to": string,          // Дата окончания диапазона времени для экспорта результатов
+  "from": string,        // Дата начала временного диапазона для экспорта результатов
+  "new": boolean         // Экспортировать ли только новые результаты?
+}
+
+ +

Responses:

+
+
200 OK
+

Returns CSV file with quiz results.

+
+
Content-Type: text/csv
+
+
+
+
+ +
+

Telegram Endpoints

+ +
+

Create Telegram Account

+ POST + /telegram/create +

Authorize server in Telegram account.

+ +

Request Body:

+
+
{
+  "ApiID": integer,      // Telegram API ID
+  "ApiHash": string,     // Telegram API Hash
+  "PhoneNumber": string, // Phone number
+  "Password": string     // Account password
+}
+
+ +

Responses:

+
+
200 OK
+

Returns signature for code verification.

+
+
{
+  "signature": string    // Session identifier for code verification
+}
+
+
+ +
+
409 Conflict
+

Account already exists and is active.

+
+
+
+ +
+

Audience Endpoints

+ +
+

Create Quiz Audience

+ POST + /quiz/{quizID}/auditory +

Create audience for a quiz.

+ +

Path Parameters:

+
+ quizID - ID of the quiz +
+ +

Responses:

+
+
200 OK
+

Returns ID of created audience.

+
+
{
+  "id": integer    // ID of created auditory
+}
+
+
+
+
+ +
+

Statistics Endpoints

+ +
+

Get Question Statistics

+ POST + /statistic/{quizID}/questions +

Get statistics for specific questions in a quiz.

+
+ + +
+ +
+

Account Endpoints

+ +
+

Add Lead Target

+ POST + /account/leadtarget +

Add a target destination for lead notifications.

+
+ + +
+
+ + + + \ No newline at end of file diff --git a/cypress.config.ts b/cypress.config.ts index 87067adb..2a383c70 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -3,8 +3,23 @@ import { defineConfig } from "cypress"; export default defineConfig({ e2e: { baseUrl: 'http://localhost:3000', - viewportWidth: 1440, - viewportHeight: 900, - supportFile: false, + viewportWidth: 1280, + viewportHeight: 720, + video: true, + screenshotOnRunFailure: true, + supportFile: 'cypress/support/e2e.ts', + defaultCommandTimeout: 10000, + pageLoadTimeout: 30000, + requestTimeout: 10000, + responseTimeout: 30000, + setupNodeEvents(on, config) { + // implement node event listeners here + }, + }, + component: { + devServer: { + framework: 'react', + bundler: 'vite', + }, }, }); diff --git a/cypress/e2e/personalization.cy.ts b/cypress/e2e/personalization.cy.ts new file mode 100644 index 00000000..6a51a5c8 --- /dev/null +++ b/cypress/e2e/personalization.cy.ts @@ -0,0 +1,75 @@ +/// + +describe('Personalization Flow', () => { + beforeEach(() => { + // Логинимся перед каждым тестом + cy.login(); + }); + + it('should complete personalization flow and open link in new tab', () => { + // Ищем нужный квиз и нажимаем редактировать + cy.contains('Сочетание перестановки и размещения') + .parent() + .parent() + .contains('Редактировать') + .click(); + + // Переходим на вкладку персонализации + cy.contains('Персонализация').click(); + + // Ждем загрузки данных + cy.get('.MuiSkeleton-root', { timeout: 30000 }).should('not.exist'); + cy.wait(6000); + + // Удаляем все существующие ссылки + cy.get('body').then(($body) => { + if ($body.find('.delete_aud').length > 0) { + // Пока есть кнопки удаления - удаляем ссылки + const deleteLinks = () => { + // Находим первую кнопку удаления и кликаем по ней + cy.get('.delete_aud').first().click(); + // Подтверждаем удаление + cy.get('#delete_OK').click(); + // Проверяем, остались ли еще кнопки удаления + cy.get('body').then(($body) => { + if ($body.find('.delete_aud').length > 0) { + deleteLinks(); + } + }); + }; + deleteLinks(); + } + }); + + // Выбираем пол (М) + cy.contains('М').click(); + + // Генерируем случайный возраст от 1 до 99 + const randomAge = Math.floor(Math.random() * 99) + 1; + + // Вводим возраст + cy.get('input[placeholder="Введите возраст"]') + .type(randomAge.toString()) + .should('have.value', randomAge.toString()); + + // Нажимаем кнопку Ок + cy.contains('Ок').click(); + + // Ждем появления ссылки и получаем её текст + cy.get('.link', { timeout: 30000 }) + .should('be.visible') + .invoke('text') + .then((text) => { + // Исправляем домен в ссылке + const url = new URL(text); + url.hostname = 's.hbpn.link'; + const correctUrl = url.toString(); + + // Переходим на страницу по исправленной ссылке + cy.visit(correctUrl); + + // Проверяем содержимое страницы + cy.contains('Сочетание перестановки и размещения').should('exist'); + }); + }); +}); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts new file mode 100644 index 00000000..f58ee6c2 --- /dev/null +++ b/cypress/support/commands.ts @@ -0,0 +1,28 @@ +/// + +declare global { + namespace Cypress { + interface Chainable { + login(): Chainable + } + } +} + +Cypress.Commands.add('login', () => { + // Пробуем перейти на страницу входа + cy.visit('/signin', { + timeout: 10000, // Увеличиваем таймаут до 10 секунд + failOnStatusCode: false // Не падаем при ошибках статуса + }); + + // Проверяем, что мы на странице входа + cy.url().should('include', '/signin'); + + // Вводим данные для входа + cy.get('#email', { timeout: 10000 }).should('be.visible').type('test@test.ru'); + cy.get('#password', { timeout: 10000 }).should('be.visible').type('testtest'); + cy.get('button[type="submit"]', { timeout: 10000 }).should('be.visible').click(); + + // Ждем успешного входа + cy.url().should('not.include', '/signin', { timeout: 10000 }); +}); \ No newline at end of file diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts new file mode 100644 index 00000000..7c16f0c9 --- /dev/null +++ b/cypress/support/e2e.ts @@ -0,0 +1,13 @@ +// Import commands.js using ES2015 syntax: +import './commands'; + +// Alternatively you can use CommonJS syntax: +// require('./commands') + +declare global { + namespace Cypress { + interface Chainable { + login(): Chainable + } + } +} \ No newline at end of file diff --git a/deployments/staging/docker-compose.yaml b/deployments/staging/docker-compose.yaml index 6ba8ce9c..77b80c51 100644 --- a/deployments/staging/docker-compose.yaml +++ b/deployments/staging/docker-compose.yaml @@ -1,15 +1,7 @@ -version: "3" services: squiz: container_name: squiz restart: unless-stopped - image: $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID - networks: - - marketplace_penahub_frontend - labels: - com.pena.domains: squiz.pena.digital + image: gitea.pena/squiz/frontpanel/staging:$GITHUB_RUN_NUMBER hostname: squiz tty: true -networks: - marketplace_penahub_frontend: - external: true diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..b51269e5 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,15 @@ +module.exports = { + transformIgnorePatterns: [ + '/node_modules/(?!(@frontend/kitui|@frontend/squzanswerer)/)' + ], + moduleNameMapper: { + '^@/(.*)$': '/src/$1', + '^@utils/(.*)$': '/src/utils/$1', + '^@assets/(.*)$': '/src/assets/$1' + }, + setupFilesAfterEnv: ['/src/setupTests.ts'], + testEnvironment: 'jsdom', + transform: { + '^.+\\.(ts|tsx)$': 'ts-jest' + } +}; \ No newline at end of file diff --git a/package.json b/package.json index 466a2d68..5f34f899 100755 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "@craco/craco": "^7.0.0", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@frontend/kitui": "^1.0.88", + "@frontend/kitui": "^1.0.108", "@frontend/squzanswerer": "^1.0.57", "@mui/icons-material": "^5.10.14", "@mui/material": "^5.10.14", @@ -69,7 +69,9 @@ "test": "craco test", "eject": "craco eject", "code:format": "prettier --write --ignore-unknown", - "prepare": "husky install" + "prepare": "husky install", + "cypress:open": "cypress open", + "cypress:run": "cypress run" }, "browserslist": { "production": [ @@ -86,10 +88,12 @@ "devDependencies": { "@emoji-mart/data": "^1.2.1", "@emoji-mart/react": "^1.1.1", + "@types/cypress": "^1.1.6", "@types/cytoscape-popper": "^2.0.4", "@types/react-beautiful-dnd": "^13.1.4", "@types/react-cytoscapejs": "^1.2.4", "craco-alias": "^3.0.1", + "cypress": "^14.4.1", "husky": "^8.0.3", "lint-staged": "^15.2.0", "prettier": "^3.1.1" diff --git a/src/App.tsx b/src/App.tsx index 68b6ad6d..d6195646 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -35,6 +35,7 @@ const { DesignPage } = lazily(() => import("./pages/DesignPage/DesignPage")); const { IntegrationsPage } = lazily(() => import("./pages/IntegrationsPage/IntegrationsPage")); const { QuizAnswersPage } = lazily(() => import("./pages/QuizAnswersPage/QuizAnswersPage")); const ChatImageNewWindow = lazy(() => import("@ui_kit/FloatingSupportChat/ChatImageNewWindow")); +const PersonalizationAI = lazy(() => import("./pages/PersonalizationAI/PersonalizationAI")); let params = new URLSearchParams(document.location.search); const isTest = Boolean(params.get("test")) @@ -60,6 +61,12 @@ const routeslink = [ sidebar: true, footer: true, }, + { + path: "/personalization-ai", + page: PersonalizationAI, + header: true, + sidebar: true, + }, ] as const; const LazyLoading = ({ children, fallback }: SuspenseProps) => ( diff --git a/src/api/auditory.ts b/src/api/auditory.ts new file mode 100644 index 00000000..dfa814aa --- /dev/null +++ b/src/api/auditory.ts @@ -0,0 +1,108 @@ +import { makeRequest } from "@frontend/kitui"; +import { parseAxiosError } from "@utils/parse-error"; + +const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`; + +// Types +export interface AuditoryItem { + id: number; + quiz_id: number; + sex: number; // 0 - женский, 1 - мужской, 2 - оба + age: string; + deleted: boolean; + created_at: number; +} + +export interface AuditoryResponse { + ID: number; + quiz_id: number; + sex: number; + age: string; + deleted: boolean; + created_at: number; +} + +// Request Types +export interface AuditoryGetRequest { + quizId: number; +} + +export interface AuditoryDeleteRequest { + id: number; +} + +export interface AuditoryAddRequest { + sex: number; + age: string; +} + +// Parameters +export interface AuditoryGetParams { + quizId: number; +} + +export interface AuditoryDeleteParams { + quizId: number; + auditoryId: number; +} + +export interface AuditoryAddParams { + quizId: number; + body: AuditoryAddRequest; +} + +// API calls +export const auditoryGet = async ({ quizId }: AuditoryGetParams): Promise<[AuditoryItem[] | null, string?]> => { + if (!quizId) { + return [null, "Quiz ID is required"]; + } + + try { + const response = await makeRequest({ + url: `${API_URL}/quiz/${quizId}/auditory`, + method: "GET", + }); + + return [response]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + return [null, `Не удалось получить аудиторию. ${error}`]; + } +}; + +export const auditoryDelete = async ({ quizId, auditoryId }: AuditoryDeleteParams): Promise<[AuditoryResponse | null, string?]> => { + if (!quizId || !auditoryId) { + return [null, "Quiz ID and Auditory ID are required"]; + } + + try { + const response = await makeRequest({ + url: `${API_URL}/quiz/${quizId}/auditory/${auditoryId}`, + method: "DELETE", + }); + + return [response]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + return [null, `Не удалось удалить аудиторию. ${error}`]; + } +}; + +export const auditoryAdd = async ({ quizId, body }: AuditoryAddParams): Promise<[AuditoryResponse | null, string?]> => { + if (!quizId) { + return [null, "Quiz ID is required"]; + } + + try { + const response = await makeRequest({ + url: `${API_URL}/quiz/${quizId}/auditory`, + body, + method: "POST", + }); + + return [response]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + return [null, `Не удалось добавить аудиторию. ${error}`]; + } +}; \ No newline at end of file diff --git a/src/api/quiz.ts b/src/api/quiz.ts index f43c3f06..1bcea534 100644 --- a/src/api/quiz.ts +++ b/src/api/quiz.ts @@ -148,8 +148,8 @@ export const addQuizImages = async ( const name = image?.name ? transliterate(image?.name.replace(/\s/g, '_')) : "blob" //Замена всех побелов на _ - const renamedImage = new File([image], name) - + const renamedImage = new File([image], name) + formData.append("quiz", quizId.toString()); formData.append("image", renamedImage); diff --git a/src/api/tariff.ts b/src/api/tariff.ts index a0be6e70..48efae84 100644 --- a/src/api/tariff.ts +++ b/src/api/tariff.ts @@ -1,13 +1,11 @@ import { makeRequest } from "@api/makeRequest"; - import { parseAxiosError } from "@utils/parse-error"; - import type { GetTariffsResponse } from "@frontend/kitui"; const API_URL = `${process.env.REACT_APP_DOMAIN}/strator/tariff`; export const getTariffs = async ( - page: number, + page: number = 1, ): Promise<[GetTariffsResponse | null, string?]> => { try { const tariffs = await makeRequest({ @@ -17,7 +15,6 @@ export const getTariffs = async ( return [tariffs]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - return [null, `Ошибка при получении списка тарифов. ${error}`]; } }; diff --git a/src/api/tariffs.ts b/src/api/tariffs.ts new file mode 100644 index 00000000..c8f86a9f --- /dev/null +++ b/src/api/tariffs.ts @@ -0,0 +1,9 @@ +import { makeRequest } from '@utils/makeRequest'; +import type { GetTariffsResponse } from '@/model/tariff'; + +export const getTariffs = async (): Promise<[GetTariffsResponse | null, string?]> => { + return makeRequest({ + url: `${process.env.REACT_APP_DOMAIN}/tariffs`, + method: 'GET' + }); +}; \ No newline at end of file diff --git a/src/assets/icons/AiPersonalizationIcon.svg b/src/assets/icons/AiPersonalizationIcon.svg new file mode 100644 index 00000000..74f20dc9 --- /dev/null +++ b/src/assets/icons/AiPersonalizationIcon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/AiPersonalizationIcon.tsx b/src/assets/icons/AiPersonalizationIcon.tsx new file mode 100644 index 00000000..fc815fa1 --- /dev/null +++ b/src/assets/icons/AiPersonalizationIcon.tsx @@ -0,0 +1,12 @@ +import * as React from "react"; +import { SvgIcon, SvgIconProps } from "@mui/material"; + +const AiPersonalizationIcon = (props: SvgIconProps) => ( + + + + + +); + +export default AiPersonalizationIcon; \ No newline at end of file diff --git a/src/pages/Analytics/General.tsx b/src/pages/Analytics/General.tsx index 306b1d4e..be9b7b88 100644 --- a/src/pages/Analytics/General.tsx +++ b/src/pages/Analytics/General.tsx @@ -83,11 +83,11 @@ const GeneralItem = ({ xAxis={[ { data: statiscticsResult ? days : Object.keys(general), - valueFormatter: (value) => - moment.unix(Number(value)).format("DD/MM/YYYY HH") + - statiscticsResult - ? "" - : "ч", + valueFormatter: (value) => { + const timestamp = Number(value); + if (isNaN(timestamp)) return 'Invalid Date'; + return moment.unix(timestamp).format(statiscticsResult ? "DD/MM/YYYY" : "DD/MM/YYYY HH") + (statiscticsResult ? "" : "ч"); + }, }, ]} series={[ diff --git a/src/pages/InstallQuiz/InstallQuiz.tsx b/src/pages/InstallQuiz/InstallQuiz.tsx index f344e368..795353ab 100644 --- a/src/pages/InstallQuiz/InstallQuiz.tsx +++ b/src/pages/InstallQuiz/InstallQuiz.tsx @@ -3,8 +3,10 @@ import { decrementCurrentStep } from "@root/quizes/actions"; import ArrowLeft from "@/assets/icons/questionsPage/arrowLeft"; import QuizInstallationCard from "./QuizInstallationCard/QuizInstallationCard"; import QuizLinkCard from "./QuizLinkCard"; +import { useNavigate } from "react-router-dom"; export default function InstallQuiz() { + const navigate = useNavigate(); return ( <> + diff --git a/src/pages/PersonalizationAI/AgeInputWithSelect.tsx b/src/pages/PersonalizationAI/AgeInputWithSelect.tsx new file mode 100644 index 00000000..3703373f --- /dev/null +++ b/src/pages/PersonalizationAI/AgeInputWithSelect.tsx @@ -0,0 +1,181 @@ +import React, { useState, useRef } from 'react'; +import { + Box, + InputBase, + IconButton, + Menu, + MenuItem, + Paper, + Popper, + Grow, + ClickAwayListener, + MenuList, + useTheme, + FormHelperText +} from '@mui/material'; +import ArrowDownIcon from "@/assets/icons/ArrowDownIcon"; + +interface AgeInputWithSelectProps { + value: string; + onChange: (value: string) => void; + onErrorChange?: (isError: boolean) => void; +} + +const AgeInputWithSelect = ({ value, onChange, onErrorChange }: AgeInputWithSelectProps) => { + const theme = useTheme(); + const [open, setOpen] = useState(false); + const anchorRef = useRef(null); + const [errorType, setErrorType] = useState<'format' | 'range' | false>(false); + + // Валидация: только число или диапазон число-число, и диапазон 0-150 + const validate = (val: string) => { + if (!val) return false; + // Число (только положительное) + if (/^-?\d+$/.test(val)) { + const num = Number(val); + if (num < 0 || num > 150) return 'range'; + return false; + } + // Диапазон (только положительные числа) + const rangeMatch = val.match(/^(-?\d+)-(-?\d+)$/); + if (rangeMatch) { + const left = Number(rangeMatch[1]); + const right = Number(rangeMatch[2]); + if (left < 0 || left > 150 || right < 0 || right > 150 || left > right) return 'range'; + return false; + } + return 'format'; + }; + + const handleInputChange = (e: React.ChangeEvent) => { + const filtered = e.target.value.replace(/[^\d-]/g, ''); + onChange(filtered); + const err = validate(filtered); + setErrorType(err); + if (onErrorChange) onErrorChange(!!err); + }; + + const handleInputBlur = (e: React.FocusEvent) => { + const trimmed = e.target.value.replace(/\s+/g, ''); + onChange(trimmed); + const err = validate(trimmed); + setErrorType(err); + if (onErrorChange) onErrorChange(!!err); + }; + + const handleSelectItemClick = (selectedValue: string) => { + onChange(selectedValue); + setErrorType(false); + setOpen(false); + }; + + const handleToggle = () => { + setOpen((prevOpen) => !prevOpen); + }; + + const handleClose = (event: Event) => { + if (anchorRef.current && anchorRef.current.contains(event.target as HTMLElement)) { + return; + } + setOpen(false); + }; + + return ( + + + {errorType === 'format' && ( + + можно только число или диапазон + + )} + {errorType === 'range' && ( + + таких возрастов нет + + )} + + + + + + {({ TransitionProps, placement }) => ( + + + + + handleSelectItemClick('')}>Выберите возраст + handleSelectItemClick('18-24')}>18-24 + handleSelectItemClick('25-34')}>25-34 + handleSelectItemClick('35-44')}>35-44 + handleSelectItemClick('45-54')}>45-54 + handleSelectItemClick('55+')}>55+ + + + + + )} + + + ); +}; + +export default AgeInputWithSelect; \ No newline at end of file diff --git a/src/pages/PersonalizationAI/AuditoryLink.tsx b/src/pages/PersonalizationAI/AuditoryLink.tsx new file mode 100644 index 00000000..66ed1213 --- /dev/null +++ b/src/pages/PersonalizationAI/AuditoryLink.tsx @@ -0,0 +1,98 @@ +import { AuditoryItem } from "@/api/auditory"; +import Trash from "@/assets/icons/trash"; +import { useCurrentQuiz } from "@/stores/quizes/hooks"; +import { InfoPopover } from "@/ui_kit/InfoPopover"; +import TooltipClickInfo from "@/ui_kit/Toolbars/TooltipClickInfo"; +import { useDomainDefine } from "@/utils/hooks/useDomainDefine"; +import { IconButton, ListItem, Typography, useTheme } from "@mui/material"; +import { CopyButton } from "./CopyButton"; + +interface AuditoryLinkProps { + item: AuditoryItem; + index: number; + onDelete: (id: number) => void; + utmParams: string +} + +export const AuditoryLink = ({ utmParams, item, index, onDelete }: AuditoryLinkProps) => { + const theme = useTheme(); + const quiz = useCurrentQuiz(); + const { isTestServer } = useDomainDefine(); + + const handleCopy = (text: string) => { + navigator.clipboard.writeText(text); + }; + + const handleDelete = () => { + onDelete(item.id); + }; + + const linkText = `${isTestServer ? "https://s.hbpn.link/" : "https://hbpn.link/"}${quiz?.qid}?_paud=${item.id}${utmParams}`; + + return ( + + + + + + + + + + } + > + + {linkText} + + + ); +}; \ No newline at end of file diff --git a/src/pages/PersonalizationAI/AuditoryList.tsx b/src/pages/PersonalizationAI/AuditoryList.tsx new file mode 100644 index 00000000..a84c7e2a --- /dev/null +++ b/src/pages/PersonalizationAI/AuditoryList.tsx @@ -0,0 +1,49 @@ +import { auditoryGet, AuditoryResponse, AuditoryItem } from "@/api/auditory"; +import ArrowDownIcon from "@/assets/icons/ArrowDownIcon"; +import { useCurrentQuiz } from "@/stores/quizes/hooks"; +import { useDomainDefine } from "@/utils/hooks/useDomainDefine"; +import { Box, Collapse, IconButton, List, Typography, useTheme } from "@mui/material"; +import { useEffect, useState } from "react"; +import { AuditoryLink } from "./AuditoryLink"; + +export const AuditoryList = ({utmParams, auditory, onDelete}:{utmParams:string,auditory:AuditoryItem[], onDelete: (id: number) => void}) => { + const theme = useTheme(); + const { isTestServer } = useDomainDefine(); + const [linksOpen, setLinksOpen] = useState(true); + + console.log("auditory-___---_auditory__---__-__auditory_------__---__-__---_------__---__-__---_------__---__-____--__") + console.log(auditory) + + return ( + <> + + + + Ваши сохраненные ссылки + + setLinksOpen((prev) => !prev)} + size="large" + > + + + + + + {auditory.map((item, idx) => ( + + ))} + + + + + ); +}; \ No newline at end of file diff --git a/src/pages/PersonalizationAI/CopyButton.tsx b/src/pages/PersonalizationAI/CopyButton.tsx new file mode 100644 index 00000000..df82a2f5 --- /dev/null +++ b/src/pages/PersonalizationAI/CopyButton.tsx @@ -0,0 +1,161 @@ +import { IconButton, Skeleton, useTheme, Tooltip, ClickAwayListener } from "@mui/material"; +import { useEffect, useState } from "react"; +import CopyIcon from "@/assets/icons/CopyIcon"; +import { useSnackbar } from "notistack"; + +interface CopyButtonProps { + created_at: number; + onCopy: (text: string) => void; + text: string; +} + +export const CopyButton = ({ created_at, onCopy, text }: CopyButtonProps) => { + const theme = useTheme(); + const { enqueueSnackbar } = useSnackbar(); + const [open, setOpen] = useState(false); + const [timeLeft, setTimeLeft] = useState(""); + + const getCreatedTime = (timestamp: number) => { + // Если timestamp в секундах (10 цифр) + if (timestamp.toString().length === 10) { + return new Date(timestamp * 1000).getTime(); + } + // Если timestamp в миллисекундах (13 цифр) + return new Date(timestamp).getTime(); + }; + + const formatTimeLeft = (milliseconds: number) => { + const minutes = Math.floor(milliseconds / (1000 * 60)); + const seconds = Math.floor((milliseconds % (1000 * 60)) / 1000); + return `${minutes}:${seconds.toString().padStart(2, '0')}`; + }; + + const [isLoading, setIsLoading] = useState(() => { + if (!created_at) return false; + const now = new Date().getTime(); + const created = getCreatedTime(created_at); + const diffInMinutes = (now - created) / (1000 * 60); + return diffInMinutes < 3; + }); + + useEffect(() => { + if (!created_at) return; + + const now = new Date().getTime(); + const created = getCreatedTime(created_at); + const diffInMinutes = (now - created) / (1000 * 60); + + if (now - created < 1000) { + setIsLoading(true); + } + + if (diffInMinutes < 3) { + const timeLeft = Math.ceil((3 - diffInMinutes) * 60 * 1000); + setTimeLeft(formatTimeLeft(timeLeft)); + + const timer = setInterval(() => { + const currentTime = new Date().getTime(); + const elapsed = currentTime - created; + const remaining = 3 * 60 * 1000 - elapsed; + + if (remaining <= 0) { + setIsLoading(false); + clearInterval(timer); + return; + } + + setTimeLeft(formatTimeLeft(remaining)); + }, 1000); + + return () => clearInterval(timer); + } + }, [created_at]); + + const handleClick = () => { + if (isLoading) return; + onCopy(text); + enqueueSnackbar("Ссылка успешно скопирована", { variant: "success" }); + }; + + const handleTooltipClose = () => { + setOpen(false); + }; + + const handleTooltipOpen = () => { + setOpen(true); + }; + + if (isLoading) { + return ( + +
+ + + +
+
+ ); + } + + return ( + + + + ); +}; \ No newline at end of file diff --git a/src/pages/PersonalizationAI/GenderAndAgeSelector.tsx b/src/pages/PersonalizationAI/GenderAndAgeSelector.tsx new file mode 100644 index 00000000..720022f3 --- /dev/null +++ b/src/pages/PersonalizationAI/GenderAndAgeSelector.tsx @@ -0,0 +1,212 @@ +import { Box, FormControl, FormLabel, Checkbox, FormControlLabel, useTheme, Button, useMediaQuery } from "@mui/material"; +import CheckboxIcon from "@icons/Checkbox"; +import AgeInputWithSelect from "./AgeInputWithSelect"; +import { useState, useEffect } from "react"; + +interface GenderAndAgeSelectorProps { + gender: string; + age: string; + ageError: boolean; + onGenderChange: (gender: string) => void; + onAgeChange: (age: string) => void; + onAgeErrorChange: (error: boolean) => void; + onStartCreate: () => void; +} + +export default function GenderAndAgeSelector({ + gender, + age, + ageError, + onGenderChange, + onAgeChange, + onAgeErrorChange, + onStartCreate +}: GenderAndAgeSelectorProps) { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down(845)); + const [maleChecked, setMaleChecked] = useState(false); + const [femaleChecked, setFemaleChecked] = useState(false); + + // Синхронизируем состояние чекбоксов с пропсом gender + useEffect(() => { + if (gender === '1') { + setMaleChecked(true); + setFemaleChecked(false); + } else if (gender === '0') { + setMaleChecked(false); + setFemaleChecked(true); + } else if (gender === '2') { + setMaleChecked(true); + setFemaleChecked(true); + } else { + setMaleChecked(false); + setFemaleChecked(false); + } + }, [gender]); + + const handleGenderChange = (type: 'male' | 'female', checked: boolean) => { + if (type === 'male') { + setMaleChecked(checked); + } else { + setFemaleChecked(checked); + } + + // Обновляем значение gender в родительском компоненте + if (type === 'male' && checked && !femaleChecked) { + onGenderChange('1'); // Только мужской + } else if (type === 'female' && checked && !maleChecked) { + onGenderChange('0'); // Только женский + } else if (type === 'male' && checked && femaleChecked) { + onGenderChange('2'); // Оба пола + } else if (type === 'female' && checked && maleChecked) { + onGenderChange('2'); // Оба пола + } else if (type === 'male' && !checked && femaleChecked) { + onGenderChange('0'); // Только женский + } else if (type === 'female' && !checked && maleChecked) { + onGenderChange('1'); // Только мужской + } else { + onGenderChange(''); // Ничего не выбрано + } + }; + + return ( + + + + + Пол + + + } + checkedIcon={} + checked={maleChecked} + onChange={(e) => handleGenderChange('male', e.target.checked)} + /> + } + label="М" + /> + } + checkedIcon={} + checked={femaleChecked} + onChange={(e) => handleGenderChange('female', e.target.checked)} + /> + } + label="Ж" + /> + + + + + + Возраст + + + + + + + + ); +} \ No newline at end of file diff --git a/src/pages/PersonalizationAI/GenderSelector.tsx b/src/pages/PersonalizationAI/GenderSelector.tsx new file mode 100644 index 00000000..04dc11e2 --- /dev/null +++ b/src/pages/PersonalizationAI/GenderSelector.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { Box, Typography, useTheme } from '@mui/material'; +import { useMediaQuery } from '@mui/material'; +import { InfoPopover } from './InfoPopover'; +import { GenderButton } from './GenderButton'; + +interface GenderSelectorProps { + value: string[]; + onChange: (value: string[]) => void; +} + +export const GenderSelector: React.FC = ({ value, onChange }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('sm')); + + const handleGenderClick = (gender: string) => { + if (value.includes(gender)) { + onChange(value.filter(g => g !== gender)); + } else { + onChange([...value, gender]); + } + }; + + return ( + + + + Пол + + + + + handleGenderClick('male')} + icon="male" + label="Мужской" + /> + handleGenderClick('female')} + icon="female" + label="Женский" + /> + + + ); +}; \ No newline at end of file diff --git a/src/pages/PersonalizationAI/PayModal.tsx b/src/pages/PersonalizationAI/PayModal.tsx new file mode 100644 index 00000000..2e51c828 --- /dev/null +++ b/src/pages/PersonalizationAI/PayModal.tsx @@ -0,0 +1,54 @@ +import { Box, Button, Modal, Typography } from "@mui/material" + +interface Props { + open: boolean; + onClose: () => void; + onCreate: () => void; +} + + +export const PayModal = ({ + open, + onClose, + onCreate +}: Props) => { + return ( + + + + Данная услуга предоставляется за 500 рублей/опрос. Готовы оплатить? + + + + + + + + ); +} \ No newline at end of file diff --git a/src/pages/PersonalizationAI/PersonalizationAI.tsx b/src/pages/PersonalizationAI/PersonalizationAI.tsx new file mode 100644 index 00000000..c80b744a --- /dev/null +++ b/src/pages/PersonalizationAI/PersonalizationAI.tsx @@ -0,0 +1,392 @@ +import { Box, Container, Typography, TextField, Button, List, ListItem, IconButton, Modal } from "@mui/material"; +import { InfoPopover } from '@ui_kit/InfoPopover'; +import GenderAndAgeSelector from "./GenderAndAgeSelector"; +import { useEffect, useState } from "react"; +import CustomTextField from "@ui_kit/CustomTextField"; +import { useTheme } from "@mui/material"; +import { AuditoryItem, auditoryAdd, auditoryDelete, auditoryGet } from "@/api/auditory"; +import { useCurrentQuiz } from "@/stores/quizes/hooks"; +import { AuditoryList } from "./AuditoryList"; +import { useSnackbar } from "notistack"; +import { PayModal } from "./PayModal"; +import { useUserStore } from "@/stores/user"; +import { cartApi } from "@/api/cart"; +import { outCart } from "../Tariffs/Tariffs"; +import { inCart } from "../Tariffs/Tariffs"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; +import { useToken } from "@frontend/kitui"; +import { useSWRConfig } from "swr"; +import { makeRequest } from "@api/makeRequest"; +import { setUserAccount, setCustomerAccount } from "@/stores/user"; +import { quizApi } from "@api/quiz"; +import { setQuizes } from "@root/quizes/actions"; +import TooltipClickInfo from "@/ui_kit/Toolbars/TooltipClickInfo"; + +const tariff = isTestServer ? "6844b8858258f5cc35791ef7" : "6851db40acfb4d3e5fcd9b19"; +export default function PersonalizationAI() { + const theme = useTheme(); + const [auditory, setAuditory] = useState([]); + const [deleteModal, setDeleteModal] = useState(0); + const [link, setLink] = useState(''); + const [utmParams, setUtmParams] = useState(''); + const quiz = useCurrentQuiz(); + const { enqueueSnackbar } = useSnackbar(); + const privilegesOfUser = useUserStore((state) => state.userAccount?.privileges); + const user = useUserStore((state) => state.customerAccount); + const token = useToken(); + const userId = useUserStore((state) => state.userId); + + const [gender, setGender] = useState(''); + const [age, setAge] = useState(''); + const [ageError, setAgeError] = useState(false); + const [isModalOpen, setIsModalOpen] = useState(false); + // Обновляем данные пользователя через SWR + const { mutate } = useSWRConfig(); + + const resetForm = () => { + setGender(''); + setAge(''); + setAgeError(false); + }; + + + const createNewLink = async () => { + if (!quiz?.backendId) { + enqueueSnackbar('Ошибка: не выбран квиз', { variant: 'error' }); + return; + } + + try { + const [result, error] = await auditoryAdd({ + quizId: quiz.backendId, + body: { + sex: parseInt(gender), + age + } + }); + + if (error) { + enqueueSnackbar('Не удалось добавить ссылку', { variant: 'error' }); + return [, error]; + } + + if (result) { + handleAdd({ + id: result.ID, + quiz_id: quiz.backendId, + sex: parseInt(gender), + age, + deleted: false, + created_at: Date.now() + }); + enqueueSnackbar('Ссылка успешно добавлена', { variant: 'success' }); + resetForm(); + setIsModalOpen(false); + + // Обновляем данные пользователя после успешного создания ссылки + try { + const [userAccountResult, customerAccountResult] = await Promise.all([ + makeRequest({ + url: `${process.env.REACT_APP_DOMAIN}/squiz/account/get`, + method: "GET", + useToken: true, + withCredentials: false, + }).catch(error => { + console.log(error) + enqueueSnackbar("Ошибка при обновлении данных пользователя", { variant: "error" }); + return null; + }), + makeRequest({ + url: `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1/account`, + method: "GET", + useToken: true, + withCredentials: false, + }).catch(error => { + console.log(error) + enqueueSnackbar("Ошибка при обновлении данных клиента", { variant: "error" }); + return null; + }) + ]); + + if (userAccountResult) { + setUserAccount(userAccountResult); + } + if (customerAccountResult) { + setCustomerAccount(customerAccountResult); + } + } catch (error) { + console.log(error) + enqueueSnackbar("Ошибка при обновлении данных", { variant: "error" }); + } + } + } catch (error) { + enqueueSnackbar('Произошла ошибка при добавлении', { variant: 'error' }); + } + }; + + useEffect(() => { + (async () => { + if (quiz?.backendId) { + const [result, error] = await auditoryGet({ quizId: quiz.backendId }); + console.log("result-___---_------__---__-__---_------__---__-__---_------__---__-__---_------__---__-____--__") + console.log(result) + if (result) { + setAuditory(result); + } + } + })(); + }, [quiz]); + + const handleDelete = async () => { + // 1. Закрываем модалку + setDeleteModal(0); + + // 2. Находим индекс объекта в стейте + const indexToDelete = auditory.findIndex(item => item.id === deleteModal); + if (indexToDelete === -1) return; + + // 3. Сохраняем удаляемый объект + const deletedItem = auditory[indexToDelete]; + + // 4. Меняем стейт, вырезая объект + setAuditory(prev => prev.filter(item => item.id !== deleteModal)); + + try { + // 5. Вызываем функцию удаления + const [result, error] = await auditoryDelete({ + quizId: quiz?.backendId, + auditoryId: deleteModal + }); + + if (error) { + // 6. Если удалить не удалось - показываем снекбар и возвращаем ссылку + enqueueSnackbar('Не удалось удалить ссылку', { variant: 'error' }); + setAuditory(prev => { + const newArray = [...prev]; + newArray.splice(indexToDelete, 0, deletedItem); + return newArray; + }); + } + } catch (error) { + // Обработка ошибки сети или других ошибок + enqueueSnackbar('Произошла ошибка при удалении', { variant: 'error' }); + setAuditory(prev => { + const newArray = [...prev]; + newArray.splice(indexToDelete, 0, deletedItem); + return newArray; + }); + } + } + + const handleAdd = (item: AuditoryItem) => { + setAuditory(old => ([...old, item])); + // Очищаем форму после успешного добавления + setGender(''); + setAge(''); + } + + const handleLinkChange = (e: React.ChangeEvent) => { + const newLink = e.target.value; + setLink(newLink); + + // Регулярное выражение для поиска параметров URL + const paramRegex = /[?&]([^=&]+)=([^&]*)/g; + const params: Record = {}; + let match; + + // Ищем все параметры в строке + while ((match = paramRegex.exec(newLink)) !== null) { + const key = decodeURIComponent(match[1]); + const value = decodeURIComponent(match[2]); + params[key] = value; + } + + // Преобразуем объект параметров в строку URL + const paramString = Object.entries(params) + .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) + .join('&'); + + setUtmParams(paramString ? `&${paramString}` : ""); + }; + + console.log("______----giga_chat-----__--_---_--_----__--__-__--_--__--__--_---_______-quiz") + console.log(quiz?.giga_chat) + const startCreate = async () => { + if (quiz?.giga_chat) { + createNewLink(); + } else { + setIsModalOpen(true); + } + }; + + const tryBuy = async ({ id, price }: { id: string; price: number }) => { + //Если в корзине что-то было - выкладываем содержимое и запоминаем чо там лежало + if (user?.cart?.length > 0) { + outCart(user.cart); + } + //Добавляем желаемый тариф в корзину + const [_, addError] = await cartApi.add(tariff); + + if (addError) { + //Развращаем товары в корзину + inCart(); + return; + } + + //Если нам хватает денежек - покупаем тариф + const [data, payError] = await cartApi.pay(); + + if (payError || !data) { + //если денег не хватило + if (payError?.includes("insufficient funds") || payError?.includes("Payment Required")) { + var link = document.createElement("a"); + link.href = `https://${isTestServer ? "s" : ""}hub.pena.digital/quizpayment?action=squizpay&dif=50000&data=${token}&userid=${userId}&from=AI&wayback=ai_${quiz?.backendId}`; + document.body.appendChild(link); + link.click(); + return; + } + + //другая ошибка + enqueueSnackbar("Произошла ошибка. Попробуйте позже"); + return; + } + + //Развращаем товары в корзину + inCart(); + + //Показываем сообщение об успешной покупке + enqueueSnackbar("Тариф успешно приобретен", { variant: "success" }); + + + // Создаем новую ссылку после обновления данных + await createNewLink(); + + + // Обновляем данные квиза после успешной оплаты + console.log("Обновляем данные квиза после оплаты"); + const [quizes, quizesError] = await quizApi.getList(); + console.log("Получены данные квизов:", quizes); + if (!quizesError) { + setQuizes(quizes); + console.log("Данные квизов обновлены в сторе"); + } else { + console.error("Ошибка при получении данных квизов:", quizesError); + } + + }; + + return ( + <> + + + Персонализация вопросов с помощью AI + + +Данный раздел позволяет вам создавать персонализированный опрос под каждую целевую аудиторию отдельно, наш AI перефразирует ваши вопросы согласно настройкам. +Для этого нужно выбрать пол и возраст вашей аудитории и получите персональную ссылку с нужными настройками в списке ниже. + +Так же вы можете обогатить свою ссылку UTM метками в поле "вставьте свою ссылку"и этим метки применятся ко всем вашим ссылкам. + +ВАЖНО: если ваши вопросы уже подходят целевой аудитории, то персонализированы они скорее всего не будут. {/* Первый белый блок */} + + + + + {/* Ссылка */} + + + Ссылка + + {/* + + Данное поле создано для обогащения utm метками вашей ссылки. Нужно скопировать ссылку вашего квиза, задать настройки ца, вставить ссылку в поле, прописать метки(советуем использовать динамические), и нажать "ок" выше поля. Метки будут применены ко всем ссылкам с персонализацией в рамках данного квиза. + + */} + + + Вставьте ссылку со всеми utm-метками + + + + + + + + + setDeleteModal(0)} + aria-labelledby="modal-modal-title" + aria-describedby="modal-modal-description" + > + + Уверены, что хотите удалить ссылку? + + + + + { + setIsModalOpen(false); + }} + onCreate={tryBuy} + /> + + ); +} diff --git a/src/pages/Questions/AnswerDraggableList/index.tsx b/src/pages/Questions/AnswerDraggableList/index.tsx index 6db802bb..b5f41dc2 100644 --- a/src/pages/Questions/AnswerDraggableList/index.tsx +++ b/src/pages/Questions/AnswerDraggableList/index.tsx @@ -2,7 +2,11 @@ import { Box } from "@mui/material"; import { reorderQuestionVariants } from "@root/questions/actions"; import { type ReactNode } from "react"; import type { DropResult } from "react-beautiful-dnd"; -import { DragDropContext, Droppable } from "react-beautiful-dnd"; +import { DragDropContext as DragDropContextOriginal } from "react-beautiful-dnd"; +import { StrictModeDroppable } from "./StrictModeDroppable"; + +// Исправляем типизацию для DragDropContext +const DragDropContext = DragDropContextOriginal as any; type AnswerDraggableListProps = { questionId: string; @@ -14,21 +18,36 @@ export const AnswerDraggableList = ({ variants, }: AnswerDraggableListProps) => { const onDragEnd = ({ destination, source }: DropResult) => { - if (destination) { + // Проверяем наличие необходимых данных + if (!destination || !source) return; + + // Проверяем, что индексы действительно изменились + if (destination.index === source.index) return; + + // Проверяем валидность индексов + if (source.index < 0 || destination.index < 0) return; + + try { reorderQuestionVariants(questionId, source.index, destination.index); + } catch (error) { + console.error('Error reordering variants:', error); + // Здесь можно добавить уведомление пользователю об ошибке } }; return ( - + {(provided) => ( - + {variants} {provided.placeholder} )} - + ); }; diff --git a/src/pages/ResultPage/ResultPage.tsx b/src/pages/ResultPage/ResultPage.tsx index c49ef5e3..a70dcb38 100644 --- a/src/pages/ResultPage/ResultPage.tsx +++ b/src/pages/ResultPage/ResultPage.tsx @@ -3,6 +3,7 @@ import { ResultSettings } from "./ResultSettings"; import { decrementCurrentStep, incrementCurrentStep, + setCurrentStep, } from "@root/quizes/actions"; import { Box, Button } from "@mui/material"; import ArrowLeft from "@icons/questionsPage/arrowLeft"; diff --git a/src/pages/Tariffs/Tariffs.tsx b/src/pages/Tariffs/Tariffs.tsx index 49b63c1e..5a886bb0 100644 --- a/src/pages/Tariffs/Tariffs.tsx +++ b/src/pages/Tariffs/Tariffs.tsx @@ -1,10 +1,6 @@ -import { logout } from "@api/auth"; import { activatePromocode } from "@api/promocode"; -import type { Tariff } from "@frontend/kitui"; import { useToken } from "@frontend/kitui"; -import { makeRequest } from "@api/makeRequest"; import ArrowLeft from "@icons/questionsPage/arrowLeft"; -import type { GetTariffsResponse } from "@model/tariff"; import { Box, Button, @@ -12,15 +8,11 @@ import { IconButton, Modal, Paper, - Select, Typography, useMediaQuery, useTheme, - MenuItem, } from "@mui/material"; -import { clearQuizData } from "@root/quizes/store"; -import { cleanAuthTicketData } from "@root/ticket"; -import { clearUserData, useUserStore } from "@root/user"; +import { useUserStore } from "@root/user"; import { LogoutButton } from "@ui_kit/LogoutButton"; import { useDomainDefine } from "@utils/hooks/useDomainDefine"; import { enqueueSnackbar } from "notistack"; @@ -34,16 +26,14 @@ import { createTariffElements } from "./tariffsUtils/createTariffElements"; import { currencyFormatter } from "./tariffsUtils/currencyFormatter"; import { useWallet, setCash } from "@root/cash"; import { handleLogoutClick } from "@utils/HandleLogoutClick"; -import { getDiscounts } from "@api/discounts"; import { cartApi } from "@api/cart"; -import { getUser } from "@api/user"; -import { getTariffs } from "@api/tariff"; -import type { Discount } from "@model/discounts"; import { Other } from "./pages/Other"; import { ModalRequestCreate } from "./ModalRequestCreate"; import { cancelCC, useCC } from "@/stores/cc"; import { NavSelect } from "./NavSelect"; +import { useTariffs } from '@utils/hooks/useTariffs'; +import { useDiscounts } from '@utils/hooks/useDiscounts'; const StepperText: Record = { day: "Тарифы на время", @@ -59,9 +49,11 @@ function TariffPage() { const isMobile = useMediaQuery(theme.breakpoints.down(600)); const userId = useUserStore((state) => state.userId); const navigate = useNavigate(); - const [tariffs, setTariffs] = useState([]); - const [user, setUser] = useState(); - const [discounts, setDiscounts] = useState([]); + const user = useUserStore((state) => state.customerAccount); + const a = useUserStore((state) => state.customerAccount); //c wallet + console.log("________________34563875693785692576_____________USERRRRRRR") + console.log(a) + const { data: discounts } = useDiscounts(userId); const [isRequestCreate, setIsRequestCreate] = useState(false); const [openModal, setOpenModal] = useState({}); const { cashString, cashCop, cashRub } = useWallet(); @@ -70,56 +62,20 @@ function TariffPage() { const [promocodeField, setPromocodeField] = useState(""); const cc = useCC(store => store.cc) - const getTariffsList = async (): Promise => { - const tariffsList: Tariff[] = []; - let page = 2 - const [tariffsResponse, tariffsResponseError] = await getTariffs(page - 1); -console.log(tariffsResponse) - if (tariffsResponseError || !tariffsResponse) { - return tariffsList; - } - tariffsList.push(...tariffsResponse.tariffs); + const { data: tariffs, error: tariffsError, isLoading: tariffsLoading } = useTariffs(); - for (page; page <= tariffsResponse.totalPages; page += 1) { - const [tariffsResult] = await getTariffs(page); - - if (tariffsResult) { - tariffsList.push(...tariffsResult.tariffs); - } - } - - return tariffsList; - }; +console.log("________34563875693785692576_____ TARIFFS") +console.log(tariffs) useEffect(() => { - const get = async () => { - const [user, userError] = await getUser(); - - if (userError) { - return; - } - - const tariffsList = await getTariffsList(); - - if (userId) { - const [discounts] = await getDiscounts(userId); - - if (discounts?.length) { - setDiscounts(discounts); - } - } - - setUser(user); - setTariffs(tariffsList); - + if (a) { let cs = currencyFormatter.format(Number(user.wallet.cash) / 100); let cc = Number(user.wallet.cash); let cr = Number(user.wallet.cash) / 100; setCash(cs, cc, cr); - }; - get(); - }, []); + } + }, [a]); useEffect(() => { if (cc) { @@ -203,32 +159,17 @@ console.log(tariffsResponse) if (error) { enqueueSnackbar(error); - return; } enqueueSnackbar(greetings); - - if (!userId) { - return; - } - - const [discounts, discountsError] = await getDiscounts(userId); - - if (discountsError) { - throw new Error(discountsError); - } - - if (discounts?.length) { - setDiscounts(discounts); - } } const startRequestCreate = () => { setIsRequestCreate(true) } - + if (!a) return null; return ( <> setSelectedItem("hide") }, { @@ -446,7 +387,7 @@ export const inCart = () => { localStorage.setItem("saveCart", "[]"); } }; -const outCart = (cart: string[]) => { +export const outCart = (cart: string[]) => { //Сделаем муторно и подольше, зато при прерывании сессии данные потеряются минимально if (cart.length > 0) { cart.forEach(async (id: string) => { diff --git a/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx b/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx index 7aad4952..7999e51f 100644 --- a/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx +++ b/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx @@ -19,6 +19,8 @@ export const createTariffElements = ( ) => { console.log("start work createTariffElements") console.log("filteredTariffs ", filteredTariffs) + console.log("user ", user) + console.log("user.isUserNko, ", user.isUserNko) const tariffElements = filteredTariffs .filter((tariff) => tariff.privileges.length > 0) .map((tariff, index) => { @@ -27,7 +29,7 @@ export const createTariffElements = ( discounts, user.wallet.spent, [], - user.isUserNko, + user.status === "nko", user.userId, ); diff --git a/src/pages/createQuize/QuizGallery/templates/Auto.ts b/src/pages/createQuize/QuizGallery/templates/Auto.ts index aecfc213..86547616 100644 --- a/src/pages/createQuize/QuizGallery/templates/Auto.ts +++ b/src/pages/createQuize/QuizGallery/templates/Auto.ts @@ -11,58 +11,59 @@ import AutoIcon8 from "@/assets/quiz-templates/auto/auto-8.jpg"; import AutoIcon9 from "@/assets/quiz-templates/auto/auto-9.jpg"; import AutoIcon10 from "@/assets/quiz-templates/auto/auto-10.jpg"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const AUTO_TEMPLATES: Category = { categoryType: "Auto", category: "Авто", templates: [ { - quizId: "eb885519-d9c2-41a5-a69c-6105d2bd9bef", + quizId: isTestServer ? "b1b0ed51-e2de-4b48-a8ca-d55e42b290ca" : "eb885519-d9c2-41a5-a69c-6105d2bd9bef", title: "Узнайте, что у вас с машиной", picture: AutoIcon1, }, { - quizId: "68f080e2-ae70-4a1a-be09-05c3decea592", + quizId: isTestServer ? "037f6f16-58e9-4854-a3fd-ccbdaa2ef901" : "68f080e2-ae70-4a1a-be09-05c3decea592", title: "Узнай стоимость и сроки выкупа своего автомобиля", picture: AutoIcon2, }, { - quizId: "446a5e79-8f10-4fb0-aa0f-165e3fbd8d36", + quizId: isTestServer ? "f5eadfa3-9cfc-4429-9854-380f5240fbbe" : "446a5e79-8f10-4fb0-aa0f-165e3fbd8d36", title: "Автошкола «Руль в Руки»", picture: AutoIcon3, }, { - quizId: "f30c7d80-852e-405d-8308-a124636b5ffa", + quizId: isTestServer ? "1f4d6841-9ee6-43ba-9d3d-929bbf2a5252" : "f30c7d80-852e-405d-8308-a124636b5ffa", title: "Узнайте, в какой компании выгодней КАСКО и ОСАГО", picture: AutoIcon4, }, { - quizId: "e200c96f-9c7a-4859-9bd2-65e42a6450b3", + quizId: isTestServer ? "dc5d523f-3922-4407-883c-22fc07f440d6" : "e200c96f-9c7a-4859-9bd2-65e42a6450b3", title: "Пройди тест, чтобы рассчитать стоимость необходимых детейлинг услуг", picture: AutoIcon5, }, { - quizId: "824c4553-ecb5-43e8-9b62-efc4844b01a8", + quizId: isTestServer ? "1e3dd6a6-34fb-44fc-9583-fd85de35b553" : "824c4553-ecb5-43e8-9b62-efc4844b01a8", title: "Онлайн-калькулятор шиномонтажных услуг", picture: AutoIcon6, }, { - quizId: "42423a16-1159-4c5c-bb45-4e9940ab6098", + quizId: isTestServer ? "15a14d9a-7afc-44f8-b162-eddcc327911a" : "42423a16-1159-4c5c-bb45-4e9940ab6098", title: "Калькулятор расчёта стоимости тонировки автомобиля", picture: AutoIcon7, }, { - quizId: "a0dfe680-30ff-4cac-91a5-28eb79889b68", + quizId: isTestServer ? "5c65c221-ac6d-4544-9f93-222b5790310b" : "a0dfe680-30ff-4cac-91a5-28eb79889b68", title: "Рассчитайте стоимость проката премиум-автомобиля за 3 минуты", picture: AutoIcon8, }, { - quizId: "18145500-1fdd-4814-9607-8775fb1a5ea7", + quizId: isTestServer ? "bec775f0-2e0a-47b2-8f74-4ab03ee0b29e" : "18145500-1fdd-4814-9607-8775fb1a5ea7", title: "Безопасное автокресло для вашего ребенка", picture: AutoIcon9, }, { - quizId: "63aa090c-8943-4a50-a10a-be394e75188b", + quizId: isTestServer ? "81a7b7e5-3045-4a5a-a850-b05d53d4bc82" : "63aa090c-8943-4a50-a10a-be394e75188b", title: "Подберём для вас премиум-автомобиль для проката", picture: AutoIcon10, }, diff --git a/src/pages/createQuize/QuizGallery/templates/Education.ts b/src/pages/createQuize/QuizGallery/templates/Education.ts index f8d012cf..5eb88288 100644 --- a/src/pages/createQuize/QuizGallery/templates/Education.ts +++ b/src/pages/createQuize/QuizGallery/templates/Education.ts @@ -11,59 +11,60 @@ import EductionIcon8 from "@/assets/quiz-templates/education/education-8.jpg"; import EductionIcon9 from "@/assets/quiz-templates/education/education-9.jpg"; import EductionIcon10 from "@/assets/quiz-templates/education/education-10.jpg"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const EDUCATION_TEMPLATES: Category = { categoryType: "Education", category: "Образование", templates: [ { - quizId: "27c10a81-f629-4af4-bdd0-2eb6c9cf10a8", + quizId: isTestServer ? "845cb5eb-bca8-495d-826f-e7b52a271b41" : "27c10a81-f629-4af4-bdd0-2eb6c9cf10a8", title: "Получите приглашение на занятие по программированию для ребёнка", picture: EductionIcon1, }, { - quizId: "bf9aaa3b-5d2d-4f82-9d5e-74862d73d10e", + quizId: isTestServer ? "33042986-9ff3-408e-898b-13b53319cb08" : "bf9aaa3b-5d2d-4f82-9d5e-74862d73d10e", title: "Научим играть любимую песню на фортепиано за 7 занятий", picture: EductionIcon2, }, { - quizId: "e2ed3948-6da2-48f4-86c7-42118b5abf85", + quizId: isTestServer ? "e7751cf8-467e-40e8-bd4d-0935ccab934b" : "e2ed3948-6da2-48f4-86c7-42118b5abf85", title: "Подбери репетитора для своего ребёнка со скидкой в 20%", picture: EductionIcon3, }, { - quizId: "076d3d12-c8f0-442a-b918-7f6085daa3ec", + quizId: isTestServer ? "a9e40faa-4cd5-495e-8812-acc0dde2dee2" : "076d3d12-c8f0-442a-b918-7f6085daa3ec", title: "Обратная связь о вебинаре", picture: EductionIcon4, }, { - quizId: "9914fe9c-19b4-47b1-aef8-a3c8e44f4c4c", + quizId: isTestServer ? "ab3fb1bc-afc8-4cf1-b77a-3fcff361d5be" : "9914fe9c-19b4-47b1-aef8-a3c8e44f4c4c", title: "Хотите выучить английский?", picture: EductionIcon5, }, { - quizId: "ec9c252e-ea2c-489a-809d-27522b7c1972", + quizId: isTestServer ? "a2900f7b-cf24-4a9b-b5da-f7f99dbd8a1b" : "ec9c252e-ea2c-489a-809d-27522b7c1972", title: "Ответьте на 4 вопроса и узнайте, куда записать ребенка чтобы развивать его таланты", picture: EductionIcon6, }, { - quizId: "45acb5b0-1dca-45fe-aaa0-88895bd5b237", + quizId: isTestServer ? "" : "45acb5b0-1dca-45fe-aaa0-88895bd5b237", title: "Поделитесь мнением о конференции", picture: EductionIcon7, }, { - quizId: "a9f17936-30c8-41ff-84d4-668840e02b56", + quizId: isTestServer ? "" : "a9f17936-30c8-41ff-84d4-668840e02b56", title: "Научитесь красиво петь и управлять своим голосом", picture: EductionIcon8, }, { - quizId: "51c4d927-4d27-405d-ab7e-6c2707418017", + quizId: isTestServer ? "" : "51c4d927-4d27-405d-ab7e-6c2707418017", title: "Узнайте, подойдёт ли вам профессия «Разработчик Phyton»?", categoryDescription: "(С ветвлением)", picture: EductionIcon9, }, { - quizId: "6063ee99-3188-43aa-89bc-895d90b08628", + quizId: isTestServer ? "e6dc608c-055a-44bd-ba2e-6cb185b378fe" : "6063ee99-3188-43aa-89bc-895d90b08628", title: "Проверьте своё знание английского языка", categoryDescription: "(С ветвлением)", picture: EductionIcon10, diff --git a/src/pages/createQuize/QuizGallery/templates/Health.ts b/src/pages/createQuize/QuizGallery/templates/Health.ts index f3879971..a11503b8 100644 --- a/src/pages/createQuize/QuizGallery/templates/Health.ts +++ b/src/pages/createQuize/QuizGallery/templates/Health.ts @@ -21,125 +21,126 @@ import HealthIcon18 from "@/assets/quiz-templates/health/health-18.jpg"; import HealthIcon19 from "@/assets/quiz-templates/health/health-19.jpg"; import HealthIcon20 from "@/assets/quiz-templates/health/health-20.jpg"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const HEALTH_TEMPLATES: Category = { categoryType: "Health", category: "Здоровье и уход", templates: [ { - quizId: "294c9c27-a189-4aa1-b792-a4d4612c99bf", + quizId: isTestServer ? "1927cf61-d80c-431c-8a04-4abca7c84b1e" : "294c9c27-a189-4aa1-b792-a4d4612c99bf", title: "Узнайте, сколько будет стоить ваш маникюр", categoryDescription: "Косметология", picture: HealthIcon1, }, { - quizId: "89fc7b57-9a13-4889-9e70-9d08714085f5", + quizId: isTestServer ? "cdb28a49-4bd4-411f-be8c-bc4bcdd577ab" : "89fc7b57-9a13-4889-9e70-9d08714085f5", title: "Узнайте стоимость услуг косметолога в Казани", categoryDescription: "Косметология", picture: HealthIcon2, }, { - quizId: "425c75c7-9412-485e-930f-3ae65f517fab", + quizId: isTestServer ? "6e6e8039-6d5e-4bc2-983a-f0e39f4b91c8" : "425c75c7-9412-485e-930f-3ae65f517fab", title: "Узнайте, как правильно ухаживать за вашим типом кожи в домашних условиях", categoryDescription: "Косметология", picture: HealthIcon3, }, { - quizId: "99461154-6296-4c8c-930d-2b1809f221cd", + quizId: isTestServer ? "1dcec3e5-5bfc-481a-bf80-5a1ca8941e89" : "99461154-6296-4c8c-930d-2b1809f221cd", title: "Какая косметологическая процедура вам нужна?", categoryDescription: "Косметология", picture: HealthIcon4, }, { - quizId: "cbf6a8d4-538a-4edf-9477-062a15361b04", + quizId: isTestServer ? "3cf82c7a-44c9-49d0-bbeb-97a84f6ebe8f" : "cbf6a8d4-538a-4edf-9477-062a15361b04", title: "5 вопросов до улыбки вашей мечты", categoryDescription: "Стоматология", picture: HealthIcon5, }, { - quizId: "017d9d5c-57a8-4eca-95c1-11db847a0e18", + quizId: isTestServer ? "3520c146-3cd9-43c6-9ef2-42571ff06a3e" : "017d9d5c-57a8-4eca-95c1-11db847a0e18", title: "Пройдите небольшой опрос, и узнайте, какая процедура у стоматолога вам нужна", categoryDescription: "Стоматология", picture: HealthIcon6, }, { - quizId: "162cb4f1-ab0a-49c4-b773-16932700f871", + quizId: isTestServer ? "aaa50e95-cd8c-4458-b82e-0139174d85ee" : "162cb4f1-ab0a-49c4-b773-16932700f871", title: "Какой врач мне нужен?", picture: HealthIcon7, }, { - quizId: "c851276b-505d-492b-9acb-5cd85e6fe3a7", + quizId: isTestServer ? "d81b56a0-0961-41ca-8816-cc391bf75efb" : "c851276b-505d-492b-9acb-5cd85e6fe3a7", title: "Психологическая помощь", categoryDescription: "Психолог", picture: HealthIcon8, }, { - quizId: "2fa1d438-72ac-49b2-95b6-73a8c9d8347a", + quizId: isTestServer ? "f4a0e414-b739-4a2e-8001-3de6eb1304c3" : "2fa1d438-72ac-49b2-95b6-73a8c9d8347a", title: "Ищешь психолога?", categoryDescription: "Психолог", picture: HealthIcon9, }, { - quizId: "b0b30965-ec43-4718-8a1f-2ae35f932a61", + quizId: isTestServer ? "f10774b0-23f6-4525-a2fd-b3ffd9d59cce" : "b0b30965-ec43-4718-8a1f-2ae35f932a61", title: "Подбор медицинского центра для лечебного массажа", categoryDescription: "Массаж", picture: HealthIcon10, }, { - quizId: "722aff37-d247-4341-9908-412e41f9d7cd", + quizId: isTestServer ? "418d735e-8134-4742-963b-8fdf392aebd3" : "722aff37-d247-4341-9908-412e41f9d7cd", title: "Исследование рынка мобильных приложений для здоровья", picture: HealthIcon11, }, { - quizId: "f0d800bc-2df0-42a6-8457-5c7759021854", + quizId: isTestServer ? "63552fb8-1586-4f14-a7c7-b75736294a87" : "f0d800bc-2df0-42a6-8457-5c7759021854", title: "Выполним стрижки и окрашивания любой сложности", categoryDescription: "Косметология", picture: HealthIcon12, }, { - quizId: "f88e2eb6-66e6-41ba-9d3d-1d7fe69d30d8", + quizId: isTestServer ? "4f4c6b83-a73c-4dbe-8776-ab93a073503d" : "f88e2eb6-66e6-41ba-9d3d-1d7fe69d30d8", title: "Массажный салон «Промято» в Ярославле", categoryDescription: "Массаж", picture: HealthIcon13, }, { - quizId: "9b2d47e8-d45f-48b7-a7fd-1c9c35edab17", + quizId: isTestServer ? "d47812bc-b7ac-4325-9eb1-496f1e60ab2c" : "9b2d47e8-d45f-48b7-a7fd-1c9c35edab17", title: "Подбери себе направление в йоге", categoryDescription: "Йога", picture: HealthIcon14, }, { - quizId: "8f6a1b3f-27fc-4e1c-a117-f67867e5df65", + quizId: isTestServer ? "bcd65cdd-07e7-480f-b305-596b815d1bb9" : "8f6a1b3f-27fc-4e1c-a117-f67867e5df65", title: "Подберите за 2 минуты рацион готового питания", categoryDescription: "Питание", picture: HealthIcon15, }, { - quizId: "73ff039f-3e93-4412-80ab-749f54c9bafa", + quizId: isTestServer ? "07f118c8-84fb-473a-9c83-357246fecaf1" : "73ff039f-3e93-4412-80ab-749f54c9bafa", title: "Рассчитайте стоимость установки грудных имплантов", picture: HealthIcon16, }, { - quizId: "2b4be94e-3505-41ae-85bb-c6c4a4d1bcd4", + quizId: isTestServer ? "ecba00e5-3990-4501-8b7a-fbee50383625" : "2b4be94e-3505-41ae-85bb-c6c4a4d1bcd4", title: "Не знаете, как выбрать очки? Подберите оправу под свои параметры", categoryDescription: "Зрение", picture: HealthIcon17, }, { - quizId: "28b133a5-0e6a-46b9-bd6b-81a44b808341", + quizId: isTestServer ? "1315b676-2abb-49e6-a959-89e2963bbe53" : "28b133a5-0e6a-46b9-bd6b-81a44b808341", title: "Санаторий в Подмосковье для пожилых людей", categoryDescription: "Санаторий", picture: HealthIcon18, }, { - quizId: "88a8e952-1475-4052-b99a-bbb7eb31249c", + quizId: isTestServer ? "d439fa6a-e13b-4a38-9bea-9414ee82c9fd" : "88a8e952-1475-4052-b99a-bbb7eb31249c", title: "Свежие блюда своими руками. 15 минут и готово", categoryDescription: "Питание", picture: HealthIcon19, }, { - quizId: "6baf144a-7401-442a-a513-6bc5aa3f1a6a", + quizId: isTestServer ? "de88083b-f02d-4a53-8afa-2c646d6aa588" : "6baf144a-7401-442a-a513-6bc5aa3f1a6a", title: "Рассчитайте стоимость отдыха в лучшей бане Москвы", picture: HealthIcon20, }, diff --git a/src/pages/createQuize/QuizGallery/templates/Production.ts b/src/pages/createQuize/QuizGallery/templates/Production.ts index a9ec3f22..24cf7280 100644 --- a/src/pages/createQuize/QuizGallery/templates/Production.ts +++ b/src/pages/createQuize/QuizGallery/templates/Production.ts @@ -11,58 +11,59 @@ import ProductionIcon8 from "@/assets/quiz-templates/production/production-8.jpg import ProductionIcon9 from "@/assets/quiz-templates/production/production-9.jpg"; import ProductionIcon10 from "@/assets/quiz-templates/production/production-10.jpg"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const PRODUCTION_TEMPLATES: Category = { categoryType: "Production", category: "Производство", templates: [ { - quizId: "14859665-e8ea-4e4a-b381-af88179f8ba3", + quizId: isTestServer ? "2745eb4a-e592-4319-9e6c-4e3f7b9503d2" : "14859665-e8ea-4e4a-b381-af88179f8ba3", title: "Рассчитайте стоимость постельного белья", picture: ProductionIcon1, }, { - quizId: "39cb17b6-10df-4107-abb8-6726d4845cbf", + quizId: isTestServer ? "1f18bf94-24c7-4f08-8362-e7efd2923359" : "39cb17b6-10df-4107-abb8-6726d4845cbf", title: "Ответьте на 4 вопроса и подберите межкомнатную дверь", picture: ProductionIcon2, }, { - quizId: "21b125ed-0213-4a3c-bd30-1a75b3953f4a", + quizId: isTestServer ? "75a52c54-9ebf-4785-bd11-8c432125005a" : "21b125ed-0213-4a3c-bd30-1a75b3953f4a", title: "Узнай стоимость производства и монтажа металлических ворот", picture: ProductionIcon3, }, { - quizId: "ed1a01f4-9497-4a79-adac-8f4fbf7f26f5", + quizId: isTestServer ? "2bc49b0b-e356-43bb-ac4e-37d135c48b2d" : "ed1a01f4-9497-4a79-adac-8f4fbf7f26f5", title: "Заполните анкету, чтобы заказать изготовление ювелирного изделия", picture: ProductionIcon4, }, { - quizId: "c94834f8-dd3a-43a0-8d40-6ebae4f475ed", + quizId: isTestServer ? "38880384-214d-4ac5-95f7-8ceb2f6060b5" : "c94834f8-dd3a-43a0-8d40-6ebae4f475ed", title: "Идеальный пол для любого помещения", picture: ProductionIcon5, }, { - quizId: "35ccb5b5-f4d2-4bbc-b172-5984356e7cfb", + quizId: isTestServer ? "d8189d8a-eb1d-41d7-9aee-62db91bd0ee0" : "35ccb5b5-f4d2-4bbc-b172-5984356e7cfb", title: "Рассчитайте стоимость изготовления зеркала", picture: ProductionIcon6, }, { - quizId: "e89d3758-2cfb-4566-9eb2-733c1c11ea03", + quizId: isTestServer ? "a1c7240c-af97-4405-9724-f02155e140df" : "e89d3758-2cfb-4566-9eb2-733c1c11ea03", title: "Подбери лучшие кеды", picture: ProductionIcon7, }, { - quizId: "26f00205-8373-4d00-bd93-7ced6cd0f509", + quizId: isTestServer ? "2031fe03-4f3e-4144-8cbf-26715b54d973" : "26f00205-8373-4d00-bd93-7ced6cd0f509", title: "Идеальная кровать для вашего ребенка", picture: ProductionIcon8, }, { - quizId: "4cc7cacf-30a9-4571-9319-dd186b915624", + quizId: isTestServer ? "46824071-75e7-4988-b157-960471ad7234" : "4cc7cacf-30a9-4571-9319-dd186b915624", title: "Рассчитайте стоимость кухни ручной работы из Италии с доставкой в Россию", picture: ProductionIcon9, }, { - quizId: "0d839f24-53e8-4dbd-9d9b-c57ac8e53a9c", + quizId: isTestServer ? "df3aff58-afb1-4876-a97a-2d792373894e" : "0d839f24-53e8-4dbd-9d9b-c57ac8e53a9c", title: "Узнайте примерную стоимость индивидуального пошива одежды", picture: ProductionIcon10, }, diff --git a/src/pages/createQuize/QuizGallery/templates/RealEstate.ts b/src/pages/createQuize/QuizGallery/templates/RealEstate.ts index bbe1bbd8..ecf18975 100644 --- a/src/pages/createQuize/QuizGallery/templates/RealEstate.ts +++ b/src/pages/createQuize/QuizGallery/templates/RealEstate.ts @@ -11,62 +11,63 @@ import RealEstateIcon8 from "@/assets/quiz-templates/real-estate/real-estate-8.j import RealEstateIcon9 from "@/assets/quiz-templates/real-estate/real-estate-9.jpg"; import RealEstateIcon10 from "@/assets/quiz-templates/real-estate/real-estate-10.jpg"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const REAL_ESTATE_TEMPLATES: Category = { categoryType: "RealEstate", category: "Недвижимость", templates: [ { - quizId: "d3930e95-ae95-4e2f-b9f9-79b929c2e1e6", + quizId: isTestServer ? "af9ed905-3947-4396-a9d9-a3b233451349" : "d3930e95-ae95-4e2f-b9f9-79b929c2e1e6", title: "Рассчитайте стоимость каркасного дома своей мечты", categoryDescription: "Строительство и ремонт", picture: RealEstateIcon1, }, { - quizId: "4e488b9b-d273-4f1c-b729-991fcbc006cd", + quizId: isTestServer ? "67b2c10a-a1f8-4eee-82a6-3aa7cd938566" : "4e488b9b-d273-4f1c-b729-991fcbc006cd", title: "Краткосрочная аренда коммерческих помещений", categoryDescription: "Аренда", picture: RealEstateIcon2, }, { - quizId: "84605c72-ce1d-49fb-a40e-7ed2ab96ac7d", + quizId: isTestServer ? "eacc428a-b724-4c26-9573-a179f23aef81" : "84605c72-ce1d-49fb-a40e-7ed2ab96ac7d", title: "Подберем новостройку под ваши критерии", picture: RealEstateIcon3, }, { - quizId: "ab701ab8-b8ad-4f45-a1ef-f0ab5357a587", + quizId: isTestServer ? "b77623d9-b73e-4eab-9137-6cd3e3722bfa" : "ab701ab8-b8ad-4f45-a1ef-f0ab5357a587", title: "15 лучших предложений от застройщиков в Москве", picture: RealEstateIcon4, }, { - quizId: "a5998d6c-c055-4702-bfc7-e1185fffa6c6", + quizId: isTestServer ? "8ebca441-50f2-4ed8-a648-fd35a86976e9" : "a5998d6c-c055-4702-bfc7-e1185fffa6c6", title: "Подберем идеальное жильё в Риме", picture: RealEstateIcon5, }, { - quizId: "bfbf97f2-3eba-4386-a794-4fa8f5825ac1", + quizId: isTestServer ? "1df0c5b6-5d15-427f-8972-651b0a8e67d7" : "bfbf97f2-3eba-4386-a794-4fa8f5825ac1", title: "Подбери уютный коттедж для отдыха в Подмосковье за 1 минуту", picture: RealEstateIcon6, }, { - quizId: "1b6ce902-0568-43c2-90a1-55dec710cb4f", + quizId: isTestServer ? "2857158a-18e0-4de7-bf0f-f1915ad95db1" : "1b6ce902-0568-43c2-90a1-55dec710cb4f", title: "Среди сотен новостроек подберём для вас самые подходящие", picture: RealEstateIcon7, }, { - quizId: "0dfa128f-8c2b-4519-8cf4-05f9171979e1", + quizId: isTestServer ? "df32e587-660c-4248-8fd3-c6e9b1752ae0" : "0dfa128f-8c2b-4519-8cf4-05f9171979e1", title: "Рассчитайте стоимость бронирования клуба для мероприятий", categoryDescription: "Aренда", picture: RealEstateIcon8, }, { - quizId: "8c4c8e3d-19cb-4c55-8952-558b877245bd", + quizId: isTestServer ? "9151a489-0d31-4442-a868-db0779322697" : "8c4c8e3d-19cb-4c55-8952-558b877245bd", title: "Запишитесь на консультацию и получите каталог объектов в перспективных районах Дубая", categoryDescription: "Услуги риелтора", picture: RealEstateIcon9, }, { - quizId: "36ebbe5d-4d85-453d-b5d2-51cdf7f95327", + quizId: isTestServer ? "6bcee3c8-951f-4745-8858-2b2cd6f6d282" : "36ebbe5d-4d85-453d-b5d2-51cdf7f95327", title: "Строим дома за 90 дней вместе со всеми коммуникациями и электричеством", categoryDescription: "Строительство и ремонт", diff --git a/src/pages/createQuize/QuizGallery/templates/Repair.ts b/src/pages/createQuize/QuizGallery/templates/Repair.ts index 2a378acc..2ec4b539 100644 --- a/src/pages/createQuize/QuizGallery/templates/Repair.ts +++ b/src/pages/createQuize/QuizGallery/templates/Repair.ts @@ -11,59 +11,60 @@ import RepairIcon8 from "@/assets/quiz-templates/repair/repair-8.jpg"; import RepairIcon9 from "@/assets/quiz-templates/repair/repair-9.jpg"; import RepairIcon10 from "@/assets/quiz-templates/repair/repair-10.jpg"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const REPAIR_TEMPLATES: Category = { categoryType: "Repair", category: "Ремонт", templates: [ { - quizId: "556760d9-652b-4ff1-91d5-3dc629650882", + quizId: isTestServer ? "d15ca3f0-8d59-4ac3-b168-6ac3246a22bb" : "556760d9-652b-4ff1-91d5-3dc629650882", title: "Капитальный ремонт квартир с фиксированной ценой", picture: RepairIcon1, }, { - quizId: "8f034581-71fb-467e-82dd-a415d4b8d73c", + quizId: isTestServer ? "62295ce9-58ad-42c5-9827-e3b180c8c4f7" : "8f034581-71fb-467e-82dd-a415d4b8d73c", title: "Натяжные потолки с гарантией 25 лет", picture: RepairIcon2, }, { - quizId: "fcb8c47b-f409-400c-b3d5-66657755f885", + quizId: isTestServer ? "d46febb0-3e79-4b83-8d7f-d104991a9359" : "fcb8c47b-f409-400c-b3d5-66657755f885", title: "Рассчитайте стоимость пластиковых окон", picture: RepairIcon3, }, { - quizId: "7544a8d3-ff03-491d-9189-1433fe307ad0", + quizId: isTestServer ? "d473b5a6-4d70-49d3-bacb-35ce21cd88fe" : "7544a8d3-ff03-491d-9189-1433fe307ad0", title: "Рассчитайте стоимость установки тёплого пола", picture: RepairIcon4, }, { - quizId: "dcf8bd1d-4c3f-4d1a-9efa-3d25991068f9", + quizId: isTestServer ? "a1bba994-a733-4817-a9bb-c64a68d670c8" : "dcf8bd1d-4c3f-4d1a-9efa-3d25991068f9", title: "Рассчитайте стоимость лестницы под ключ по вашим параметрам всего за одну минуту", picture: RepairIcon5, }, { - quizId: "2a921839-e5c8-45aa-afca-703d0dad8fad", + quizId: isTestServer ? "ad2fd24a-c28d-469c-95ea-78626fc51719" : "2a921839-e5c8-45aa-afca-703d0dad8fad", title: "Ответьте на 5 вопросов и рассчитайте стоимость вентиляции с монтажом под объект", picture: RepairIcon6, }, { - quizId: "ed13de01-f803-456a-b237-3644c808a0a1", + quizId: isTestServer ? "831303b3-aa9d-4115-936e-c46b899dd9b0" : "ed13de01-f803-456a-b237-3644c808a0a1", title: "Узнайте стоимость освещения вашего объекта", picture: RepairIcon7, }, { - quizId: "8d05e910-df1f-4ad3-9679-c0c3f7b7e575", + quizId: isTestServer ? "48c57689-3999-4f52-90ef-b26232fc400d" : "8d05e910-df1f-4ad3-9679-c0c3f7b7e575", title: "Узнайте стоимость кухни на заказ", picture: RepairIcon8, }, { - quizId: "9cabba56-2861-40dc-8f33-800745c3c949", + quizId: isTestServer ? "b61ca69f-d0e1-4754-ab91-2ec56fa45ca3" : "9cabba56-2861-40dc-8f33-800745c3c949", title: "Узнай стоимость дизайна интерьера под ключ", picture: RepairIcon9, }, { - quizId: "1c0eb1ad-ed3e-43f9-bcba-f094d13fef5b", + quizId: isTestServer ? "bc6aad09-b0e0-419c-87d8-6dd9770cc12e" : "1c0eb1ad-ed3e-43f9-bcba-f094d13fef5b", title: "Требуется штукатурка? Узнайте примерную стоимость работ и материалов.", picture: RepairIcon10, diff --git a/src/pages/createQuize/QuizGallery/templates/Research.ts b/src/pages/createQuize/QuizGallery/templates/Research.ts index a3554d52..1669aae5 100644 --- a/src/pages/createQuize/QuizGallery/templates/Research.ts +++ b/src/pages/createQuize/QuizGallery/templates/Research.ts @@ -11,57 +11,58 @@ import ResearchIcon8 from "@/assets/quiz-templates/research/research-8.jpg"; import ResearchIcon9 from "@/assets/quiz-templates/research/research-9.jpg"; import ResearchIcon10 from "@/assets/quiz-templates/research/research-10.jpg"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const RESEARCH_TEMPLATES: Category = { categoryType: "Research", category: "Исследовательские", templates: [ { - quizId: "1b356222-e762-4f3d-87e5-4c3d6c0a9467", + quizId: isTestServer ? "14f05b7d-abd1-4069-83ef-52e5fb748592" : "1b356222-e762-4f3d-87e5-4c3d6c0a9467", title: "Общественные настроения. Социальное самочувствие граждан", picture: ResearchIcon1, }, { - quizId: "7e901bea-6774-48b7-b31f-b62fd21ac88f", + quizId: isTestServer ? "b06f995a-7b35-493d-9614-a57cbbeae619" : "7e901bea-6774-48b7-b31f-b62fd21ac88f", title: "Социальные институты и проблемы общества", picture: ResearchIcon2, }, { - quizId: "2570ccef-563c-4d8e-a052-d6ad142fb789", + quizId: isTestServer ? "47a72329-e3fe-4164-94d2-87ec8471de39" : "2570ccef-563c-4d8e-a052-d6ad142fb789", title: "Уровень жизни населения", picture: ResearchIcon3, }, { - quizId: "b9394ed2-25e0-4e55-9d2a-9577856e903d", + quizId: isTestServer ? "54b0eccc-2ba2-4f48-8947-98449478a56f" : "b9394ed2-25e0-4e55-9d2a-9577856e903d", title: "Проблемы семьи и семейные отношения", picture: ResearchIcon4, }, { - quizId: "922088b6-9e02-4a0f-b6af-a7150781d4eb", + quizId: isTestServer ? "e7c67cc4-6e80-4c78-81d0-62669274fd3e" : "922088b6-9e02-4a0f-b6af-a7150781d4eb", title: "Здоровье и здравоохранение", picture: ResearchIcon5, }, { - quizId: "528ef773-2da5-4988-b687-b393d687ed00", + quizId: isTestServer ? "8c155f0c-9025-4779-be2c-17119a49fd40" : "528ef773-2da5-4988-b687-b393d687ed00", title: "Религия и Церковь", picture: ResearchIcon6, }, { - quizId: "8887c07c-831f-40c6-9bf7-951ab09546da", + quizId: isTestServer ? "afa35959-9df4-4ff8-9b3c-9a6ede888931" : "8887c07c-831f-40c6-9bf7-951ab09546da", title: "Трудоустройство молодежи", picture: ResearchIcon7, }, { - quizId: "850fde64-0462-40f7-992e-44fd0177e3b7", + quizId: isTestServer ? "75a252ec-b9e6-4764-acef-5d490a170e0b" : "850fde64-0462-40f7-992e-44fd0177e3b7", title: "Культура и ценности", picture: ResearchIcon8, }, { - quizId: "2c6ba86a-6c86-47b2-b71c-3c4ebaf29fbb", + quizId: isTestServer ? "18ca6609-5390-45ea-81e0-b6d3d26277bf" : "2c6ba86a-6c86-47b2-b71c-3c4ebaf29fbb", title: "Наука и технологии", picture: ResearchIcon9, }, { - quizId: "7ccd26ff-ccf5-4d6c-a148-1612a970211e", + quizId: isTestServer ? "cf3e02e5-b5d7-43d2-9ea3-888112387695" : "7ccd26ff-ccf5-4d6c-a148-1612a970211e", title: "Бизнес и предпринимательство", picture: ResearchIcon10, }, diff --git a/src/pages/createQuize/QuizGallery/templates/Services.ts b/src/pages/createQuize/QuizGallery/templates/Services.ts index 542a3263..153d868a 100644 --- a/src/pages/createQuize/QuizGallery/templates/Services.ts +++ b/src/pages/createQuize/QuizGallery/templates/Services.ts @@ -11,67 +11,68 @@ import ServiceIcon10 from "@/assets/quiz-templates/services/service-10.jpg"; import ServiceIcon11 from "@/assets/quiz-templates/services/service-11.jpg"; import type { Category } from "../Template"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const SERVICE_TEMPLATES: Category = { categoryType: "Services", category: "Услуги", templates: [ { - quizId: "a3490800-1ad3-4944-bb9c-32189d36b75c", + quizId: isTestServer ? "a055f7c1-34eb-4969-bf6a-1c701e1217b1" : "a3490800-1ad3-4944-bb9c-32189d36b75c", title: "Ответьте на 3 вопроса и узнайте, паспорт какой европейской страны вам подойдёт", picture: ServiceIcon1, }, { - quizId: "785fed83-6608-4029-ae22-6a26ce621e5f", + quizId: isTestServer ? "9fd1eff3-e342-4ae8-8e2a-2929c83af9cd" : "785fed83-6608-4029-ae22-6a26ce621e5f", title: "Ответьте на 7 вопросов, чтобы получить коммерческое предложение от маркетолога", picture: ServiceIcon2, }, { - quizId: "dfa3733f-66ce-4335-b83a-2c6511cbd1ce", + quizId: isTestServer ? "baf9468d-31b8-422f-9baa-efe2b00ac2af" : "dfa3733f-66ce-4335-b83a-2c6511cbd1ce", title: "Ответьте на пару вопросов, чтобы найти свой индивидуальный стиль одежды", picture: ServiceIcon3, }, { - quizId: "8bf582a9-0a66-4f7b-bc0f-3c2f656c7449", + quizId: isTestServer ? "934e9f8f-ab9c-443b-8693-ce132baae9d1" : "8bf582a9-0a66-4f7b-bc0f-3c2f656c7449", title: "Обменяйте рубли на валюту с комиссией 0%", picture: ServiceIcon4, }, { - quizId: "206ba071-afe9-4ee0-a722-a24a4f592679", + quizId: isTestServer ? "16cdb992-4338-417b-a8f5-0684c062e2cb" : "206ba071-afe9-4ee0-a722-a24a4f592679", title: "Рассчитайте стоимость уборки вашей квартиры", picture: ServiceIcon5, }, { - quizId: "6938ff93-52eb-4296-86bf-fe5aa3fddabf", + quizId: isTestServer ? "c3c5bf13-8498-4c35-9b58-1b9d6114fc47" : "6938ff93-52eb-4296-86bf-fe5aa3fddabf", title: "Забронируйте номер в зоогостинице для своего любимого питомца", picture: ServiceIcon6, }, { - quizId: "5262bc69-1ea0-446c-a16f-e929b6190e6d", + quizId: isTestServer ? "" : "5262bc69-1ea0-446c-a16f-e929b6190e6d", title: "Организуем перевозку под ключ", picture: ServiceIcon7, }, { - quizId: "9f8015f7-07fc-4acb-92dd-6e00505884cc", + quizId: isTestServer ? "37bc6554-1634-4b0c-8d95-abf589c8f56d" : "9f8015f7-07fc-4acb-92dd-6e00505884cc", title: "Рассчитайте стоимость ремонта пластиковых окон за 3 минуты", picture: ServiceIcon8, }, { - quizId: "259749bf-a54f-4a8e-ab5a-4cd0862d7504", + quizId: isTestServer ? "5ff47f56-2f50-42c8-af1e-936c8f63aca2" : "259749bf-a54f-4a8e-ab5a-4cd0862d7504", title: "Поможем подобрать эскиз для татуировки", picture: ServiceIcon9, }, { - quizId: "e107c0cd-4fa1-4a8f-938a-10a329b6528d", + quizId: isTestServer ? "4fc3dd99-b818-40ac-81d4-75150308608e" : "e107c0cd-4fa1-4a8f-938a-10a329b6528d", title: "Подбери себе лучшего юриста за 30 секунд", categoryDescription: "Юр услуги", picture: ServiceIcon10, }, { - quizId: "ce7903b1-3dfb-4a28-a2a4-0b41af447ae1", + quizId: isTestServer ? "ad4adfed-8e82-4d77-8675-6c024ab492ad" : "ce7903b1-3dfb-4a28-a2a4-0b41af447ae1", title: "Рассчитайте размер ипотечного кредитования, ответив на 4 вопроса", categoryDescription: "Юр услуги", picture: ServiceIcon11, diff --git a/src/pages/createQuize/QuizGallery/templates/Tourism.ts b/src/pages/createQuize/QuizGallery/templates/Tourism.ts index 1a16e7a5..e05fa388 100644 --- a/src/pages/createQuize/QuizGallery/templates/Tourism.ts +++ b/src/pages/createQuize/QuizGallery/templates/Tourism.ts @@ -10,58 +10,59 @@ import TourismIcon9 from "@/assets/quiz-templates/tourism/tourism-9.jpg"; import TourismIcon10 from "@/assets/quiz-templates/tourism/tourism-10.jpg"; import type { Category } from "../Template"; +import { isTestServer } from "@/utils/hooks/useDomainDefine"; export const TOURISM_TEMPLATES: Category = { categoryType: "Tourism", category: "Туризм", templates: [ { - quizId: "f7a2b3b8-2548-47d8-afb3-f2c69a3a0a81", + quizId: isTestServer ? "0d42bc16-c927-4d49-8764-deb4e4f14c4f" : "f7a2b3b8-2548-47d8-afb3-f2c69a3a0a81", title: "Подбор туристической страховки", picture: TourismIcon1, }, { - quizId: "e0927ded-5c4c-4d45-a5ba-c2e938362ffa", + quizId: isTestServer ? "897e3908-28e3-494e-a0be-0e3a0264b946" : "e0927ded-5c4c-4d45-a5ba-c2e938362ffa", title: "Оцените свои шансы на получение визы в США", picture: TourismIcon2, }, { - quizId: "23af97f4-0b8f-4d8b-8099-66ebef409ce1", + quizId: isTestServer ? "c4eec832-3e34-4486-b4db-e32812f924ea" : "23af97f4-0b8f-4d8b-8099-66ebef409ce1", title: "Персональный тур с лучшими местами в Германии", picture: TourismIcon3, }, { - quizId: "ca3bd705-7d41-4ff1-ae4c-0b2d4a8faa30", + quizId: isTestServer ? "67fbd981-e77d-4f43-8e37-9b2e94dc4afa" : "ca3bd705-7d41-4ff1-ae4c-0b2d4a8faa30", title: "Подберём лучший вариант тура под ваши критерии", picture: TourismIcon4, }, { - quizId: "5c2effd9-fe6a-40e6-9752-3f61dc20d6fa", + quizId: isTestServer ? "dd965dcf-aeca-4c39-8ee9-0dde372204b6" : "5c2effd9-fe6a-40e6-9752-3f61dc20d6fa", title: "Выберем самый подходящий для вас тур в Грузию", picture: TourismIcon5, }, { - quizId: "b559a764-6f55-4dc2-a9c4-aecd8b96003c", + quizId: isTestServer ? "e8d98b38-fbda-486e-b69a-b036f74703c8" : "b559a764-6f55-4dc2-a9c4-aecd8b96003c", title: "Бонжур, Сена! Подберём для вас тур по Франции", picture: TourismIcon6, }, { - quizId: "e33bf54b-9ad5-4cb9-b552-77148264d6af", + quizId: isTestServer ? "52018c8a-53e7-4d76-8fc3-4e3bd414ee3e" : "e33bf54b-9ad5-4cb9-b552-77148264d6af", title: "Персональный тур в Египет с лучшими местами страны", picture: TourismIcon7, }, { - quizId: "c5815b1d-4991-4df2-ae14-8713d7f313b9", + quizId: isTestServer ? "740b5ee8-0ab4-441f-8f75-e22b3a61ab36" : "c5815b1d-4991-4df2-ae14-8713d7f313b9", title: "Тур по местам России", picture: TourismIcon8, }, { - quizId: "a0a4dce8-43bb-4978-a802-96d384465df4", + quizId: isTestServer ? "5e0d7397-6e05-4f81-b24f-a625c2da12d3" : "a0a4dce8-43bb-4978-a802-96d384465df4", title: "Подберём для вас тур с самыми красивыми местами мира", picture: TourismIcon9, }, { - quizId: "0749abc5-a352-41b9-85c3-db7541326f23", + quizId: isTestServer ? "65fdf9a0-d30d-4728-abe3-b9a64c965269" : "0749abc5-a352-41b9-85c3-db7541326f23", title: "Выберем лучшие туристические места для вас", picture: TourismIcon10, }, diff --git a/src/ui_kit/InfoPopover.tsx b/src/ui_kit/InfoPopover.tsx new file mode 100644 index 00000000..a28b9e67 --- /dev/null +++ b/src/ui_kit/InfoPopover.tsx @@ -0,0 +1,59 @@ +import { useState, MouseEvent, ReactNode } from "react"; +import Info from "@icons/Info"; + +import { Paper, Popover, SxProps, Typography } from "@mui/material"; + +export const InfoPopover = ({ + blink = false, + sx, + children = "подсказка" +}: { + blink?: boolean, + sx?: SxProps, + children?: ReactNode +}) => { + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event: MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + + return ( + <> + + + + {children} + + + + ); +}; \ No newline at end of file diff --git a/src/ui_kit/MenuItem.tsx b/src/ui_kit/MenuItem.tsx index 70254b7e..d2bd1ed5 100755 --- a/src/ui_kit/MenuItem.tsx +++ b/src/ui_kit/MenuItem.tsx @@ -31,6 +31,7 @@ export default function MenuItem({ px: 0, pt: "5px", pb: "3px", + whiteSpace: "break-spaces" }} > state.currentStep); const quiz = useCurrentQuiz(); const { pathname } = useLocation(); + const isMobile = useMediaQuery(theme.breakpoints.down(650)); const navigate = useNavigate(); const changeMenuItem = (index: number) => { @@ -47,17 +49,18 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) { return ( {!isMenuCollapsed && ( @@ -99,7 +103,7 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) { )} - + {quizSetupSteps.map((menuItem, index) => { const Icon = menuItem.sidebarIcon; @@ -168,6 +172,20 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) { /> } /> + { + navigate("/personalization-ai"); + setCurrentStep(17); + setTryShowAmoTokenExpiredDialog(true); + }} + text={"Персонализация вопросов с помощью AI"} + isCollapsed={isMenuCollapsed} + isActive={pathname.startsWith("/personalization-ai")} + disabled={pathname.startsWith("/personalization-ai") ? false : quiz === undefined ? true : quiz?.config.type === null} + icon={ + + } + /> { navigate("/integrations"); diff --git a/src/ui_kit/Sidebar/SidebarModal/index.tsx b/src/ui_kit/Sidebar/SidebarModal/index.tsx index 9286f305..0c639355 100644 --- a/src/ui_kit/Sidebar/SidebarModal/index.tsx +++ b/src/ui_kit/Sidebar/SidebarModal/index.tsx @@ -22,7 +22,7 @@ export const SidebarModal = ({ onClick={handleClick} sx={{ outline: "none", - overflow: "hidden", + overflow: "auto", maxWidth: "230px", maxHeight: "400px", width: "100%", diff --git a/src/ui_kit/Toolbars/TooltipClickInfo.tsx b/src/ui_kit/Toolbars/TooltipClickInfo.tsx index b95f5384..98d63986 100644 --- a/src/ui_kit/Toolbars/TooltipClickInfo.tsx +++ b/src/ui_kit/Toolbars/TooltipClickInfo.tsx @@ -12,6 +12,7 @@ export default function TooltipClickInfo({ title }: { title: string }) { const handleTooltipOpen = () => { setOpen(true); }; + return ( <> @@ -19,14 +20,21 @@ export default function TooltipClickInfo({ title }: { title: string }) { diff --git a/src/utils/hooks/useAutoPay.ts b/src/utils/hooks/useAutoPay.ts index d0591061..cc46fde5 100644 --- a/src/utils/hooks/useAutoPay.ts +++ b/src/utils/hooks/useAutoPay.ts @@ -6,6 +6,7 @@ import { useEffect } from "react"; import { redirect, useNavigate, useSearchParams } from "react-router-dom"; import { calcTimeOfReadyPayCart, cancelPayCartProcess, startPayCartProcess, useNotEnoughMoneyAmount } from "@/stores/notEnoughMoneyAmount"; import { startCC } from "@/stores/cc"; +import { setEditQuizId, setCurrentStep } from "@root/quizes/actions"; export const useAfterPay = () => { const navigate = useNavigate(); @@ -17,7 +18,19 @@ export const useAfterPay = () => { const purpose = searchParams.get("purpose"); const paymentUserId = searchParams.get("userid"); const currentCC = searchParams.get("cc"); + const wayback = searchParams.get("wayback"); + // Обработка wayback параметра + useEffect(() => { + if (wayback) { + const quizId = wayback.split("_")[1]; + if (quizId) { + setEditQuizId(Number(quizId)); + setCurrentStep(17); // Шаг для персонализации AI + navigate("/personalization-ai"); + } + } + }, [wayback, navigate]); useEffect(() => { //Звёзды сошлись, будем оплачивать корзину @@ -25,7 +38,7 @@ export const useAfterPay = () => { if (purpose === "paycart") { setSearchParams({}, { replace: true }); - if (currentCC) { startCC() } + if (currentCC) startCC() (async () => { //Проверяем можем ли мы оплатить корзину здесь и сейчас diff --git a/src/utils/hooks/useDiscounts.ts b/src/utils/hooks/useDiscounts.ts new file mode 100644 index 00000000..21c71ed9 --- /dev/null +++ b/src/utils/hooks/useDiscounts.ts @@ -0,0 +1,10 @@ +import useSWR from 'swr'; +import { getDiscounts } from '@api/discounts'; +import type { Discount } from '@model/discounts'; + +export const useDiscounts = (userId: string | null) => { + return useSWR( + userId ? `discounts/${userId}` : null, + () => getDiscounts(userId!).then(([data]) => data) + ); +}; \ No newline at end of file diff --git a/src/utils/hooks/useDomainDefine.ts b/src/utils/hooks/useDomainDefine.ts index 73a893b7..ac809abc 100644 --- a/src/utils/hooks/useDomainDefine.ts +++ b/src/utils/hooks/useDomainDefine.ts @@ -11,3 +11,6 @@ export function useDomainDefine(): { isTestServer: boolean } { return { isTestServer }; } + +const host = window.location.hostname; +export const isTestServer = host.includes("s"); \ No newline at end of file diff --git a/src/utils/hooks/useTariffs.ts b/src/utils/hooks/useTariffs.ts new file mode 100644 index 00000000..fd1097d2 --- /dev/null +++ b/src/utils/hooks/useTariffs.ts @@ -0,0 +1,19 @@ +import useSWR from 'swr'; +import { getTariffs } from '@/api/tariff'; +import type { GetTariffsResponse, Tariff } from '@frontend/kitui'; + +export const useTariffs = () => { + const { data, error, isLoading } = useSWR('tariffs', async () => { + const [response] = await getTariffs(); + if (response?.tariffs) { + return response.tariffs; + } + return []; + }); + + return { + data, + error, + isLoading + }; +}; \ No newline at end of file diff --git a/src/utils/hooks/useUser.ts b/src/utils/hooks/useUser.ts new file mode 100644 index 00000000..3d734315 --- /dev/null +++ b/src/utils/hooks/useUser.ts @@ -0,0 +1,7 @@ +import useSWR from 'swr'; +import { getUser } from '@api/user'; +import type { User } from '@frontend/kitui'; + +export const useUser = () => { + return useSWR('user', getUser); +}; \ No newline at end of file diff --git a/src/utils/hooks/useUserAccountFetcher.ts b/src/utils/hooks/useUserAccountFetcher.ts index add6d374..f057114f 100644 --- a/src/utils/hooks/useUserAccountFetcher.ts +++ b/src/utils/hooks/useUserAccountFetcher.ts @@ -1,9 +1,7 @@ import { useEffect, useLayoutEffect, useRef } from "react"; import { createUserAccount, devlog } from "@frontend/kitui"; import { isAxiosError } from "axios"; - import { makeRequest } from "@api/makeRequest"; - import type { UserAccount } from "@frontend/kitui"; import { setUserAccount } from "@/stores/user"; @@ -20,10 +18,12 @@ export const useUserAccountFetcher = ({ }) => { const onNewUserAccountRef = useRef(onNewUserAccount); const onErrorRef = useRef(onError); + useLayoutEffect(() => { onNewUserAccountRef.current = onNewUserAccount; onErrorRef.current = onError; }, [onError, onNewUserAccount]); + useEffect(() => { if (!userId) return; const controller = new AbortController(); diff --git a/yarn.lock b/yarn.lock index 976cdd04..00050294 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1235,7 +1235,39 @@ resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== -"@emoji-mart/data@^1.1.2": +"@cypress/request@^3.0.8": + version "3.0.8" + resolved "https://registry.npmjs.org/@cypress/request/-/request-3.0.8.tgz#992f1f42ba03ebb14fa5d97290abe9d015ed0815" + integrity sha512-h0NFgh1mJmm1nr4jCwkGHwKneVYKghUyWe6TMNrk0B9zsjAJxpg8C4/+BAcmLgCPa1vj1V8rNUaILl+zYRUWBQ== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~4.0.0" + http-signature "~1.4.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + performance-now "^2.1.0" + qs "6.14.0" + safe-buffer "^5.1.2" + tough-cookie "^5.0.0" + tunnel-agent "^0.6.0" + uuid "^8.3.2" + +"@cypress/xvfb@^1.2.4": + version "1.2.4" + resolved "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== + dependencies: + debug "^3.1.0" + lodash.once "^4.1.1" + +"@emoji-mart/data@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@emoji-mart/data/-/data-1.2.1.tgz#0ad70c662e3bc603e23e7d98413bd1e64c4fcb6c" integrity sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw== @@ -1411,10 +1443,10 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429" integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg== -"@frontend/kitui@^1.0.88": - version "1.0.92" - resolved "http://gitea.pena/api/packages/skeris/npm/%40frontend%2Fkitui/-/1.0.92/kitui-1.0.92.tgz#9e75e1d0b3dbcc8744aea0402f40416d7a540c73" - integrity sha512-r/+rJbo63XpaivtMalZ0x5rxj3oIfLWQxJ3OqvohFVy+JF/e2FEgePVl2BvomcjYDeTM1eJru+nmvzONdMTfCA== +"@frontend/kitui@^1.0.108": + version "1.0.108" + resolved "http://gitea.pena/api/packages/skeris/npm/%40frontend%2Fkitui/-/1.0.108/kitui-1.0.108.tgz#1bb609dfe07668b6fd9a7b8618c229e0bb609f1e" + integrity sha512-4DiF7GHX0RbBMZpFioclc3B87N+HrGLv1B3DveUCdHzukfxvFXyEKnRZQ4wYljO2A3FLSD9+4Dr6cSuZYw95OQ== dependencies: immer "^10.0.2" reconnecting-eventsource "^1.6.2" @@ -2346,6 +2378,13 @@ dependencies: "@types/node" "*" +"@types/cypress@^1.1.6": + version "1.1.6" + resolved "https://registry.npmjs.org/@types/cypress/-/cypress-1.1.6.tgz#b190688acffb847a3f5c4cee15c82d4f2a342ee6" + integrity sha512-CfeLLD3+6vIWe2AO5hR63f1c8EbRzrp/j1ExubAwOTpwZFZvF3Nm9cOPQiUwzNmAUmZuhO0QVH98Qlujni6nPw== + dependencies: + cypress "*" + "@types/cytoscape-popper@^2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/cytoscape-popper/-/cytoscape-popper-2.0.4.tgz#cd1e81d28b202e2bfc5608e0e60ae53c908bf0e3" @@ -2680,6 +2719,16 @@ "@types/node" "*" "@types/send" "*" +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== + +"@types/sizzle@^2.3.2": + version "2.3.9" + resolved "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz#d4597dbd4618264c414d7429363e3f50acb66ea2" + integrity sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w== + "@types/sockjs@^0.3.33": version "0.3.36" resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" @@ -2730,6 +2779,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yauzl@^2.9.1": + version "2.10.3" + resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999" + integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q== + dependencies: + "@types/node" "*" + "@typescript-eslint/eslint-plugin@^5.5.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" @@ -3025,6 +3081,14 @@ agent-base@6: dependencies: debug "4" +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -3064,7 +3128,12 @@ ajv@^8.0.0, ajv@^8.6.0, ajv@^8.9.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" -ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -3135,6 +3204,11 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -3287,17 +3361,34 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + ast-types-flow@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + async-function@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b" integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA== -async@^3.2.3: +async@^3.2.0, async@^3.2.3: version "3.2.6" resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== @@ -3331,6 +3422,16 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.13.2" + resolved "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz#0aa167216965ac9474ccfa83892cfb6b3e1e52ef" + integrity sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw== + axe-core@^4.10.0: version "4.10.3" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.3.tgz#04145965ac7894faddbac30861e5d8f11bfd14fc" @@ -3495,11 +3596,23 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + bfj@^7.0.2: version "7.1.0" resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.1.0.tgz#c5177d522103f9040e1b12980fe8c38cf41d3f8b" @@ -3521,6 +3634,11 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== +blob-util@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" + integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== + bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -3606,11 +3724,24 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@^5.7.1: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + builtin-modules@^3.1.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" @@ -3621,6 +3752,11 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cachedir@^2.3.0: + version "2.4.0" + resolved "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d" + integrity sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ== + call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" @@ -3695,6 +3831,11 @@ case-sensitive-paths-webpack-plugin@^2.4.0: resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3735,6 +3876,11 @@ char-regex@^2.0.0: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.2.tgz#81385bb071af4df774bff8721d0ca15ef29ea0bb" integrity sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg== +check-more-types@^2.24.0: + version "2.24.0" + resolved "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== + check-types@^11.2.3: version "11.2.3" resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.3.tgz#1ffdf68faae4e941fce252840b1787b8edc93b71" @@ -3765,6 +3911,11 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== +ci-info@^4.1.0: + version "4.2.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz#cbd21386152ebfe1d56f280a3b5feccbd96764c7" + integrity sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg== + cjs-module-lexer@^1.0.0: version "1.4.3" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" @@ -3782,6 +3933,18 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + cli-cursor@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" @@ -3789,6 +3952,23 @@ cli-cursor@^5.0.0: dependencies: restore-cursor "^5.0.0" +cli-table3@0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz#36ce9b7af4847f288d3cdd081fbd09bf7bd237b8" + integrity sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA== + dependencies: + string-width "^4.2.0" + optionalDependencies: + colors "1.4.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + cli-truncate@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-4.0.0.tgz#6cc28a2924fee9e25ce91e973db56c7066e6172a" @@ -3882,12 +4062,17 @@ colord@^2.9.1: resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== -colorette@^2.0.10, colorette@^2.0.20: +colorette@^2.0.10, colorette@^2.0.16, colorette@^2.0.20: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== -combined-stream@^1.0.8: +colors@1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -3909,6 +4094,11 @@ commander@^4.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" @@ -4013,6 +4203,11 @@ core-js@^3.19.2: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.41.0.tgz#57714dafb8c751a6095d028a7428f1fb5834a776" integrity sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA== +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -4068,7 +4263,7 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -4289,6 +4484,55 @@ current-device@^0.10.2: resolved "https://registry.yarnpkg.com/current-device/-/current-device-0.10.2.tgz#1e40176bee7da655383ab7245b853fae7d2dfc8e" integrity sha512-FN223n2Cp1fRI/gyjJEAdagHhJ/2Z2STz3tUg1t4F259BhmVRCChkmxcgFtjYJsWuIacQEs7bqJpnAczIXIkWw== +cypress@*, cypress@^14.4.1: + version "14.4.1" + resolved "https://registry.npmjs.org/cypress/-/cypress-14.4.1.tgz#6e586ba098503b594561d5f8f746a9db6556ed2a" + integrity sha512-YSGvVXtTqSGRTyHbaxHI5dHU/9xc5ymaTIM4BU85GKhj980y6XgA3fShSpj5DatS8knXMsAvYItQxVQFHGpUtw== + dependencies: + "@cypress/request" "^3.0.8" + "@cypress/xvfb" "^1.2.4" + "@types/sinonjs__fake-timers" "8.1.1" + "@types/sizzle" "^2.3.2" + arch "^2.2.0" + blob-util "^2.0.2" + bluebird "^3.7.2" + buffer "^5.7.1" + cachedir "^2.3.0" + chalk "^4.1.0" + check-more-types "^2.24.0" + ci-info "^4.1.0" + cli-cursor "^3.1.0" + cli-table3 "0.6.1" + commander "^6.2.1" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.4" + enquirer "^2.3.6" + eventemitter2 "6.4.7" + execa "4.1.0" + executable "^4.1.1" + extract-zip "2.0.1" + figures "^3.2.0" + fs-extra "^9.1.0" + getos "^3.2.1" + is-installed-globally "~0.4.0" + lazy-ass "^1.6.0" + listr2 "^3.8.3" + lodash "^4.17.21" + log-symbols "^4.0.0" + minimist "^1.2.8" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + process "^0.11.10" + proxy-from-env "1.0.0" + request-progress "^3.0.0" + semver "^7.7.1" + supports-color "^8.1.1" + tmp "~0.2.3" + tree-kill "1.2.2" + untildify "^4.0.0" + yauzl "^2.10.0" + cytoscape-popper@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/cytoscape-popper/-/cytoscape-popper-2.0.0.tgz#d93917695a9b8af3dbda1d8ee433618ac4d4e359" @@ -4367,6 +4611,13 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -4408,6 +4659,11 @@ date-fns@^3.0.6: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf" integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== +dayjs@^1.10.4: + version "1.11.13" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" + integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== + debug@2.6.9, debug@^2.6.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -4422,7 +4678,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, d dependencies: ms "^2.1.3" -debug@^3.2.7: +debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -4728,6 +4984,14 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4790,6 +5054,13 @@ encodeurl@~2.0.0: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== +end-of-stream@^1.1.0: + version "1.4.5" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" + integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== + dependencies: + once "^1.4.0" + enhanced-resolve@^5.17.1: version "5.18.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" @@ -4803,6 +5074,14 @@ enquire.js@^2.1.6: resolved "https://registry.yarnpkg.com/enquire.js/-/enquire.js-2.1.6.tgz#3e8780c9b8b835084c3f60e166dbc3c2a3c89814" integrity sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw== +enquirer@^2.3.6: + version "2.4.1" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -5294,6 +5573,11 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +eventemitter2@6.4.7: + version "6.4.7" + resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== + eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -5309,6 +5593,21 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +execa@4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -5339,6 +5638,13 @@ execa@^8.0.1: signal-exit "^4.1.0" strip-final-newline "^3.0.0" +executable@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -5402,6 +5708,32 @@ express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -5454,6 +5786,20 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +figures@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -5582,6 +5928,11 @@ foreground-child@^3.1.0: cross-spawn "^7.0.6" signal-exit "^4.0.1" +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.3" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" @@ -5621,6 +5972,17 @@ form-data@^4.0.0: es-set-tostringtag "^2.1.0" mime-types "^2.1.12" +form-data@~4.0.0: + version "4.0.3" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz#608b1b3f3e28be0fccf5901fc85fb3641e5cf0ae" + integrity sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + hasown "^2.0.2" + mime-types "^2.1.12" + formik@^2.4.5: version "2.4.6" resolved "https://registry.yarnpkg.com/formik/-/formik-2.4.6.tgz#4da75ca80f1a827ab35b08fd98d5a76e928c9686" @@ -5659,7 +6021,7 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0, fs-extra@^9.0.1: +fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -5755,6 +6117,13 @@ get-proto@^1.0.0, get-proto@^1.0.1: dunder-proto "^1.0.1" es-object-atoms "^1.0.0" +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -5774,6 +6143,20 @@ get-symbol-description@^1.1.0: es-errors "^1.3.0" get-intrinsic "^1.2.6" +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== + dependencies: + async "^3.2.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -5817,6 +6200,13 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== + dependencies: + ini "2.0.0" + global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -6098,6 +6488,15 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-signature@~1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz#dee5a9ba2bf49416abc544abd6d967f6a94c8c3f" + integrity sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg== + dependencies: + assert-plus "^1.0.0" + jsprim "^2.0.2" + sshpk "^1.18.0" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -6106,6 +6505,11 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -6152,6 +6556,11 @@ identity-obj-proxy@^3.0.0: dependencies: harmony-reflect "^1.4.6" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^5.2.0: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" @@ -6223,6 +6632,11 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + ini@^1.3.5: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" @@ -6406,6 +6820,14 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-installed-globally@~0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + is-map@^2.0.2, is-map@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" @@ -6434,7 +6856,7 @@ is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== -is-path-inside@^3.0.3: +is-path-inside@^3.0.2, is-path-inside@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -6522,11 +6944,16 @@ is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15: dependencies: which-typed-array "^1.1.16" -is-typedarray@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-weakmap@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" @@ -6574,6 +7001,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" @@ -7206,6 +7638,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" @@ -7269,7 +7706,7 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@^0.4.0: +json-schema@0.4.0, json-schema@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== @@ -7279,6 +7716,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + json2mq@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/json2mq/-/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a" @@ -7321,6 +7763,16 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== +jsprim@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" + integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -7383,6 +7835,11 @@ launch-editor@^2.6.0: picocolors "^1.0.0" shell-quote "^1.8.1" +lazy-ass@^1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -7447,6 +7904,20 @@ lint-staged@^15.2.0: string-argv "^0.3.2" yaml "^2.7.0" +listr2@^3.8.3: + version "3.14.0" + resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" + integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" + listr2@^8.2.5: version "8.2.5" resolved "https://registry.yarnpkg.com/listr2/-/listr2-8.2.5.tgz#5c9db996e1afeb05db0448196d3d5f64fec2593d" @@ -7520,6 +7991,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -7535,6 +8011,24 @@ lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-symbols@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + log-update@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.1.0.tgz#1a04ff38166f94647ae1af562f4bd6a15b1b7cd4" @@ -7680,7 +8174,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@^2.1.35, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@^2.1.35, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -7746,7 +8240,7 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -7894,7 +8388,7 @@ notistack@^3.0.1: clsx "^1.1.0" goober "^2.0.33" -npm-run-path@^4.0.1: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -8036,14 +8530,14 @@ on-headers@~1.0.2: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -onetime@^5.1.2: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -8097,6 +8591,11 @@ optionator@^0.9.3: type-check "^0.4.0" word-wrap "^1.2.5" +ospath@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== + own-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358" @@ -8141,6 +8640,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-retry@^4.5.0: version "4.6.2" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" @@ -8255,6 +8761,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -8280,7 +8791,7 @@ pidtree@^0.6.0: resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== -pify@^2.3.0: +pify@^2.2.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== @@ -8884,7 +9395,7 @@ prettier@^3.1.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.3.tgz#4fc2ce0d657e7a02e602549f053b239cb7dfe1b5" integrity sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw== -pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1, pretty-bytes@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== @@ -8930,6 +9441,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise@^8.1.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" @@ -8967,6 +9483,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -8979,6 +9500,14 @@ psl@^1.1.33: dependencies: punycode "^2.3.1" +pump@^3.0.0: + version "3.0.3" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d" + integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -8996,6 +9525,13 @@ qs@6.13.0: dependencies: side-channel "^1.0.6" +qs@6.14.0: + version "6.14.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" + integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== + dependencies: + side-channel "^1.1.0" + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" @@ -9526,6 +10062,13 @@ renderkid@^3.0.0: lodash "^4.17.21" strip-ansi "^6.0.1" +request-progress@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" + integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg== + dependencies: + throttleit "^1.0.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -9597,6 +10140,14 @@ resolve@^2.0.0-next.5: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + restore-cursor@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-5.1.0.tgz#0766d95699efacb14150993f55baf0953ea1ebe7" @@ -9615,7 +10166,7 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== -rfdc@^1.4.1: +rfdc@^1.3.0, rfdc@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== @@ -9651,6 +10202,13 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +rxjs@^7.5.1: + version "7.8.2" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" + integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== + dependencies: + tslib "^2.1.0" + safe-array-concat@^1.1.2, safe-array-concat@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" @@ -9662,7 +10220,7 @@ safe-array-concat@^1.1.2, safe-array-concat@^1.1.3: has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -9689,7 +10247,7 @@ safe-regex-test@^1.0.3, safe-regex-test@^1.1.0: es-errors "^1.3.0" is-regex "^1.2.1" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -9786,6 +10344,11 @@ semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== +semver@^7.7.1: + version "7.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + send@0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" @@ -9982,6 +10545,24 @@ slash@^4.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + slice-ansi@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" @@ -10094,6 +10675,21 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sshpk@^1.18.0: + version "1.18.0" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -10381,7 +10977,7 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: +supports-color@^8.0.0, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -10571,6 +11167,16 @@ throat@^6.0.1: resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== +throttleit@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz#304ec51631c3b770c65c6c6f76938b384000f4d5" + integrity sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ== + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" @@ -10591,6 +11197,23 @@ tiny-warning@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tldts-core@^6.1.86: + version "6.1.86" + resolved "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz#a93e6ed9d505cb54c542ce43feb14c73913265d8" + integrity sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA== + +tldts@^6.1.32: + version "6.1.86" + resolved "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz#087e0555b31b9725ee48ca7e77edc56115cd82f7" + integrity sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ== + dependencies: + tldts-core "^6.1.86" + +tmp@~0.2.3: + version "0.2.3" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -10623,6 +11246,13 @@ tough-cookie@^4.0.0: universalify "^0.2.0" url-parse "^1.5.3" +tough-cookie@^5.0.0: + version "5.1.2" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz#66d774b4a1d9e12dc75089725af3ac75ec31bed7" + integrity sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A== + dependencies: + tldts "^6.1.32" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -10644,6 +11274,11 @@ transliteration@^2.3.5: dependencies: yargs "^17.5.1" +tree-kill@1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + tryer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" @@ -10693,7 +11328,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -10705,6 +11340,18 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -10884,6 +11531,11 @@ unquote@~1.1.1: resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" @@ -10976,6 +11628,15 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +verror@1.10.0: + version "1.10.0" + resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -11450,6 +12111,15 @@ workbox-window@6.6.1: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" @@ -11559,6 +12229,14 @@ yargs@^17.5.1: y18n "^5.0.5" yargs-parser "^21.1.1" +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"