diff --git a/apps/dashboard/src/main/java/com/akto/action/HomeAction.java b/apps/dashboard/src/main/java/com/akto/action/HomeAction.java index 9d52698ebf..5477201b90 100644 --- a/apps/dashboard/src/main/java/com/akto/action/HomeAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/HomeAction.java @@ -50,6 +50,12 @@ public String verifyEmail(){ @Override public String execute() { + try { + String nodeEnv = System.getenv("NODE_ENV"); + servletRequest.setAttribute("nodeEnv", nodeEnv != null ? nodeEnv : "production"); + } catch(Exception e){ + } + servletRequest.setAttribute("isSaas", InitializerListener.isSaas); if(DashboardMode.isOnPremDeployment()){ if (GithubLogin.getGithubUrl() != null) { @@ -93,7 +99,6 @@ public String execute() { } return redirectToAuth0(servletRequest, servletResponse, accessToken, new BasicDBObject()); } - // Use existing flow return "SUCCESS"; } diff --git a/apps/dashboard/src/main/java/com/akto/action/agents/AgentAction.java b/apps/dashboard/src/main/java/com/akto/action/agents/AgentAction.java new file mode 100644 index 0000000000..60ba9fb1b9 --- /dev/null +++ b/apps/dashboard/src/main/java/com/akto/action/agents/AgentAction.java @@ -0,0 +1,461 @@ +package com.akto.action.agents; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.bson.conversions.Bson; + +import com.akto.action.UserAction; +import com.akto.dao.agents.AgentRunDao; +import com.akto.dao.agents.AgentSubProcessSingleAttemptDao; +import com.akto.dao.context.Context; +import com.akto.dto.agents.*; +import com.amazonaws.util.StringUtils; +import com.mongodb.BasicDBObject; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Projections; +import com.mongodb.client.model.Updates; +import com.opensymphony.xwork2.Action; + +public class AgentAction extends UserAction { + + Map data; + String agent; + + List agentRuns; + + public String getAllAgentRuns() { + Bson filter = Filters.eq(AgentRun._STATE, State.RUNNING); + if(!StringUtils.isNullOrEmpty(this.agent)){ + filter = Filters.and(filter, Filters.eq("agent", agent)); + } + agentRuns = AgentRunDao.instance.findAll(filter); + return Action.SUCCESS.toUpperCase(); + } + + private static final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + + public String createAgentRun() { + + if (data == null || data.isEmpty()) { + addActionError("Agent Init document is empty"); + return Action.ERROR.toUpperCase(); + } + + if (agent == null || agent.isEmpty()) { + addActionError("Agent is empty"); + return Action.ERROR.toUpperCase(); + } + + Agent agentModule; + try { + agentModule = Agent.valueOf(agent); + } catch (Exception e) { + addActionError("Invalid agent"); + return Action.ERROR.toUpperCase(); + } + + AgentRun existingScheduledOrRunningRuns = AgentRunDao.instance.findOne(Filters.in( + AgentRun._STATE, Arrays.asList(State.SCHEDULED, State.RUNNING))); + + if (existingScheduledOrRunningRuns != null) { + addActionError("An existing agent run is running or scheduled. " + + "Let it complete or stop it before starting another"); + return Action.ERROR.toUpperCase(); + } + + String processId = UUID.randomUUID().toString(); + + agentRun = new AgentRun(processId, data, agentModule, + Context.now(), 0, 0, State.SCHEDULED); + AgentRunDao.instance.insertOne(agentRun); + + // TODO: Use health check for dashboard to trigger the agent module. + int accountId = Context.accountId.get(); + executorService.schedule( new Runnable() { + public void run() { + Context.accountId.set(accountId); + try { + AgentRunDao.instance.updateOne( + Filters.eq(AgentRun.PROCESS_ID, processId), + Updates.combine( + Updates.setOnInsert(AgentRun.START_TIMESTAMP, Context.now()), + Updates.set(AgentRun._STATE, State.RUNNING) + ) + ); + } catch (Exception e) { + e.printStackTrace(); + } + } + }, 5 , TimeUnit.SECONDS); + + return Action.SUCCESS.toUpperCase(); + } + + public String updateAgentRun() { + State updatedState = null; + try { + updatedState = State.valueOf(state); + } catch (Exception e) { + } + + if (updatedState != null) { + List updates = new ArrayList<>(); + updates.add(Updates.set(AgentRun._STATE, updatedState)); + if (updatedState.equals(State.COMPLETED)) { + updates.add(Updates.set(AgentRun.END_TIMESTAMP, Context.now())); + } + AgentRunDao.instance.updateOne( + Filters.eq(AgentRun.PROCESS_ID, processId), + Updates.combine(updates)); + } + return Action.SUCCESS.toUpperCase(); + } + + Agent[] agents; + + AgentRun agentRun; + + String processId; + String subProcessId; + int attemptId; + String state; + + AgentSubProcessSingleAttempt subprocess; + + public String getMemberAgents() { + agents = Agent.values(); + return Action.SUCCESS.toUpperCase(); + } + + Model[] models; + + public String getAgentModels() { + models = Model.values(); + return Action.SUCCESS.toUpperCase(); + } + + List subProcesses; + + public String getAllSubProcesses() { + if (processId == null || processId.isEmpty()) { + addActionError("Process id is invalid"); + return Action.ERROR.toUpperCase(); + } + Bson processIdFilter = Filters.eq(AgentRun.PROCESS_ID, processId); + + agentRun = AgentRunDao.instance.findOne(processIdFilter); + + if (agentRun == null) { + addActionError("No process found"); + return Action.ERROR.toUpperCase(); + } + + subProcesses = AgentSubProcessSingleAttemptDao.instance.findAll(processIdFilter); + return Action.SUCCESS.toUpperCase(); + } + + public String getSubProcess() { + + if (processId == null || processId.isEmpty()) { + addActionError("Process id is invalid"); + return Action.ERROR.toUpperCase(); + } + + Bson processIdFilter = Filters.eq(AgentRun.PROCESS_ID, processId); + + agentRun = AgentRunDao.instance.findOne(processIdFilter); + + if (agentRun == null) { + addActionError("No process found"); + return Action.ERROR.toUpperCase(); + } + + Bson filter = Filters.and( + Filters.eq(AgentSubProcessSingleAttempt.PROCESS_ID, this.processId.toString()), + Filters.eq(AgentSubProcessSingleAttempt.SUB_PROCESS_ID, this.subProcessId), + Filters.eq(AgentSubProcessSingleAttempt.ATTEMPT_ID, this.attemptId) + ); + subprocess = AgentSubProcessSingleAttemptDao.instance.findOne(filter); + + return Action.SUCCESS.toUpperCase(); + + } + + public String updateAgentSubprocess() { + + if (processId == null || processId.isEmpty()) { + addActionError("Process id is invalid"); + return Action.ERROR.toUpperCase(); + } + + Bson processIdFilter = Filters.eq(AgentRun.PROCESS_ID, processId); + + agentRun = AgentRunDao.instance.findOne(processIdFilter); + + if (agentRun == null) { + addActionError("No process found"); + return Action.ERROR.toUpperCase(); + } + + Bson filter = Filters.and( + Filters.eq(AgentSubProcessSingleAttempt.PROCESS_ID, this.processId), + Filters.eq(AgentSubProcessSingleAttempt.SUB_PROCESS_ID, this.subProcessId), + Filters.eq(AgentSubProcessSingleAttempt.ATTEMPT_ID, this.attemptId) + ); + + List updates = new ArrayList<>(); + + updates.add(Updates.setOnInsert(AgentSubProcessSingleAttempt.CREATED_TIMESTAMP, Context.now())); + + State updatedState = null; + try { + updatedState = State.valueOf(state); + } catch (Exception e) { + } + + if (updatedState != null) { + AgentSubProcessSingleAttempt subProcess = AgentSubProcessSingleAttemptDao.instance.findOne(filter); + if (subProcess == null) { + addActionError("No subprocess found"); + return Action.ERROR.toUpperCase(); + } + + if (State.COMPLETED.equals(subProcess.getState()) + && (State.ACCEPTED.equals(updatedState) || + State.DISCARDED.equals(updatedState) || + State.USER_PROVIDED_SOLUTION.equals(updatedState) || + State.RE_ATTEMPT.equals(updatedState))) { + updates.add(Updates.set(AgentSubProcessSingleAttempt._STATE, updatedState)); + + } else { + addActionError("Invalid state"); + return Action.ERROR.toUpperCase(); + } + + // TODO: handle more state conditions + }else { + updates.add(Updates.setOnInsert(AgentSubProcessSingleAttempt._STATE, State.SCHEDULED)); + } + + /* + * For a new subprocess. + */ + if (data != null) { + updates.add(Updates.set(AgentSubProcessSingleAttempt.USER_INPUT, data)); + } + + /* + * Upsert: true. + * Since state management is through dashboard, + * all subprocess' are created here and only modified using the agent-module + */ + subprocess = AgentSubProcessSingleAttemptDao.instance.updateOne(filter, Updates.combine(updates)); + + return Action.SUCCESS.toUpperCase(); + } + + String subProcessHeading; + + public String getSubProcessHeading() { + return subProcessHeading; + } + + public void setSubProcessHeading(String subProcessHeading) { + this.subProcessHeading = subProcessHeading; + } + + BasicDBObject response; + public String feedDataToAgent(){ + try { + AgentRun agentRun = AgentRunDao.instance.findOne(Filters.eq(AgentRun._STATE, State.SCHEDULED.toString())); + response = new BasicDBObject(); + if(agentRun != null){ + // case 1: info about the agent as the agent is just triggered + response.put("type", "init"); + response.put("data", agentRun); + }else{ + // case 2: info about the agent as the agent is running + AgentRun agentRunRunning = AgentRunDao.instance.findOne(Filters.eq(AgentRun._STATE, State.RUNNING.toString()), Projections.include(AgentRun.PROCESS_ID)); + if(agentRunRunning != null){ + response.put("type", "subTask"); + // get subprocess data of the latest one only, i am assuming that if chosen retry attempt, the data of later will get cleaned up from mongo, the new one would be inserted + AgentSubProcessSingleAttempt subprocess = AgentSubProcessSingleAttemptDao.instance.findLatestOne(Filters.eq(AgentSubProcessSingleAttempt.PROCESS_ID, agentRunRunning.getProcessId())); + response.put("data", subprocess); + } + + // else case is nothing is running or scheduled, hence empty object is sufficient for + } + } catch (Exception e) { + e.printStackTrace(); + return ERROR.toUpperCase(); + } + + return SUCCESS.toUpperCase(); + } + + String type; + public void setType(String type) { + this.type = type; + } + + List logs; + + public void setLogs(List logs) { + this.logs = logs; + } + + public String receiveDataFromAgent(){ + response = new BasicDBObject(); + Bson filter = Filters.and( + Filters.eq(AgentSubProcessSingleAttempt.PROCESS_ID, this.processId), + Filters.eq(AgentSubProcessSingleAttempt.SUB_PROCESS_ID, this.subProcessId), + Filters.eq(AgentSubProcessSingleAttempt.ATTEMPT_ID, this.attemptId) + ); + switch (type) { + case "logs": + AgentSubProcessSingleAttemptDao.instance.updateOne( + filter, + Updates.addEachToSet(AgentSubProcessSingleAttempt._LOGS, this.logs) + ); + break; + + case "stateChange": + State state = State.valueOf(this.state); + + Bson update = Updates.set(AgentSubProcessSingleAttempt._STATE, state); + if(this.data != null && !this.data.isEmpty()){ + update = Updates.combine( + update, + Updates.set(AgentSubProcessSingleAttempt.PROCESS_OUTPUT, this.data) + ); + } + try { + AgentSubProcessSingleAttemptDao.instance.updateOne( + filter, + update + ); + } catch (Exception e) { + e.printStackTrace(); + return ERROR.toUpperCase(); + } + break; + case "subProcessHeading": + AgentSubProcessSingleAttemptDao.instance.updateOne( + filter, + Updates.set(AgentSubProcessSingleAttempt.SUB_PROCESS_HEADING, subProcessHeading) + ); + break; + default: + break; + } + response.put("success", "200 ok"); + return SUCCESS.toUpperCase(); + } + + public List getAgentRuns() { + return agentRuns; + } + + public void setAgentRuns(List agentRuns) { + this.agentRuns = agentRuns; + } + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + + public String getAgent() { + return agent; + } + + public void setAgent(String agent) { + this.agent = agent; + } + + public Agent[] getAgents() { + return agents; + } + + public void setAgents(Agent[] agents) { + this.agents = agents; + } + + public AgentRun getAgentRun() { + return agentRun; + } + + public void setAgentRun(AgentRun agentRun) { + this.agentRun = agentRun; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getSubProcessId() { + return subProcessId; + } + + public void setSubProcessId(String subProcessId) { + this.subProcessId = subProcessId; + } + + public int getAttemptId() { + return attemptId; + } + + public void setAttemptId(int attemptId) { + this.attemptId = attemptId; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public AgentSubProcessSingleAttempt getSubprocess() { + return subprocess; + } + + public void setSubprocess(AgentSubProcessSingleAttempt subprocess) { + this.subprocess = subprocess; + } + + public List getSubProcesses() { + return subProcesses; + } + + public void setSubProcesses(List subProcesses) { + this.subProcesses = subProcesses; + } + + public Model[] getModels() { + return models; + } + + public void setModels(Model[] models) { + this.models = models; + } + + public BasicDBObject getResponse() { + return response; + } + +} diff --git a/apps/dashboard/src/main/java/com/akto/action/agents/AgentHelperAction.java b/apps/dashboard/src/main/java/com/akto/action/agents/AgentHelperAction.java new file mode 100644 index 0000000000..b2c41e61a1 --- /dev/null +++ b/apps/dashboard/src/main/java/com/akto/action/agents/AgentHelperAction.java @@ -0,0 +1,131 @@ +package com.akto.action.agents; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import com.akto.action.CustomDataTypeAction; +import com.akto.action.UserAction; +import com.akto.action.CustomDataTypeAction.ConditionFromUser; +import com.akto.dao.SampleDataDao; +import com.akto.dao.context.Context; +import com.akto.dto.data_types.Predicate.Type; +import com.akto.dto.traffic.SampleData; +import com.akto.util.enums.GlobalEnums.Severity; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Sorts; +import com.opensymphony.xwork2.Action; + +public class AgentHelperAction extends UserAction { + + int skip; + int apiCollectionId; + int limit; + SampleData sample; + + public String fetchAllResponsesForApiCollectionOrdered() { + + limit = Math.min(Math.max(1, limit), 10); + skip = Math.max(0, skip); + + List sampleData = SampleDataDao.instance.findAll(Filters.eq( + "_id.apiCollectionId", apiCollectionId), skip, limit, Sorts.descending("_id")); + + if (sampleData.isEmpty()) { + addActionError("sample data not found"); + return Action.ERROR.toUpperCase(); + } + + /* + * TODO: optimise this to send only samples which are actually different, + * i.e. contain different parameters + */ + sample = sampleData.get(0); + return Action.SUCCESS.toUpperCase(); + } + + List dataTypeKeys; + + private static final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + + public String createSensitiveResponseDataTypes(){ + + int accountId = Context.accountId.get(); + Map session = getSession(); + + final String NAME_PREFIX = "DATA_TYPE_"; + executorService.schedule( new Runnable() { + public void run() { + try { + Context.accountId.set(accountId); + for(String datatype: dataTypeKeys){ + Map valueMap = new HashMap<>(); + valueMap.put("value", datatype); + ConditionFromUser conditionFromUser = new ConditionFromUser(Type.EQUALS_TO, valueMap); + CustomDataTypeAction customDataTypeAction = new CustomDataTypeAction(); + customDataTypeAction.setKeyConditionFromUsers(Arrays.asList(conditionFromUser)); + customDataTypeAction.setKeyOperator("OR"); + customDataTypeAction.setValueOperator("OR"); + customDataTypeAction.setOperator("OR"); + customDataTypeAction.setName(NAME_PREFIX+datatype); + customDataTypeAction.setRedacted(false); + customDataTypeAction.setSensitiveAlways(false); + customDataTypeAction.setSensitivePosition(Arrays.asList("RESPONSE_PAYLOAD", "RESPONSE_HEADER")); + customDataTypeAction.setActive(true); + customDataTypeAction.setCreateNew(true); + customDataTypeAction.setDataTypePriority(Severity.MEDIUM); + customDataTypeAction.setSession(session); + customDataTypeAction.execute(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }, 0 , TimeUnit.SECONDS); + return Action.SUCCESS.toUpperCase(); + } + + public List getDataTypeKeys() { + return dataTypeKeys; + } + + public void setDataTypeKeys(List dataTypeKeys) { + this.dataTypeKeys = dataTypeKeys; + } + + public int getSkip() { + return skip; + } + + public void setSkip(int skip) { + this.skip = skip; + } + + public int getApiCollectionId() { + return apiCollectionId; + } + + public void setApiCollectionId(int apiCollectionId) { + this.apiCollectionId = apiCollectionId; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public SampleData getSample() { + return sample; + } + + public void setSample(SampleData sample) { + this.sample = sample; + } +} diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index dce752135e..aff034f8d0 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -8205,6 +8205,317 @@ + + + + + AI_AGENTS + READ_WRITE + Create an agent run + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ_WRITE + Update an agent run + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + true + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + true + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + AI_AGENTS + READ + + + 403 + false + ^actionErrors.* + + + AI_AGENTS + + + + 422 + false + ^actionErrors.* + + + 403 + false + ^actionErrors.* + + + + + + + + response + + + 422 + false + ^actionErrors.* + + + + + + + + + + 422 + false + ^actionErrors.* + + + \ No newline at end of file diff --git a/apps/dashboard/web/pages/login.jsp b/apps/dashboard/web/pages/login.jsp index 2a38088e38..8a47324bcc 100644 --- a/apps/dashboard/web/pages/login.jsp +++ b/apps/dashboard/web/pages/login.jsp @@ -20,6 +20,7 @@ + diff --git a/apps/dashboard/web/polaris_web/.babelrc b/apps/dashboard/web/polaris_web/.babelrc index d5e9936eb6..a9dd57ced3 100644 --- a/apps/dashboard/web/polaris_web/.babelrc +++ b/apps/dashboard/web/polaris_web/.babelrc @@ -1,4 +1,11 @@ { - "presets": ["@babel/preset-env", "@babel/preset-react"], - "plugins": ["@babel/plugin-proposal-object-rest-spread","@babel/plugin-transform-runtime"] + "presets": [ + "@babel/preset-env", + ["@babel/preset-react", {"runtime": "automatic"}], + "@babel/preset-typescript" + ], + "plugins": [ + "@babel/plugin-proposal-object-rest-spread", + "@babel/plugin-transform-runtime" + ] } \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/package-lock.json b/apps/dashboard/web/polaris_web/package-lock.json index b6a7e720ad..49b4f4c7e4 100644 --- a/apps/dashboard/web/polaris_web/package-lock.json +++ b/apps/dashboard/web/polaris_web/package-lock.json @@ -14,17 +14,23 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@mui/material": "^5.9.2", "@mui/x-date-pickers": "^5.0.0", + "@radix-ui/react-select": "^2.1.6", "@shopify/polaris": "^11.2.1", "@stigg/react-sdk": "^4.8.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "@tiptap/extension-placeholder": "^2.11.5", + "@tiptap/react": "^2.11.5", + "@tiptap/starter-kit": "^2.11.5", "assert": "^2.1.0", "axios": "^1.4.0", "buffer": "^6.0.3", "dayjs": "^1.11.5", "deep-diff": "^1.0.2", "file-saver": "^2.0.5", + "hast-util-from-html": "^2.0.3", + "hast-util-to-mdast": "^10.1.2", "highcharts": "^11.1.0", "highcharts-react-official": "^3.2.0", "html-react-parser": "^4.0.0", @@ -33,7 +39,11 @@ "is-ip": "^5.0.1", "leven": "^4.0.0", "lodash": "^4.17.21", + "mdast-util-gfm": "^3.1.0", + "mdast-util-to-markdown": "^2.1.2", + "micromark-extension-gfm": "^3.0.0", "monaco-editor": "^0.40.0", + "motion": "^12.4.7", "react": "^18.2.0", "react-dom": "^18.2.0", "react-flow-renderer": "^10.3.12", @@ -43,6 +53,7 @@ "react-syntax-highlighter": "^15.6.1", "stream": "^0.0.2", "timers": "^0.1.1", + "vaul": "^1.1.2", "web-vitals": "^2.1.4", "xml2js": "^0.6.2", "zustand": "^4.3.8" @@ -55,6 +66,10 @@ "@babel/plugin-transform-runtime": "^7.22.5", "@babel/preset-env": "^7.22.5", "@babel/preset-react": "^7.22.5", + "@babel/preset-typescript": "^7.26.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", "babel-eslint": "^10.1.0", "babel-loader": "^9.1.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", @@ -65,9 +80,11 @@ "css-loader": "^6.8.1", "file-loader": "^6.2.0", "monaco-editor-webpack-plugin": "^7.1.0", + "react-refresh": "^0.16.0", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", "terser-webpack-plugin": "^5.3.9", + "typescript": "^4.9.5", "webpack": "^5.88.0", "webpack-cli": "^5.1.4", "workbox-webpack-plugin": "^7.0.0" @@ -151,12 +168,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -217,25 +235,26 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", + "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", "dependencies": { - "@babel/types": "^7.22.10", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -268,18 +287,16 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz", - "integrity": "sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.26.9.tgz", + "integrity": "sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.26.9", "semver": "^6.3.1" }, "engines": { @@ -352,37 +369,37 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -392,20 +409,20 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "engines": { "node": ">=6.9.0" } @@ -427,13 +444,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", - "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -442,23 +459,13 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -476,25 +483,25 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "engines": { "node": ">=6.9.0" } @@ -525,23 +532,13 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "node_modules/@babel/parser": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/types": "^7.26.9" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", - "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -857,11 +854,11 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -965,11 +962,11 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", - "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1343,13 +1340,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.11.tgz", - "integrity": "sha512-o2+bg7GDS60cJMgz9jWqRUsWkMzLCxp+jFDeDUT5sjRlAxcJWZ2ylNdI7QQ2+CH5hWu7OnN+Cv3htt7AkSf96g==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dependencies": { - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1768,14 +1764,15 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.11.tgz", - "integrity": "sha512-0E4/L+7gfvHub7wsbTv03oRtD69X31LByy44fGmFzbZScpupFByMcgCJ0VbBTkzyjSJKuRoGN8tcijOWKTmqOA==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.8.tgz", + "integrity": "sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.11", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.22.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1969,15 +1966,15 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.11.tgz", - "integrity": "sha512-tWY5wyCZYBGY7IlalfKI1rLiGlIfnwsRHZqlky0HVv8qviwQ1Uo/05M6+s+TcTCVa6Bmoo2uJW5TMFX6Wa4qVg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.11", - "@babel/plugin-transform-typescript": "^7.22.11" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1992,9 +1989,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", - "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", + "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2003,32 +2000,29 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", - "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.11", - "@babel/types": "^7.22.11", - "debug": "^4.1.0", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", + "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -2036,13 +2030,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2420,17 +2413,27 @@ } }, "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } }, + "node_modules/@emotion/cache/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/cache/node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" + }, "node_modules/@emotion/hash": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", @@ -2485,9 +2488,9 @@ } }, "node_modules/@emotion/sheet": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, "node_modules/@emotion/styled": { "version": "11.11.0", @@ -2530,9 +2533,9 @@ } }, "node_modules/@emotion/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==" }, "node_modules/@emotion/weak-memoize": { "version": "0.3.1", @@ -2628,28 +2631,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", - "integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==", + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.1.1" + "@floating-ui/utils": "^0.2.9" } }, "node_modules/@floating-ui/dom": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz", - "integrity": "sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==", + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.4.1", - "@floating-ui/utils": "^0.1.1" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", - "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.5.1" + "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -2657,9 +2663,10 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", - "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "license": "MIT" }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.4.2", @@ -4113,13 +4120,13 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -4134,9 +4141,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { "node": ">=6.0.0" } @@ -4156,9 +4163,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4169,64 +4176,31 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.13", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.13.tgz", - "integrity": "sha512-uC0l97pBspfDAp+iz2cJq8YZ8Sd9i73V77+WzUiOAckIVEyCm5dyVDZCCO2/phmzckVEeZCGcytybkjMQuhPQw==", - "dependencies": { - "@babel/runtime": "^7.22.10", - "@emotion/is-prop-valid": "^1.2.1", - "@floating-ui/react-dom": "^2.0.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.7", - "@popperjs/core": "^2.11.8", - "clsx": "^2.0.0", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.14.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.7.tgz", - "integrity": "sha512-sCWTUNElBPgB30iLvWe3PU7SIlTKZNf6/E/sko85iHVeHCM6WPkDw+y89CrZYjhFNmPqt2fIQM/pZu+rP2lFLA==", + "version": "5.16.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.14.tgz", + "integrity": "sha512-sbjXW+BBSvmzn61XyTMun899E7nGPTXwqD9drm1jBUAvWEhJpPFIRxwQQiATWZnd9rvdxtnhhdsDxEGWI0jxqA==", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/material": { - "version": "5.14.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.7.tgz", - "integrity": "sha512-jIZj9F7zMv6IlyaYDVv5M2Kp20jIX8c0kzuwteySHS/A0IvPVyomQEPtWc51MCbpDNCqzwoZUp3rQtA2lI8k7A==", - "dependencies": { - "@babel/runtime": "^7.22.10", - "@mui/base": "5.0.0-beta.13", - "@mui/core-downloads-tracker": "^5.14.7", - "@mui/system": "^5.14.7", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.7", - "@types/react-transition-group": "^4.4.6", - "clsx": "^2.0.0", - "csstype": "^3.1.2", + "version": "5.16.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.14.tgz", + "integrity": "sha512-eSXQVCMKU2xc7EcTxe/X/rC9QsV2jUe8eLM3MUCPYbo6V52eCE436akRIvELq/AqZpxx2bwkq7HC0cRhLB+yaw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.14", + "@mui/system": "^5.16.14", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.14", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1", - "react-is": "^18.2.0", + "react-is": "^19.0.0", "react-transition-group": "^4.4.5" }, "engines": { @@ -4234,14 +4208,14 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -4255,13 +4229,18 @@ } } }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", + "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" + }, "node_modules/@mui/private-theming": { - "version": "5.14.7", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.7.tgz", - "integrity": "sha512-Y86+hmDnJab2Ka42PgxKpK3oL7EiacbeeX3X/lG9LGO0wSc45wZjHeTfIlVSkkUCkexiMKEJp5NlSjZhr27NRQ==", + "version": "5.16.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.14.tgz", + "integrity": "sha512-12t7NKzvYi819IO5IapW2BcR33wP/KAVrU8d7gLhGHoAmhDxyXlRoKiRij3TOD8+uzk0B6R9wHUNKi4baJcRNg==", "dependencies": { - "@babel/runtime": "^7.22.10", - "@mui/utils": "^5.14.7", + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.14", "prop-types": "^15.8.1" }, "engines": { @@ -4269,11 +4248,11 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -4282,13 +4261,13 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.14.7", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.7.tgz", - "integrity": "sha512-hKBETEDsIAkL8/mBwPiQj/vw28OeIhMXC3Tvj4J2bb9snxAKpiZioR1PwqP+6P41twsC/GKBd0Vr9oaWYaHuMg==", + "version": "5.16.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.14.tgz", + "integrity": "sha512-UAiMPZABZ7p8mUW4akDV6O7N3+4DatStpXMZwPlt+H/dA0lt67qawN021MNND+4QTpjaiMYxbhKZeQcyWCbuKw==", "dependencies": { - "@babel/runtime": "^7.22.10", - "@emotion/cache": "^11.11.0", - "csstype": "^3.1.2", + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.13.5", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -4296,12 +4275,12 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -4313,17 +4292,17 @@ } }, "node_modules/@mui/system": { - "version": "5.14.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.7.tgz", - "integrity": "sha512-jeZtHglc+Pi6qjGoopT6O4RqYXVBMqHVOsjMGP0hxGSSPm1T4gsAu7jU8eqGx9YwwjvvJ0eotTjFqw7iJ6qE2Q==", - "dependencies": { - "@babel/runtime": "^7.22.10", - "@mui/private-theming": "^5.14.7", - "@mui/styled-engine": "^5.14.7", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.14.7", - "clsx": "^2.0.0", - "csstype": "^3.1.2", + "version": "5.16.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.14.tgz", + "integrity": "sha512-KBxMwCb8mSIABnKvoGbvM33XHyT+sN0BzEBG+rsSc0lLQGzs7127KWkCA6/H8h6LZ00XpBEME5MAj8mZLiQ1tw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.14", + "@mui/styled-engine": "^5.16.14", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.14", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -4331,13 +4310,13 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -4352,11 +4331,11 @@ } }, "node_modules/@mui/types": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", - "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "version": "7.2.21", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz", + "integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -4365,27 +4344,39 @@ } }, "node_modules/@mui/utils": { - "version": "5.14.7", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.7.tgz", - "integrity": "sha512-RtheP/aBoPogVdi8vj8Vo2IFnRa4mZVmnD0RGlVZ49yF60rZs+xP4/KbpIrTr83xVs34QmHQ2aQ+IX7I0a0dDw==", - "dependencies": { - "@babel/runtime": "^7.22.10", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^18.2.1", + "version": "5.16.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.14.tgz", + "integrity": "sha512-wn1QZkRzSmeXD1IguBVvJJHV3s6rxJrfb6YuC9Kk6Noh9f8Fb54nUs5JRkKm+BOerRhj5fLg05Dhx/H3Ofb8Mg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "react-is": "^19.0.0" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", + "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" + }, "node_modules/@mui/x-date-pickers": { "version": "5.0.20", "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.20.tgz", @@ -4493,18 +4484,17 @@ } }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz", - "integrity": "sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", + "integrity": "sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==", + "license": "MIT", "dependencies": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", + "ansi-html": "^0.0.9", "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", "html-entities": "^2.1.0", "loader-utils": "^2.0.4", - "schema-utils": "^3.0.0", + "schema-utils": "^4.2.0", "source-map": "^0.7.3" }, "engines": { @@ -4516,7 +4506,7 @@ "sockjs-client": "^1.4.0", "type-fest": ">=0.17.0 <5.0.0", "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x", + "webpack-dev-server": "3.x || 4.x || 5.x", "webpack-hot-middleware": "2.x", "webpack-plugin-serve": "0.x || 1.x" }, @@ -4541,23 +4531,6 @@ } } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -4575,77 +4548,620 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@remix-run/router": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.8.0.tgz", - "integrity": "sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==", - "engines": { - "node": ">=14.0.0" - } + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==", + "license": "MIT" }, - "node_modules/@rollup/plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", - "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "node_modules/@radix-ui/primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.2.tgz", + "integrity": "sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==", + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - }, - "engines": { - "node": ">= 10.0.0" + "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { - "@types/babel__core": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { "optional": true } } }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "node_modules/@radix-ui/react-collection": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.2.tgz", + "integrity": "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==", + "license": "MIT", "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">= 10.0.0" + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", + "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "license": "MIT", "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.6.tgz", + "integrity": "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==", + "license": "MIT", "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" }, - "engines": { + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz", + "integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz", + "integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz", + "integrity": "sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.4.tgz", + "integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz", + "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz", + "integrity": "sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz", + "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.2.tgz", + "integrity": "sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", + "license": "MIT" + }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", + "license": "MIT" + }, + "node_modules/@remix-run/router": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.8.0.tgz", + "integrity": "sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { "node": ">= 8.0.0" }, "peerDependencies": { @@ -5346,6 +5862,24 @@ "node": ">=12" } }, + "node_modules/@testing-library/react/node_modules/@types/react": { + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "peer": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@testing-library/react/node_modules/@types/react-dom": { + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, "node_modules/@testing-library/react/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -5425,6 +5959,405 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@tiptap/core": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.11.5.tgz", + "integrity": "sha512-jb0KTdUJaJY53JaN7ooY3XAxHQNoMYti/H6ANo707PsLXVeEqJ9o8+eBup1JU5CuwzrgnDc2dECt2WIGX9f8Jw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.11.5.tgz", + "integrity": "sha512-MZfcRIzKRD8/J1hkt/eYv49060GTL6qGR3NY/oTDuw2wYzbQXXLEbjk8hxAtjwNn7G+pWQv3L+PKFzZDxibLuA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.11.5.tgz", + "integrity": "sha512-OAq03MHEbl7MtYCUzGuwb0VpOPnM0k5ekMbEaRILFU5ZC7cEAQ36XmPIw1dQayrcuE8GZL35BKub2qtRxyC9iA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bubble-menu": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.11.5.tgz", + "integrity": "sha512-rx+rMd7EEdht5EHLWldpkzJ56SWYA9799b33ustePqhXd6linnokJCzBqY13AfZ9+xp3RsR6C0ZHI9GGea0tIA==", + "license": "MIT", + "dependencies": { + "tippy.js": "^6.3.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bullet-list": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.11.5.tgz", + "integrity": "sha512-VXwHlX6A/T6FAspnyjbKDO0TQ+oetXuat6RY1/JxbXphH42nLuBaGWJ6pgy6xMl6XY8/9oPkTNrfJw/8/eeRwA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.11.5.tgz", + "integrity": "sha512-xOvHevNIQIcCCVn9tpvXa1wBp0wHN/2umbAZGTVzS+AQtM7BTo0tz8IyzwxkcZJaImONcUVYLOLzt2AgW1LltA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code-block": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.11.5.tgz", + "integrity": "sha512-ksxMMvqLDlC+ftcQLynqZMdlJT1iHYZorXsXw/n+wuRd7YElkRkd6YWUX/Pq/njFY6lDjKiqFLEXBJB8nrzzBA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.11.5.tgz", + "integrity": "sha512-7I4BRTpIux2a0O2qS3BDmyZ5LGp3pszKbix32CmeVh7lN9dV7W5reDqtJJ9FCZEEF+pZ6e1/DQA362dflwZw2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.11.5.tgz", + "integrity": "sha512-uIN7L3FU0904ec7FFFbndO7RQE/yiON4VzAMhNn587LFMyWO8US139HXIL4O8dpZeYwYL3d1FnDTflZl6CwLlg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-floating-menu": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.11.5.tgz", + "integrity": "sha512-HsMI0hV5Lwzm530Z5tBeyNCBNG38eJ3qjfdV2OHlfSf3+KOEfn6a5AUdoNaZO02LF79/8+7BaYU2drafag9cxQ==", + "license": "MIT", + "dependencies": { + "tippy.js": "^6.3.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-gapcursor": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.11.5.tgz", + "integrity": "sha512-kcWa+Xq9cb6lBdiICvLReuDtz/rLjFKHWpW3jTTF3FiP3wx4H8Rs6bzVtty7uOVTfwupxZRiKICAMEU6iT0xrQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.11.5.tgz", + "integrity": "sha512-q9doeN+Yg9F5QNTG8pZGYfNye3tmntOwch683v0CCVCI4ldKaLZ0jG3NbBTq+mosHYdgOH2rNbIORlRRsQ+iYQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.11.5.tgz", + "integrity": "sha512-x/MV53psJ9baRcZ4k4WjnCUBMt8zCX7mPlKVT+9C/o+DEs/j/qxPLs95nHeQv70chZpSwCQCt93xMmuF0kPoAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-history": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.11.5.tgz", + "integrity": "sha512-b+wOS33Dz1azw6F1i9LFTEIJ/gUui0Jwz5ZvmVDpL2ZHBhq1Ui0/spTT+tuZOXq7Y/uCbKL8Liu4WoedIvhboQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-horizontal-rule": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.11.5.tgz", + "integrity": "sha512-3up2r1Du8/5/4ZYzTC0DjTwhgPI3dn8jhOCLu73m5F3OGvK/9whcXoeWoX103hYMnGDxBlfOje71yQuN35FL4A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.11.5.tgz", + "integrity": "sha512-9VGfb2/LfPhQ6TjzDwuYLRvw0A6VGbaIp3F+5Mql8XVdTBHb2+rhELbyhNGiGVR78CaB/EiKb6dO9xu/tBWSYA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.11.5.tgz", + "integrity": "sha512-Mp5RD/pbkfW1vdc6xMVxXYcta73FOwLmblQlFNn/l/E5/X1DUSA4iGhgDDH4EWO3swbs03x2f7Zka/Xoj3+WLg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-ordered-list": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.11.5.tgz", + "integrity": "sha512-Cu8KwruBNWAaEfshRQR0yOSaUKAeEwxW7UgbvF9cN/zZuKgK5uZosPCPTehIFCcRe+TBpRtZQh+06f/gNYpYYg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.11.5.tgz", + "integrity": "sha512-YFBWeg7xu/sBnsDIF/+nh9Arf7R0h07VZMd0id5Ydd2Qe3c1uIZwXxeINVtH0SZozuPIQFAT8ICe9M0RxmE+TA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.11.5.tgz", + "integrity": "sha512-Pr+0Ju/l2ZvXMd9VQxtaoSZbs0BBp1jbBDqwms88ctpyvQFRfLSfSkqudQcSHyw2ROOz2E31p/7I7fpI8Y0CLA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.11.5.tgz", + "integrity": "sha512-PVfUiCqrjvsLpbIoVlegSY8RlkR64F1Rr2RYmiybQfGbg+AkSZXDeO0eIrc03//4gua7D9DfIozHmAKv1KN3ow==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.11.5.tgz", + "integrity": "sha512-Gq1WwyhFpCbEDrLPIHt5A8aLSlf8bfz4jm417c8F/JyU0J5dtYdmx0RAxjnLw1i7ZHE7LRyqqAoS0sl7JHDNSQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text-style": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.11.5.tgz", + "integrity": "sha512-YUmYl0gILSd/u/ZkOmNxjNXVw+mu8fpC2f8G4I4tLODm0zCx09j9DDEJXSrM5XX72nxJQqtSQsCpNKnL0hfeEQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/pm": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.11.5.tgz", + "integrity": "sha512-z9JFtqc5ZOsdQLd9vRnXfTCQ8v5ADAfRt9Nm7SqP6FUHII8E1hs38ACzf5xursmth/VonJYb5+73Pqxk1hGIPw==", + "license": "MIT", + "dependencies": { + "prosemirror-changeset": "^2.2.1", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.23.0", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.6.3", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.37.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/react": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.11.5.tgz", + "integrity": "sha512-Dp8eHL1G+R/C4+QzAczyb3t1ovexEIZx9ln7SGEM+cT1KHKAw9XGPRgsp92+NQaYI+EdEb/YqoBOSzQcd18/OQ==", + "license": "MIT", + "dependencies": { + "@tiptap/extension-bubble-menu": "^2.11.5", + "@tiptap/extension-floating-menu": "^2.11.5", + "@types/use-sync-external-store": "^0.0.6", + "fast-deep-equal": "^3", + "use-sync-external-store": "^1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.11.5.tgz", + "integrity": "sha512-SLI7Aj2ruU1t//6Mk8f+fqW+18uTqpdfLUJYgwu0CkqBckrkRZYZh6GVLk/02k3H2ki7QkFxiFbZrdbZdng0JA==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^2.11.5", + "@tiptap/extension-blockquote": "^2.11.5", + "@tiptap/extension-bold": "^2.11.5", + "@tiptap/extension-bullet-list": "^2.11.5", + "@tiptap/extension-code": "^2.11.5", + "@tiptap/extension-code-block": "^2.11.5", + "@tiptap/extension-document": "^2.11.5", + "@tiptap/extension-dropcursor": "^2.11.5", + "@tiptap/extension-gapcursor": "^2.11.5", + "@tiptap/extension-hard-break": "^2.11.5", + "@tiptap/extension-heading": "^2.11.5", + "@tiptap/extension-history": "^2.11.5", + "@tiptap/extension-horizontal-rule": "^2.11.5", + "@tiptap/extension-italic": "^2.11.5", + "@tiptap/extension-list-item": "^2.11.5", + "@tiptap/extension-ordered-list": "^2.11.5", + "@tiptap/extension-paragraph": "^2.11.5", + "@tiptap/extension-strike": "^2.11.5", + "@tiptap/extension-text": "^2.11.5", + "@tiptap/extension-text-style": "^2.11.5", + "@tiptap/pm": "^2.11.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -5915,6 +6848,22 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -5924,6 +6873,12 @@ "@types/unist": "*" } }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT" + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -5951,9 +6906,9 @@ "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" }, "node_modules/@types/q": { "version": "1.5.6", @@ -5971,36 +6926,26 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "version": "19.0.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", + "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.2.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", - "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-is": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz", - "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==", - "dependencies": { - "@types/react": "*" + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz", + "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==", + "peerDependencies": { + "@types/react": "^19.0.0" } }, "node_modules/@types/react-transition-group": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", - "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", - "dependencies": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "peerDependencies": { "@types/react": "*" } }, @@ -6022,11 +6967,6 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, - "node_modules/@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" - }, "node_modules/@types/semver": { "version": "7.5.1", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", @@ -6101,6 +7041,12 @@ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.5.5", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", @@ -6833,6 +7779,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-html": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", + "integrity": "sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -6890,6 +7848,18 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/aria-query": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", @@ -8990,9 +9960,9 @@ } }, "node_modules/clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } @@ -9116,7 +10086,8 @@ "node_modules/common-path-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true }, "node_modules/common-tags": { "version": "1.8.2", @@ -9292,6 +10263,12 @@ "node": ">=10" } }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT" + }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -9777,9 +10754,9 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/currency-symbol-map": { "version": "5.1.0", @@ -10080,6 +11057,12 @@ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, "node_modules/detect-port-alt": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", @@ -11929,6 +12912,33 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "12.4.7", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.4.7.tgz", + "integrity": "sha512-VhrcbtcAMXfxlrjeHPpWVu2+mkcoR31e02aNSR7OUS/hZAciKa8q6o3YN2mA1h+jjscRsSyKvX6E1CiY/7OLMw==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.4.5", + "motion-utils": "^12.0.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -12044,6 +13054,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", @@ -12342,56 +13361,399 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dependencies": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hast-util-embedded": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", + "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-embedded/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-from-html/node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-from-parse5/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/hast-util-from-parse5/node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-from-parse5/node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/property-information": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz", + "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-from-parse5/node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-is-body-ok-link": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.1.tgz", + "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-body-ok-link/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-minify-whitespace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hast-util-minify-whitespace/-/hast-util-minify-whitespace-1.0.1.tgz", + "integrity": "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-minify-whitespace/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-is-body-ok-link": "^3.0.0", + "hast-util-is-element": "^3.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/hast-util-phrasing/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/hast-util-to-html/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, + "@types/unist": "*" + } + }, + "node_modules/hast-util-to-html/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/hast-util-to-html/node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "node_modules/hast-util-to-html/node_modules/property-information": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz", + "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==", "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-html/node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/hast-util-to-jsx-runtime": { @@ -12481,6 +13843,72 @@ "inline-style-parser": "0.2.4" } }, + "node_modules/hast-util-to-mdast": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/hast-util-to-mdast/-/hast-util-to-mdast-10.1.2.tgz", + "integrity": "sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-phrasing": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "hast-util-to-text": "^4.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-minify-whitespace": "^6.0.0", + "trim-trailing-lines": "^2.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-mdast/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-to-text/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -12705,6 +14133,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/html-webpack-plugin": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", @@ -17184,14 +18622,14 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -17353,6 +18791,15 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/lint-staged": { "version": "12.5.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.5.0.tgz", @@ -17764,6 +19211,61 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mdast-util-from-markdown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", @@ -17788,12 +19290,113 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, + "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", @@ -18065,6 +19668,12 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -18179,6 +19788,127 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -18689,6 +20419,47 @@ "webpack": "^4.5.0 || 5.x" } }, + "node_modules/motion": { + "version": "12.4.7", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.4.7.tgz", + "integrity": "sha512-mhegHAbf1r80fr+ytC6OkjKvIUegRNXKLWNPrCN2+GnixlNSPwT03FtKqp9oDny1kNcLWZvwbmEr+JqVryFrcg==", + "license": "MIT", + "dependencies": { + "framer-motion": "^12.4.7", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.4.5", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.4.5.tgz", + "integrity": "sha512-Q2xmhuyYug1CGTo0jdsL05EQ4RhIYXlggFS/yPhQQRNzbrhjKQ1tbjThx5Plv68aX31LsUQRq4uIkuDxdO5vRQ==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.0.0" + } + }, + "node_modules/motion-utils": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.0.0.tgz", + "integrity": "sha512-MNFiBKbbqnmvOjkPyOKgHUp3Q6oiokLkI1bEwm5QA28cxMZrv0CbbBGDNmhF6DIXsi1pCQBSs0dX8xjeER1tmA==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -19113,6 +20884,12 @@ "node": ">= 0.8.0" } }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -20772,75 +22549,270 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/prosemirror-changeset": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", + "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", + "license": "MIT", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.0.tgz", + "integrity": "sha512-6toodS4R/Aah5pdsrIwnTYPEjW70SlO5a66oo5Kk+CIrgJz3ukOoS+FYDGqvQlAX5PxoGWDX1oD++tn5X3pyRA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.10.2" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", + "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", + "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", + "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", + "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", + "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz", + "integrity": "sha512-Sl+oMfMtAjWtlcZoj/5L/Q39MpEnVZ840Xo330WJWUvgyhNmLBLN7MsHn07s53nG/KImevWHSE6fEj4q/GihHw==", + "license": "MIT", + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.20.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", + "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "license": "MIT", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.24.1.tgz", + "integrity": "sha512-YM053N+vTThzlWJ/AtPtF1j0ebO36nvbmDy4U7qA2XQB8JVaQp1FmB9Jhrps8s+z+uxhhVTny4m20ptUvhk0Mg==", + "license": "MIT", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz", + "integrity": "sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==", "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "prosemirror-model": "^1.19.0" } }, - "node_modules/private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true, - "engines": { - "node": ">= 0.6" + "node_modules/prosemirror-schema-list": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.0.tgz", + "integrity": "sha512-gg1tAfH1sqpECdhIHOA/aLg2VH3ROKBWQ4m8Qp9mBKrOxQRW61zc+gMCI8nh22gnBzd1t2u1/NPLmO3nAa3ssg==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "node_modules/prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "node_modules/prosemirror-tables": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.6.4.tgz", + "integrity": "sha512-TkDY3Gw52gRFRfRn2f4wJv5WOgAOXLJA2CQJYIJ5+kdFbfj3acR4JUW6LX2e1hiEBiUwvEhzH5a3cZ5YSztpIA==", + "license": "MIT", "dependencies": { - "asap": "~2.0.6" + "prosemirror-keymap": "^1.2.2", + "prosemirror-model": "^1.24.1", + "prosemirror-state": "^1.4.3", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.37.2" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" }, - "engines": { - "node": ">= 6" + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "node_modules/prosemirror-transform": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz", + "integrity": "sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ==", + "license": "MIT", "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" + "prosemirror-model": "^1.21.0" } }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "node_modules/prosemirror-view": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.38.0.tgz", + "integrity": "sha512-O45kxXQTaP9wPdXhp8TKqCR+/unS/gnfg9Q93svQcB3j0mlp2XSPAmsPefxHADwzC+fbNS404jqRxm3UQaGvgw==", "license": "MIT", "dependencies": { - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" } }, "node_modules/proxy-addr": { @@ -20881,6 +22853,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -21268,13 +23249,61 @@ "integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==" }, "node_modules/react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.16.0.tgz", + "integrity": "sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-router": { "version": "6.15.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz", @@ -21516,6 +23545,15 @@ "node": ">=8" } }, + "node_modules/react-scripts/node_modules/react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-scripts/node_modules/sass-loader": { "version": "12.6.0", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", @@ -21888,6 +23926,28 @@ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-switch": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/react-switch/-/react-switch-7.0.0.tgz", @@ -22133,6 +24193,29 @@ "jsesc": "bin/jsesc" } }, + "node_modules/rehype-minify-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/rehype-minify-whitespace/-/rehype-minify-whitespace-6.0.2.tgz", + "integrity": "sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-minify-whitespace": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-minify-whitespace/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -22522,6 +24605,12 @@ "node": ">=8" } }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -23966,19 +26055,20 @@ "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==" }, + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "license": "MIT", + "dependencies": { + "@popperjs/core": "^2.9.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -24041,6 +26131,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/trim-trailing-lines": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-2.1.0.tgz", + "integrity": "sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/trough": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", @@ -24241,7 +26341,7 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -24250,6 +26350,12 @@ "node": ">=4.2.0" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -24348,6 +26454,26 @@ "node": ">=8" } }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -24522,6 +26648,49 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", @@ -24611,6 +26780,19 @@ "node": ">= 0.8" } }, + "node_modules/vaul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", + "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -24625,6 +26807,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", @@ -24660,6 +26862,12 @@ "browser-process-hrtime": "^1.0.0" } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, "node_modules/w3c-xmlserializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", @@ -24699,6 +26907,16 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/web-vitals": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", diff --git a/apps/dashboard/web/polaris_web/package.json b/apps/dashboard/web/polaris_web/package.json index 10b9f7bcd5..c180caffef 100644 --- a/apps/dashboard/web/polaris_web/package.json +++ b/apps/dashboard/web/polaris_web/package.json @@ -9,17 +9,23 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@mui/material": "^5.9.2", "@mui/x-date-pickers": "^5.0.0", + "@radix-ui/react-select": "^2.1.6", "@shopify/polaris": "^11.2.1", "@stigg/react-sdk": "^4.8.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "@tiptap/extension-placeholder": "^2.11.5", + "@tiptap/react": "^2.11.5", + "@tiptap/starter-kit": "^2.11.5", "assert": "^2.1.0", "axios": "^1.4.0", "buffer": "^6.0.3", "dayjs": "^1.11.5", "deep-diff": "^1.0.2", "file-saver": "^2.0.5", + "hast-util-from-html": "^2.0.3", + "hast-util-to-mdast": "^10.1.2", "highcharts": "^11.1.0", "highcharts-react-official": "^3.2.0", "html-react-parser": "^4.0.0", @@ -28,7 +34,11 @@ "is-ip": "^5.0.1", "leven": "^4.0.0", "lodash": "^4.17.21", + "mdast-util-gfm": "^3.1.0", + "mdast-util-to-markdown": "^2.1.2", + "micromark-extension-gfm": "^3.0.0", "monaco-editor": "^0.40.0", + "motion": "^12.4.7", "react": "^18.2.0", "react-dom": "^18.2.0", "react-flow-renderer": "^10.3.12", @@ -38,12 +48,14 @@ "react-syntax-highlighter": "^15.6.1", "stream": "^0.0.2", "timers": "^0.1.1", + "vaul": "^1.1.2", "web-vitals": "^2.1.4", "xml2js": "^0.6.2", "zustand": "^4.3.8" }, "scripts": { - "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --config web/webpack.config.js", + "rmdist": "rimraf web/dist", + "dev": "npm run rmdist && cross-env NODE_ENV=development webpack serve --config web/webpack.config.dev.js", "build": "cross-env NODE_ENV=production VERSION=$RELEASE_VERSION webpack --progress --config web/webpack.config.js", "hot": "cross-env NODE_ENV=development VERSION=$RELEASE_VERSION webpack --watch --progress --config web/webpack.config.js" }, @@ -72,6 +84,10 @@ "@babel/plugin-transform-runtime": "^7.22.5", "@babel/preset-env": "^7.22.5", "@babel/preset-react": "^7.22.5", + "@babel/preset-typescript": "^7.26.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", "babel-eslint": "^10.1.0", "babel-loader": "^9.1.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", @@ -82,9 +98,11 @@ "css-loader": "^6.8.1", "file-loader": "^6.2.0", "monaco-editor-webpack-plugin": "^7.1.0", + "react-refresh": "^0.16.0", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", "terser-webpack-plugin": "^5.3.9", + "typescript": "^4.9.5", "webpack": "^5.88.0", "webpack-cli": "^5.1.4", "workbox-webpack-plugin": "^7.0.0" diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/header/Headers.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/header/Headers.js index 9cb53d2392..6a6647aa81 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/header/Headers.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/header/Headers.js @@ -1,5 +1,5 @@ import { TopBar, Icon, Text, ActionList, Modal, TextField, HorizontalStack, Box, Avatar, VerticalStack, Button, Scrollable } from '@shopify/polaris'; -import { NotificationMajor, CustomerPlusMajor, LogOutMinor, NoteMinor, ResourcesMajor, UpdateInventoryMajor, PageMajor, DynamicSourceMajor, PhoneMajor, ChatMajor } from '@shopify/polaris-icons'; +import { NotificationMajor, CustomerPlusMajor, LogOutMinor, NoteMinor, ResourcesMajor, UpdateInventoryMajor, PageMajor, DynamicSourceMajor, PhoneMajor, ChatMajor, SettingsMajor } from '@shopify/polaris-icons'; import { useState, useCallback, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import Store from '../../../store'; @@ -209,18 +209,18 @@ export default function Header() { const secondaryMenuMarkup = ( - + {(Object.keys(currentTestsObj).length > 0 && currentTestsObj?.testRunsArr?.length !== 0 && currentTestsObj?.totalTestsCompleted > 0) ? - + - + Test run status {`${currentTestsObj.totalTestsQueued} tests queued`} : null} - @@ -228,8 +228,12 @@ export default function Header() { } actions={[]} /> + navigate("/dashboard/settings/about")} /> + } + /> - ); const topBarMarkup = ( diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/leftnav/LeftNav.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/leftnav/LeftNav.js index 629eb21c9f..5b3ba67b19 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/leftnav/LeftNav.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/layouts/leftnav/LeftNav.js @@ -6,6 +6,7 @@ import { MarketingFilledMinor, ReportFilledMinor, DiamondAlertMinor, + StarFilledMinor, FinancesMinor, } from "@shopify/polaris-icons"; import {useLocation, useNavigate} from "react-router-dom"; @@ -257,67 +258,103 @@ export default function LeftNav() { subNavigationItems: reportsSubNavigationItems, key: "6", }, - window?.STIGG_FEATURE_WISE_ALLOWED?.THREAT_DETECTION?.isGranted ? - { - label: ( - - API Protection - - ), - icon: DiamondAlertMinor, - onClick: () => { - handleSelect("dashboard_threat_actor"); - navigate("/dashboard/protection/threat-actor"); - setActive("normal"); - }, - selected: leftNavSelected.includes("_threat"), - url: "#", - key: "7", - subNavigationItems: [ - { - label: "Threat Actors", - onClick: () => { - navigate("/dashboard/protection/threat-actor"); - handleSelect("dashboard_threat_actor"); - setActive("active"); - }, - selected: leftNavSelected === "dashboard_threat_actor", + ...(window?.STIGG_FEATURE_WISE_ALLOWED?.THREAT_DETECTION?.isGranted ? [{ + label: ( + + API Protection + + ), + icon: DiamondAlertMinor, + onClick: () => { + handleSelect("dashboard_threat_actor"); + navigate("/dashboard/protection/threat-actor"); + setActive("normal"); + }, + selected: leftNavSelected.includes("_threat"), + url: "#", + key: "7", + subNavigationItems: [ + { + label: "Threat Actors", + onClick: () => { + navigate("/dashboard/protection/threat-actor"); + handleSelect("dashboard_threat_actor"); + setActive("active"); }, - { - label: "Threat Activity", - onClick: () => { - navigate("/dashboard/protection/threat-activity"); - handleSelect("dashboard_threat_activity"); - setActive("active"); - }, - selected: - leftNavSelected === "dashboard_threat_activity", + selected: leftNavSelected === "dashboard_threat_actor", + }, + { + label: "Threat Activity", + onClick: () => { + navigate("/dashboard/protection/threat-activity"); + handleSelect("dashboard_threat_activity"); + setActive("active"); }, - { - label: "APIs Under Threat", - onClick: () => { - navigate("/dashboard/protection/threat-api"); - handleSelect("dashboard_threat_api"); - setActive("active"); - }, - selected: - leftNavSelected === "dashboard_threat_api", + selected: + leftNavSelected === "dashboard_threat_activity", + }, + { + label: "APIs Under Threat", + onClick: () => { + navigate("/dashboard/protection/threat-api"); + handleSelect("dashboard_threat_api"); + setActive("active"); }, - { - label: "Threat Policy", - onClick: () => { - navigate("/dashboard/protection/threat-policy"); - handleSelect("dashboard_threat_policy"); - setActive("active"); - }, - selected: - leftNavSelected === "dashboard_threat_policy", + selected: + leftNavSelected === "dashboard_threat_api", + }, + { + label: "Threat Policy", + onClick: () => { + navigate("/dashboard/protection/threat-policy"); + handleSelect("dashboard_threat_policy"); + setActive("active"); }, - ], - } - : {}, + selected: + leftNavSelected === "dashboard_threat_policy", + }, + ], + }] : []), + { + label: ( + + AI Agents + + ), + icon: StarFilledMinor, + onClick: () => { + handleSelect("agent_team_members"); + navigate("/dashboard/agent-team/members"); + setActive("normal"); + }, + selected: leftNavSelected.includes("agent_team"), + url: "#", + key: "8", + // subNavigationItems: [ + // { + // label: "Members", + // onClick: () => { + // navigate("/dashboard/agent-team/members"); + // handleSelect("agent_team_members"); + // setActive("active"); + // }, + // selected: leftNavSelected === "agent_team_members", + // }, + // { + // label: "Hired Members", + // onClick: () => { + // navigate("/dashboard/agent-team/hired-members"); + // handleSelect("agent_team_hired_members"); + // setActive("active"); + // }, + // selected: + // leftNavSelected === "agent_team_hired_members", + // } + // ], + } ]} /> + {/* Settings navigation section commented out + */} ); diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/GridRows.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/GridRows.jsx index 35b0f016e5..50a6fbc070 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/GridRows.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/GridRows.jsx @@ -3,21 +3,26 @@ import React from 'react' function GridRows(props) { - const {columns , items, CardComponent, buttonText, onButtonClick, changedColumns} = props; + const {columns , items, CardComponent, buttonText, onButtonClick, changedColumns, cardType, verticalGap, horizontalGap} = props; let usedColumns = changedColumns && changedColumns > 0 ? changedColumns : columns const rows = Math.ceil((items?.length)/usedColumns) const widthChanged = Math.floor(((usedColumns * 100)/columns)) + '%' + const useVerticalGap = verticalGap ? verticalGap : "5" + const useHorizontalGap = horizontalGap ? horizontalGap : "5" return (
- + {Array.from({length: rows}).map((_,index)=>( - + {Array.from({ length: usedColumns }).map((_, col) => { const itemIndex = index * usedColumns + col; const item = items[itemIndex]; if (item) { + if (cardType && cardType == "AGENTS") { + return + } return ; } })} diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/TitleWithInfo.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/TitleWithInfo.jsx index 4d6518640a..ab9b3a2258 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/TitleWithInfo.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/components/shared/TitleWithInfo.jsx @@ -1,7 +1,9 @@ import { Avatar, Box, HorizontalStack, Link, Popover, Text, Tooltip } from '@shopify/polaris' import React, { useState } from 'react' -function TitleWithInfo({titleComp, textProps, titleText, tooltipContent, docsUrl}) { +function TitleWithInfo(props) { + + const { titleComp, textProps, titleText, tooltipContent, docsUrl } = props const content = docsUrl ? diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/Dashboard.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/Dashboard.jsx index 95b82ceda8..087a9f6747 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/Dashboard.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/Dashboard.jsx @@ -214,7 +214,7 @@ function Dashboard() { })}
: null} - {func.checkLocal() && !(location.pathname.includes("test-editor") || location.pathname.includes("settings") || location.pathname.includes("onboarding") || location.pathname.includes("summary")) ?
+ {func.checkLocal() && !(location.pathname.includes("test-editor") || location.pathname.includes("settings") || location.pathname.includes("onboarding") || location.pathname.includes("summary")) ?
Need a 1:1 experience? + + +} + +export default AgentRowCard; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/AgentTeam.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/AgentTeam.tsx new file mode 100644 index 0000000000..5fa9aac9dc --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/AgentTeam.tsx @@ -0,0 +1,100 @@ +import React, { useEffect, useState } from 'react'; +import { useAgentsStore } from './agents.store'; +import { Agent } from './types'; +import AgentWindow from './components/AgentWindow'; +import { Button } from '@shopify/polaris'; +import PageWithMultipleCards from '../../components/layouts/PageWithMultipleCards'; +import GridRows from '../../components/shared/GridRows'; +import AgentRowCard from './AgentRowCard'; +import TitleWithInfo from "../../../../apps/dashboard/components/shared/TitleWithInfo" +import api from './api'; + +const AGENT_IMAGES = ["/public/agents/secret-agent-1.svg", + "/public/agents/secret-agent-2.svg", + "/public/agents/secret-agent-3.svg", + "/public/agents/secret-agent-4.svg" +] + +function AgentTeam() { + const { setAvailableModels, currentAgent, setCurrentAgent } = useAgentsStore(); + + const [Agents, setAgents] = useState([]) + + useEffect(() => { + api.getMemberAgents().then((res: { agents: any; }) => { + if(res && res.agents){ + let agents = res.agents.map((x: { _name: string; agentFunctionalName: string; description: string; },i: number) => { + return { + id: x._name, + name: x.agentFunctionalName, + description: x.description, + image: AGENT_IMAGES[(i%(AGENT_IMAGES.length))], + } + }) + setAgents(agents) + } + }) + + api.getAgentModels().then((res: { models: any; }) => { + if(res && res.models){ + let models = res.models.map((x: { _name: string; modelName: string; }) =>{ + return { + id: x._name, + name: x.modelName + } + }) + setAvailableModels(models); + } + }) + + }, []); + + const closeAction = () => { + setCurrentAgent(null) + setShowAgentWindow(false) + } + + const onButtonClick = (agent: Agent | null ) => { + setCurrentAgent(agent) + setShowAgentWindow(true) + } + + const agents = ( + + ) + + const pageComponents = [agents] + + const [showAgentWindow, setShowAgentWindow] = useState(false) + + return ( + <> + + } + // secondaryActions={[ + // // TODO: implement Knowledge base functionality + // + // ]} + /> + + + ) +} + +export default AgentTeam; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/agents.store.ts b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/agents.store.ts new file mode 100644 index 0000000000..17c3254a55 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/agents.store.ts @@ -0,0 +1,72 @@ +import { create } from "zustand"; +import { Model, Agent, PromptContent, AgentState } from "./types"; +import { devtools, persist, createJSONStorage } from "zustand/middleware"; + +// Define the blocking states +const BLOCKING_STATES: AgentState[] = ["thinking", "paused"]; +export const isBlockingState = (state: AgentState) => BLOCKING_STATES.includes(state); + +interface AgentsStore { + availableModels: Model[]; + selectedModel: Model | null; + setSelectedModel: (model: Model) => void; + setAvailableModels: (models: Model[]) => void; + currentPrompt: PromptContent; + setCurrentPrompt: (prompt: PromptContent) => void; + currentAgent: Agent | null; + setCurrentAgent: (agent: Agent | null) => void; + attemptedInBlockedState: boolean; + setAttemptedInBlockedState: (attempted: boolean) => void; + agentState: AgentState; + setAgentState: (state: AgentState) => void; + selectedRepository: string | null; + setSelectedRepository: (repo: string) => void; + currentProcessId: string | null; + setCurrentProcessId: (currentProcessId: string) => void; + currentSubprocess: string | null; + setCurrentSubprocess: (subprocess: string) => void; + currentAttempt: number + setCurrentAttempt: (subprocess: number) => void; + resetStore: () => void; +} + +// Zustand Store with Middleware +export const useAgentsStore = create()( + devtools( + persist( + (set, get) => ({ + availableModels: [], + selectedModel: null, + setSelectedModel: (model: Model) => set({ selectedModel: model }), + setAvailableModels: (models: Model[]) => set({ availableModels: models }), + currentPrompt: { html: "", markdown: "" }, + setCurrentPrompt: (prompt: PromptContent) => set({ currentPrompt: prompt }), + currentAgent: null, + setCurrentAgent: (agent: Agent | null) => set({ currentAgent: agent }), + attemptedInBlockedState: false, + setAttemptedInBlockedState: (attempted: boolean) => + set({ attemptedInBlockedState: attempted }), + agentState: "idle", + setAgentState: (state: AgentState) => set({ agentState: state }), + selectedRepository: null, + setSelectedRepository: (repo: string) => set({ selectedRepository: repo }), + currentSubprocess: '0', + setCurrentSubprocess: (subprocess: string) => set({ currentSubprocess: subprocess }), + currentProcessId:"", + setCurrentProcessId: (currentProcessId: string) => set({ currentProcessId: currentProcessId }), + currentAttempt: 0, + setCurrentAttempt: (attempt: number) => set({ currentAttempt: attempt }), + + resetStore: () => set({ + attemptedInBlockedState: false, + agentState: "idle", + selectedRepository: null, + currentSubprocess: '0', + currentProcessId: "", + currentAttempt: 0, + }), + }), + { name: "agentsStore", storage: createJSONStorage(() => localStorage) } + ) + ) +); diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/agents/FindVulnerabilities.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/agents/FindVulnerabilities.tsx new file mode 100644 index 0000000000..42ff58f1ca --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/agents/FindVulnerabilities.tsx @@ -0,0 +1,104 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { Scrollable, VerticalStack } from '@shopify/polaris'; +import { AgentRun, AgentSubprocess, State } from '../types'; +import { Subprocess } from '../components/agentResponses/Subprocess'; +import { useAgentsStore } from '../agents.store'; +import api from '../api'; + +export const FindVulnerabilitiesAgent = (props) => { + + const {agentId, finalCTAShow, setFinalCTAShow} = props + + const [currentAgentRun, setCurrentAgentRun] = useState(null); + const [subprocesses, setSubprocesses] = useState([]); + + // ?? Where exactly is agent steps being used. + // I didn't find any use case, we can remove it. + const { setCurrentAttempt, setCurrentSubprocess, setCurrentProcessId, resetStore} = useAgentsStore(); + + const getAllAgentRuns = async () => { + try { + const response = (await api.getAllAgentRuns(agentId)); + const agentRuns = response.agentRuns as AgentRun[]; + setCurrentAgentRun(agentRuns[0]); + if (agentRuns.length > 0 && agentRuns[0]?.processId) { + setCurrentProcessId(agentRuns[0]?.processId) + } else { + // TODO: handle cases here, because the above API only gets "RUNNING" Agents. + // setCurrentProcessId("") + resetStore(); + } + } catch(error) { + resetStore(); + } + } + + const getAllSubProcesses = async (processId: string) => { + // polling for all subprocesses; + const response = await api.getAllSubProcesses({ + processId: processId + }); + const subprocesses = response.subProcesses as AgentSubprocess[]; + + setSubprocesses(subprocesses); + + if(subprocesses.length > 0) { + // if page-reload, this will be called to fill the data required in the localstorage + let newestSubprocess = subprocesses[0] + subprocesses.forEach((subprocess) => { + if(subprocess.createdTimestamp > newestSubprocess.createdTimestamp){ + newestSubprocess = subprocess + } + }); + setCurrentSubprocess(newestSubprocess.subProcessId) + setCurrentAttempt(newestSubprocess.attemptId) + } + if(subprocesses.length === 0) { + // create first subprocess of the agent run here + const response = await api.updateAgentSubprocess({ + processId: processId, + subProcessId: "1", + attemptId: 1 + }); + setCurrentSubprocess("1"); + setCurrentAttempt(1); + const subprocess = response.subprocess as AgentSubprocess; + setSubprocesses([...subprocesses, subprocess]); + } + + } + const intervalRef = useRef(null); + + useEffect(() => { + if (!currentAgentRun || currentAgentRun?.state !== State.RUNNING) { + setCurrentAttempt(0); + setCurrentSubprocess("0"); + intervalRef.current = setInterval(getAllAgentRuns, 2000); + } else { + getAllSubProcesses(currentAgentRun.processId); + } + + return () => { + if (intervalRef.current) { + clearInterval(intervalRef.current); + intervalRef.current = null; + } + }; + }, [currentAgentRun]); + + return ( + + + {subprocesses.length > 0 && subprocesses.map((subprocess, index) => ( + + ))} + + + ) +} diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/api.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/api.js new file mode 100644 index 0000000000..32afd9f2cb --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/api.js @@ -0,0 +1,67 @@ +import request from "@/util/request"; +const api = { + getAgentModels: async () => { + return await request({ + url: '/api/getAgentModels', + method: 'post', + data: {} + }) + }, + getMemberAgents: async () => { + return await request({ + url: '/api/getMemberAgents', + method: 'post', + data: {} + }) + }, + + createAgentRun: async (data) => { + return await request({ + url: '/api/createAgentRun', + method: 'post', + data: data + }) + }, + + getAllSubProcesses: async (data) => { + return await request({ + url: '/api/getAllSubProcesses', + method: 'post', + data: data + }) + }, + + getSubProcess: async (data) => { + return await request({ + url: '/api/getSubProcess', + method: 'post', + data: data + }) + }, + + updateAgentSubprocess: async (data) => { + return await request({ + url: '/api/updateAgentSubprocess', + method: 'post', + data: data + }) + }, + + getAllAgentRuns: async (agent) => { + return await request({ + url: '/api/getAllAgentRuns', + method: 'post', + data: {agent} + }) + }, + + updateAgentRun: async (data) => { + return await request({ + url: '/api/updateAgentRun', + method: 'post', + data: data + }) + }, +} + +export default api; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentHeader.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentHeader.tsx new file mode 100644 index 0000000000..43bfca0868 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentHeader.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { Text } from '@shopify/polaris'; +import { AgentImage } from './AgentImage'; +import { Agent } from '../types'; + +export const AgentHeader = ({ agent }: { agent: Agent | null }) => { + if (!agent) return null; + + return ( +
+
+ +
+ {agent.name} + + {agent.description} + +
+
+
+ ); +} \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentImage.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentImage.tsx new file mode 100644 index 0000000000..e7aec411b7 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentImage.tsx @@ -0,0 +1,9 @@ +import React from 'react'; + +export const AgentImage = ({ src, alt }: { src: string, alt: string }) => { + return ( +
+ {alt} +
+ ) +} \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentWindow.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentWindow.tsx new file mode 100644 index 0000000000..b46d003c9a --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/AgentWindow.tsx @@ -0,0 +1,99 @@ +import React, { useState } from 'react'; +import { PromptComposer } from './PromptComposer'; +import { Agent } from '../types'; +import { AgentHeader } from './AgentHeader'; +import { FindVulnerabilitiesAgent } from '../agents/FindVulnerabilities'; +import { Box, Scrollable, VerticalStack } from '@shopify/polaris'; +import RepositoryInitializer from './RepositoryInitializer'; +import SensitiveDataAgentInitializer from './SensitiveDataAgentInitializer'; +import FlyLayout from '../../../components/layouts/FlyLayout'; +import SensitiveDataTypeCTA from './finalctas/SensitiveDataTypeCTA'; +import ApiGroupAgentInitializer from './ApiGroupAgentInitializer'; +import { useAgentsStore } from '../agents.store'; + +interface AgentWindowProps { + agent: Agent | null; + onClose: () => void; + open: boolean; +} + +function AgentWindow({ agent, onClose, open }: AgentWindowProps) { + + const [finalCTAShow, setFinalCTAShow] = useState(false) + const { currentProcessId } = useAgentsStore() + + const renderAgentWindow = () => { + switch (agent?.id) { + case 'FIND_VULNERABILITIES_FROM_SOURCE_CODE': + return ( + + {(currentProcessId === null || currentProcessId.length === 0) ? : <>} + + + ) + case 'FIND_SENSITIVE_DATA_TYPES': + return ( + + {(currentProcessId === null || currentProcessId.length === 0) ? : <> } + + + ) + case 'GROUP_APIS': + return( + + {(currentProcessId === null || currentProcessId.length === 0) ? : <> } + + + ) + case 'FIND_FALSE_POSITIVE': + return (<>) + default: + return (<>) + } + } + + function AgentFinalCTA() { + switch (agent?.id) { + case 'FIND_VULNERABILITIES_FROM_SOURCE_CODE': + return (<>) + case 'FIND_SENSITIVE_DATA_TYPES': + return () + case 'GROUP_APIS': + return (<>) + case 'FIND_FALSE_POSITIVE': + return (<>) + default: + return (<>) + } + } + + const components = [
+ +
+
+ +
+ + {renderAgentWindow()} + + +
+
+
+ +
+
] + + return ( + { }} + isHandleClose={true} + handleClose={onClose} + title={"Agent Details"} + components={components} + /> + ) +} + +export default AgentWindow; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/ApiGroupAgentInitializer.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/ApiGroupAgentInitializer.jsx new file mode 100644 index 0000000000..b7982f7508 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/ApiGroupAgentInitializer.jsx @@ -0,0 +1,69 @@ +import { Box, VerticalStack, Text, Button } from "@shopify/polaris"; +import React, { useState } from "react"; +import DropdownSearch from "../../../components/shared/DropdownSearch"; +import PersistStore from "../../../../main/PersistStore"; +import agentApi from '../api' +import func from "../../../../../util/func"; + +function ApiGroupAgentInitializer(props) { + + const { agentType } = props + + const [selectedCollections, setSelectedCollections] = useState([]); + const allCollections = PersistStore(state => state.allCollections) + const optionsList = allCollections.filter(x => !x.deactivated).map((x) => { + return { + label: x.displayName, + value: x.id, + } + }) + + async function startAgent(collectionIds) { + if (collectionIds.length === 0) { + func.setToast(true, true, "Please select collections to run the agent") + return + } + + await agentApi.createAgentRun({ + agent: agentType, + data: { + apiCollectionIds: collectionIds + } + }) + func.setToast(true, false, "Agent run scheduled") + } + + function StartButton() { + return + } + + function CollectionSelector() { + return ( + + + + Hey! Let's select API collections to run the API grouping agent on. + + + + + + + + ) + } + + return + } + + +export default ApiGroupAgentInitializer \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/BlockedState.css b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/BlockedState.css new file mode 100644 index 0000000000..c5bf3a05b8 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/BlockedState.css @@ -0,0 +1,40 @@ +#approve-button { + display: flex; + padding: 2px 8px; + align-items: center; + gap: 10px; + border-radius: 4px; + background: var(--akto-primary); + box-shadow: 0px 1px 0px 0px rgba(0, 0, 0, 0.08), 0px -1px 0px 0px rgba(0, 0, 0, 0.20) inset; + color: white; + text-align: center; + font-size: 12px; + font-style: normal; + font-weight: 600; + line-height: 16px; /* 133.333% */ +} + +#discard-button { + display: flex; + align-items: center; + gap: 4px; + color: #6D7175; + text-align: center; + cursor: pointer; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; /* 142.857% */ +} + +@keyframes ellipsis { + 0% { + clip-path: inset(0 100% 0 0); + } + 50% { + clip-path: inset(0 0 0 0); + } + 100% { + clip-path: inset(0 0 0 0); + } +} \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/BlockedState.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/BlockedState.tsx new file mode 100644 index 0000000000..86d6c2348a --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/BlockedState.tsx @@ -0,0 +1,98 @@ +import { Button, Icon, Text } from '@shopify/polaris'; +import { PauseMajor } from '@shopify/polaris-icons'; +import React from 'react'; +import { motion, AnimatePresence } from 'motion/react'; +import { isBlockingState, useAgentsStore } from '../agents.store'; + +import './BlockedState.css'; + +interface BlockedStateProps { + onResume: () => void; + onDiscard: () => void; +} + +export const BlockedState = ({ onResume, onDiscard }: BlockedStateProps) => { + const { agentState, setAttemptedInBlockedState, attemptedInBlockedState, setAgentState } = useAgentsStore(); + + const handleResume = () => { + setAgentState('idle'); + onResume(); + } + + const isPaused = agentState === 'paused'; + const isThinking = agentState === 'thinking'; + + const show = isPaused || isThinking; + + const handleDiscard = () => { + setAgentState('idle'); + onDiscard(); + } + + return ( + + {show && ( + { + setAttemptedInBlockedState(false); + } + } + } + }} + className="absolute min-h-[38px] -top-[38px] py-2 px-3 w-[90%] left-1/2 -translate-x-1/2 bg-[var(--agent-grey-background)] border border-[var(--borderShadow-box-shadow)] rounded-t-sm flex justify-between items-center z-[100]" + > + { + isPaused && ( + <> +
+ + + Paused (Member is waiting for your response) + +
+
+ + +
+ + )} + { + isThinking && ( + <> + + Thinking + ... + + + ) + } +
+ )} +
+ ); +}; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/ModelPicker.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/ModelPicker.tsx new file mode 100644 index 0000000000..10908f2f18 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/ModelPicker.tsx @@ -0,0 +1,113 @@ +import * as Select from '@radix-ui/react-select'; +import React, { MouseEventHandler, useEffect, useState } from 'react'; +import { CaretDownMinor, CaretUpMinor, TickMinor } from '@shopify/polaris-icons'; +import { motion, AnimatePresence } from 'framer-motion'; + +import { Icon, Text } from '@shopify/polaris'; +import { Model } from '../types'; +import { isBlockingState, useAgentsStore } from '../agents.store'; + +export const MODELS: Model[] = [ + { id: 'claude-3-sonnet', name: 'Claude-3.5-sonnet' }, + { id: 'gpt-4o', name: 'GPT-4o' }, + { id: 'gpt-4o-mini', name: 'GPT-4o-mini' }, + { id: 'gpt-3.5-turbo', name: 'GPT-3.5-turbo' }, + { id: 'gemini-1.5-flash', name: 'Gemini-1.5-flash' }, + // Add other models here +]; + +interface ModelPickerProps { + selectedModel: Model | null; + setSelectedModel: (modelId: Model) => void; + availableModels: Model[]; +} + +export const ModelPicker = ({ availableModels, selectedModel, setSelectedModel }: ModelPickerProps) => { + const [open, setOpen] = useState(false); + + const onModelChange = (value: string) => { + const model = availableModels.find((model) => model.id === value); + if (model) { + setSelectedModel(model); + } + }; + + const { agentState, setAttemptedInBlockedState } = useAgentsStore(); + + const isInBlockedState = isBlockingState(agentState); + + useEffect(() => { + if (availableModels.length > 0) { + setSelectedModel(availableModels[0]); + } + }, [availableModels]); + + const handleTriggerClick: MouseEventHandler = (event) => { + if (isInBlockedState) { + setAttemptedInBlockedState(true); + event.preventDefault(); + } else { + setOpen(true); + } + } + + const trigger = ( + + ) + + + return ( + + {isInBlockedState ? trigger : {trigger}} + + + + + {availableModels.map((model, index) => ( + + {model.name} + + + + + ))} + + + + + + ); +}; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/PromptComposer.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/PromptComposer.tsx new file mode 100644 index 0000000000..e6a5be8d35 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/PromptComposer.tsx @@ -0,0 +1,151 @@ +import React, { useEffect, useState } from 'react'; +import { useEditor, EditorContent } from '@tiptap/react'; +import StarterKit from '@tiptap/starter-kit'; +import Placeholder from '@tiptap/extension-placeholder'; +import ListItem from '@tiptap/extension-list-item'; +import OrderedList from '@tiptap/extension-ordered-list'; +import BulletList from '@tiptap/extension-bullet-list'; +import './composer.styles.css'; + +import { Button, Tooltip } from '@shopify/polaris'; + +import { SendMajor } from '@shopify/polaris-icons'; + +import { ModelPicker } from './ModelPicker'; +import { isBlockingState, useAgentsStore } from '../agents.store'; +import { PromptPayload, State } from '../types'; +import { getPromptContent } from '../utils'; +import { BlockedState } from './BlockedState'; +import api from '../api'; +import func from '../../../../../util/func'; +import { intermediateStore } from '../intermediate.store'; +import { structuredOutputFormat } from '../constants'; + + +interface PromptComposerProps { + onSend: (prompt: PromptPayload) => void; + agentId: string | undefined; +} + +export const PromptComposer = ({ onSend, agentId }: PromptComposerProps) => { + const [isFocused, setIsFocused] = useState(false); + const { currentProcessId, currentSubprocess, currentAttempt } = useAgentsStore(); + const { filteredUserInput } = intermediateStore(); + const { + currentPrompt, + setCurrentPrompt, + availableModels, + selectedModel, + setSelectedModel, + agentState, + setAttemptedInBlockedState, + } = useAgentsStore(); + + const isInBlockedState = isBlockingState(agentState); + const editor = useEditor({ + extensions: [ + StarterKit, + Placeholder.configure({ + placeholder: 'Message agent...', + showOnlyWhenEditable: false, + }), + ListItem, + OrderedList, + BulletList, + ], + content: '', + editorProps: { + attributes: { + class: 'prose prose-slate focus:outline-none', + }, + }, + onUpdate: ({ editor }) => { + setCurrentPrompt(getPromptContent(editor)); + }, + onFocus: () => { + setIsFocused(true); + }, + onBlur: () => { + setIsFocused(false); + } + }); + + useEffect(() => { + editor?.setEditable(!isInBlockedState); + }, [isInBlockedState]); + + if (!editor) return null; + + const handleSend = () => { + if (!selectedModel || !currentPrompt) return; + + const prompt: PromptPayload = { + model: selectedModel, + prompt: currentPrompt, + } + + onSend(prompt); + } + + async function onResume() { + + // when selected choices are provided by the user, accepted case should be returned to the agent + // agent if gets user-input, with the accepted state, it should take that into account + + await api.updateAgentSubprocess({ + processId: currentProcessId, + subProcessId: currentSubprocess, + attemptId: currentAttempt, + state: filteredUserInput !== null ? State.USER_PROVIDED_SOLUTION : State.ACCEPTED.toString(), + data: { selectedOptions: structuredOutputFormat(filteredUserInput, agentId , currentSubprocess || "") } + }); + func.setToast(true, false, "Member solution accepted") + } + + async function onDiscard() { + await api.updateAgentSubprocess({ + processId: currentProcessId, + subProcessId: currentSubprocess, + attemptId: currentAttempt, + state: filteredUserInput !== null ? State.USER_PROVIDED_SOLUTION : State.DISCARDED.toString(), + data: { selectedOptions: structuredOutputFormat(filteredUserInput, agentId , currentSubprocess || "") } + }); + func.setToast(true, false, "Member solution discarded") + } + + return ( +
+ +
+
isInBlockedState && setAttemptedInBlockedState(true)}> + {/* */} +
+ isInBlockedState && setAttemptedInBlockedState(true)} /> +
+
+
+ {availableModels.length > 0 && ( + + )} +
+ +
isInBlockedState && setAttemptedInBlockedState(true)}> +
+
+
+
+ ); +}; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/RepositoryInitializer.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/RepositoryInitializer.tsx new file mode 100644 index 0000000000..8635d30b7d --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/RepositoryInitializer.tsx @@ -0,0 +1,164 @@ +import { Box, Button, HorizontalStack, Text, TextField, VerticalStack } from '@shopify/polaris' +import React, { useState } from 'react' +import SSOTextfield from '../../../../signup/components/SSOTextfield' +import { RepoPayload, RepoType } from '../types' +import api from '../../quick_start/api' +import { useAgentsStore } from '../agents.store' +import func from "../../../../../util/func" +import GridRows from '../../../components/shared/GridRows' +import SelectRepoComp from './agentResponses/SelectRepoComp' +import DropdownSearch from '../../../components/shared/DropdownSearch' +import agentApi from '../api' + +function RepositoryInitializer({agentType}: {agentType: string}) { + const { setSelectedRepository } = useAgentsStore() + const [reposList, setReposList] = useState([]) + const [selectedConnection, setSelectedConnection] = React.useState('') + const [selectedRepo, setSelectedRepo] = React.useState('') + const [selectedProject, setSelectedProject] = React.useState('') + const [temp, setTemp] = React.useState('') + const getIcon = (id:string) => { + switch (id) { + case 'GITHUB': + return '/public/github.svg'; + case 'GITLAB': + return '/public/gitlab.svg'; + case 'BIT_BUCKET': + return '/public/bitbucket.svg'; + default: + return ''; + } + } + const handleClick = async (id: string) => { + try { + const resp: any = await api.fetchCodeAnalysisRepos(id); + if(resp?.codeAnalysisRepos.length !== 0) { + const formattedRepos: RepoPayload[] = resp?.codeAnalysisRepos.map((x: any) => ({ + repo: x.repoName, + project: x.projectName, + lastRun: x.lastRun, + scheduleTime: x.scheduleTime, + })); + setReposList(formattedRepos.sort((a, b) => b.lastRun - a.lastRun)); + setSelectedConnection(id) + }else{ + window.open("/dashboard/quick-start?connect=" + id.toLowerCase(), "_blank"); + } + } catch (error) { + window.open("/dashboard/quick-start?connect=" + id.toLowerCase(), "_blank"); + } + } + + const handleClickRepo = async (repo: string, project: string, localString: string | null) => { + setSelectedProject(project); + setSelectedRepo(repo); + setSelectedRepository(repo + "/" + project); + await agentApi.createAgentRun({ + agent: agentType, + data: { + projectDir: func.checkLocal() ? localString : repo + "/" + project + } + }) + } + + const connectionOptions: RepoType[] = [ + { + id: 'GITHUB', + logo: '/public/github.svg', + text: 'Continue with GitHub', + onClickFunc: () => handleClick('GITHUB') + }, + { + id: 'GITLAB', + logo: '/public/gitlab.svg', + text: 'Continue with GitLab', + onClickFunc: () => handleClick('GITLAB') + }, + { + id: 'BIT_BUCKET', + logo: '/public/bitbucket.svg', + text: 'Continue with BitBucket', + onClickFunc: () => handleClick('BIT_BUCKET') + } + ] + + function RepoInitializer () { + return( + + + + + + Integrate the tools + Connect your repository to begin scanning and protecting your code. Choose your preferred source. + + + {connectionOptions.map((connection, index) => ( + + ))} + {func.checkLocal() ? setTemp(x)} + connectedRight={} + /> : null} + + + + + + ) + } + + function RepoSelector () { + return( + + + + Hey! I see you've connected your {func.toSentenceCase(selectedConnection)} account. Found {reposList.length} repositories which one would you like me to analyze? + + + { + return{ + label: x.project + " / " + x.repo , + value: x.repo + "/" + x.project, + } + }) + } + setSelected={(x:string) => { + handleClickRepo(x.split("/")[0], x.split("/")[1], null) + }} + value={selectedRepo.length > 0 ?selectedRepo + "/" + selectedProject : ""} + /> + + + + Recently added: + { + return { + ...x, + icon: getIcon(selectedConnection) + } + })} CardComponent={SelectRepoComp} horizontalGap={"3"} verticalGap={"3"} columns={3} + onButtonClick={(repo:string, project:string) => { + handleClickRepo(repo, project, null) + }} + /> + + + + ) + } + + return ( + selectedConnection.length === 0 ? : + ) +} + +export default RepositoryInitializer \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/SensitiveDataAgentInitializer.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/SensitiveDataAgentInitializer.jsx new file mode 100644 index 0000000000..3f8f23d6a2 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/SensitiveDataAgentInitializer.jsx @@ -0,0 +1,68 @@ +import { Box, VerticalStack, Text, Button } from "@shopify/polaris"; +import React, { useState } from "react"; +import DropdownSearch from "../../../components/shared/DropdownSearch"; +import PersistStore from "../../../../main/PersistStore"; +import agentApi from '../api' +import func from "../../../../../util/func"; + +function SensitiveDataAgentInitializer(props) { + + const { agentType } = props + + const [selectedCollections, setSelectedCollections] = useState([]); + const allCollections = PersistStore(state => state.allCollections) + const optionsList = allCollections.filter(x => !x.deactivated).map((x) => { + return { + label: x.displayName, + value: x.id, + } + }) + + async function startAgent(collectionIds) { + if (collectionIds.length === 0) { + func.setToast(true, true, "Please select collections to run the agent") + return + } + + await agentApi.createAgentRun({ + agent: agentType, + data: { + apiCollectionIds: collectionIds + } + }) + func.setToast(true, false, "Agent run scheduled") + } + + function StartButton() { + return + } + + function CollectionSelector() { + return ( + + + + Hey! Let's select API collections to run the sensitive data type scanner on. + + + + + + + + ) + } + + return +} + +export default SensitiveDataAgentInitializer; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/AuthOptions.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/AuthOptions.tsx new file mode 100644 index 0000000000..5e3aa8bad3 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/AuthOptions.tsx @@ -0,0 +1,41 @@ +import { Text, Icon } from '@shopify/polaris'; +import { KeyMajor } from '@shopify/polaris-icons'; +import React, { useState } from 'react'; + +type AgentOptionProps = { + options: string[]; + text: string; + onSelect: (option: string) => void; + showIcon?: boolean; +} + +export const AgentOptions = ({ options, onSelect, text, showIcon = true }: AgentOptionProps) => { + const [selectedOption, setSelectedOption] = useState(null); + + const handleSelect = (option: string) => { + setSelectedOption(option); + onSelect(option); + } + + return ( +
+ {text} +
+ {options.map((option) => ( + + ))} +
+
+ ) +} \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/OutputSelector.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/OutputSelector.tsx new file mode 100644 index 0000000000..f2371b51e1 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/OutputSelector.tsx @@ -0,0 +1,75 @@ +import React, { useEffect, useState } from 'react' +import { HorizontalStack, Text, TextField, VerticalStack } from "@shopify/polaris" +import DropdownSearch from "../../../../components/shared/DropdownSearch" + +interface OutputSelectorProps { + onHandleSelect: (selectedChoice: any, outputOptions: any) => void; + processOutput: Record; +} + +export const getMessageFromObj = (obj: any, key:string) => { + if(typeof obj === "string"){ + return obj; + }else{ + if(obj[key]){ + return obj[key]; + } + } +} + +function OutputSelector({onHandleSelect, processOutput} : OutputSelectorProps) { + + const getStringMessage = (type: string, options: any[]) =>{ + let maxOutputOptions = type === "multiple" ? 3 : 1; + let messageString = ""; + options.slice(0, maxOutputOptions).forEach((option: any) => { + messageString += getMessageFromObj(option, "textValue") + " "; + }) + if(maxOutputOptions < options.length && type === "multiple"){ + messageString += "and " + (options.length - maxOutputOptions) + " more..."; + } + return messageString; + } + const messageString = processOutput?.outputMessage + "\n We are moving forward with the following option(s):\n"; + + const allowMultiple = processOutput?.selectionType === "multiple" + const initialValue = !allowMultiple ? + getMessageFromObj(processOutput?.outputOptions[0], "textValue") : + processOutput?.outputOptions.map((option: any) => (option.value !== undefined ? option.value : option)); + const [filteredChoices, setFilteredChoices] = useState(initialValue); + const handleSelected = (selectedChoices: any) => { + setFilteredChoices(selectedChoices); + } + + useEffect(() => { + onHandleSelect(filteredChoices, processOutput) + },[filteredChoices]) + + return ( + + + {messageString} + {getStringMessage(processOutput?.selectionType, processOutput?.outputOptions)} + + + For editing or more info: + {processOutput?.outputOptions.length > 1 ? { + return { + label: option.textValue!==undefined ? option?.textValue : option, + value: option.value!==undefined ? option.value : option, + } + })} + placeHolder={"Edit choice(s)"} + setSelected={(selectedChoices: any) => handleSelected(selectedChoices)} + preSelected={filteredChoices} + value={processOutput?.selectedType === 'multiple' ?`${filteredChoices.length} choice${filteredChoices.length===1 ? "" : "s"} selected` : filteredChoices} + /> : setFilteredChoices(val)}/>} + + + + ) +} + +export default OutputSelector diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/SelectRepoComp.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/SelectRepoComp.jsx new file mode 100644 index 0000000000..306afd0ca6 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/SelectRepoComp.jsx @@ -0,0 +1,25 @@ +import { Avatar, Box, Button, HorizontalStack } from '@shopify/polaris'; +import React from 'react' +import TooltipText from '../../../../components/shared/TooltipText'; + +function SelectRepoComp(props) { + const {repo, project, icon} = props.cardObj + + return( + + ) +} + + +export default SelectRepoComp \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/Subprocess.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/Subprocess.tsx new file mode 100644 index 0000000000..7e50616b35 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/agentResponses/Subprocess.tsx @@ -0,0 +1,204 @@ +import React, { useState, useEffect } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { AgentRun, AgentSubprocess, State } from "../../types"; +import { CaretDownMinor } from "@shopify/polaris-icons"; +import api from "../../api"; +import { useAgentsStore } from "../../agents.store"; +import STEPS_PER_AGENT_ID from "../../constants"; +import { VerticalStack, Text } from "@shopify/polaris"; +import OutputSelector, { getMessageFromObj } from "./OutputSelector"; +import { intermediateStore } from "../../intermediate.store"; + +export const Subprocess = ({agentId, processId, subProcessFromProp, finalCTAShow, setFinalCTAShow}: {agentId: string, processId:string, subProcessFromProp: AgentSubprocess, finalCTAShow: boolean, setFinalCTAShow: (show: boolean) => void}) => { + const [subprocess, setSubprocess] = useState(subProcessFromProp); + const [expanded, setExpanded] = useState(true); + + const {setCurrentAttempt, setCurrentSubprocess, currentSubprocess, currentAttempt, setAgentState } = useAgentsStore(); + const { setFilteredUserInput, setOutputOptions } = intermediateStore(); + + + const createNewSubprocess = async (newSubIdNumber: number) => { + let subProcess: AgentSubprocess; + const newSubId = (newSubIdNumber).toLocaleString() + const newRes = await api.updateAgentSubprocess({ + processId: processId, + subProcessId: newSubId, + attemptId: 1 + }); + subProcess = newRes.subprocess as AgentSubprocess; + setCurrentSubprocess(newSubId); + setCurrentAttempt(1); + setAgentState('thinking'); + return subProcess; + } + + const handleSelect = (selectedChoices: any, outputOptions: any) => { + console.log(selectedChoices); + setOutputOptions(outputOptions); + setFilteredUserInput(selectedChoices); + } + + useEffect(() => { + const fetchSubprocess = async () => { + // if(currentSubprocess !== subProcessFromProp.subProcessId){ + // return; + // } + const response = await api.getSubProcess({ + processId: processId, + subProcessId: currentSubprocess, + attemptId: currentAttempt, + }); + let subProcess = response.subprocess as AgentSubprocess; + let agentRun = response.agentRun as AgentRun + + if(subProcess !== null && subProcess.state === State.RUNNING) { + setAgentState("thinking") + } + + /* handle new subprocess creation from here + State => ACCEPTED. + Since we already know, how many total steps are going to be there, + we cross check if this would have been the last step. + */ + if (subProcess !== null && subProcess.state === State.ACCEPTED) { + const newSubIdNumber = Number(currentSubprocess) + 1; + if (newSubIdNumber > STEPS_PER_AGENT_ID[agentId]) { + if(agentRun.state !== "COMPLETED"){ + setFinalCTAShow(true) + await api.updateAgentRun({ processId: processId, state: "COMPLETED" }) + } else { + setAgentState("idle") + } + } else { + // create new subprocess without retry attempt now + subProcess = await createNewSubprocess(newSubIdNumber); + setSubprocess(subProcess); + } + } + + /* + PENDING => completed by the agent + blocked on user to accept / discard (provide solution) / retry with hint. + */ + if(subProcess !== null && subProcess.state === State.COMPLETED) { + setAgentState("paused") + const allowMultiple = subProcess.processOutput?.selectionType === "multiple" + const initialValue = !allowMultiple ? + getMessageFromObj(subProcess.processOutput?.outputOptions[0], "textValue") : + subProcess.processOutput?.outputOptions.map((option: any) => (option.value !== undefined ? option.value : option)); + + // set filtered input default here if needed + } + + /* + DISCARDED => discarded by the user => hence re-attempting the whole subprocess. + */ + if(subProcess !== null && subProcess.state === State.RE_ATTEMPT) { + const tempRes = await api.updateAgentSubprocess({ + processId: processId, + subProcessId: currentSubprocess, + attemptId: currentAttempt + 1 + }); + subProcess = tempRes.subprocess as AgentSubprocess; + setSubprocess(subProcess); + setCurrentAttempt(currentAttempt + 1); + setAgentState("thinking") + } + + if(subProcess !== null && subProcess.state === State.AGENT_ACKNOWLEDGED) { + subProcess = await createNewSubprocess(Number(currentSubprocess) + 1); + setFilteredUserInput(null); + setSubprocess(subProcess); + } + + if(subProcess !== null) { + setSubprocess(subProcess); + if(subProcess.state === State.USER_PROVIDED_SOLUTION){ + // waiting for agent to acknowledge the solution that user provided. + // setFilteredUserInput(null); + setAgentState("idle") + } + }else{ + setAgentState("idle") + } + + } + + const interval = setInterval(fetchSubprocess, 2000); + /* + We do not want to refresh current subprocess, + if we're already at final CTA. + */ + if (finalCTAShow) { + clearInterval(interval); + } + return () => clearInterval(interval); + }, [currentSubprocess, finalCTAShow]); + + if (!subprocess) { + return null; + } + + return ( + +
+ + + + +
+ + {subprocess?.logs?.map((log, index) => ( + + {log.log} + + ))} + +
+
+
+
+ {subprocess.state === State.COMPLETED && subprocess.processOutput !== null && + { + handleSelect(selectedChoices, outputOptions); + }} + /> + } + {subprocess.state === State.ACCEPTED && subprocess.processOutput !== null && + {subprocess.processOutput?.outputMessage} + } + {subprocess.state === State.DISCARDED && subprocess.userInput !== null && + {subprocess.userInput?.inputMessage} + } +
+ ); +} \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/composer.styles.css b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/composer.styles.css new file mode 100644 index 0000000000..b431116b4a --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/composer.styles.css @@ -0,0 +1,62 @@ + +.ProseMirror { + position: relative; + outline: none !important; + min-height: 24px; + max-height: 96px; + overflow-y: auto; + line-height: 24px; +} + +.ProseMirror p { + margin: 0; + line-height: 24px; +} + +.ProseMirror ul, +.ProseMirror ol { + padding-inline-start: 16px; + margin-block-start: 8px; + margin-block-end: 8px; +} + +.ProseMirror ul { + list-style-type: disc; +} + +.ProseMirror ol { + list-style-type: decimal; +} + + +.ProseMirror p.is-editor-empty:first-child::before { + color: #9ca3af; + content: attr(data-placeholder); + float: left; + height: 0; + pointer-events: none; + position: absolute; +} + +/* Custom scrollbar styles */ +.ProseMirror::-webkit-scrollbar { + width: 6px; +} + +.ProseMirror::-webkit-scrollbar-track { + background: transparent; +} + +.ProseMirror::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.2); + border-radius: 3px; +} + +.ProseMirror code { + background-color: #ECEBFF; + padding: 2px 4px; + border-radius: 4px; + font-size: 12px; + font-weight: 500; + color: #374151; +} diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/finalctas/SensitiveDataTypeCTA.tsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/finalctas/SensitiveDataTypeCTA.tsx new file mode 100644 index 0000000000..7fc64749fb --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/finalctas/SensitiveDataTypeCTA.tsx @@ -0,0 +1,42 @@ +import { Modal, VerticalStack, Text } from "@shopify/polaris" +import React from "react" +import { intermediateStore } from "../../intermediate.store"; +import api from "./api"; +import func from "../../../../../../util/func"; + +function SensitiveDataTypeCTA(props) { + + const { show, setShow } = props + + const { filteredUserInput } = intermediateStore(); + + async function saveFunction () { + await api.createSensitiveResponseDataTypes({ dataTypeKeys: filteredUserInput }) + func.setToast(true, false, "Sensitive data types are being created") + setShow(false) + } + + return ( + saveFunction() + }} open={show} + onClose={() => setShow(false)} + > + + + + Do you want to add the {filteredUserInput?.length} selected sensitive data types to Akto ? + + + + + + + + ) +} + +export default SensitiveDataTypeCTA \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/finalctas/api.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/finalctas/api.js new file mode 100644 index 0000000000..7ddf563cad --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/components/finalctas/api.js @@ -0,0 +1,12 @@ +import request from "@/util/request"; +const api = { + createSensitiveResponseDataTypes: async (data) => { + return await request({ + url: '/api/createSensitiveResponseDataTypes', + method: 'post', + data: data + }) + }, +} + +export default api; \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/constants.ts b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/constants.ts new file mode 100644 index 0000000000..46668aa6fd --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/constants.ts @@ -0,0 +1,37 @@ + +const STEPS_PER_AGENT_ID = { + "FIND_VULNERABILITIES_FROM_SOURCE_CODE": 5, + "FIND_APIS_FROM_SOURCE_CODE": 2, + "FIND_SENSITIVE_DATA_TYPES": 1, + "CREATE_TEST_TEMPLATES": 1, + "GROUP_APIS": 1, + "FIND_FALSE_POSITIVE": 1, +} + +export function structuredOutputFormat (output: any, agentType: string | undefined, subProcessId: string): any { + console.log("output", output) + switch (agentType) { + case "FIND_VULNERABILITIES_FROM_SOURCE_CODE": + switch (subProcessId) { + case "1": + return { + "chosenBackendDirectory": output + } + case "2": + if(typeof output === "string") { + const jsonStr = `{${output}}`; + const obj = JSON.parse(jsonStr); + console.log("obj", obj) + return obj + }else{ + return output + } + default: + return output + } + default: + return output + } +} + +export default STEPS_PER_AGENT_ID \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/intermediate.store.ts b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/intermediate.store.ts new file mode 100644 index 0000000000..d755e7015d --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/intermediate.store.ts @@ -0,0 +1,25 @@ +import { create } from "zustand"; +import { devtools, persist, createJSONStorage } from "zustand/middleware"; + +interface AgentsStore { + filteredUserInput: any | null; + setFilteredUserInput: (filteredUserInput: any) => void; + outputOptions: any | null; + setOutputOptions: (outputOptions: any) => void; + +} + +// Zustand Store with Middleware +export const intermediateStore = create()( + devtools( + persist( + (set, get) => ({ + filteredUserInput: null, + setFilteredUserInput: (filteredUserInput: any) => set({ filteredUserInput: filteredUserInput }), + outputOptions: null, + setOutputOptions: (outputOptions: any) => set({ outputOptions: outputOptions }), + }), + { name: "intermediateStore", storage: createJSONStorage(() => sessionStorage) } + ) + ) +); diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/types.ts b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/types.ts new file mode 100644 index 0000000000..79822dbdf4 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/types.ts @@ -0,0 +1,80 @@ +export type Model = { + id: string; + name: string; +} + +export type RepoType = { + id: string; + logo: string; + text: string; + onClickFunc: () => void; +} + +export type RepoPayload = { + repo: string; + project: string; + lastRun: number; + scheduleTime: number; +} + +export type Agent = { + id: string; + name: string; + description: string; + image: string; +} + +export type PromptContent = { + html: string; + markdown: string; +} + +export type PromptPayload = { + model: Model; + prompt: PromptContent; +} + +export type AgentState = 'paused' | 'idle' | 'thinking' | 'error'; + +export enum State { + STOPPED = 'STOPPED', + RUNNING = 'RUNNING', + COMPLETED = 'COMPLETED', + SCHEDULED = 'SCHEDULED', + FAILED = 'FAILED', + DISCARDED = 'DISCARDED', + ACCEPTED = 'ACCEPTED', + PENDING = 'PENDING', + RE_ATTEMPT = "RE_ATTEMPT", + USER_PROVIDED_SOLUTION = "USER_PROVIDED_SOLUTION", + AGENT_ACKNOWLEDGED = "AGENT_ACKNOWLEDGED", +} + +export type AgentRun = { + processId: string; + agentInitDocument?: Record; + agent: string; + createdTimestamp: number; + startTimestamp: number; + endTimestamp: number; + state: State; +} + +export type AgentLog = { + log: string; + eventTimestamp: number; +} + +export type AgentSubprocess = { + processId: string; + subProcessId: string; + subProcessHeading: string | null; + userInput: Record | null; + createdTimestamp: number; + startTimestamp: number; + endTimestamp: number; + state: State; + logs: AgentLog[] | null; + attemptId: number; + processOutput: Record | null; +} diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/utils.ts b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/utils.ts new file mode 100644 index 0000000000..b45943e4bd --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/agent_team/utils.ts @@ -0,0 +1,71 @@ +import { Editor } from "@tiptap/react"; +import { fromHtml } from 'hast-util-from-html'; +import { toMdast } from 'hast-util-to-mdast'; + +import { toMarkdown } from 'mdast-util-to-markdown'; +import { gfm } from 'micromark-extension-gfm'; +import { gfmToMarkdown } from 'mdast-util-gfm'; +import { AgentLog, AgentSubprocess, PromptContent, State } from "./types"; + + +export const getPromptContent = (editor: Editor): PromptContent => { + const html = editor.getHTML(); + const hast = fromHtml(html); + const mdast = toMdast(hast); + + const markdown = toMarkdown(mdast, { + extensions: [gfmToMarkdown()], + }); + + return { + html, + markdown, + }; +}; + + +export const dummySubprocess: AgentSubprocess = { + processId: '1', + subprocessId: '1', + subprocessHeading: 'Subprocess Heading', + userInput: {}, + createdTimestamp: 1714204800, + startedTimestamp: 1714204800, + endedTimestamp: 1714204800, + state: State.RUNNING, + logs: [], + attemptId: '1', + processOutput: {}, +} + +const logs: AgentLog[] = [] +const subprocess = { + ...dummySubprocess, + logs, +}; + +export const getFakeSubProcess = (subprocessId: string, processId: string) => { + // Create a new subprocess instance for each call + const subprocess: AgentSubprocess = { + ...dummySubprocess, + processId, + subprocessId, + logs: [], + }; + + return subprocess; +} + +export const appendLog = (subprocess: AgentSubprocess) => { + const newSubprocess = { + ...subprocess, + logs: [ + ...subprocess.logs, + { + log: `A vertically stacked set of interactive headings that each reveal an associated section of content.`, + eventTimestamp: 1714204800 + subprocess.logs.length * 1000, + } + ] + }; + return newSubprocess; +} \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/dashboard.css b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/dashboard.css index 7c136a4814..44bdc985e3 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/dashboard.css +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/dashboard.css @@ -102,6 +102,14 @@ --color-disabled: #ebebeb ; --color-options: #0d5aa7 ; --white: #ffffff; + --borderShadow-box-shadow: #AEB4B9; + --inset-box-shadow: 0px 1px 0px 0px #898F94 inset; + --agent-grey-background: #F6F6F7; + + --text-default: #202223; + --text-subdued: #6D7175; + + --background-selected: #EDEEEF; --p-color-bg-primary: var(--akto-primary) !important; --p-color-bg-primary-hover: #5400CB !important; diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/QuickStart.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/QuickStart.jsx index 7ac3c31266..bf644aa7bb 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/QuickStart.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/QuickStart.jsx @@ -4,6 +4,7 @@ import api from './api' import UpdateConnections from './components/UpdateConnections' import SpinnerCentered from "../../components/progress/SpinnerCentered" import QuickStartStore from './quickStartStore' +import quickStartFunc from './transform' function QuickStart() { @@ -11,8 +12,21 @@ function QuickStart() { const [myConnections, setMyConnections] = useState([]) const [loading, setLoading] = useState(false) const setActive = QuickStartStore(state => state.setActive) + const setCurrentCardObj = QuickStartStore(state => state.setCurrentConnector) + + const sourceCodeObjectList = quickStartFunc.getSourceCodeConnectors() + const searchParams = new URLSearchParams(window.location.search); + + const queryConnector = sourceCodeObjectList.filter((x) => x.key.toLowerCase() === searchParams.get('connect')) const fetchConnections = async () => { + + if(queryConnector.length > 0) { + setActive("update") + setLoading(false) + setCurrentCardObj(queryConnector[0]) + return; + } setLoading(true) await api.fetchQuickStartPageState().then((resp)=> { setMyConnections(resp.configuredItems) @@ -28,7 +42,7 @@ function QuickStart() { const component = ( loading ? : - myConnections.length > 0 ? + (myConnections.length > 0 || queryConnector.length) > 0?
: diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/components/UpdateConnections.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/components/UpdateConnections.jsx index e86c7b1481..872009fd28 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/components/UpdateConnections.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/components/UpdateConnections.jsx @@ -8,8 +8,6 @@ import TitleWithInfo from '@/apps/dashboard/components/shared/TitleWithInfo'; import FlyLayout from '../../../components/layouts/FlyLayout'; function UpdateConnections(props) { - - const { myConnections } = props; const obj = quickStartFunc.getConnectorsListCategorized() const [newCol, setNewCol] = useState(0) diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/transform.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/transform.js index 1e0608f6d1..99e1ba196b 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/transform.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/quick_start/transform.js @@ -1067,6 +1067,12 @@ const quickStartFunc = { "Source Code": sourceCode, } }, + getSourceCodeConnectors: function () { + const sourceCode = [ + apiInventoryFromSourceCodeObj, githubObj, gitlabObj, bitbucketObj + ]; + return sourceCode + }, getConnectorsList: function () { diff --git a/apps/dashboard/web/polaris_web/web/src/apps/main/App.js b/apps/dashboard/web/polaris_web/web/src/apps/main/App.js index c969d54ce8..46d8f51789 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/main/App.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/main/App.js @@ -33,6 +33,7 @@ import DataTypes from "../dashboard/pages/observe/data_types/DataTypes"; import IssuesPage from "../dashboard/pages/issues/IssuesPage/IssuesPage"; import CompliancePage from "../dashboard/pages/issues/IssuesPage/CompliancePage"; import QuickStart from "../dashboard/pages/quick_start/QuickStart"; +import AgentTeam from "../dashboard/pages/agent_team/AgentTeam"; import Webhooks from "../dashboard/pages/settings/integrations/webhooks/Webhooks"; import Webhook from "../dashboard/pages/settings/integrations/webhooks/Webhook"; import TestRolesPage from "../dashboard/pages/testing/TestRolesPage/TestRolesPage"; @@ -223,6 +224,19 @@ const router = createBrowserRouter([ path: "quick-start", element: , }, + { + path: "agent-team", + children: [ + { + path: "members", + element: + }, + { + path: "hired-members", + element: + } + ] + }, ] }, { diff --git a/apps/dashboard/web/polaris_web/web/src/apps/main/onboardingData.js b/apps/dashboard/web/polaris_web/web/src/apps/main/onboardingData.js index 48726391c6..bca8ddafd3 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/main/onboardingData.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/main/onboardingData.js @@ -671,6 +671,19 @@ const learnMoreObject = { value: "https://www.youtube.com/watch?v=4BIBra9J0Ek" } ] + }, + // TODO: update docs links + dashboard_agent_team_members: { + docsLink: [ + { + content: "Using agents", + value: "https://docs.akto.io/" + }, + { + content: "Discover agents", + value: "https://docs.akto.io/" + } + ], } } diff --git a/apps/dashboard/web/polaris_web/web/webpack.config.dev.js b/apps/dashboard/web/polaris_web/web/webpack.config.dev.js new file mode 100644 index 0000000000..538dd97812 --- /dev/null +++ b/apps/dashboard/web/polaris_web/web/webpack.config.dev.js @@ -0,0 +1,94 @@ +const path = require('path') +const webpack = require('webpack') +const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin') +require("babel-polyfill") + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + mode: 'development', + entry: { + "babel-polyfill": "babel-polyfill", + main: './web/src/apps/main/index.js', + 'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js', + 'json.worker': 'monaco-editor/esm/vs/language/json/json.worker', + }, + output: { + path: path.resolve(__dirname, './dist'), + publicPath: 'http://localhost:3000/dist/', + filename: '[name].js' + }, + module: { + rules: [ + { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, + { + test: /\.scss$/, + use: ['style-loader', 'css-loader', 'sass-loader'], + }, + { + test: /\.sass$/, + use: [ + 'style-loader', + 'css-loader', + { + loader: 'sass-loader', + options: { + indentedSyntax: true, + sassOptions: { indentedSyntax: true } + } + } + ] + }, + { + test: /\.(js|jsx|ts|tsx)$/, + exclude: /node_modules\/(?!(tiptap|tiptap-utils|are-you-es5|tiptap-extensions|monaco-yaml|monaco-worker-manager|monaco-marker-data-provider|monaco-editor)\/).*/, + use: { + loader: 'babel-loader', + options: { + presets: [ + "@babel/preset-env", + ["@babel/preset-react", {"runtime": "automatic"}], + "@babel/preset-typescript" + ], + plugins: [require.resolve('react-refresh/babel')] + } + } + }, + { + test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/, + type: "asset" + } + ] + }, + resolve: { + alias: { + '@': resolve('/web/src') + }, + extensions: ['*', '.js', '.jsx', '.json', '.ts', '.tsx'] + }, + devServer: { + port: 3000, + hot: true, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS", + "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization" + }, + historyApiFallback: true, + client: { + overlay: true, + }, + }, + devtool: 'eval-source-map', + plugins: [ + new ReactRefreshWebpackPlugin(), + ], + performance: { + hints: false + } +} \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/webpack.config.js b/apps/dashboard/web/polaris_web/web/webpack.config.js index 148e0c2ec7..d42325de38 100644 --- a/apps/dashboard/web/polaris_web/web/webpack.config.js +++ b/apps/dashboard/web/polaris_web/web/webpack.config.js @@ -14,10 +14,12 @@ function hashGenerator() { process.env.HASH = hashGenerator() module.exports = { - entry: {"babel-polyfill": "babel-polyfill", main: './web/src/apps/main/index.js', - 'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js', - 'json.worker': 'monaco-editor/esm/vs/language/json/json.worker', -}, + entry: { + "babel-polyfill": "babel-polyfill", + main: './web/src/apps/main/index.js', + 'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js', + 'json.worker': 'monaco-editor/esm/vs/language/json/json.worker', + }, output: { path: path.resolve(__dirname, './dist'), publicPath: process.env.VERSION ==='' || process.env.VERSION.includes("akto-release-version") ? '/polaris_web/web/dist/': 'https://d1hvi6xs55woen.cloudfront.net/polaris_web/' + process.env.VERSION + '/dist/', @@ -58,18 +60,18 @@ module.exports = { ] }, { - test: /\.(js|jsx)$/, + test: /\.(ts|tsx|js|jsx)$/, exclude: /node_modules\/(?!(tiptap|tiptap-utils|are-you-es5|tiptap-extensions|monaco-yaml|monaco-worker-manager|monaco-marker-data-provider|monaco-editor)\/).*/, use: { loader: 'babel-loader', options: { presets: [ "@babel/preset-env", - ["@babel/preset-react", {"runtime": "automatic"}] - ] + ["@babel/preset-react", {"runtime": "automatic"}], + "@babel/preset-typescript" + ] } } - }, { test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/, @@ -81,7 +83,7 @@ module.exports = { alias: { '@': resolve('/web/src') }, - extensions: ['*', '.js', '.jsx', '.json'] + extensions: ['.ts', '.tsx', '.js', '.jsx', '.json', '*'] }, devServer: { historyApiFallback: true, diff --git a/apps/dashboard/web/public/agents/secret-agent-1.svg b/apps/dashboard/web/public/agents/secret-agent-1.svg new file mode 100644 index 0000000000..f30618dc61 --- /dev/null +++ b/apps/dashboard/web/public/agents/secret-agent-1.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/dashboard/web/public/agents/secret-agent-2.svg b/apps/dashboard/web/public/agents/secret-agent-2.svg new file mode 100644 index 0000000000..7c860d8d4a --- /dev/null +++ b/apps/dashboard/web/public/agents/secret-agent-2.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/dashboard/web/public/agents/secret-agent-3.svg b/apps/dashboard/web/public/agents/secret-agent-3.svg new file mode 100644 index 0000000000..4617e4ba85 --- /dev/null +++ b/apps/dashboard/web/public/agents/secret-agent-3.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/dashboard/web/public/agents/secret-agent-4.svg b/apps/dashboard/web/public/agents/secret-agent-4.svg new file mode 100644 index 0000000000..8497a822fa --- /dev/null +++ b/apps/dashboard/web/public/agents/secret-agent-4.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/dashboard/web/public/agents/secret-agent-5.svg b/apps/dashboard/web/public/agents/secret-agent-5.svg new file mode 100644 index 0000000000..3d388f532f --- /dev/null +++ b/apps/dashboard/web/public/agents/secret-agent-5.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/database-abstractor/src/main/java/com/akto/action/AgentAction.java b/apps/database-abstractor/src/main/java/com/akto/action/AgentAction.java new file mode 100644 index 0000000000..337bbd9910 --- /dev/null +++ b/apps/database-abstractor/src/main/java/com/akto/action/AgentAction.java @@ -0,0 +1,326 @@ +package com.akto.action; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.bson.conversions.Bson; + +import com.akto.dao.agents.AgentHealthCheckDao; +import com.akto.dao.agents.AgentRunDao; +import com.akto.dao.agents.AgentSubProcessSingleAttemptDao; +import com.akto.dao.context.Context; +import com.akto.dto.agents.AgentLog; +import com.akto.dto.agents.AgentRun; +import com.akto.dto.agents.AgentSubProcessSingleAttempt; +import com.akto.dto.agents.HealthCheck; +import com.akto.dto.agents.State; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Sorts; +import com.mongodb.client.model.Updates; +import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionSupport; + +public class AgentAction extends ActionSupport { + + String instanceId; + String version; + String processId; + + public String agentHealth() { + + if (instanceId == null || instanceId.isEmpty()) { + addActionError("InstanceId is empty"); + return Action.ERROR.toUpperCase(); + } + + Bson instanceFilter = Filters.eq(HealthCheck.INSTANCE_ID, instanceId); + + List updates = new ArrayList<>(); + + if (version == null || version.isEmpty()) { + addActionError("Agent Version is missing"); + return Action.ERROR.toUpperCase(); + } + + updates.add(Updates.set(HealthCheck.LAST_HEALTH_CHECK_TIMESTAMP, Context.now())); + updates.add(Updates.set(HealthCheck._VERSION, version)); + updates.add(Updates.set(HealthCheck.PROCESS_ID, processId)); + + /* + * This operation has upsert: true. + */ + AgentHealthCheckDao.instance.updateOne(instanceFilter, Updates.combine(updates)); + + Bson timeoutFilter = Filters.lt(HealthCheck.LAST_HEALTH_CHECK_TIMESTAMP, + Context.now() - HealthCheck.HEALTH_CHECK_TIMEOUT); + + AgentHealthCheckDao.instance.deleteAll(timeoutFilter); + + return Action.SUCCESS.toUpperCase(); + } + + AgentRun agentRun; + + public String findEarliestPendingAgentRun() { + + List oldestRunList = AgentRunDao.instance.findAll(Filters.eq(AgentRun._STATE, State.SCHEDULED), 0, 1, + Sorts.ascending(AgentRun.CREATED_TIMESTAMP)); + + if (oldestRunList.isEmpty()) { + return Action.SUCCESS.toUpperCase(); + } + + agentRun = oldestRunList.get(0); + return Action.SUCCESS.toUpperCase(); + } + + String state; + + public String updateAgentProcessState() { + + if (processId == null || processId.isEmpty()) { + addActionError("Process id is invalid"); + return Action.ERROR.toUpperCase(); + } + + Bson processIdFilter = Filters.eq(AgentRun.PROCESS_ID, processId); + + agentRun = AgentRunDao.instance.findOne(processIdFilter); + + if (agentRun == null) { + addActionError("No process found"); + return Action.ERROR.toUpperCase(); + } + + State updatedState = null; + try { + updatedState = State.valueOf(state); + } catch (Exception e) { + addActionError("Invalid process state"); + return Action.ERROR.toUpperCase(); + } + + List updates = new ArrayList<>(); + + /* + * TODO: Add all validations for state filters based + * on current filters and updated filters + */ + if (State.RUNNING.equals(updatedState)) { + if (State.SCHEDULED.equals(agentRun.getState())) { + updates.add(Updates.set(AgentRun._STATE, State.RUNNING)); + updates.add(Updates.set(AgentRun.START_TIMESTAMP, Context.now())); + } else { + addActionError("Only scheduled process can be started"); + return Action.ERROR.toUpperCase(); + } + } + + if (State.COMPLETED.equals(updatedState)) { + if (State.RUNNING.equals(agentRun.getState())) { + updates.add(Updates.set(AgentRun._STATE, State.COMPLETED)); + updates.add(Updates.set(AgentRun.END_TIMESTAMP, Context.now())); + } else { + addActionError("Only running process can be completed"); + return Action.ERROR.toUpperCase(); + } + } + + AgentRunDao.instance.updateOne(processIdFilter, Updates.combine(updates)); + + return Action.SUCCESS.toUpperCase(); + + } + + int attemptId; + String subProcessId; + String subProcessHeading; + String log; + Map processOutput; + AgentSubProcessSingleAttempt subprocess; + + public String updateAgentSubprocess() { + + if (processId == null || processId.isEmpty()) { + addActionError("Process id is invalid"); + return Action.ERROR.toUpperCase(); + } + + Bson processIdFilter = Filters.eq(AgentRun.PROCESS_ID, processId); + + agentRun = AgentRunDao.instance.findOne(processIdFilter); + + if (agentRun == null) { + addActionError("No process found"); + return Action.ERROR.toUpperCase(); + } + + Bson filter = AgentSubProcessSingleAttemptDao.instance.getFiltersForAgentSubProcess(processId, subProcessId, attemptId); + + AgentSubProcessSingleAttempt subProcess = AgentSubProcessSingleAttemptDao.instance.findOne(filter); + + if (subProcess == null) { + addActionError("No subprocess found"); + return Action.ERROR.toUpperCase(); + } + + State updatedState = null; + try { + updatedState = State.valueOf(state); + } catch (Exception e) { + } + + List updates = new ArrayList<>(); + + if (updatedState!=null && State.RUNNING.equals(updatedState) && State.SCHEDULED.equals(subProcess.getState())) { + updates.add(Updates.set(AgentSubProcessSingleAttempt.START_TIMESTAMP, Context.now())); + updates.add(Updates.set(AgentSubProcessSingleAttempt._STATE, State.RUNNING)); + } + + if (subProcessHeading != null) { + updates.add(Updates.set(AgentSubProcessSingleAttempt.SUB_PROCESS_HEADING, subProcessHeading)); + } + + if (log != null) { + updates.add(Updates.addToSet(AgentSubProcessSingleAttempt._LOGS, new AgentLog(log, Context.now()))); + } + + if (updatedState!=null && processOutput != null && State.COMPLETED.equals(updatedState)) { + updates.add(Updates.set(AgentSubProcessSingleAttempt.PROCESS_OUTPUT, processOutput)); + updates.add(Updates.set(AgentSubProcessSingleAttempt._STATE, State.COMPLETED)); + updates.add(Updates.set(AgentSubProcessSingleAttempt.END_TIMESTAMP, Context.now())); + } + + /* + * Upsert: false + * because the state is controlled by user inputs. + */ + subprocess = AgentSubProcessSingleAttemptDao.instance.updateOneNoUpsert(filter, Updates.combine(updates)); + + return Action.SUCCESS.toUpperCase(); + } + + /* + * + * flow for subprocess: + * + * subprocess complete + * |-> user accepts -> accept state marked from dashboard + * and agent moves to next subprocess, which is also created from dashboard. + * |-> user declines -> declined state marked from dashboard + * and new subprocess single attempt created from dashboard with user input. + * + */ + + public String getSubProcess() { + + if (processId == null || processId.isEmpty()) { + addActionError("Process id is invalid"); + return Action.ERROR.toUpperCase(); + } + + Bson processIdFilter = Filters.eq(AgentRun.PROCESS_ID, processId); + + agentRun = AgentRunDao.instance.findOne(processIdFilter); + + if (agentRun == null) { + addActionError("No process found"); + return Action.ERROR.toUpperCase(); + } + + Bson filter = AgentSubProcessSingleAttemptDao.instance.getFiltersForAgentSubProcess(processId, subProcessId, attemptId); + subprocess = AgentSubProcessSingleAttemptDao.instance.findOne(filter); + + return Action.SUCCESS.toUpperCase(); + } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public AgentRun getAgentRun() { + return agentRun; + } + + public void setAgentRun(AgentRun agentRun) { + this.agentRun = agentRun; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public int getAttemptId() { + return attemptId; + } + + public void setAttemptId(int attemptId) { + this.attemptId = attemptId; + } + + public String getSubProcessId() { + return subProcessId; + } + + public void setSubProcessId(String subProcessId) { + this.subProcessId = subProcessId; + } + + public String getSubProcessHeading() { + return subProcessHeading; + } + + public void setSubProcessHeading(String subProcessHeading) { + this.subProcessHeading = subProcessHeading; + } + + public String getLog() { + return log; + } + + public void setLog(String log) { + this.log = log; + } + + public Map getProcessOutput() { + return processOutput; + } + + public void setProcessOutput(Map processOutput) { + this.processOutput = processOutput; + } + + public AgentSubProcessSingleAttempt getSubprocess() { + return subprocess; + } + + public void setSubprocess(AgentSubProcessSingleAttempt subprocess) { + this.subprocess = subprocess; + } + +} \ No newline at end of file diff --git a/apps/database-abstractor/src/main/resources/struts.xml b/apps/database-abstractor/src/main/resources/struts.xml index 471cf7f368..42754410ee 100644 --- a/apps/database-abstractor/src/main/resources/struts.xml +++ b/apps/database-abstractor/src/main/resources/struts.xml @@ -453,6 +453,61 @@ + + + + + + 422 + false + ^actionErrors.* + + + + + + + + + 422 + false + ^actionErrors.* + + + + + + + + + 422 + false + ^actionErrors.* + + + + + + + + + 422 + false + ^actionErrors.* + + + + + + + + + 422 + false + ^actionErrors.* + + + diff --git a/libs/dao/src/main/java/com/akto/DaoInit.java b/libs/dao/src/main/java/com/akto/DaoInit.java index c5ac5b9e3b..6cf8740240 100644 --- a/libs/dao/src/main/java/com/akto/DaoInit.java +++ b/libs/dao/src/main/java/com/akto/DaoInit.java @@ -66,6 +66,7 @@ import com.akto.dto.CollectionConditions.MethodCondition; import com.akto.dto.CollectionConditions.TestConfigsAdvancedSettings; import com.akto.dto.DependencyNode.ParamInfo; +import com.akto.dto.agents.State; import com.akto.dto.auth.APIAuth; import com.akto.dto.billing.Organization; import com.akto.dto.billing.OrganizationFlags; @@ -351,7 +352,8 @@ public static CodecRegistry createCodecRegistry(){ new EnumCodec<>(CustomAuthType.TypeOfToken.class), new EnumCodec<>(TrafficAlerts.ALERT_TYPE.class), new EnumCodec<>(ApiInfo.ApiType.class), - new EnumCodec<>(CodeAnalysisRepo.SourceCodeType.class) + new EnumCodec<>(CodeAnalysisRepo.SourceCodeType.class), + new EnumCodec<>(State.class) ); return fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry, diff --git a/libs/dao/src/main/java/com/akto/dao/agents/AgentHealthCheckDao.java b/libs/dao/src/main/java/com/akto/dao/agents/AgentHealthCheckDao.java new file mode 100644 index 0000000000..ac36523840 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dao/agents/AgentHealthCheckDao.java @@ -0,0 +1,20 @@ +package com.akto.dao.agents; + +import com.akto.dao.CommonContextDao; +import com.akto.dto.agents.HealthCheck; + +public class AgentHealthCheckDao extends CommonContextDao { + + public static final AgentHealthCheckDao instance = new AgentHealthCheckDao(); + + @Override + public String getCollName() { + return "agent_health_check"; + } + + @Override + public Class getClassT() { + return HealthCheck.class; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dao/agents/AgentRunDao.java b/libs/dao/src/main/java/com/akto/dao/agents/AgentRunDao.java new file mode 100644 index 0000000000..1984d07323 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dao/agents/AgentRunDao.java @@ -0,0 +1,22 @@ +package com.akto.dao.agents; + +import com.akto.dao.AccountsContextDao; +import com.akto.dto.agents.AgentRun; + +public class AgentRunDao extends AccountsContextDao { + + public static final AgentRunDao instance = new AgentRunDao(); + + // TODO: create indices + + @Override + public String getCollName() { + return "agent_runs"; + } + + @Override + public Class getClassT() { + return AgentRun.class; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dao/agents/AgentSubProcessSingleAttemptDao.java b/libs/dao/src/main/java/com/akto/dao/agents/AgentSubProcessSingleAttemptDao.java new file mode 100644 index 0000000000..6db4b990e5 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dao/agents/AgentSubProcessSingleAttemptDao.java @@ -0,0 +1,39 @@ +package com.akto.dao.agents; + +import java.util.ArrayList; +import java.util.List; + +import org.bson.conversions.Bson; + +import com.akto.dao.AccountsContextDao; +import com.akto.dto.agents.AgentSubProcessSingleAttempt; +import com.mongodb.client.model.Filters; + +public class AgentSubProcessSingleAttemptDao extends AccountsContextDao{ + + public static final AgentSubProcessSingleAttemptDao instance = new AgentSubProcessSingleAttemptDao(); + + // TODO: create indices + + public Bson getFiltersForAgentSubProcess(String processId, String subProcessId, int attemptId) { + List filters = new ArrayList<>(); + + filters.add(Filters.eq(AgentSubProcessSingleAttempt.PROCESS_ID, processId)); + filters.add(Filters.eq(AgentSubProcessSingleAttempt.SUB_PROCESS_ID, subProcessId)); + filters.add(Filters.eq(AgentSubProcessSingleAttempt.ATTEMPT_ID, attemptId)); + + return Filters.and(filters); + } + + + @Override + public String getCollName() { + return "agent_sub_process_attempts"; + } + + @Override + public Class getClassT() { + return AgentSubProcessSingleAttempt.class; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dto/agents/Agent.java b/libs/dao/src/main/java/com/akto/dto/agents/Agent.java new file mode 100644 index 0000000000..3569e2131b --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/agents/Agent.java @@ -0,0 +1,42 @@ +package com.akto.dto.agents; + +public enum Agent { + + FIND_VULNERABILITIES_FROM_SOURCE_CODE("Matt", "Vulnerability scanner", + "Your code's guardian that identifies security weaknesses and shields against potential attacks"), + FIND_APIS_FROM_SOURCE_CODE("Lisa", "Source code analyser", + "An intelligent agent that analyzes your source code for API endpoints and data flow patterns"), + FIND_SENSITIVE_DATA_TYPES("Damon", "Sensitive data type scanner", + "The privacy sentinel that spots exposed personal information in your API ecosystem"), + CREATE_TEST_TEMPLATES("Edward", "Test template creator", + "Your testing companion that builds customized templates tailored to your API architecture"), + GROUP_APIS("Suzy", "API grouping tool", + "The organization wizard that clusters your APIs into logical service groups and relationships"), + FIND_FALSE_POSITIVE("Lizzie", "Test false positive finder", + "Error detective that hunts down misleading test failures to improve quality assurance efficiency"); + + private final String agentEnglishName; + + public String getAgentEnglishName() { + return agentEnglishName; + } + + private final String agentFunctionalName; + + public String getAgentFunctionalName() { + return agentFunctionalName; + } + + private final String description; + + public String getDescription() { + return description; + } + + Agent(String agentEnglishName, String agentFunctionalName, String description) { + this.agentEnglishName = agentEnglishName; + this.agentFunctionalName = agentFunctionalName; + this.description = description; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dto/agents/AgentLog.java b/libs/dao/src/main/java/com/akto/dto/agents/AgentLog.java new file mode 100644 index 0000000000..436c357182 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/agents/AgentLog.java @@ -0,0 +1,31 @@ +package com.akto.dto.agents; + +public class AgentLog { + String log; + int eventTimestamp; + + public AgentLog(String log, int eventTimestamp) { + this.log = log; + this.eventTimestamp = eventTimestamp; + } + + public AgentLog() { + } + + public String getLog() { + return log; + } + + public void setLog(String log) { + this.log = log; + } + + public int getEventTimestamp() { + return eventTimestamp; + } + + public void setEventTimestamp(int eventTimestamp) { + this.eventTimestamp = eventTimestamp; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dto/agents/AgentRun.java b/libs/dao/src/main/java/com/akto/dto/agents/AgentRun.java new file mode 100644 index 0000000000..fe03dd638f --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/agents/AgentRun.java @@ -0,0 +1,105 @@ +package com.akto.dto.agents; + +import java.util.Map; + +public class AgentRun { + + /* + * This is a random generated UUID + * The process id for the entire agent. Created once per agent. + * process e.g. finding vulnerabilities from source code + * Same as AgentSubProcessSingleAttempt.processId + */ + String processId; + final public static String PROCESS_ID = "processId"; + /* + * Contains agent init information + * e.g. for vulnerability finding agent may contain the repository to run the + * agent on. + * for sensitive data finding agent may contain the collection to run the agent + * on. + * + * Generic Map data type because the data may vary according to agent. + */ + Map agentInitDocument; + Agent agent; + int createdTimestamp; + final public static String CREATED_TIMESTAMP = "createdTimestamp"; + final public static String START_TIMESTAMP = "startTimestamp"; + int startTimestamp; + final public static String END_TIMESTAMP = "endTimestamp"; + int endTimestamp; + State state; + final public static String _STATE = "state"; + + public AgentRun(String processId, Map agentInitDocument, Agent agent, int createdTimestamp, + int startTimestamp, int endTimestamp, State state) { + this.processId = processId; + this.agentInitDocument = agentInitDocument; + this.agent = agent; + this.createdTimestamp = createdTimestamp; + this.startTimestamp = startTimestamp; + this.endTimestamp = endTimestamp; + this.state = state; + } + + public AgentRun() { + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public Map getAgentInitDocument() { + return agentInitDocument; + } + + public void setAgentInitDocument(Map agentInitDocument) { + this.agentInitDocument = agentInitDocument; + } + + public Agent getAgent() { + return agent; + } + + public void setAgent(Agent agent) { + this.agent = agent; + } + + public int getCreatedTimestamp() { + return createdTimestamp; + } + + public void setCreatedTimestamp(int createdTimestamp) { + this.createdTimestamp = createdTimestamp; + } + + public int getStartTimestamp() { + return startTimestamp; + } + + public void setStartTimestamp(int startTimestamp) { + this.startTimestamp = startTimestamp; + } + + public int getEndTimestamp() { + return endTimestamp; + } + + public void setEndTimestamp(int endTimestamp) { + this.endTimestamp = endTimestamp; + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dto/agents/AgentSubProcessSingleAttempt.java b/libs/dao/src/main/java/com/akto/dto/agents/AgentSubProcessSingleAttempt.java new file mode 100644 index 0000000000..fc080c3f5a --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/agents/AgentSubProcessSingleAttempt.java @@ -0,0 +1,223 @@ +package com.akto.dto.agents; + +import java.util.List; +import java.util.Map; + +public class AgentSubProcessSingleAttempt { + + /* + * This is a random generated UUID + * The process id for the entire agent. Created once per agent. + * process e.g. finding vulnerabilities from source code + * Same as AgentRun.processId + */ + String processId; + final public static String PROCESS_ID = "processId"; + /* + * The sub process id for the subprocess in the agent. + * subprocess e.g. find authentication mechanisms subprocess + * inside finding vulnerabilities from source code process. + * + * Cardinal number for subProcess + * + * This ID is per subProcess. + * So for multiple attempts remains same. + */ + String subProcessId; + final public static String SUB_PROCESS_ID = "subProcessId"; + String subProcessHeading; + final public static String SUB_PROCESS_HEADING = "subProcessHeading"; + + /* + * By default user input is empty. + * User can provide input if they choose to, + * to help the agent. + * + * Using a generic type here as the user input + * could be in a variety of formats + * + * TODO: make abstract classes for userInput, agentOutput and apiInitDocument + * and implement them based on feedback on what to expect to/from agent. + * + */ + Map userInput; + final public static String USER_INPUT = "userInput"; + int createdTimestamp; + final public static String CREATED_TIMESTAMP = "createdTimestamp"; + int startTimestamp; + final public static String START_TIMESTAMP = "startTimestamp"; + int endTimestamp; + final public static String END_TIMESTAMP = "endTimestamp"; + State state; + final public static String _STATE = "state"; + /* + * Cardinal number for attempt + */ + int attemptId; + final public static String ATTEMPT_ID = "attemptId"; + List logs; + final public static String _LOGS = "logs"; + /* + * Using a generic type here as the agent output + * could be in a variety of formats + * + * e.g. + * + * backendDirectoriesFound: [ '/app/dir1', '/app/dir2' ] + * backendFrameworksFound: ['struts2', 'mux'] + * vulnerabilities: "The source code contains no vulnerabilities" + * vulnerabilitiesFound: [ {vulnerability: 'BOLA', severity: 'HIGH', + * listOfAPIs:['/api/testing', '/api/finalTesting', '/api/finalFinalTesting']} ] + * + */ + Map processOutput; + final public static String PROCESS_OUTPUT = "processOutput"; + + public class CurrentProcessState { + String processId; + String subProcessId; + int attemptId; + + public CurrentProcessState(String processId, String subProcessId, int attemptId) { + this.processId = processId; + this.subProcessId = subProcessId; + this.attemptId = attemptId; + } + + public CurrentProcessState() { + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getSubProcessId() { + return subProcessId; + } + + public void setSubProcessId(String subProcessId) { + this.subProcessId = subProcessId; + } + + public int getAttemptId() { + return attemptId; + } + + public void setAttemptId(int attemptId) { + this.attemptId = attemptId; + } + + } + + public AgentSubProcessSingleAttempt(String processId, String subProcessId, String subProcessHeading, + Map userInput, int createdTimestamp, int startTimestamp, int endTimestamp, State state, + int attemptId, List logs, Map processOutput) { + this.processId = processId; + this.subProcessId = subProcessId; + this.subProcessHeading = subProcessHeading; + this.userInput = userInput; + this.createdTimestamp = createdTimestamp; + this.startTimestamp = startTimestamp; + this.endTimestamp = endTimestamp; + this.state = state; + this.attemptId = attemptId; + this.logs = logs; + this.processOutput = processOutput; + } + + public AgentSubProcessSingleAttempt() { + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getSubProcessId() { + return subProcessId; + } + + public void setSubProcessId(String subProcessId) { + this.subProcessId = subProcessId; + } + + public String getSubProcessHeading() { + return subProcessHeading; + } + + public void setSubProcessHeading(String subProcessHeading) { + this.subProcessHeading = subProcessHeading; + } + + public int getStartTimestamp() { + return startTimestamp; + } + + public void setStartTimestamp(int startTimestamp) { + this.startTimestamp = startTimestamp; + } + + public int getEndTimestamp() { + return endTimestamp; + } + + public void setEndTimestamp(int endTimestamp) { + this.endTimestamp = endTimestamp; + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + public int getAttemptId() { + return attemptId; + } + + public void setAttemptId(int attemptId) { + this.attemptId = attemptId; + } + + public List getLogs() { + return logs; + } + + public void setLogs(List logs) { + this.logs = logs; + } + + public Map getProcessOutput() { + return processOutput; + } + + public void setProcessOutput(Map processOutput) { + this.processOutput = processOutput; + } + + public Map getUserInput() { + return userInput; + } + + public void setUserInput(Map userInput) { + this.userInput = userInput; + } + + public int getCreatedTimestamp() { + return createdTimestamp; + } + + public void setCreatedTimestamp(int createdTimestamp) { + this.createdTimestamp = createdTimestamp; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dto/agents/HealthCheck.java b/libs/dao/src/main/java/com/akto/dto/agents/HealthCheck.java new file mode 100644 index 0000000000..d747289c5b --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/agents/HealthCheck.java @@ -0,0 +1,68 @@ +package com.akto.dto.agents; + +public class HealthCheck { + + /* + * Random UUID generated on client side. + */ + String instanceId; + public static final String INSTANCE_ID = "instanceId"; + int lastHealthCheckTimestamp; + public static final String LAST_HEALTH_CHECK_TIMESTAMP = "lastHealthCheckTimestamp"; + /* + * Eventually version can help with what all agents are supported on a module. + */ + String version; + public static final String _VERSION = "version"; + /* + * If the instance is running a process, + * processId is filled. + * Else, empty. + */ + String processId; + public static final String PROCESS_ID = "processId"; + + final public static int HEALTH_CHECK_TIMEOUT = 5 * 60 * 60; + + public HealthCheck(String instanceId, int lastHealthCheckTimestamp, String version) { + this.instanceId = instanceId; + this.lastHealthCheckTimestamp = lastHealthCheckTimestamp; + this.version = version; + } + + public HealthCheck() { + } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public int getLastHealthCheckTimestamp() { + return lastHealthCheckTimestamp; + } + + public void setLastHealthCheckTimestamp(int lastHealthCheckTimestamp) { + this.lastHealthCheckTimestamp = lastHealthCheckTimestamp; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dto/agents/Model.java b/libs/dao/src/main/java/com/akto/dto/agents/Model.java new file mode 100644 index 0000000000..bf9bf27ccc --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/agents/Model.java @@ -0,0 +1,18 @@ +package com.akto.dto.agents; + +public enum Model { + + // TODO: use this enum in agent code. + OPEN_AI_GPT_4o_mini("OpenAI GPT-4o mini"); + + private final String modelName; + + Model(String modelName) { + this.modelName = modelName; + } + + public String getModelName() { + return modelName; + } + +} diff --git a/libs/dao/src/main/java/com/akto/dto/agents/State.java b/libs/dao/src/main/java/com/akto/dto/agents/State.java new file mode 100644 index 0000000000..1847c5bd0c --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/agents/State.java @@ -0,0 +1,23 @@ +package com.akto.dto.agents; + +public enum State { + + STOPPED, // agent/subprocess stopped + RUNNING, // agent/subprocess running + COMPLETED, // subprocess completed by agent, waiting on user for + // 1. approve + // 2. discard => + // 2a. reattempt + // 2b. provide solution + SCHEDULED, // agent/subprocess scheduled + FAILED, // agent/subprocess failed + DISCARDED, // subprocess discarded by user and solution provided by user + // creates new subprocess with state USER_PROVIDED_SOLUTION, attempt+1 and preserves agent solution here. + USER_PROVIDED_SOLUTION, // subprocess discarded by user and solution provided by user + RE_ATTEMPT, // subprocess discarded by user and attempted again with more information + // => creates a new subprocess with attemptId+1 + // => preserves agent solution here. + ACCEPTED, // subprocess accepted by user. + PENDING, // subprocess ... + AGENT_ACKNOWLEDGED, // agent acknowledged the user-input +} \ No newline at end of file diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java index f97ca62b60..9e946fabe2 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java @@ -14,7 +14,8 @@ public enum AccessGroups { SETTINGS, ADMIN, DEBUG_INFO, - USER; + USER, + AI; public static AccessGroups[] getAccessGroups() { return values(); @@ -43,7 +44,9 @@ public enum Feature { BILLING(AccessGroups.SETTINGS), INVITE_MEMBERS(AccessGroups.DEBUG_INFO), ADMIN_ACTIONS(AccessGroups.ADMIN), - USER_ACTIONS(AccessGroups.USER); + USER_ACTIONS(AccessGroups.USER), + AI_AGENTS(AccessGroups.AI); + private final AccessGroups accessGroup; Feature(AccessGroups accessGroup) {