diff --git a/.changeset/pr-710-2025280865.md b/.changeset/pr-710-2025280865.md new file mode 100644 index 000000000..aa807db07 --- /dev/null +++ b/.changeset/pr-710-2025280865.md @@ -0,0 +1,5 @@ + +--- +"fusion-project-portal": minor +--- +Portal administration application. for managing portal configurations diff --git a/.github/actions/es-lint/action.yml b/.github/actions/es-lint/action.yml index 757d7842e..280034531 100644 --- a/.github/actions/es-lint/action.yml +++ b/.github/actions/es-lint/action.yml @@ -22,7 +22,7 @@ runs: report-json: "eslint-report.log.json" - name: Upload ESLint report - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 continue-on-error: true with: name: eslint-report.log.json diff --git a/.github/actions/get-fusion-token/action.yml b/.github/actions/get-fusion-token/action.yml new file mode 100644 index 000000000..f2a218683 --- /dev/null +++ b/.github/actions/get-fusion-token/action.yml @@ -0,0 +1,32 @@ +name: Get Fusion token +description: "Runs a composite step action" +inputs: + client-id: + description: "SP client id" + required: true + tenant-id: + description: "Equinor tenant id" + required: true + resource-id: + description: "Resource id" + required: true + +outputs: + token: + description: "Fusion token" + value: ${{ steps.token.outputs.token }} + +runs: + using: "composite" + steps: + - name: "Login to Azure" + uses: azure/login@v1 + with: + client-id: ${{inputs.client-id}} + tenant-id: ${{ inputs.tenant-id }} + allow-no-subscriptions: true + + - name: "Obtain token for upload" + id: token + shell: bash + run: echo "token=$(az account get-access-token --resource '${{ inputs.resource-id }}' | jq '.accessToken')" >> $GITHUB_OUTPUT diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index a662f8c48..9d35eae92 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -9,3 +9,14 @@ runs: cd client yarn install --frozen-lockfile shell: bash + + - name: Install Fusion CLI + run: | + npm i -g @equinor/fusion-framework-cli + shell: bash + + - name: Install App Deps + run: | + cd client/apps/portal-administration + yarn install + shell: bash diff --git a/.github/workflows/common-release.yml b/.github/workflows/common-release.yml index 858b0ccdc..d5cf80401 100644 --- a/.github/workflows/common-release.yml +++ b/.github/workflows/common-release.yml @@ -108,3 +108,46 @@ jobs: --from-environment test --to-environment prod --deployment ${{ steps.get_active_deployments.outputs.activeDeploymentApi }} + + releas-admin: + name: Production Release Portal Administartion Application + needs: changesets + environment: production + runs-on: ubuntu-latest + if: needs.changesets.outputs.published == 'true' + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Get fusion token + id: "get-fusion-token" + uses: ./.github/actions/get-fusion-token + with: + client-id: ${{secrets.AZURE_SP_FUSION}} + tenant-id: ${{secrets.AZURE_TENANT_ID}} + resource-id: ${{secrets.AZURE_FUSION_SCOPE}} + + - name: Install + run: | + cd client + yarn install + npm i -g @equinor/fusion-framework-cli + cd apps/portal-administration + yarn install + + - name: Build + run: | + cd client + yarn build + + - name: Deploy + run: | + cd client/apps/portal-administration + yarn bundle + curl -T "app-bundle.zip" -H "Authorization: bearer ${{steps.get-fusion-token.outputs.token}}" -H "Content-Disposition: attachment; filename=app-bundle.zip" -H "Content-Type: application/zip" -X POST --show-error -i --url https://fusion-s-portal-fprd.azurewebsites.net/api/apps/portal-administration/versions + + - name: Publish + run: | + curl -H "Authorization: bearer ${{steps.get-fusion-token.outputs.token}}" -X POST --show-error -i --url https://fusion-s-portal-fprd.azurewebsites.net/api/apps/portal-administration/publish diff --git a/.github/workflows/deploy-apps-test.yml b/.github/workflows/deploy-apps-test.yml new file mode 100644 index 000000000..609a5697d --- /dev/null +++ b/.github/workflows/deploy-apps-test.yml @@ -0,0 +1,58 @@ +name: Deploy apps CI + +on: + push: + branches: ["main"] + paths: + - "client/apps/portal-administration/**" + +permissions: + actions: read + checks: write + contents: read + deployments: write + id-token: write + +jobs: + build: + environment: non-prod + name: Deploy + timeout-minutes: 15 + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Get fusion token + id: "get-fusion-token" + uses: ./.github/actions/get-fusion-token + with: + client-id: ${{secrets.AZURE_SP_FUSION}} + tenant-id: ${{secrets.AZURE_TENANT_ID}} + resource-id: ${{secrets.AZURE_FUSION_SCOPE}} + + - name: Install + run: | + cd client + yarn install + npm i -g @equinor/fusion-framework-cli + cd apps/portal-administration + yarn install + + - name: Build + run: | + cd client + yarn build + + - name: Deploy + run: | + cd client/apps/portal-administration + yarn bundle + curl -T "app-bundle.zip" -H "Authorization: bearer ${{steps.get-fusion-token.outputs.token}}" -H "Content-Disposition: attachment; filename=app-bundle.zip" -H "Content-Type: application/zip" -X POST --show-error -i --url https://fusion-s-portal-ci.azurewebsites.net/api/apps/portal-administration/versions + + - name: Publish + run: | + curl -H "Authorization: bearer ${{steps.get-fusion-token.outputs.token}}" -X POST --show-error -i --url https://fusion-s-portal-ci.azurewebsites.net/api/apps/portal-administration/publish diff --git a/client/.gitignore b/client/.gitignore index f39d94bd9..1984de817 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -42,4 +42,5 @@ testem.log # System Files .DS_Store -Thumbs.db \ No newline at end of file +Thumbs.db +*.zip diff --git a/client/apps/portal-administration/app.config.ts b/client/apps/portal-administration/app.config.ts new file mode 100644 index 000000000..3033864c2 --- /dev/null +++ b/client/apps/portal-administration/app.config.ts @@ -0,0 +1,13 @@ +import { mergeAppConfigs, defineAppConfig } from '@equinor/fusion-framework-cli'; +export default defineAppConfig((_env, { base }) => + mergeAppConfigs(base, { + environment: { + endpoints: { + client: { + baseUri: 'https://backend-fusion-project-portal-test.radix.equinor.com', + defaultScopes: ['api://02f3484c-cad0-4d1d-853d-3a9e604b38f3/access_as_user'], + }, + }, + }, + }) +); diff --git a/client/apps/portal-administration/app.manifest.config.ts b/client/apps/portal-administration/app.manifest.config.ts new file mode 100644 index 000000000..239159317 --- /dev/null +++ b/client/apps/portal-administration/app.manifest.config.ts @@ -0,0 +1,9 @@ +import { defineAppManifest, mergeManifests } from '@equinor/fusion-framework-cli'; + +export default defineAppManifest((env, { base }) => { + return mergeManifests(base, { + name: 'Portal Administration', + shortName: 'PA', + description: 'Portal Administration tool for fusion as a service', + }); +}); diff --git a/client/apps/portal-administration/package.json b/client/apps/portal-administration/package.json new file mode 100644 index 000000000..ed850f8c9 --- /dev/null +++ b/client/apps/portal-administration/package.json @@ -0,0 +1,46 @@ +{ + "name": "portal-administration", + "version": "1.0.0", + "description": "", + "private": true, + "type": "module", + "main": "src/index.ts", + "scripts": { + "build": "fusion-framework-cli app build", + "dev": "fusion-framework-cli app dev", + "docker": "cd .. && sh docker-script.sh app-react", + "bundle": "fusion-framework-cli app pack" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@equinor/fusion-framework-cli": "^9.12.14", + "@types/react": "^18.2.20", + "@types/react-dom": "^18.2.7", + "typescript": "^5.1.3", + "vitest": "^2.0.5" + }, + "dependencies": { + "react-router-dom": "^6.26.0", + "@equinor/fusion-react-side-sheet": "^1.3.3", + "@equinor/fusion-framework-module-navigation": "^4.0.6", + "@equinor/fusion-framework-react-app": "^5.2.7", + "@ag-grid-community/core": "^32.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "@ag-grid-community/react": "^32.1.0", + "@equinor/eds-core-react": "^0.40.1", + "@equinor/eds-icons": "^0.19.3", + "@equinor/eds-tokens": "^0.9.2", + "@equinor/fusion-react-searchable-dropdown": "^0.5.2", + "@equinor/workspace-ag-grid": "^3.0.2", + "@hookform/resolvers": "^3.9.0", + "@tanstack/react-query": "^5.51.23", + "@tanstack/react-query-devtools": "^5.51.23", + "react-hook-form": "^7.52.2", + "rxjs": "^7.8.1", + "styled-components": "^6.1.1", + "uuidv7": "^1.0.1", + "zod": "^3.23.8" + } +} \ No newline at end of file diff --git a/client/apps/portal-administration/src/App.tsx b/client/apps/portal-administration/src/App.tsx new file mode 100644 index 000000000..8b2fcf037 --- /dev/null +++ b/client/apps/portal-administration/src/App.tsx @@ -0,0 +1,29 @@ +import { RouterProvider } from 'react-router-dom'; +import { useRouter } from '@equinor/fusion-framework-react-app/navigation'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import styled from 'styled-components'; +import routes from './routes'; +import { tokens } from '@equinor/eds-tokens'; + +const queryClient = new QueryClient(); + +const Style = { + Root: styled.div` + background-color: ${tokens.colors.ui.background__light.hex}; + position: absolute; + height: 100%; + width: 100%; + overflow: hidden; + `, +}; + +export default function () { + const router = useRouter(routes); + return ( + + + Error...

} /> +
+
+ ); +} diff --git a/client/apps/portal-administration/src/components/Actions/ActivateSelectedButton.tsx b/client/apps/portal-administration/src/components/Actions/ActivateSelectedButton.tsx new file mode 100644 index 000000000..287c1b643 --- /dev/null +++ b/client/apps/portal-administration/src/components/Actions/ActivateSelectedButton.tsx @@ -0,0 +1,37 @@ +import { Button, Icon } from '@equinor/eds-core-react'; +import { AppManifestResponse, FormattedError, PortalApp } from '../../types'; +import { UseMutateAsyncFunction } from '@tanstack/react-query'; +import { Result } from '../../query/apps-queries'; +import { add_circle_outlined } from '@equinor/eds-icons'; + +type ActivateSelectedButtonProps = { + selection: PortalApp[]; + activateSelected: UseMutateAsyncFunction< + Result[], + FormattedError, + PortalApp[], + { + prevApps: AppManifestResponse[]; + newApps: AppManifestResponse[]; + } + >; +}; + +export const ActivateSelectedButton = ({ selection, activateSelected }: ActivateSelectedButtonProps) => { + const isActive = selection.some((a) => a.isActive); + + if (isActive) { + return null; + } + + return ( + + ); +}; diff --git a/client/apps/portal-administration/src/components/Actions/ActivateSelectedWithContextButton.tsx b/client/apps/portal-administration/src/components/Actions/ActivateSelectedWithContextButton.tsx new file mode 100644 index 000000000..f7c2e4586 --- /dev/null +++ b/client/apps/portal-administration/src/components/Actions/ActivateSelectedWithContextButton.tsx @@ -0,0 +1,32 @@ +import { Button, Icon } from '@equinor/eds-core-react'; +import { PortalApp } from '../../types'; + +import { add_circle_filled } from '@equinor/eds-icons'; + +type ActivateSelectedWithContextButtonProps = { + selection: PortalApp[]; + activateSelectedWithContext: VoidFunction; +}; + +export const ActivateSelectedWithContextButton = ({ + selection, + activateSelectedWithContext, +}: ActivateSelectedWithContextButtonProps) => { + const isActive = selection.some((a) => a.isActive); + + if (isActive) { + return null; + } + + return ( + + ); +}; diff --git a/client/apps/portal-administration/src/components/Actions/EditSelectedButton.tsx b/client/apps/portal-administration/src/components/Actions/EditSelectedButton.tsx new file mode 100644 index 000000000..9ee046ff6 --- /dev/null +++ b/client/apps/portal-administration/src/components/Actions/EditSelectedButton.tsx @@ -0,0 +1,29 @@ +import { Button, Icon } from '@equinor/eds-core-react'; +import { PortalApp } from '../../types'; + +import { add_circle_outlined, edit } from '@equinor/eds-icons'; + +type EditSelectedButtonProps = { + selection: PortalApp[]; + editSelection: VoidFunction; +}; + +export const EditSelectedButton = ({ selection, editSelection }: EditSelectedButtonProps) => { + const isActive = selection.some((a) => !a.isActive); + + if (isActive) { + return null; + } + + return ( + + ); +}; diff --git a/client/apps/portal-administration/src/components/Actions/MakeGlobalAppsButton.tsx b/client/apps/portal-administration/src/components/Actions/MakeGlobalAppsButton.tsx new file mode 100644 index 000000000..ad35fb267 --- /dev/null +++ b/client/apps/portal-administration/src/components/Actions/MakeGlobalAppsButton.tsx @@ -0,0 +1,38 @@ +import { Button, Icon } from '@equinor/eds-core-react'; +import { AppManifestResponse, FormattedError, PortalApp } from '../../types'; +import { UseMutateAsyncFunction } from '@tanstack/react-query'; +import { Result } from '../../query/apps-queries'; +import { check_circle_outlined } from '@equinor/eds-icons'; + +type MakeSelectionGlobalButtonProps = { + selection: PortalApp[]; + makeSelectionGlobal: UseMutateAsyncFunction< + Result[], + FormattedError, + PortalApp[], + { + prevApps: AppManifestResponse[]; + newApps: AppManifestResponse[]; + } + >; +}; + +export const MakeSelectionGlobalButton = ({ selection, makeSelectionGlobal }: MakeSelectionGlobalButtonProps) => { + const isActive = selection.some((a) => a.isActive); + + if (!isActive) { + return null; + } + + return ( + + ); +}; diff --git a/client/apps/portal-administration/src/components/Actions/RemoveAppsButton.tsx b/client/apps/portal-administration/src/components/Actions/RemoveAppsButton.tsx new file mode 100644 index 000000000..5edd8b4b9 --- /dev/null +++ b/client/apps/portal-administration/src/components/Actions/RemoveAppsButton.tsx @@ -0,0 +1,39 @@ +import { Button, Icon } from '@equinor/eds-core-react'; +import { AppManifestResponse, FormattedError, PortalApp } from '../../types'; +import { UseMutateAsyncFunction } from '@tanstack/react-query'; +import { Result } from '../../query/apps-queries'; +import { remove_outlined } from '@equinor/eds-icons'; + +type RemoveAppsButtonProps = { + selection: PortalApp[]; + removeApps: UseMutateAsyncFunction< + Result[], + FormattedError, + PortalApp[], + { + prevApps: AppManifestResponse[]; + newApps: AppManifestResponse[]; + } + >; +}; + +export const RemoveAppsButton = ({ selection, removeApps }: RemoveAppsButtonProps) => { + const isActive = selection.some((a) => !a.isActive); + const appsToRemove = selection.filter((a) => a.isActive); + + if (isActive) { + return null; + } + + return ( + + ); +}; diff --git a/client/apps/portal-administration/src/components/AgStyle.tsx b/client/apps/portal-administration/src/components/AgStyle.tsx new file mode 100644 index 000000000..7c6dfa87b --- /dev/null +++ b/client/apps/portal-administration/src/components/AgStyle.tsx @@ -0,0 +1,54 @@ +import { Chip } from '@equinor/eds-core-react'; +import { tokens } from '@equinor/eds-tokens'; +import styled from 'styled-components'; + +export const AgStyles = { + CellWrapper: styled.div` + display: flex; + gap: 0.5rem; + justify-content: flex-end; + align-items: center; + `, + TextCellWrapper: styled.div` + display: flex; + padding: 0.5rem; + overflow: hidden; + `, + Chip: styled(Chip)` + margin-top: 0.25rem; + `, + TableContent: styled.div` + padding-top: 1rem; + position: relative; + height: calc(100% - 3rem); + width: 100%; + `, + + Icon: styled.span` + > svg { + width: 25px; + } + `, + Indicator: styled.span<{ active?: string }>` + display: block; + height: 16px; + width: 16px; + background-color: ${({ active }) => + active === 'true' + ? tokens.colors.interactive.success__resting.hex + : tokens.colors.interactive.disabled__fill.hex}; + border-radius: 50%; + margin-top: 0.5rem; + `, + Wrapper: styled.div` + .ag-theme-alpine-fusion { + --ag-borders: solid 0px !important; + } + .ag-header, + .ag-advanced-filter-header { + border-bottom: solid 1px var(--ag-border-color) !important; + } + height: 100%; + position: relative; + `, +}; diff --git a/client/apps/portal-administration/src/components/DataClarification.tsx b/client/apps/portal-administration/src/components/DataClarification.tsx new file mode 100644 index 000000000..674b3f76f --- /dev/null +++ b/client/apps/portal-administration/src/components/DataClarification.tsx @@ -0,0 +1,80 @@ +import { Popover, Typography, Chip, Icon } from '@equinor/eds-core-react'; +import { info_circle } from '@equinor/eds-icons'; +import { tokens } from '@equinor/eds-tokens'; + +import { useState, useRef } from 'react'; +import { styled } from 'styled-components'; + +const Styles = { + Chip: styled(Chip)` + background-color: ${tokens.colors.ui.background__info.rgba}; + padding: 0 0.5rem; + margin: 0 1rem; + `, + Content: styled(Popover.Content)` + display: flex; + flex-direction: column; + gap: 1rem; + `, + Ul: styled.ul` + margin: 0 2rem; + padding: 0; + `, +}; + +export const DataClarification = () => { + const [isOpen, setIsOpen] = useState(false); + const handleOpen = () => { + setIsOpen((s) => !s); + }; + const handleClose = () => { + setIsOpen(false); + }; + const referenceElement = useRef(null); + + return ( + <> + + Internal Data Access + + + + + Internal Data Access + + + + You are accessing data that is subject to strict handling and storage protocols. Please ensure + you are familiar with Equinor’s information classification scheme as outlined in{' '} + WR0158 + . + + + By proceeding, you acknowledge your responsibility in maintaining the confidentiality and + appropriate handling of this information. + +
+ By accessing this data, you agree to the following: + + +
  • To only use the data for its intended and authorized purpose.
  • +
  • To not share the data with individuals who do not have the necessary clearance.
  • +
    +
    +
    + + For further details on the classification and labelling of information, please refer to{' '} + WR1211{' '} + - Information security, cyber security and privacy protection. + +
    +
    + + ); +}; diff --git a/client/apps/portal-administration/src/components/Dialogue/DeleteDialog.tsx b/client/apps/portal-administration/src/components/Dialogue/DeleteDialog.tsx new file mode 100644 index 000000000..f61dc3b32 --- /dev/null +++ b/client/apps/portal-administration/src/components/Dialogue/DeleteDialog.tsx @@ -0,0 +1,54 @@ +import { Button, Dialog, Icon, Typography } from '@equinor/eds-core-react'; +import { warning_outlined } from '@equinor/eds-icons'; +import { tokens } from '@equinor/eds-tokens'; +import { styled } from 'styled-components'; + +type DeleteDialogProps = { + open: boolean; + onClose: () => void; + onDelete: () => void; + title: string; + type: 'Portal' | 'Context' | 'Context Type'; +}; + +const Style = { + Actions: styled(Dialog.Actions)` + gap: 1rem; + display: flex; + flex-direction: row; + `, + Dialog: styled(Dialog)` + width: 500px; + `, + Row: styled.div` + padding: 1rem; + gap: 1rem; + display: flex; + flex-direction: row; + align-items: center; + `, +}; + +export const DeleteDialog = ({ open, onClose, onDelete, title, type }: DeleteDialogProps) => { + return ( + + + Delete {type} - {title} + + + + + + Are you sure you want to delete this {type.toLowerCase()}?
    +
    +
    +
    + + + + +
    + ); +}; diff --git a/client/apps/portal-administration/src/components/FormComponents/DescriptionInput.tsx b/client/apps/portal-administration/src/components/FormComponents/DescriptionInput.tsx new file mode 100644 index 000000000..9b824127d --- /dev/null +++ b/client/apps/portal-administration/src/components/FormComponents/DescriptionInput.tsx @@ -0,0 +1,27 @@ +import { Icon, TextField } from '@equinor/eds-core-react'; +import { error_filled } from '@equinor/eds-icons'; +import { FieldErrors, UseFormRegister } from 'react-hook-form'; +import { PortalInputs } from '../../schema'; + +type DescriptionInputProps = { + register: UseFormRegister; + errors: FieldErrors<{ + description?: string | undefined; + }>; +}; + +export const DescriptionInput = ({ register, errors }: DescriptionInputProps) => { + return ( + } + label="Description" + maxLength={500} + /> + ); +}; diff --git a/client/apps/portal-administration/src/components/FormComponents/IconInput.tsx b/client/apps/portal-administration/src/components/FormComponents/IconInput.tsx new file mode 100644 index 000000000..4f558e706 --- /dev/null +++ b/client/apps/portal-administration/src/components/FormComponents/IconInput.tsx @@ -0,0 +1,66 @@ +import { Label, Icon, TextField } from '@equinor/eds-core-react'; +import { error_filled } from '@equinor/eds-icons'; +import { UseFormRegister, FieldErrors } from 'react-hook-form'; +import { PortalInputs } from '../../schema'; +import styled from 'styled-components'; +import * as AllIcons from '@equinor/eds-icons'; + +const Style = { + Row: styled.div` + gap: 1rem; + display: flex; + flex-direction: row; + `, + IconWrapper: styled.div` + background: #00707920; + display: flex; + justify-content: center; + align-items: center; + aspect-ratio: 1 / 1; + width: 132px; + `, + Icon: styled.span` + > svg { + width: 100px; + } + `, +}; + +type IconInputProps = { + register: UseFormRegister; + errors: FieldErrors<{ + icon?: string | undefined; + }>; + icon: string; +}; + +export const IconInput = ({ register, errors, icon }: IconInputProps) => { + return ( + +
    +
    + } + label="Icon" + /> +
    + ); +}; diff --git a/client/apps/portal-administration/src/components/FormComponents/IdInput.tsx b/client/apps/portal-administration/src/components/FormComponents/IdInput.tsx new file mode 100644 index 000000000..38572e2f0 --- /dev/null +++ b/client/apps/portal-administration/src/components/FormComponents/IdInput.tsx @@ -0,0 +1,26 @@ +import { Icon, TextField } from '@equinor/eds-core-react'; +import { error_filled } from '@equinor/eds-icons'; +import { FieldErrors, UseFormRegister } from 'react-hook-form'; +import { PortalInputs } from '../../schema'; + +type IdInputProps = { + register: UseFormRegister; + errors: FieldErrors<{ + id?: string | undefined; + }>; +}; + +export const IdInput = ({ register, errors }: IdInputProps) => { + return ( + } + label="Portal ID" + maxLength={500} + /> + ); +}; diff --git a/client/apps/portal-administration/src/components/FormComponents/NameIntput.tsx b/client/apps/portal-administration/src/components/FormComponents/NameIntput.tsx new file mode 100644 index 000000000..5b00b96a4 --- /dev/null +++ b/client/apps/portal-administration/src/components/FormComponents/NameIntput.tsx @@ -0,0 +1,25 @@ +import { Icon, TextField } from '@equinor/eds-core-react'; +import { error_filled } from '@equinor/eds-icons'; +import { FieldErrors, UseFormRegister } from 'react-hook-form'; +import { PortalInputs } from '../../schema'; + +type NameInputProps = { + register: UseFormRegister; + errors: FieldErrors<{ + name?: string | undefined; + }>; +}; + +export const NameInput = ({ register, errors }: NameInputProps) => { + return ( + } + maxLength={51} + label="Portal Name *" + /> + ); +}; diff --git a/client/apps/portal-administration/src/components/FormComponents/ShortNameInput.tsx b/client/apps/portal-administration/src/components/FormComponents/ShortNameInput.tsx new file mode 100644 index 000000000..f04c672bf --- /dev/null +++ b/client/apps/portal-administration/src/components/FormComponents/ShortNameInput.tsx @@ -0,0 +1,25 @@ +import { Icon, TextField } from '@equinor/eds-core-react'; +import { error_filled } from '@equinor/eds-icons'; +import { FieldErrors, UseFormRegister } from 'react-hook-form'; +import { PortalInputs } from '../../schema'; + +type ShortNameInputProps = { + register: UseFormRegister; + errors: FieldErrors<{ + shortName?: string | undefined; + }>; +}; + +export const ShortNameInput = ({ register, errors }: ShortNameInputProps) => { + return ( + } + maxLength={15} + label="Short Name *" + /> + ); +}; diff --git a/client/apps/portal-administration/src/components/FormComponents/SubTextInput.tsx b/client/apps/portal-administration/src/components/FormComponents/SubTextInput.tsx new file mode 100644 index 000000000..0af0bd812 --- /dev/null +++ b/client/apps/portal-administration/src/components/FormComponents/SubTextInput.tsx @@ -0,0 +1,25 @@ +import { Icon, TextField } from '@equinor/eds-core-react'; +import { error_filled } from '@equinor/eds-icons'; +import { FieldErrors, UseFormRegister } from 'react-hook-form'; +import { PortalInputs } from '../../schema'; + +type SubtextInputProps = { + register: UseFormRegister; + errors: FieldErrors<{ + subtext?: string | undefined; + }>; +}; + +export const SubtextInput = ({ register, errors }: SubtextInputProps) => { + return ( + } + maxLength={50} + label="Subtext *" + /> + ); +}; diff --git a/client/apps/portal-administration/src/components/Header.tsx b/client/apps/portal-administration/src/components/Header.tsx new file mode 100644 index 000000000..4351ed4a5 --- /dev/null +++ b/client/apps/portal-administration/src/components/Header.tsx @@ -0,0 +1,21 @@ +import { Typography } from "@equinor/eds-core-react"; +import styled from "styled-components"; + +const Style = { + Content: styled.div` + display: flex; + padding: 0.5rem 1rem; + `, +}; + +interface HeaderProps { + title?: string; +} + +export const Header = ({ title }: HeaderProps) => { + return ( + + {title || "Portal Administration"} + + ); +}; diff --git a/client/apps/portal-administration/src/components/HeaderStyle.ts b/client/apps/portal-administration/src/components/HeaderStyle.ts new file mode 100644 index 000000000..f5c766dfd --- /dev/null +++ b/client/apps/portal-administration/src/components/HeaderStyle.ts @@ -0,0 +1,37 @@ +import { Tabs, Breadcrumbs } from '@equinor/eds-core-react'; +import styled from 'styled-components'; + +export const HeaderStyle = { + Wrapper: styled.div` + height: calc(100% - 6rem); + width: 100%; + position: absolute; + `, + TabsListWrapper: styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + height: 44px; + border-bottom: 2px solid #e0e0e0; + `, + Content: styled.div` + padding: 1rem; + width: -webkit-fill-available; + `, + Tab: styled(Tabs.Tab)` + ${({ active }) => (!active ? 'border-bottom-color: transparent;' : '')}; + border-bottom-width: 2px; + `, + Row: styled.div` + display: flex; + align-items: center; + `, + + Breadcrumbs: styled(Breadcrumbs)` + > * > li > * { + overflow: visible; + font-size: 1.25em; + } + `, +}; diff --git a/client/apps/portal-administration/src/components/InfoPopover.tsx b/client/apps/portal-administration/src/components/InfoPopover.tsx new file mode 100644 index 000000000..1168030e8 --- /dev/null +++ b/client/apps/portal-administration/src/components/InfoPopover.tsx @@ -0,0 +1,38 @@ +import { Button, Popover, Icon } from '@equinor/eds-core-react'; +import { info_circle } from '@equinor/eds-icons'; +import { useState, useRef, PropsWithChildren } from 'react'; + +export const InfoPopover = ({ children, title }: PropsWithChildren<{ title: string }>) => { + const [isOpen, setIsOpen] = useState(false); + const handleOpen = () => { + setIsOpen((s) => !s); + }; + const handleClose = () => { + setIsOpen(false); + }; + const referenceElement = useRef(null); + + return ( + <> + + + + + {title} + + {children} + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Loading.tsx b/client/apps/portal-administration/src/components/Loading.tsx new file mode 100644 index 000000000..1f49cee19 --- /dev/null +++ b/client/apps/portal-administration/src/components/Loading.tsx @@ -0,0 +1,21 @@ +import { CircularProgress } from "@equinor/eds-core-react"; +import styled from "styled-components"; + +type LoadingProps = { + detail: string; +}; +export const Loading = ({ detail }: LoadingProps) => ( + +
    {detail}
    +
    +); + +const Wrapper = styled.div` + display: flex; + height: 100%; + width: 100%; + justify-content: center; + align-items: center; + gap: 1.2em; + flex-direction: column; +`; diff --git a/client/apps/portal-administration/src/components/Message.tsx b/client/apps/portal-administration/src/components/Message.tsx new file mode 100644 index 000000000..63ea0d2f3 --- /dev/null +++ b/client/apps/portal-administration/src/components/Message.tsx @@ -0,0 +1,114 @@ +import { IconData, error_outlined, warning_outlined } from '@equinor/eds-icons'; +import { Icon } from '@equinor/eds-core-react'; +import { tokens } from '@equinor/eds-tokens'; +import styled from 'styled-components'; +import { PropsWithChildren } from 'react'; + +export type Variant = 'Warning' | 'Error' | 'Info' | 'NoContent'; + +export const Message = ({ title, messages, type = 'Info', children }: PropsWithChildren) => { + const variant = getIconVariant(type); + + return ( + + {title && ( + + + + + {title} + + )} + {messages && ( + + {messages?.map((message, i) => ( +
  • {message}
  • + ))} +
    + )} + {children && children} +
    + ); +}; + +export const getIconVariant = (type: Variant) => { + const variant: Record = { + Error: { + data: warning_outlined, + color: tokens.colors.interactive.danger__resting.rgba, + backColor: tokens.colors.interactive.danger__highlight.hex, + type: 'Error', + }, + Warning: { + data: error_outlined, + color: tokens.colors.interactive.warning__resting.rgba, + backColor: tokens.colors.interactive.warning__highlight.hex, + type: 'Warning', + }, + Info: { + data: error_outlined, + color: tokens.colors.infographic.primary__moss_green_100.rgba, + backColor: tokens.colors.interactive.primary__selected_highlight.hex, + type: 'Info', + }, + NoContent: { + data: error_outlined, + color: tokens.colors.infographic.primary__moss_green_100.rgba, + backColor: tokens.colors.interactive.primary__selected_highlight.hex, + type: 'NoContent', + }, + }; + return variant[type]; +}; + +export type MessageProps = { + type?: Variant; + title?: string; + messages?: string[]; +}; + +export const Styled = { + StyledCardIndicator: styled.div<{ color: string }>` + position: absolute; + display: block; + left: 0; + width: 8px; + height: 100%; + background-color: ${({ color }) => color}; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + `, + Content: styled.div` + display: flex; + flex-direction: column; + `, + Header: styled.div` + display: flex; + flex-direction: row; + align-items: center; + `, + Icon: styled.span<{ color: string }>` + flex: none; + border-radius: 100px; + background-color: ${({ color }) => color}; + width: 40px; + height: 40px; + margin-right: 16px; + display: inline-flex; + align-items: center; + justify-content: center; + overflow: visible; + `, + UL: styled.ul` + display: block; + list-style-type: disc; + margin-block-start: 1em; + margin-block-end: 0px; + margin-inline-start: 0px; + margin-inline-end: 0px; + padding-inline-start: 35px; + & > li { + padding-bottom: 0.5rem; + } + `, +}; diff --git a/client/apps/portal-administration/src/components/OnboardedApps/AppSelector.tsx b/client/apps/portal-administration/src/components/OnboardedApps/AppSelector.tsx new file mode 100644 index 000000000..1f85a8323 --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedApps/AppSelector.tsx @@ -0,0 +1,154 @@ +import { SearchableDropdownResultItem, SearchableDropdownResult } from '@equinor/fusion-react-searchable-dropdown'; +import { useFramework } from '@equinor/fusion-framework-react'; +import { useCallback, useMemo, useState } from 'react'; +import { Autocomplete, Icon, Typography } from '@equinor/eds-core-react'; +import { useQuery } from '@tanstack/react-query'; +import styled from 'styled-components'; +import { error_filled } from '@equinor/eds-icons'; +import { FieldError } from 'react-hook-form'; + +const singleItem = (props: unknown): SearchableDropdownResultItem => { + return Object.assign({ id: '0', title: 'Dummy title' }, props); +}; + +function contextResultMapped(apps: App[]): SearchableDropdownResult { + return apps.map((app) => + singleItem({ + id: app.appKey, + title: app.displayName, + subTitle: app.appKey, + }) + ); +} + +const minQueryLength = 2; + +type App = { + appKey: string; + displayName: string; +}; + +export const useResolver = () => { + const client = useFramework().modules.serviceDiscovery.createClient('apps'); + + const searchQuery = useCallback(async (): Promise => { + let searchResult: SearchableDropdownResult = []; + if (!client) { + return []; + } + + try { + const apps = (await (await client).json<{ value: App[] }>('/apps')).value; + + if (apps[0] && !apps[0]) return searchResult; + // Structure as type + searchResult = contextResultMapped(apps); + + if (searchResult.length === 0) { + searchResult.push(singleItem({ title: 'No matches...', isDisabled: true })); + } + + return searchResult; + } catch (e) { + return [ + singleItem({ + title: 'API Error', + subTitle: e, + isDisabled: true, + isError: true, + }), + ]; + } + }, [client]); + + return { searchQuery }; +}; + +export const useAppSearch = () => { + const { searchQuery } = useResolver(); + + return useQuery({ + queryKey: ['apps'], + queryFn: async () => await searchQuery(), + }); +}; + +export const AppSelector = ({ + onChange, + errors, + message, +}: { + onChange: (context?: SearchableDropdownResultItem) => void; + + errors?: FieldError; + message?: string; +}) => { + const [input, setInput] = useState(''); + const { data, isLoading } = useAppSearch(); + + const search = async (input: string) => { + setInput(input); + }; + + const options = useMemo(() => { + return ( + data?.filter( + (app) => + app.id.toLowerCase().includes(input.toLowerCase()) || + app.title?.toLowerCase().includes(input.toLowerCase()) + ) || [] + ); + }, [data, input]); + + return ( + + id="apps-types" + onInputChange={search} + options={options} + loading={isLoading} + variant={errors && 'error'} + helperText={message} + helperIcon={errors && } + onOptionsChange={(value) => { + onChange(value?.selectedItems[0]); + }} + onKeyDown={(event) => { + if (event.key === 'Enter') { + console.log(event.key); + setInput(''); + } + }} + noOptionsText={isLoading ? 'Loading data..' : 'No options'} + optionComponent={CustomItem} + optionLabel={(contextTypes) => contextTypes.title || 'No App found'} + itemCompare={(item, compare) => { + return item === compare; + }} + optionsFilter={() => true} + label="Select App" + multiline + /> + ); +}; + +const Style = { + ItemWrapper: styled.div` + display: flex; + flex-direction: column; + padding: 1rem 0rem; + min-width: 500px; + gap: 0.25rem; + `, +}; + +function CustomItem(option: SearchableDropdownResultItem) { + const { title, subTitle } = option; + return ( + + {title} + + {subTitle} + + + ); +} diff --git a/client/apps/portal-administration/src/components/OnboardedApps/AppSideSheet.tsx b/client/apps/portal-administration/src/components/OnboardedApps/AppSideSheet.tsx new file mode 100644 index 000000000..46ff0c01a --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedApps/AppSideSheet.tsx @@ -0,0 +1,80 @@ +import { Card, TextField, Autocomplete, Typography, Checkbox } from '@equinor/eds-core-react'; + +import SideSheet from '@equinor/fusion-react-side-sheet'; +import styled from 'styled-components'; +import { PortalApp } from '../../types'; +import { useGetContextTypes } from '../../hooks/use-context-type-query'; +import { useEditOnboardedApp } from '../../hooks/use-onboarded-apps'; +import { PartialWithDefined } from '../../types/utils'; + +const Style = { + Wrapper: styled.div` + display: flex; + flex-direction: column; + gap: 2rem; + `, + PadTop: styled(Typography)` + padding-bottom: 1rem; + `, + Card: styled(Card)<{ col?: number }>` + box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.2), 0px 2px 4px -2px rgba(16, 24, 40, 0.2); + width: ${({ col }) => `calc(calc(100vw / ${col || 3} ) - 3rem)`}; + `, +}; + +export function AppSideSheet({ + app, + onClose, +}: { + app?: PartialWithDefined; + onClose: VoidFunction; +}) { + const { data: contextTypes } = useGetContextTypes(); + const { mutateAsync } = useEditOnboardedApp(app?.appKey); + if (!app) return null; + return ( + { + onClose(); + }} + isDismissable={true} + > + + + + + +
    + Context + + + + +
    +
    + Context Type + This is the context types that the application supports + contextTypes.type} + initialSelectedOptions={app.contexts} + itemCompare={(item, compare) => { + return item.type === compare.type; + }} + onOptionsChange={(change) => { + mutateAsync({ + appKey: app.appKey, + contextTypes: change.selectedItems.map((c) => c.type), + }); + }} + label="Context Types" + /> +
    +
    +
    +
    + ); +} diff --git a/client/apps/portal-administration/src/components/OnboardedApps/AppsTable.tsx b/client/apps/portal-administration/src/components/OnboardedApps/AppsTable.tsx new file mode 100644 index 000000000..0f35a787a --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedApps/AppsTable.tsx @@ -0,0 +1,131 @@ +import { CustomCellRendererProps } from '@ag-grid-community/react'; +import { Button, Icon } from '@equinor/eds-core-react'; +import { ClientGrid } from '@equinor/workspace-ag-grid'; + +import { useRef, useState } from 'react'; + +import { useDeleteOnboardedApp } from '../../hooks/use-onboarded-apps'; +import { PortalApp } from '../../types'; +import { AppSideSheet } from './AppSideSheet'; +import { delete_to_trash, edit } from '@equinor/eds-icons'; +import { AgStyles } from '../AgStyle'; +import { OnboardedAppsActionBar } from './OnboardedAppsActionBar'; +import { useResizeObserver } from '../../hooks/use-resise-observer'; +import { Message } from '../Message'; + +export const AppsTable = ({ onboardedApps }: { onboardedApps: PortalApp[] | undefined }) => { + const [selectedApp, setSelectedApp] = useState(); + const [selectedApps, setSelectedApps] = useState([]); + const { mutateAsync: deleteAppByAppKey } = useDeleteOnboardedApp(); + + const ref = useRef(null); + const [_, height] = useResizeObserver(ref); + + return ( + + + + height={selectedApps.length === 0 ? height : height - 150} + rowData={onboardedApps || []} + noRowsOverlayComponent={() => } + rowSelection="multiple" + rowHeight={36} + defaultColDef={{ + filter: true, + flex: 1, + sortable: true, + resizable: true, + }} + autoSizeStrategy={{ + type: 'fitGridWidth', + defaultMinWidth: 80, + defaultMaxWidth: 700, + }} + onGridReady={(event) => { + const api = event.api; + api.sizeColumnsToFit(); + }} + onRowDataUpdated={() => { + setSelectedApps([]); + }} + onRowSelected={(event) => { + const selectedRows = event.api!.getSelectedRows(); + setSelectedApps(selectedRows); + }} + colDefs={[ + { + field: 'id', + headerName: 'Id', + hide: true, + }, + { + field: 'name', + headerName: 'Name', + filter: true, + }, + { + field: 'appKey', + headerName: 'App Key', + filter: true, + }, + { + field: 'description', + headerName: 'Description', + width: 700, + }, + + { + field: 'contexts', + headerName: 'Contexts Types', + filter: true, + + cellRenderer: ( + params: CustomCellRendererProps<{ + contextTypes: string[]; + appKey: string; + }> + ) => { + return ( + + {params?.data?.contextTypes?.map((type) => { + return ( + + {type} + + ); + })} + + ); + }, + }, + { + field: 'appKey', + headerName: 'Action', + maxWidth: 100, + resizable: false, + cellRenderer: (params: CustomCellRendererProps) => { + return ( + + + + ); + }, + }, + ]} + /> + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/OnboardedApps/OnboardApp.tsx b/client/apps/portal-administration/src/components/OnboardedApps/OnboardApp.tsx new file mode 100644 index 000000000..12f7e2c5f --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedApps/OnboardApp.tsx @@ -0,0 +1,152 @@ +import { Card, Button, Typography, Autocomplete, Icon } from '@equinor/eds-core-react'; + +import { zodResolver } from '@hookform/resolvers/zod'; + +import styled from 'styled-components'; + +import { SubmitHandler, useForm } from 'react-hook-form'; +import { useEffect, useState } from 'react'; +import { OnboardAppInputs, onboardAppInput } from '../../schema/app'; +import { useAddOnboardedApp, useOnboardedApps } from '../../hooks/use-onboarded-apps'; +import { useGetContextTypes } from '../../hooks/use-context-type-query'; +import { AppSelector } from './AppSelector'; +import { Row } from '@equinor/eds-core-react/dist/types/components/Table/Row'; +import { arrow_back, arrow_drop_left, chevron_down, chevron_left } from '@equinor/eds-icons'; +import { InfoPopover } from '../InfoPopover'; + +const Style = { + Wrapper: styled.div` + gap: 1rem; + display: flex; + flex-direction: column; + `, + Card: styled(Card)` + padding: 0.5rem 1rem; + `, + From: styled.form` + padding-bottom: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; + `, + ErrorWrapper: styled.div` + padding-top: 1rem; + padding-bottom: 1rem; + `, + + Row: styled.div` + display: flex; + justify-content: space-between; + align-items: center; + `, + RowHead: styled.div` + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + `, +}; + +export const OnboardApp = () => { + const { mutateAsync: createApp, reset: resetCreate } = useAddOnboardedApp(); + const { data } = useOnboardedApps(); + + const [active, setActive] = useState(false); + + const { data: contextTypes } = useGetContextTypes(); + + const { + handleSubmit, + formState: { errors, isSubmitting }, + setError, + watch, + setValue, + clearErrors, + reset, + } = useForm({ + resolver: zodResolver(onboardAppInput), + defaultValues: { + contextTypes: [], + }, + }); + const appKey = watch().appKey; + + useEffect(() => { + if (Boolean(data?.find((onboardedApp) => onboardedApp.appKey === appKey))) { + setError('appKey', { + message: `App with appKey ${appKey} is already onboarded.`, + }); + } + }, [data, appKey]); + + const onSubmit: SubmitHandler = async (app) => { + await createApp(app); + resetCreate(); + reset({ appKey: '' }); + setValue('contextTypes', []); + }; + + return ( + + + setActive((s) => !s)}> + + Onboard App + + Expand the form to onboard a new application. + By pressing the chevron icon. + + + + + {active && ( + + { + clearErrors('appKey'); + if (app) { + setValue('appKey', app.id); + } else { + setValue('appKey', '', { shouldDirty: true }); + } + }} + /> + ct.type) || []} + selectedOptions={watch().contextTypes} + onOptionsChange={({ selectedItems }) => { + setValue('contextTypes', selectedItems); + }} + itemCompare={(item, compare) => { + return item === compare; + }} + label="Context Types" + /> + + + )} + + + ); +}; diff --git a/client/apps/portal-administration/src/components/OnboardedApps/OnboardedAppsActionBar.tsx b/client/apps/portal-administration/src/components/OnboardedApps/OnboardedAppsActionBar.tsx new file mode 100644 index 000000000..ef020edb4 --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedApps/OnboardedAppsActionBar.tsx @@ -0,0 +1,75 @@ +import styled from 'styled-components'; +import { PortalApp } from '../../types'; +import { Autocomplete, Typography } from '@equinor/eds-core-react'; + +import { useEditOnboardedApps } from '../../hooks/use-onboarded-apps'; +import { useGetContextTypes } from '../../hooks/use-context-type-query'; +import { useEffect, useState } from 'react'; + +const Styles = { + Wrapper: styled.div` + margin-top: 1rem; + width: 100%; + height: 100px; + background-color: #fff; + position: relative; + padding-bottom: 2rem; + `, + Content: styled.div` + padding: 1rem; + display: flex; + justify-content: space-between; + height: min-content; + `, + Actions: styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + `, +}; + +export const OnboardedAppsActionBar = ({ selection }: { selection: PortalApp[] }) => { + const { mutateAsync: editSelected } = useEditOnboardedApps(); + const [selected, setSelected] = useState(); + + useEffect(() => { + if ( + selection.length === 1 || + selection.every((s) => s.contexts.every((context, i) => context?.type === selection[0]?.contexts[i]?.type)) + ) { + setSelected(selection[0]?.contexts.map((c) => c.type)); + } else { + setSelected([]); + } + }, [selection]); + const { data: contextTypes } = useGetContextTypes(); + if (selection.length === 0) return null; + return ( + + + + Onboarded Apps Actions + c.type) || []} + optionLabel={(contextTypes) => contextTypes} + selectedOptions={selected} + itemCompare={(item, compare) => { + return item === compare; + }} + onOptionsChange={(change) => { + console.log(change.selectedItems); + setSelected(change.selectedItems); + editSelected( + selection.map((s) => ({ appKey: s.appKey, contextTypes: change.selectedItems })) + ); + }} + label="Context Types" + /> + + Selected applications ({selection.length}) + + + ); +}; diff --git a/client/apps/portal-administration/src/components/OnboardedContexts/AddContext.tsx b/client/apps/portal-administration/src/components/OnboardedContexts/AddContext.tsx new file mode 100644 index 000000000..37db157af --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedContexts/AddContext.tsx @@ -0,0 +1,155 @@ +import { Card, Button, Icon, Autocomplete, Typography } from '@equinor/eds-core-react'; +import { add, chevron_down, chevron_left } from '@equinor/eds-icons'; +import styled from 'styled-components'; +import { useGetContextTypes } from '../../hooks/use-context-type-query'; +import { ContextSelector } from './ContextSelector'; +import { useMemo, useState } from 'react'; +import { Message } from '../Message'; +import { tokens } from '@equinor/eds-tokens'; +import { useAddContext } from '../../hooks/use-add-context'; +import { useContextById } from '../../hooks/use-context-by-id'; +import { useOnboardedContexts } from '../../hooks/use-onboarded-context'; +import { FieldError } from 'react-hook-form'; +import { InfoPopover } from '../InfoPopover'; + +const Style = { + Content: styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + `, + Card: styled(Card)<{ background?: string }>` + padding: 0.5rem 1rem; + background-color: ${({ background }) => background}; + `, + ActionBar: styled.div` + padding: 1rem; + display: flex; + justify-content: space-between; + `, + From: styled.form` + padding-bottom: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; + `, + Row: styled.div` + display: flex; + justify-content: space-between; + align-items: center; + `, + RowHead: styled.div` + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + `, +}; + +export const AddContext = () => { + const { data: contextTypes } = useGetContextTypes(); + const [types, setTypes] = useState([]); + const [activeContextIs, setActiveContextId] = useState(''); + + const [contextError, setContextError] = useState(); + const [active, setActive] = useState(false); + + const { data: selectedContext } = useContextById(activeContextIs); + const { data: onboardedContexts } = useOnboardedContexts(); + + const onboardedContextIds = useMemo(() => { + return onboardedContexts?.map((context) => context.contextId) || []; + }, [onboardedContexts]); + + const { mutateAsync } = useAddContext(); + + return ( + + + setActive((s) => !s)}> + + Add Context Type + + + Expand the form to add new context type by pressing the chevron icon. + + + + + + {active && ( + + + id="app-context-types" + multiple + options={contextTypes?.map((c) => c.type) || []} + optionLabel={(contextTypes) => contextTypes} + itemCompare={(item, compare) => { + return item === compare; + }} + onOptionsChange={({ selectedItems }) => { + setTypes(selectedItems); + }} + label="Filter Search By Context Types" + /> + { + setContextError(undefined); + }} + onOptionsChange={(context) => { + setContextError(undefined); + if (onboardedContextIds.includes(context.id)) { + setContextError({ + message: 'Context is already onboarded', + type: 'validate', + }); + return; + } + setActiveContextId(context.id); + }} + /> + + + )} + + {selectedContext && ( + + + + {selectedContext.title} + + + + {selectedContext.type.id} +

    {selectedContext.externalId}

    +

    {selectedContext.id}

    +
    +
    + )} +
    + ); +}; diff --git a/client/apps/portal-administration/src/components/OnboardedContexts/ContextSelector.tsx b/client/apps/portal-administration/src/components/OnboardedContexts/ContextSelector.tsx new file mode 100644 index 000000000..69e13f997 --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedContexts/ContextSelector.tsx @@ -0,0 +1,79 @@ +import { SearchableDropdownResultItem } from "@equinor/fusion-react-searchable-dropdown"; +import { useState } from "react"; +import { Autocomplete, Icon, Typography } from "@equinor/eds-core-react"; +import styled from "styled-components"; +import { FieldError } from "react-hook-form"; +import { useContextSearch } from "../../hooks/use-context-search"; +import { error_filled } from "@equinor/eds-icons"; + +const Style = { + ItemWrapper: styled.div` + display: flex; + flex-direction: column; + padding: 1rem 0rem; + min-width: 500px; + gap: 0.25rem; + `, +}; + +export const ContextSelector = ({ + types, + onOptionsChange, + message, + errors, + onChange, +}: { + types: string[]; + onOptionsChange: (context: SearchableDropdownResultItem) => void; + errors?: FieldError; + message?: string; + onChange?: VoidFunction; +}) => { + const [input, setInput] = useState(""); + const { data, isLoading } = useContextSearch(input, types); + + const search = async (input: string) => { + setInput(input); + }; + + return ( + + id="app-context-types" + onInputChange={search} + options={data || []} + loading={isLoading} + variant={errors && "error"} + helperText={message} + onChange={() => { + onChange && onChange(); + }} + helperIcon={ + errors && + } + onOptionsChange={(value) => { + onOptionsChange(value?.selectedItems[0]); + }} + noOptionsText={isLoading ? "Loading data.." : "No options"} + optionComponent={CustomItem} + optionLabel={(contextTypes) => contextTypes.title || "Not found"} + itemCompare={(item, compare) => { + return item === compare; + }} + optionsFilter={() => true} + label="Search Context" + multiline + /> + ); +}; + +function CustomItem(option: SearchableDropdownResultItem) { + const { title, subTitle } = option; + return ( + + {title} + + {subTitle} + + + ); +} diff --git a/client/apps/portal-administration/src/components/OnboardedContexts/ContextType.tsx b/client/apps/portal-administration/src/components/OnboardedContexts/ContextType.tsx new file mode 100644 index 000000000..1f8fd121d --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedContexts/ContextType.tsx @@ -0,0 +1,121 @@ +import { Button, Icon, Typography, TextField, Card } from '@equinor/eds-core-react'; + +import { zodResolver } from '@hookform/resolvers/zod'; + +import styled from 'styled-components'; + +import { ContextTypeInputs, contextTypeSchema } from '../../schema'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import { chevron_down, chevron_left, error_filled } from '@equinor/eds-icons'; +import { useCreateContextType, useGetContextTypes } from '../../hooks/use-context-type-query'; + +import { ContextTypeTable } from './ContextTypeTable'; +import { InfoPopover } from '../InfoPopover'; +import { useState } from 'react'; + +const Style = { + Content: styled.div` + display: flex; + flex-direction: column; + + height: 100%; + `, + Card: styled(Card)<{ background?: string }>` + padding: 0.5rem 1rem; + background-color: ${({ background }) => background}; + `, + From: styled.form` + padding-bottom: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; + `, + ErrorWrapper: styled.div` + padding-top: 1rem; + padding-bottom: 1rem; + `, + Heading: styled(Typography)` + padding: 0.5rem 0; + `, + Row: styled.div` + display: flex; + justify-content: space-between; + align-items: center; + `, + RowHead: styled.div` + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + `, +}; + +export const EditContextTypeForm = () => { + const { mutateAsync: createContextType, reset: resetCreate } = useCreateContextType(); + + const { + register, + handleSubmit, + formState: { errors, isSubmitting, isValid }, + reset, + } = useForm({ + resolver: zodResolver(contextTypeSchema), + }); + + const [active, setActive] = useState(false); + + const onSubmit: SubmitHandler = async (newContextType) => { + const contextType = await createContextType(newContextType); + + if (contextType) { + reset(); + resetCreate(); + } + }; + + const { data: contextTypes } = useGetContextTypes(); + + return ( + + + setActive((s) => !s)}> + + Add Context Type + + + Expand the form to add new context type by pressing the chevron icon. + + + + + + {active && ( + + } + label="Type *" + maxLength={31} + /> + + + )} + + {contextTypes?.length && } + + ); +}; diff --git a/client/apps/portal-administration/src/components/OnboardedContexts/ContextTypeTable.tsx b/client/apps/portal-administration/src/components/OnboardedContexts/ContextTypeTable.tsx new file mode 100644 index 000000000..98b68ab14 --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedContexts/ContextTypeTable.tsx @@ -0,0 +1,74 @@ +import { ClientGrid } from '@equinor/workspace-ag-grid'; + +import { AgStyles } from '../AgStyle'; +import { useRef } from 'react'; +import { useResizeObserver } from '../../hooks/use-resise-observer'; +import { CustomCellRendererProps } from '@ag-grid-community/react'; +import { Button, Icon } from '@equinor/eds-core-react'; +import { delete_to_trash } from '@equinor/eds-icons'; +import { useRemoveContextType } from '../../hooks/use-context-type-query'; + +export function ContextTypeTable({ contextTypes }: { contextTypes?: { type: string }[] }) { + const ref = useRef(null); + const [_, height] = useResizeObserver(ref); + const { mutateAsync: removeContextType } = useRemoveContextType(); + return ( + + + + height={height} + rowData={contextTypes || []} + enableCellTextSelection + ensureDomOrder + defaultColDef={{ + filter: true, + flex: 1, + sortable: true, + resizable: true, + }} + autoSizeStrategy={{ + type: 'fitGridWidth', + defaultMinWidth: 80, + defaultMaxWidth: 300, + }} + onGridReady={(event) => { + const api = event.api; + api.sizeColumnsToFit(); + }} + onGridSizeChanged={(event) => { + const api = event.api; + api.sizeColumnsToFit(); + }} + colDefs={[ + { + field: 'type', + headerName: 'Type', + }, + { + field: 'type', + headerName: 'Action', + maxWidth: 120, + cellRenderer: (params: CustomCellRendererProps<{ type: string }>) => { + return ( + + + + ); + }, + }, + ]} + /> + + + ); +} diff --git a/client/apps/portal-administration/src/components/OnboardedContexts/OnboardedContextsTable.tsx b/client/apps/portal-administration/src/components/OnboardedContexts/OnboardedContextsTable.tsx new file mode 100644 index 000000000..6e493e55a --- /dev/null +++ b/client/apps/portal-administration/src/components/OnboardedContexts/OnboardedContextsTable.tsx @@ -0,0 +1,74 @@ +import styled from 'styled-components'; +import { ClientGrid } from '@equinor/workspace-ag-grid'; + +import { useEditOnboardContext } from '../../hooks/use-onboarded-context'; +import { OnboardedContext } from '../../types'; +import { AgStyles } from '../AgStyle'; +import { useRef } from 'react'; +import { useResizeObserver } from '../../hooks/use-resise-observer'; + +export function OnboardedContextsTable({ onboardedContexts }: { onboardedContexts?: OnboardedContext[] }) { + const { mutateAsync } = useEditOnboardContext(); + + const ref = useRef(null); + const [_, height] = useResizeObserver(ref); + + return ( + + + + height={height} + rowData={onboardedContexts || []} + enableCellTextSelection + ensureDomOrder + defaultColDef={{ + filter: true, + flex: 1, + sortable: true, + resizable: true, + }} + autoSizeStrategy={{ + type: 'fitGridWidth', + defaultMinWidth: 80, + defaultMaxWidth: 300, + }} + onGridReady={(event) => { + const api = event.api; + api.sizeColumnsToFit(); + }} + onCellValueChanged={(event) => { + if (event.data) mutateAsync(event.data); + }} + colDefs={[ + { + field: 'id', + headerName: 'Id', + hide: true, + }, + { + field: 'title', + headerName: 'Title', + }, + { + field: 'contextId', + headerName: 'Context Id', + }, + { + field: 'externalId', + headerName: 'External Context Id', + }, + { + field: 'type', + headerName: 'Context Type', + }, + { + field: 'description', + headerName: 'Description', + editable: true, + }, + ]} + /> + + + ); +} diff --git a/client/apps/portal-administration/src/components/PageMessage/PageMessage.tsx b/client/apps/portal-administration/src/components/PageMessage/PageMessage.tsx new file mode 100644 index 000000000..d558ca9d7 --- /dev/null +++ b/client/apps/portal-administration/src/components/PageMessage/PageMessage.tsx @@ -0,0 +1,68 @@ +import { Icon, Typography } from "@equinor/eds-core-react"; +import { tokens } from "@equinor/eds-tokens"; +import { PropsWithChildren } from "react"; +import styled from "styled-components"; +import { MessageType } from "./types/types"; + +import { error_outlined } from "@equinor/eds-icons"; +import { getMessageType } from "./utils/get-page-message-type"; + +const Styles = { + Wrapper: styled.div` + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + justify-content: center; + `, + Content: styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + justify-content: center; + `, +}; + +interface ErrorPageProps { + title: string; + body?: React.FC | string; + type?: MessageType; + color?: string; +} + +export function PageMessage({ + title, + type = "Info", + color, + children, +}: PropsWithChildren) { + const currentType = getMessageType(type); + return ( + + + + + {title} + + + {children && children} + + + ); +} diff --git a/client/apps/portal-administration/src/components/PageMessage/types/types.ts b/client/apps/portal-administration/src/components/PageMessage/types/types.ts new file mode 100644 index 000000000..527dab548 --- /dev/null +++ b/client/apps/portal-administration/src/components/PageMessage/types/types.ts @@ -0,0 +1 @@ +export type MessageType = "Error" | "Info" | "Warning" | "NoContent"; diff --git a/client/apps/portal-administration/src/components/PageMessage/utils/get-page-message-type.ts b/client/apps/portal-administration/src/components/PageMessage/utils/get-page-message-type.ts new file mode 100644 index 000000000..5d70fc7f0 --- /dev/null +++ b/client/apps/portal-administration/src/components/PageMessage/utils/get-page-message-type.ts @@ -0,0 +1,30 @@ +import { tokens } from "@equinor/eds-tokens"; +import { MessageType } from "../types/types"; +import { error_outlined, file_description } from "@equinor/eds-icons"; + +export const getMessageType = (type?: MessageType) => { + switch (type) { + case "Error": + return { + color: tokens.colors.interactive.danger__resting.hex, + icon: error_outlined, + }; + case "Info": + return { + color: tokens.colors.interactive.primary__resting.hex, + icon: error_outlined, + }; + case "Warning": + return { + color: tokens.colors.interactive.warning__resting.hex, + icon: error_outlined, + }; + case "NoContent": + return { + color: tokens.colors.interactive.primary__resting.hex, + icon: file_description, + }; + default: + return undefined; + } +}; diff --git a/client/apps/portal-administration/src/components/Portal/EditPortalForm.tsx b/client/apps/portal-administration/src/components/Portal/EditPortalForm.tsx new file mode 100644 index 000000000..0a3350142 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portal/EditPortalForm.tsx @@ -0,0 +1,174 @@ +import { Card, Typography, Autocomplete, Radio } from '@equinor/eds-core-react'; + +import { zodResolver } from '@hookform/resolvers/zod'; + +import styled from 'styled-components'; + +import { SubmitHandler, useForm } from 'react-hook-form'; +import { ChangeEvent, useEffect, useMemo, useState } from 'react'; +import { useUpdatePortal } from '../../hooks/use-portal-query'; +import { PortalInputs, portalEditInputSchema } from '../../schema'; +import { ContextType, Portal } from '../../types'; +import { DescriptionInput } from '../FormComponents/DescriptionInput'; + +import { FormActionBar } from './FormActionBar'; +import { IdInput } from '../FormComponents/IdInput'; +import { NameInput } from '../FormComponents/NameIntput'; +import { ShortNameInput } from '../FormComponents/ShortNameInput'; +import { SubtextInput } from '../FormComponents/SubTextInput'; +import { IconInput } from '../FormComponents/IconInput'; + +const Style = { + Wrapper: styled.div` + gap: 1rem; + display: flex; + flex-direction: column; + padding-bottom: 2rem; + `, + Row: styled.div` + gap: 1rem; + display: flex; + flex-direction: row; + `, + Card: styled(Card)` + padding: 1rem; + `, + From: styled.form` + padding-top: 1rem; + padding-bottom: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; + `, + ErrorWrapper: styled.div` + padding-top: 1rem; + padding-bottom: 1rem; + `, + Heading: styled(Typography)` + padding: 0.5rem 0; + `, + + ActionBar: styled.div` + display: flex; + justify-content: flex-end; + gap: 1rem; + `, +}; + +export const EditPortalForm = (props: { + portal: Portal; + contextTypes: ContextType[]; + isSideSheet?: boolean; + onDisabled?: (isDisabled: boolean) => void; +}) => { + const { id, contexts } = props.portal; + const { mutateAsync: updatePortal } = useUpdatePortal(id); + + const { + register, + handleSubmit, + formState: { errors, isSubmitting, touchedFields }, + watch, + setValue, + reset, + } = useForm({ + resolver: zodResolver(portalEditInputSchema), + defaultValues: { + ...props.portal, + }, + }); + + const onSubmit: SubmitHandler = async (editedPortal) => { + await updatePortal(editedPortal); + reset(); + }; + + const [type, setType] = useState(contexts && contexts?.length > 0 ? 'context-portal' : 'app-portal'); + const onTypeChange = (event: ChangeEvent) => setType(event.target.value); + + useEffect(() => { + type === 'app-portal' && setValue('contextTypes', [], { shouldTouch: true }); + }, [type]); + + const onDisabled = props.onDisabled; + + const disabled = Object.keys(touchedFields).length <= 0; + + useEffect(() => { + onDisabled && onDisabled(disabled); + }, [disabled, onDisabled]); + + return ( + + + General + + + + + + + + + + + + Icon + + + + Portal Type + + Selection context portal makes the portal context-driven, allowing you to select one or more + supported context types for the portal to support. + + + + + + + + {type === 'context-portal' && ( + +
    + Context +
    + + ct.type) || []} + selectedOptions={watch().contextTypes} + onOptionsChange={({ selectedItems }) => { + setValue('contextTypes', selectedItems, { shouldTouch: true }); + }} + itemCompare={(item, compare) => { + return item === compare; + }} + label="Context Types" + /> +
    + )} + {!props.isSideSheet && ( + + Portal Actions + + + + + )} +
    + ); +}; diff --git a/client/apps/portal-administration/src/components/Portal/FormActionBar.tsx b/client/apps/portal-administration/src/components/Portal/FormActionBar.tsx new file mode 100644 index 000000000..88444a764 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portal/FormActionBar.tsx @@ -0,0 +1,81 @@ +import { styled } from 'styled-components'; +import { DeleteDialog } from '../Dialogue/DeleteDialog'; +import { Breadcrumbs, Button, Icon, Typography } from '@equinor/eds-core-react'; +import { save, delete_to_trash } from '@equinor/eds-icons'; +import { useState } from 'react'; +import { useDeletePortal } from '../../hooks/use-portal-query'; +import { Portal } from '../../types'; + +import { DataClarification } from '../DataClarification'; +import { useNavigate } from 'react-router-dom'; + +const Style = { + ActionBar: styled.div<{ gap: string }>` + display: flex; + justify-content: 'flex-end'; + gap: ${(props) => props.gap}; + `, + Wrapper: styled.div` + display: flex; + justify-content: space-between; + width: 100%; + `, + Row: styled.div` + display: flex; + align-items: center; + `, + Breadcrumbs: styled(Breadcrumbs)` + > * > li > * { + font-size: 1.25em; + } + `, +}; + +type FormActionBarProps = { + isDisabled: boolean; + portal: Portal; + isIcons?: boolean; + onClose?: VoidFunction; +}; + +export const FormActionBar = ({ isDisabled, portal, isIcons, onClose }: FormActionBarProps) => { + const { mutateAsync: deletePortal } = useDeletePortal(); + + const [isDeleting, setIsDeleting] = useState(false); + const navigation = useNavigate(); + return ( + + + {isIcons && } + + + + + setIsDeleting(false)} + onDelete={() => { + deletePortal(portal); + setIsDeleting(false); + navigation('/portals'); + onClose && onClose(); + }} + title={portal.name} + > + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Portal/PortalHeader.tsx b/client/apps/portal-administration/src/components/Portal/PortalHeader.tsx new file mode 100644 index 000000000..b11e13885 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portal/PortalHeader.tsx @@ -0,0 +1,117 @@ +import { HeaderStyle } from '../HeaderStyle'; +import { TabsList, useTabs } from '../../hooks/use-tabs'; +import { Breadcrumbs, Typography, Tabs, Tooltip, Icon } from '@equinor/eds-core-react'; +import { edit, apps, tag_relations, settings } from '@equinor/eds-icons'; +import { Link } from 'react-router-dom'; +import { DataClarification } from '../DataClarification'; +import { InfoPopover } from '../InfoPopover'; +import { Portal } from '../../types'; + +const Styles = HeaderStyle; + +const tabs: TabsList<'overview' | 'apps' | 'router' | 'show'> = [ + { key: 'overview', title: 'Overview', route: 'overview', description: 'Overview of the portal' }, + { + title: 'Apps Config', + key: 'apps', + route: 'apps', + description: 'Configure the applications that are available in this portal.', + }, + { + key: 'router', + title: 'Router Config', + route: 'router', + description: () => ( +
    + Configure the routing for the portal. + + The firs route is the root route for the portal. The root route is the route that is shown when the + portal is opened. + + +
    + Routes + + Routes are created by pressing the new route button, and the route is created as a child of the + selected route. The route can be edited by selecting it, and the route can be removed by pressing + the delete route button under the contextual menu. + +
    + ), + }, + { + key: 'show', + title: 'Portal Config', + route: 'show', + description: 'This is a json view of the current portal configuration, it is used by developers only.', + }, +]; + +export const PortalHeader = ({ portal }: { portal?: Portal }) => { + const { activeTab } = useTabs(tabs, 'overview'); + return ( + + + + + Portals + + + {portal ? portal.name : 'Portal'} + + + {activeTab.title} + + + + {typeof activeTab.description === 'string' ? ( + {activeTab.description} + ) : ( + + )} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Portal/ShowConfig.tsx b/client/apps/portal-administration/src/components/Portal/ShowConfig.tsx new file mode 100644 index 000000000..9d4c32fe0 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portal/ShowConfig.tsx @@ -0,0 +1,59 @@ +import React, { useEffect, useRef } from 'react'; +import styled from 'styled-components'; +import { useParams } from 'react-router-dom'; +import { useGetPortal } from '../../hooks/use-portal-query'; +import { useGetPortalApps } from '../../hooks/use-portal-apps'; +import { Card } from '@equinor/eds-core-react'; +import { Message } from '../Message'; +import { Code } from '../../utils/syntaxHighlightJson'; + +const Style = { + Wrapper: styled.div` + padding: 1rem 0; + display: flex; + width: 100%; + flex-direction: column; + `, + Content: styled.div` + padding: 1rem; + gap: 1rem; + display: flex; + flex-direction: column; + `, +}; + +export const ShowConfigPage: React.FC = () => { + const { portalId } = useParams(); + + const { data } = useGetPortal(portalId); + const { data: apps } = useGetPortalApps(portalId); + + const portal = { ...data }; + if (portal) { + delete portal.contexts; + } + + const config = { + ...portal, + + configuration: { + router: JSON.parse((portal as any)?.configuration?.router || '{}'), + }, + apps: portal.contexts && portal.contexts.length > 0 ? apps : [], + }; + + return ( + + + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/PortalApps/ActionBar.tsx b/client/apps/portal-administration/src/components/PortalApps/ActionBar.tsx new file mode 100644 index 000000000..ef2f5786b --- /dev/null +++ b/client/apps/portal-administration/src/components/PortalApps/ActionBar.tsx @@ -0,0 +1,80 @@ +import styled from 'styled-components'; +import { PortalApp } from '../../types'; +import { Typography } from '@equinor/eds-core-react'; +import { useAddPortalApps, useRemovePortalApps } from '../../hooks/use-portal-apps'; +import { usePortalContext } from '../../context/PortalContext'; +import { ContextAppSideSheet } from './ContextAppSideSheet'; +import { useState } from 'react'; +import { MakeSelectionGlobalButton } from '../Actions/MakeGlobalAppsButton'; +import { ActivateSelectedButton } from '../Actions/ActivateSelectedButton'; +import { RemoveAppsButton } from '../Actions/RemoveAppsButton'; +import { EditSelectedButton } from '../Actions/EditSelectedButton'; +import { ActivateSelectedWithContextButton } from '../Actions/ActivateSelectedWithContextButton'; + +const Styles = { + Wrapper: styled.div` + margin-top: 1rem; + width: 100%; + height: 100px; + background-color: #fff; + position: relative; + padding-bottom: 2rem; + `, + Content: styled.div` + padding: 1rem; + display: flex; + justify-content: space-between; + height: min-content; + `, + Actions: styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + `, + Row: styled.div` + display: flex; + gap: 1rem; + `, +}; + +export const ActionBar = ({ selection }: { selection: PortalApp[] }) => { + const { activePortalId } = usePortalContext(); + + const { mutateAsync: activateSelected } = useAddPortalApps(activePortalId); + const { mutateAsync: removeSelected } = useRemovePortalApps(activePortalId); + const [isOpen, setIsOpen] = useState(false); + + if (selection.length === 0) return null; + return ( + + { + setIsOpen(false); + }} + selection={selection} + isOpen={isOpen} + /> + + + Portal Application Actions + + + {/* setIsOpen(true)} + /> */} + {/* { + setIsOpen(true); + }} + selection={selection} + /> */} + + + + + Selected applications ({selection.length}) + + + ); +}; diff --git a/client/apps/portal-administration/src/components/PortalApps/ContextAppSideSheet.tsx b/client/apps/portal-administration/src/components/PortalApps/ContextAppSideSheet.tsx new file mode 100644 index 000000000..e79513793 --- /dev/null +++ b/client/apps/portal-administration/src/components/PortalApps/ContextAppSideSheet.tsx @@ -0,0 +1,114 @@ +import { Card, Typography, Button } from '@equinor/eds-core-react'; + +import SideSheet from '@equinor/fusion-react-side-sheet'; +import styled from 'styled-components'; +import { OnboardedContext, PortalApp } from '../../types'; + +import { ClientGrid } from '@equinor/workspace-ag-grid'; +import { useState } from 'react'; +import { useActiveOnboardedContext } from '../../hooks/use-active-onbaorded-context'; +import { Message } from '../Message'; +import { Link } from 'react-router-dom'; + +const Style = { + Wrapper: styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + `, + PadTop: styled(Typography)` + padding-bottom: 0.2rem; + `, + Card: styled(Card)<{ col?: number }>` + box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.2), 0px 2px 4px -2px rgba(16, 24, 40, 0.2); + width: ${({ col }) => `calc(calc(100vw / ${col || 3} ) - 3rem)`}; + `, +}; + +export function ContextAppSideSheet({ + selection, + isOpen, + onClose, +}: { + selection: PortalApp[]; + isOpen: boolean; + onClose: VoidFunction; +}) { + const { isLoading, activeContexts, contextTypes } = useActiveOnboardedContext(); + const [contexts, setSelectedContexts] = useState(); + if (!selection) return null; + return ( + { + onClose(); + }} + minWidth={600} + isDismissable={true} + > + + + + + + Selected Apps ({selection.length}) + {selection.map((app) => app.name).join(' | ')} + Contexts + + + height={900} + rowData={activeContexts} + enableCellTextSelection + ensureDomOrder + rowSelection="multiple" + rowHeight={36} + onRowSelected={(event) => { + const selectedRows = event.api!.getSelectedRows(); + + setSelectedContexts(selectedRows); + }} + noRowsOverlayComponent={() => ( + + )} + autoSizeStrategy={{ + type: 'fitGridWidth', + defaultMinWidth: 80, + defaultMaxWidth: 300, + }} + colDefs={[ + { + field: 'id', + headerName: 'Id', + hide: true, + }, + { + field: 'title', + headerName: 'Title', + }, + { + field: 'contextId', + headerName: 'Context Id', + }, + { + field: 'externalId', + headerName: 'External Context Id', + }, + { + field: 'type', + headerName: 'Context Type', + }, + ]} + /> + + + + + + ); +} diff --git a/client/apps/portal-administration/src/components/PortalApps/PortalAppTable.tsx b/client/apps/portal-administration/src/components/PortalApps/PortalAppTable.tsx new file mode 100644 index 000000000..e3c6f21df --- /dev/null +++ b/client/apps/portal-administration/src/components/PortalApps/PortalAppTable.tsx @@ -0,0 +1,126 @@ +import { ClientGrid } from '@equinor/workspace-ag-grid'; + +import { useRef, useState } from 'react'; +import { CustomCellRendererProps } from '@ag-grid-community/react'; +import { useResizeObserver } from '../../hooks/use-resise-observer'; +import { PortalApp, ContextType } from '../../types'; +import { ActionBar } from './ActionBar'; +import { AgStyles } from '../AgStyle'; +import { Message } from '../Message'; + +export const PortalAppTable = ({ portalApps }: { portalApps: PortalApp[] }) => { + const ref = useRef(null); + const [_, height] = useResizeObserver(ref); + + const [selectedApps, setSelectedApps] = useState([]); + + return ( + + + + height={selectedApps.length === 0 ? height : height - 150} + rowData={portalApps} + noRowsOverlayComponent={() => } + enableCellTextSelection + defaultColDef={{ + filter: true, + flex: 1, + sortable: true, + resizable: true, + }} + ensureDomOrder + onGridReady={(event) => { + const api = event.api; + api.sizeColumnsToFit(); + }} + rowSelection="multiple" + rowHeight={36} + autoSizeStrategy={{ + type: 'fitGridWidth', + defaultMinWidth: 80, + defaultMaxWidth: 300, + }} + onRowSelected={(event) => { + const selectedRows = event.api!.getSelectedRows(); + setSelectedApps(selectedRows); + }} + onRowDataUpdated={() => { + setSelectedApps([]); + }} + colDefs={[ + { + field: 'isActive', + headerName: 'Is Active', + maxWidth: 110, + cellRenderer: ( + params: CustomCellRendererProps<{ + isActive?: boolean; + appKey: string; + }> + ) => { + return ( + + + + ); + }, + }, + { + field: 'name', + headerName: 'Name', + filterParams: { + filterOptions: ['contains', 'startsWith', 'endsWith'], + defaultOption: 'startsWith', + }, + }, + { + field: 'appKey', + maxWidth: 350, + headerName: 'Application key', + filterParams: { + filterOptions: ['contains', 'startsWith', 'endsWith'], + defaultOption: 'startsWith', + }, + }, + + { + field: 'description', + headerName: 'Description', + filterParams: { + filterOptions: ['contains', 'startsWith', 'endsWith'], + defaultOption: 'startsWith', + }, + width: 500, + }, + { + field: 'contexts', + headerName: 'Contexts Types', + filter: false, + cellRenderer: ( + params: CustomCellRendererProps<{ + contexts: ContextType[]; + contextTypes: string[]; + appKey: string; + }> + ) => { + return ( + + {params?.data?.contextTypes?.map((type) => { + return ( + + {type} + + ); + })} + + ); + }, + }, + ]} + /> + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Portals/CreatePortalForm.tsx b/client/apps/portal-administration/src/components/Portals/CreatePortalForm.tsx new file mode 100644 index 000000000..35aa13dc3 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portals/CreatePortalForm.tsx @@ -0,0 +1,168 @@ +import { Card, Button, Typography, Autocomplete, Radio } from '@equinor/eds-core-react'; + +import { zodResolver } from '@hookform/resolvers/zod'; + +import styled from 'styled-components'; + +import { useCreatePortal } from '../../hooks/use-portal-query'; +import { PortalInputs, portalInputSchema } from '../../schema'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import { useGetContextTypes } from '../../hooks/use-context-type-query'; +import { ChangeEvent, useEffect, useState } from 'react'; +import { DescriptionInput } from '../FormComponents/DescriptionInput'; +import { NameInput } from '../FormComponents/NameIntput'; +import { ShortNameInput } from '../FormComponents/ShortNameInput'; +import { SubtextInput } from '../FormComponents/SubTextInput'; +import { IconInput } from '../FormComponents/IconInput'; + +const Style = { + Wrapper: styled.div` + gap: 1rem; + display: flex; + flex-direction: column; + `, + Heading: styled(Typography)` + padding: 0.5rem 0; + `, + Card: styled(Card)` + padding: 1rem; + `, + Form: styled.form` + padding-bottom: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; + `, + Row: styled.div` + display: flex; + flex-direction: row; + gap: 1rem; + `, + ErrorWrapper: styled.div` + padding-top: 1rem; + padding-bottom: 1rem; + `, +}; + +const ICON = `\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t`; + +export const CreatePortalForm = () => { + const { mutateAsync: createPortal, reset: resetCreate } = useCreatePortal(); + + const { + register, + handleSubmit, + formState: { errors, isSubmitting, isValid }, + reset, + clearErrors, + watch, + setValue, + } = useForm({ + resolver: zodResolver(portalInputSchema), + defaultValues: { + contextTypes: [], + icon: ICON, + }, + }); + + const onSubmit: SubmitHandler = async (newPortal) => { + const portal = await createPortal(newPortal); + + if (portal) { + reset(); + resetCreate(); + } + }; + + const { data: ContextTypes } = useGetContextTypes(); + + const [type, setType] = useState('app-portal'); + const onTypeChange = (event: ChangeEvent) => setType(event.target.value); + + useEffect(() => { + type === 'app-portal' && setValue('contextTypes', []); + }, [type]); + + return ( + + + + General + + + + + + + + + Icon + + + + Portal Type + + Selection context portal makes the portal context-driven, allowing you to select one or more + supported context types for the portal to support. + + + + + + + + {type === 'context-portal' && ( + +
    + Context +
    + + ct.type) || []} + selectedOptions={watch().contextTypes} + onOptionsChange={({ selectedItems }) => { + setValue('contextTypes', selectedItems); + }} + itemCompare={(item, compare) => { + return item === compare; + }} + label="Context Types" + /> +
    + )} + + Create Portal Actions + + + + + +
    +
    + ); +}; diff --git a/client/apps/portal-administration/src/components/Portals/PortalIcon.tsx b/client/apps/portal-administration/src/components/Portals/PortalIcon.tsx new file mode 100644 index 000000000..a914ec343 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portals/PortalIcon.tsx @@ -0,0 +1,25 @@ +export const PortalIcon = () => { + return ( + + + + + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Portals/PortalSideSheet.tsx b/client/apps/portal-administration/src/components/Portals/PortalSideSheet.tsx new file mode 100644 index 000000000..36f001468 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portals/PortalSideSheet.tsx @@ -0,0 +1,63 @@ +import { Card, Typography } from '@equinor/eds-core-react'; + +import SideSheet from '@equinor/fusion-react-side-sheet'; +import styled from 'styled-components'; +import { Portal } from '../../types'; +import { useGetContextTypes } from '../../hooks/use-context-type-query'; +import { EditPortalForm } from '../Portal/EditPortalForm'; +import { FormActionBar } from '../Portal/FormActionBar'; +import { useState } from 'react'; + +const Style = { + Wrapper: styled.div` + display: flex; + flex-direction: column; + gap: 2rem; + `, + PadTop: styled(Typography)` + padding-bottom: 1rem; + `, + PadBottom: styled.div` + padding-bottom: 0.5rem; + `, + Card: styled(Card)<{ col?: number }>` + box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.2), 0px 2px 4px -2px rgba(16, 24, 40, 0.2); + width: ${({ col }) => `calc(calc(100vw / ${col || 3} ) - 3rem)`}; + `, +}; + +export function PortalSideSheet({ portal, onClose }: { portal?: Portal; onClose: VoidFunction }) { + const { data: contextTypes } = useGetContextTypes(); + const [isDisabled, setOnDisabled] = useState(false); + if (!portal || !contextTypes) return null; + return ( + { + onClose(); + }} + isDismissable={true} + > + + + + + + + + + + { + setOnDisabled(disabled); + }} + isSideSheet + portal={portal} + contextTypes={contextTypes} + /> + + + + ); +} diff --git a/client/apps/portal-administration/src/components/Portals/PortalTable.tsx b/client/apps/portal-administration/src/components/Portals/PortalTable.tsx new file mode 100644 index 000000000..f5f004a95 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portals/PortalTable.tsx @@ -0,0 +1,229 @@ +import { ClientGrid } from '@equinor/workspace-ag-grid'; +import { Portal } from '../../types'; +import { Link } from 'react-router-dom'; +import { CustomCellRendererProps } from '@ag-grid-community/react'; +import { Button, Icon, Typography } from '@equinor/eds-core-react'; +import { edit, delete_to_trash, apps, tag_relations, assignment } from '@equinor/eds-icons'; +import { useRef, useState } from 'react'; +import { useResizeObserver } from '../../hooks/use-resise-observer'; +import * as AllIcons from '@equinor/eds-icons'; +import { useDeletePortal } from '../../hooks/use-portal-query'; +import { DeleteDialog } from '../Dialogue/DeleteDialog'; +import { PortalSideSheet } from './PortalSideSheet'; +import { AgStyles } from '../AgStyle'; +import { Message } from '../Message'; +import { usePortalContext } from '../../context/PortalContext'; +import { tokens } from '@equinor/eds-tokens'; + +export function PortalTable({ portalsData }: { portalsData?: Portal[] }) { + const { mutateAsync: deletePortal } = useDeletePortal(); + const { setActivePortalById, activePortalId } = usePortalContext(); + + const ref = useRef(null); + const [_, height] = useResizeObserver(ref); + + const [isDeleting, setIsDeleting] = useState(); + const [quickEdit, setQuickEdit] = useState(); + + return ( + + + + height={height} + rowData={portalsData || []} + noRowsOverlayComponent={() => } + rowHeight={36} + autoSizeStrategy={{ + type: 'fitGridWidth', + defaultMinWidth: 80, + defaultMaxWidth: 300, + }} + onGridReady={(event) => { + const api = event.api; + api.sizeColumnsToFit(); + }} + onGridSizeChanged={(event) => { + const api = event.api; + api.sizeColumnsToFit(); + }} + getRowStyle={(params) => { + if (params.data?.id === activePortalId) { + return { backgroundColor: tokens.colors.ui.background__info.rgba }; + } + }} + colDefs={[ + { + field: 'icon', + headerName: 'Icon', + maxWidth: 70, + minWidth: 70, + cellRenderer: ( + params: CustomCellRendererProps<{ + icon: string; + id: string; + }> + ) => { + if (!params.data?.icon) { + return null; + } + return ( + + {params.data?.icon && Object.keys(AllIcons).includes(params.data?.icon) ? ( + + ) : ( + + )} + + ); + }, + }, + { + field: 'name', + headerName: 'Name', + cellRenderer: ( + params: CustomCellRendererProps<{ + name: string; + id: string; + }> + ) => { + return ( + + + {params.data?.name} + + + ); + }, + }, + { + field: 'subtext', + headerName: 'Sub Text', + hide: true, + }, + { + field: 'shortName', + headerName: 'Short Name', + hide: true, + }, + { + field: 'description', + width: 500, + headerName: 'Description', + }, + { + field: 'contexts', + headerName: 'Contexts Types', + + cellRenderer: ( + params: CustomCellRendererProps<{ + contextTypes: string[]; + id: string; + }> + ) => { + return ( + + {params?.data?.contextTypes?.map((type) => { + return ( + + {type} + + ); + })} + + ); + }, + }, + { + field: 'id', + headerName: 'Actions', + minWidth: 300, + maxWidth: 300, + cellRenderer: (params: CustomCellRendererProps) => { + return ( + + + + + + + + ); + }, + }, + ]} + /> + setIsDeleting(undefined)} + onDelete={() => { + deletePortal(isDeleting); + setIsDeleting(undefined); + }} + title={isDeleting?.name || 'Portal'} + > + setQuickEdit(undefined)} /> + + + ); +} diff --git a/client/apps/portal-administration/src/components/Portals/PortalsHeader.tsx b/client/apps/portal-administration/src/components/Portals/PortalsHeader.tsx new file mode 100644 index 000000000..8d66a3f38 --- /dev/null +++ b/client/apps/portal-administration/src/components/Portals/PortalsHeader.tsx @@ -0,0 +1,66 @@ +import { Breadcrumbs, Typography, Tabs, Tooltip, Icon } from '@equinor/eds-core-react'; +import { view_list, add } from '@equinor/eds-icons'; +import { Link } from 'react-router-dom'; +import { TabsList, useTabs } from '../../hooks/use-tabs'; +import { DataClarification } from '../DataClarification'; +import { HeaderStyle } from '../HeaderStyle'; +import { InfoPopover } from '../InfoPopover'; + +const Styles = HeaderStyle; + +const tabs: TabsList<'portals' | 'create'> = [ + { + title: 'Portal List', + key: 'portals', + route: '/portals', + + icon: view_list, + description: `Portals are the main entry point for users to access the applications. They can be + configured with a set of applications and routes.`, + }, + { + title: 'Create New Portal', + key: 'create', + route: '/portals/create', + icon: add, + description: 'Create a new portal to manage applications and routes.', + }, +]; + +export const PortalsHeader = () => { + const { activeTab } = useTabs(tabs, 'portals'); + + return ( + + + + + Portals + + {activeTab.key === 'create' && ( + + Create + + )} + + + {activeTab.description} + + + + + + + {tabs.map((tab) => ( + + + + + + ))} + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Router/RouteForm.tsx b/client/apps/portal-administration/src/components/Router/RouteForm.tsx new file mode 100644 index 000000000..4b04e655d --- /dev/null +++ b/client/apps/portal-administration/src/components/Router/RouteForm.tsx @@ -0,0 +1,177 @@ +import { Button, Card, Icon, TextField, Typography } from '@equinor/eds-core-react'; + +import styled from 'styled-components'; + +import { error_filled, info_circle } from '@equinor/eds-icons'; + +import { useRouterConfigContext } from '../../context/RouterContext'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import { route } from '../../schema/route'; +import { Route } from '../../types/router-config'; +import { usePortalContext } from '../../context/PortalContext'; +import { useUpdatePortalConfig } from '../../hooks/use-portal-config-query'; +import { updateRoute } from '../../context/actions/router-actions'; +import { Message } from '../Message'; + +const Style = { + Content: styled.div` + padding: 0 1rem; + gap: 1rem; + display: flex; + flex-direction: column; + `, + CardContent: styled(Card.Content)` + padding: 1rem; + gap: 1rem; + `, + Form: styled.form` + display: flex; + flex-direction: column; + gap: 1rem; + `, + Row: styled.div` + gap: 1rem; + display: flex; + flex-direction: row; + `, +}; + +export const RouteForm = () => { + const { + activeRoute, + root, + updateRoute: updateRouteState, + removeRouteById, + createNewRoute, + routes, + } = useRouterConfigContext(); + const { activePortalId } = usePortalContext(); + const { mutate: updatePortalConfig } = useUpdatePortalConfig(); + const { + register, + handleSubmit, + formState: { errors, touchedFields }, + } = useForm({ + resolver: zodResolver(route), + values: activeRoute, + reValidateMode: 'onChange', + }); + + const onSubmit: SubmitHandler = async (newRoute) => { + updateRouteState(newRoute); + + if (activePortalId && routes) { + updatePortalConfig({ + id: activePortalId, + router: { root, routes: updateRoute(newRoute, routes || []) }, + }); + } + }; + + const disabled = Object.keys(touchedFields).length <= 0; + + return ( + + + + Route Config + + + + } + /> + } + /> + } + label="Description" + maxLength={501} + /> + + Route Messages + + } + /> + } + /> + + + + + + + + + + Route Actions + + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Router/RouteMenu.tsx b/client/apps/portal-administration/src/components/Router/RouteMenu.tsx new file mode 100644 index 000000000..8da5decc4 --- /dev/null +++ b/client/apps/portal-administration/src/components/Router/RouteMenu.tsx @@ -0,0 +1,72 @@ +import { Button, Icon, Menu, Typography } from '@equinor/eds-core-react'; + +import { useState } from 'react'; + +import { add, edit, more_vertical, remove_outlined } from '@equinor/eds-icons'; +import { tokens } from '@equinor/eds-tokens'; +import { Route } from '../../types/router-config'; +import { useRouterConfigContext } from '../../context/RouterContext'; + +export const RouteMenu = ({ route }: { route: Route }) => { + const [isOpen, setIsOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + const { createNewRoute, removeRouteById, setActiveRoute } = useRouterConfigContext(); + + const openMenu = () => { + setIsOpen(true); + }; + + const closeMenu = () => { + setIsOpen(false); + }; + + return ( +
    + + + + { + console.log(route); + setActiveRoute(route.id); + }} + > + + + Edit + + + { + createNewRoute(route.id); + }} + > + + + Add + + + { + removeRouteById(route.id); + }} + > + + + Remove + + + +
    + ); +}; diff --git a/client/apps/portal-administration/src/components/Router/RouteTreeItem.tsx b/client/apps/portal-administration/src/components/Router/RouteTreeItem.tsx new file mode 100644 index 000000000..df7ccf808 --- /dev/null +++ b/client/apps/portal-administration/src/components/Router/RouteTreeItem.tsx @@ -0,0 +1,45 @@ +import { tokens } from "@equinor/eds-tokens"; +import { Route } from "../../types/router-config"; +import { RouteMenu } from "./RouteMenu"; +import { useRouterConfigContext } from "../../context/RouterContext"; +import { Typography } from "@equinor/eds-core-react"; +import styled from "styled-components"; +import { TreeItem } from "../Tree/TreeItem"; + +const Style = { + Content: styled.div` + display: flex; + flex-direction: row; + align-items: center; + min-width: 150px; + justify-content: flex-end; + `, +}; + +export const RouteTreeItem = ({ route }: { route: Route }) => { + const { activeRoute, setActiveRoute } = useRouterConfigContext(); + return ( + setActiveRoute(route.id)} + selected={ + activeRoute?.id === route.id + ? tokens.colors.interactive.primary__selected_highlight.hex + : undefined + } + title={route.path} + key={route.path} + Render={() => { + return ( + + - {route.pageKey} + + + ); + }} + > + {route.children?.map((childRoute) => ( + + ))} + + ); +}; diff --git a/client/apps/portal-administration/src/components/Router/RouterConfig.tsx b/client/apps/portal-administration/src/components/Router/RouterConfig.tsx new file mode 100644 index 000000000..fc76183d6 --- /dev/null +++ b/client/apps/portal-administration/src/components/Router/RouterConfig.tsx @@ -0,0 +1,11 @@ +import { useRouterConfigContext } from '../../context/RouterContext'; +import { Code } from '../../utils/syntaxHighlightJson'; + +export const RouterConfig = () => { + const { root, routes } = useRouterConfigContext(); + const config = { + root, + routes, + }; + return ; +}; diff --git a/client/apps/portal-administration/src/components/Router/RouterEdit.tsx b/client/apps/portal-administration/src/components/Router/RouterEdit.tsx new file mode 100644 index 000000000..0242e96f8 --- /dev/null +++ b/client/apps/portal-administration/src/components/Router/RouterEdit.tsx @@ -0,0 +1,71 @@ +import styled from 'styled-components'; +import { Card } from '@equinor/eds-core-react'; + +import { useRouterConfigContext } from '../../context/RouterContext'; +import { RouterRoot } from './RouterRoot'; +import { RouteForm } from './RouteForm'; +import { RouterConfig } from './RouterConfig'; +import { Message } from '../Message'; + +const Style = { + Wrapper: styled.div` + gap: 1rem; + display: flex; + padding: 1rem 0; + width: 100%; + flex-direction: column; + `, + Content: styled.div` + padding: 0 1rem; + gap: 1rem; + display: flex; + flex-direction: column; + `, + CodeContent: styled.div` + padding: 0 1rem; + gap: 1rem; + display: flex; + + flex-direction: column; + `, + Full: styled.div` + width: 100%; + `, + CardContent: styled(Card.Content)` + padding: 1rem; + `, +}; + +export const RouterEdit = () => { + const { rootActive, configActive } = useRouterConfigContext(); + + return ( + + {configActive ? ( + + + + + + + + + ) : ( + + {rootActive ? ( + + + + ) : ( + + + + )} + + )} + + ); +}; diff --git a/client/apps/portal-administration/src/components/Router/RouterRoot.tsx b/client/apps/portal-administration/src/components/Router/RouterRoot.tsx new file mode 100644 index 000000000..c8f2fbb03 --- /dev/null +++ b/client/apps/portal-administration/src/components/Router/RouterRoot.tsx @@ -0,0 +1,126 @@ +import { Button, Card, Icon, TextField, Typography } from '@equinor/eds-core-react'; + +import styled from 'styled-components'; + +import { error_filled } from '@equinor/eds-icons'; + +import { useRouterConfigContext } from '../../context/RouterContext'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import { RootInput, rootInput } from '../../schema/route'; +import { useUpdatePortalConfig } from '../../hooks/use-portal-config-query'; +import { usePortalContext } from '../../context/PortalContext'; +import { Message } from '../Message'; + +const Style = { + Content: styled.div` + padding: 0 1rem; + gap: 1rem; + display: flex; + flex-direction: column; + `, + CardContent: styled(Card.Content)` + padding: 1rem; + gap: 1rem; + `, + Form: styled.form` + display: flex; + flex-direction: column; + gap: 1rem; + `, + Row: styled.div` + gap: 1rem; + display: flex; + flex-direction: row; + `, +}; + +export const RouterRoot = () => { + const { root, updateRoot, createNewRoute, routes } = useRouterConfigContext(); + const { mutate } = useUpdatePortalConfig(); + const { + register, + handleSubmit, + formState: { errors, touchedFields }, + } = useForm({ + resolver: zodResolver(rootInput), + values: root, + reValidateMode: 'onChange', + }); + + const { activePortalId } = usePortalContext(); + const onSubmit: SubmitHandler = async (root) => { + updateRoot(root.pageKey); + if (activePortalId) { + mutate({ + id: activePortalId, + router: { root, routes }, + }); + } + }; + + const disabled = Object.keys(touchedFields).length <= 0; + + return ( + + + + Base Route Config + + + } + label="Root Page Id" + /> + + Root Messages + + } + /> + + + + + + + + + + + + + Base Route Actions + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Router/RouterTree.tsx b/client/apps/portal-administration/src/components/Router/RouterTree.tsx new file mode 100644 index 000000000..c3cd0e028 --- /dev/null +++ b/client/apps/portal-administration/src/components/Router/RouterTree.tsx @@ -0,0 +1,84 @@ +import { Button, Typography } from '@equinor/eds-core-react'; +import { tokens } from '@equinor/eds-tokens'; +import styled from 'styled-components'; + +import { Tree } from '../Tree/Tree'; +import { useRouterConfigContext } from '../../context/RouterContext'; +import { RouteTreeItem } from './RouteTreeItem'; +import { TreeRoot } from '../Tree/TreeRoot'; + +const Style = { + Router: styled.span` + margin: 1rem 0 2rem 0; + padding: 1rem; + + background-color: ${tokens.colors.ui.background__medium.hex}; + border-right: 1px solid ${tokens.colors.ui.background__default.hex}; + display: flex; + flex-direction: column; + justify-content: space-between; + -webkit-box-shadow: -10px 0 20px 3px #00000005 inset; + -moz-box-shadow: -10px 0 20px 3px #00000005 inset; + box-shadow: -10px 0 20px 3px #00000005 inset; + `, + Top: styled.span` + display: flex; + flex-direction: column; + min-width: 350px; + `, + Wrapper: styled.div` + display: flex; + flex-direction: row; + align-items: center; + padding: 1rem; + `, +}; + +export const RouterTree = () => { + const { createNewRoute, routes, root, rootActive, toggleRoot, seeConfig } = useRouterConfigContext(); + return ( + + + + + + { + toggleRoot(); + }} + Render={() => { + return ( + + - {root.pageKey} + + ); + }} + > + {routes.map((route) => ( + + ))} + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Settings/SettingsHeader.tsx b/client/apps/portal-administration/src/components/Settings/SettingsHeader.tsx new file mode 100644 index 000000000..38fca28e6 --- /dev/null +++ b/client/apps/portal-administration/src/components/Settings/SettingsHeader.tsx @@ -0,0 +1,108 @@ +import { Breadcrumbs, Typography, Tabs, Tooltip, Icon } from '@equinor/eds-core-react'; +import { apps, add, view_list, edit, tag } from '@equinor/eds-icons'; +import { Link } from 'react-router-dom'; +import styled from 'styled-components'; +import { TabsList, useTabs } from '../../hooks/use-tabs'; +import { DataClarification } from '../DataClarification'; +import { HeaderStyle } from '../HeaderStyle'; +import { InfoPopover } from '../InfoPopover'; +import { Message } from '../Message'; + +const tabs: TabsList<'apps' | 'app' | 'add' | 'types' | 'contexts'> = [ + { + title: 'Onboarded Apps', + key: 'apps', + route: '/settings/apps', + + icon: apps, + description: 'Configure the applications that are available in this portal.', + }, + + { + key: 'contexts', + icon: view_list, + title: 'Contexts', + route: '/settings/contexts', + + description: () => ( + + To be able to make a app context specific the system needs to add the context + Search for the context that is missing + Press add to alow for the context tu be utilized + Use the context type filter to specify your search + + ), + }, + { + key: 'types', + icon: tag, + title: 'Context Types', + route: '/settings/contexts/types', + description: () => ( + + If the desired context type is not available, you can add it here. + Please note that only valid fusion context types are permitted. + + ), + }, +]; + +const Styles = { + ...HeaderStyle, + Content: styled.div` + display: flex; + width: 100%; + height: inherit; + `, + Section: styled.section` + flex-direction: column; + padding: 1rem; + display: flex; + height: inherit; + `, + Wrapper: styled.div` + display: block; + overflow: hidden; + height: 100%; + `, +}; + +export const SettingsHeader = () => { + const { activeTab } = useTabs(tabs, 'apps'); + return ( + + + + + Settings + + + + {activeTab.title} + + + + {typeof activeTab.description === 'string' ? ( + {activeTab.description} + ) : ( + + )} + + + + + + + {tabs.map((tab) => ( + + + + + + ))} + + + + + ); +}; diff --git a/client/apps/portal-administration/src/components/SideMenu.tsx b/client/apps/portal-administration/src/components/SideMenu.tsx new file mode 100644 index 000000000..7307fb058 --- /dev/null +++ b/client/apps/portal-administration/src/components/SideMenu.tsx @@ -0,0 +1,153 @@ +import { Link, useMatch, type LinkProps } from 'react-router-dom'; +import { SideBar, SidebarLinkProps } from '@equinor/eds-core-react'; + +import { dashboard, build_wrench, briefcase, apps, desktop_mac, settings, view_list, add } from '@equinor/eds-icons'; +import { usePortalContext } from '../context/PortalContext'; + +type MenuItemProps = + | SidebarLinkProps & + Partial & { + subItems?: MenuItemProps[]; + disabled?: boolean; + expanded?: boolean; + } & Pick; + +export const SideMenu = () => { + const { activePortalId } = usePortalContext(); + + const menuItems: MenuItemProps[] = [ + { + label: 'Portals', + icon: desktop_mac, + active: !!useMatch(`portals`), + to: `portals`, + as: Link, + subItems: [ + { + label: 'Portals', + icon: view_list, + to: `portals`, + active: !!useMatch(`portals`), + as: Link, + }, + { + label: 'Create New Portal', + icon: add, + to: `portals/create`, + active: !!useMatch(`portals/create`), + as: Link, + }, + ], + }, + { + label: 'Portal', + active: !!useMatch({ path: `portals/:portalId/:page`, end: true }), + icon: dashboard, + disabled: Boolean(!activePortalId), + expanded: true, + subItems: [ + { + label: 'Overview', + icon: dashboard, + to: `portals/${activePortalId}/overview`, + active: !!useMatch(`portals/:portalId/overview`), + disabled: Boolean(!activePortalId), + as: Link, + }, + { + label: 'Apps Config', + icon: build_wrench, + to: `portals/${activePortalId}/apps`, + active: !!useMatch(`portals/:portalId/apps`), + disabled: Boolean(!activePortalId), + as: Link, + }, + { + label: 'Router Config', + icon: briefcase, + to: `portals/${activePortalId}/router`, + active: !!useMatch(`portals/:portalId/router`), + disabled: Boolean(!activePortalId), + as: Link, + }, + { + label: 'Portal Config', + icon: settings, + to: `portals/${activePortalId}/show`, + active: !!useMatch(`portals/:portalId/show`), + disabled: Boolean(!activePortalId), + as: Link, + }, + ], + }, + { + label: 'Settings', + active: !!useMatch({ path: `settings`, end: false }), + icon: settings, + subItems: [ + { + label: 'Onboarded Apps', + icon: apps, + active: !!useMatch({ path: `settings/apps`, end: true }), + to: `settings/apps`, + as: Link, + }, + { + label: 'Contexts', + icon: build_wrench, + to: `settings/contexts`, + active: !!useMatch({ path: `settings/contexts`, end: true }), + as: Link, + }, + { + label: 'Context Types', + icon: build_wrench, + to: `settings/contexts/types`, + active: !!useMatch(`settings/contexts/types`), + as: Link, + }, + ], + }, + ]; + + return ( + + + + + {menuItems.map((menuItem) => { + if (menuItem.subItems && menuItem.subItems?.length > 0) { + return ( + + {menuItem.subItems.map((menuItem) => ( + + ))} + + ); + } + return ( + + ); + })} + + + ); +}; + +export default SideMenu; diff --git a/client/apps/portal-administration/src/components/Snack.tsx b/client/apps/portal-administration/src/components/Snack.tsx new file mode 100644 index 000000000..3dd903319 --- /dev/null +++ b/client/apps/portal-administration/src/components/Snack.tsx @@ -0,0 +1,51 @@ +import { Icon, Snackbar } from '@equinor/eds-core-react'; +import styled from 'styled-components'; +import { useSnackBar } from '../hooks/use-snack-bar'; +import { check_circle_outlined, error_filled } from '@equinor/eds-icons'; + +export const Snack = () => { + const { messages, removeMessage } = useSnackBar(); + + return ( + + {Object.values(messages).map(({ message, type, id }, idx) => { + return ( + { + removeMessage(id); + }} + > + + +
    {message}
    +
    +
    + ); + })} +
    + ); +}; + +const Styled = { + Wrapper: styled.div` + position: fixed; + bottom: 0; + left: 0; + padding: 1em; + `, + Snackbar: styled(Snackbar).attrs<{ $idx?: number }>((props) => ({ + $idx: props.$idx || 0, + }))` + bottom: calc(16px + (${(props) => props.$idx} * 4rem)); + `, + SnackContent: styled.div` + display: flex; + align-items: flex-end; + gap: 1em; + `, +}; diff --git a/client/apps/portal-administration/src/components/Tree/Tree.tsx b/client/apps/portal-administration/src/components/Tree/Tree.tsx new file mode 100644 index 000000000..4aafd1abf --- /dev/null +++ b/client/apps/portal-administration/src/components/Tree/Tree.tsx @@ -0,0 +1,26 @@ +import { tokens } from "@equinor/eds-tokens"; +import { PropsWithChildren } from "react"; +import styled from "styled-components"; + +const Style = { + TreeWrapper: styled.div` + position: relative; + + list-style: none; + --tree-color: ${tokens.colors.ui.background__light.hex}; + --tree-line-color: ${tokens.colors.ui.background__light.hex}; + --tree-width: 2px; + `, + Tree: styled.ul` + padding-left: 5px; + list-style: none; + `, +}; + +export const Tree = ({ children }: PropsWithChildren) => { + return ( + + {children} + + ); +}; diff --git a/client/apps/portal-administration/src/components/Tree/TreeBaseItem.tsx b/client/apps/portal-administration/src/components/Tree/TreeBaseItem.tsx new file mode 100644 index 000000000..d485dd21b --- /dev/null +++ b/client/apps/portal-administration/src/components/Tree/TreeBaseItem.tsx @@ -0,0 +1,80 @@ +import { Icon } from "@equinor/eds-core-react"; +import { chevron_down, chevron_right } from "@equinor/eds-icons"; +import { tokens } from "@equinor/eds-tokens"; +import { PropsWithChildren, FC, useState, Children } from "react"; +import styled from "styled-components"; + +const Style = { + Tree: styled.ul` + padding-left: 5px; + list-style: none; + `, + Selected: styled.div<{ selected?: string }>` + :hover { + background-color: ${tokens.colors.interactive.primary__hover_alt.hex}; + cursor: pointer; + } + `, + Content: styled.div<{ selected?: string }>` + border-radius: 5px; + background-color: ${({ selected }) => + selected ? selected : `var(--tree-color)`}; + gap: 1rem; + display: flex; + padding-left: 1rem; + flex-direction: row; + align-items: center; + justify-content: space-between; + `, + Main: styled.div` + gap: 1rem; + height: 3rem; + display: flex; + flex-direction: row; + align-items: center; + `, + Children: styled.div` + position: relative; + padding-left: 2rem; + margin-top: 0.5rem; + `, +}; + +export type TreeBaseItemProps = PropsWithChildren<{ + Render?: FC; + selected?: string; + title: string; + initOpen?: boolean; +}>; + +export const TreeBaseItem = ({ + children, + Render, + title, + selected, + initOpen, +}: TreeBaseItemProps) => { + const [toggle, setToggle] = useState(initOpen || false); + return ( + <> + + + + {children && Children.toArray(children).length > 0 ? ( + { + setToggle((s) => !s); + }} + /> + ) : null} + {title} + + {Render && } + + + {toggle ? {children} : null} + + ); +}; diff --git a/client/apps/portal-administration/src/components/Tree/TreeItem.tsx b/client/apps/portal-administration/src/components/Tree/TreeItem.tsx new file mode 100644 index 000000000..db04d2adc --- /dev/null +++ b/client/apps/portal-administration/src/components/Tree/TreeItem.tsx @@ -0,0 +1,64 @@ +import { TreeBaseItem, TreeBaseItemProps } from './TreeBaseItem'; +import styled from 'styled-components'; + +const Style = { + TreeItem: styled.li` + position: relative; + padding-top: 5px; + + padding-left: 2rem; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + + &:before { + position: absolute; + top: 25px; + left: 1rem; + width: 15px; + height: var(--tree-width); + margin: auto; + content: ''; + border-bottom: var(--tree-width) dotted var(--tree-line-color); + } + + &:after { + position: absolute; + top: 0px; + bottom: 0; + left: 1rem; + width: var(--tree-width); + height: calc(100% + 25px); + content: ''; + border-left: var(--tree-width) dotted var(--tree-line-color); + } + + &:last-child:after { + height: 25px; + } + `, +}; + +export const TreeItem = ({ + children, + Render, + title, + onClick, + selected, +}: TreeBaseItemProps & { + onClick?: React.MouseEventHandler | undefined; +}) => { + return ( + ) => { + e.preventDefault(); + e.stopPropagation(); + onClick && onClick(e); + }} + > + + {children} + + + ); +}; diff --git a/client/apps/portal-administration/src/components/Tree/TreeRoot.tsx b/client/apps/portal-administration/src/components/Tree/TreeRoot.tsx new file mode 100644 index 000000000..a2bb85c43 --- /dev/null +++ b/client/apps/portal-administration/src/components/Tree/TreeRoot.tsx @@ -0,0 +1,36 @@ +import { TreeBaseItem, TreeBaseItemProps } from './TreeBaseItem'; +import styled from 'styled-components'; + +const Style = { + TreeRoot: styled.li` + position: relative; + padding-top: 5px; + + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + `, +}; +export const TreeRoot = ({ + children, + Render, + title, + onClick, + selected, +}: TreeBaseItemProps & { + onClick?: React.MouseEventHandler | undefined; +}) => { + return ( + ) => { + e.preventDefault(); + e.stopPropagation(); + onClick && onClick(e); + }} + > + + {children} + + + ); +}; diff --git a/client/apps/portal-administration/src/config.ts b/client/apps/portal-administration/src/config.ts new file mode 100644 index 000000000..9015be402 --- /dev/null +++ b/client/apps/portal-administration/src/config.ts @@ -0,0 +1,19 @@ +import type { AppModuleInitiator } from '@equinor/fusion-framework-app'; +import { enableNavigation } from '@equinor/fusion-framework-module-navigation'; + +interface Client { + baseUri: string; + defaultScopes: string[]; +} + +export const configure: AppModuleInitiator = (configurator, { env }) => { + const { basename, config } = env; + + enableNavigation(configurator, basename); + + const environment = config?.environment as { client: Client }; + + configurator.configureHttpClient('portal-client', environment.client); +}; + +export default configure; diff --git a/client/apps/portal-administration/src/context/PortalContext.tsx b/client/apps/portal-administration/src/context/PortalContext.tsx new file mode 100644 index 000000000..b989201a2 --- /dev/null +++ b/client/apps/portal-administration/src/context/PortalContext.tsx @@ -0,0 +1,35 @@ +import { PropsWithChildren, createContext, useContext, useState } from "react"; +import { useGetPortal } from "../hooks/use-portal-query"; +import { Portal } from "../types"; + +export type PortalContextState = { + activePortalId: string | undefined; +} & Partial; + +export type PortalContext = { + setActivePortalById: (id?: string) => void; +} & PortalContextState; + +const Context = createContext({ + activePortalId: undefined, +} as PortalContext); + +export const PortalContextComponent = ({ children }: PropsWithChildren) => { + const [activePortalId, setActivePortalId] = useState(); + + const { data } = useGetPortal(activePortalId); + + const setActivePortalById = (id?: string) => { + setActivePortalId(id); + }; + + return ( + + {children} + + ); +}; + +export const usePortalContext = () => { + return useContext(Context); +}; diff --git a/client/apps/portal-administration/src/context/RouterContext.tsx b/client/apps/portal-administration/src/context/RouterContext.tsx new file mode 100644 index 000000000..242b2b458 --- /dev/null +++ b/client/apps/portal-administration/src/context/RouterContext.tsx @@ -0,0 +1,142 @@ +import { PropsWithChildren, createContext, useContext, useEffect, useMemo, useReducer } from 'react'; +import { Route, Router } from '../types/router-config'; +import { reducer } from './reducers/router-reducer'; +import { addRoute, createRoute, removeRoute } from './actions/router-actions'; +import { mockRoutes } from './mocs/routes'; +import { usePortalContext } from './PortalContext'; +import { useGetPortalConfiguration, useUpdatePortalConfig } from '../hooks/use-portal-config-query'; + +export type RouterConfigContextState = { + activeRoute?: Route; + activeRouteControl?: Route; + rootActive: boolean; + configActive: boolean; +} & Router; + +export type RouterConfigContext = { + setActiveRoute: (is?: string) => void; + handleChange: (event: React.ChangeEvent) => void; + createNewRoute: (id?: string) => void; + removeRouteById: (id: string) => void; + updateRoute: (route?: Route) => void; + updateRoot: (pageKey: string) => void; + toggleRoot: VoidFunction; + seeConfig: VoidFunction; +} & RouterConfigContextState; + +const initialState = { + root: { + pageKey: '', + messages: { + errorMessage: '', + }, + }, + activeRoute: undefined, + routes: [] as Route[], + rootActive: true, + configActive: false, +} as RouterConfigContext; + +const Context = createContext(initialState); + +export const RouterConfigContextComponent = ({ children }: PropsWithChildren) => { + const { activePortalId } = usePortalContext(); + const [state, dispatch] = useReducer(reducer, initialState); + + const { data } = useGetPortalConfiguration(activePortalId); + const { mutate: updatePortalConfig } = useUpdatePortalConfig(); + useEffect(() => { + if (data) { + updateRouter(data.router); + } + }, [data]); + + const setActiveRoute = (id?: string) => { + dispatch({ type: 'SET_ACTIVE_ROUTE', payload: { id } }); + }; + const updateRouter = (router: Router) => { + dispatch({ type: 'UPDATE_ROUTER', payload: router }); + }; + + const handleChange = (event: React.ChangeEvent) => { + dispatch({ type: 'UPDATE_ROUTE_BY_FIELD', payload: event.target }); + }; + + const toggleRoot = () => { + dispatch({ type: 'TOGGLE_ROOT' }); + }; + + const seeConfig = () => { + dispatch({ type: 'TOGGLE_CONFIG' }); + }; + + const updateRoute = (route?: Route) => { + dispatch({ + type: 'UPDATE_ROUTE', + payload: { + route, + }, + }); + }; + + const createNewRoute = (id?: string) => { + const route = createRoute(); + dispatch({ + type: 'CREATE_ROUTE', + payload: { + id, + route, + }, + }); + if (activePortalId && state.routes && state.root) { + updatePortalConfig({ + id: activePortalId, + router: { root: state.root, routes: addRoute(route, state.routes) || [] }, + }); + } + }; + const removeRouteById = (id: string) => { + dispatch({ + type: 'REMOVE_ROUTE', + payload: { + id, + }, + }); + if (activePortalId && state.routes && state.root) { + updatePortalConfig({ + id: activePortalId, + router: { root: state.root, routes: removeRoute(id, state.routes) || [] }, + }); + } + }; + const updateRoot = (pageKey: string) => { + dispatch({ + type: 'UPDATE_ROOT', + payload: { + pageKey, + }, + }); + }; + + return ( + + {children} + + ); +}; + +export const useRouterConfigContext = () => { + return useContext(Context); +}; diff --git a/client/apps/portal-administration/src/context/actions/add-route-router-actions.test.ts b/client/apps/portal-administration/src/context/actions/add-route-router-actions.test.ts new file mode 100644 index 000000000..6fd4a682b --- /dev/null +++ b/client/apps/portal-administration/src/context/actions/add-route-router-actions.test.ts @@ -0,0 +1,88 @@ +import { Route } from "../../types/router-config"; +import { addRoute } from "./router-actions"; +import { describe, it, expect } from "vitest"; +describe("addRoute", () => { + it("should add a new route to the routes array", () => { + const newRoute: Route = { + id: "new-route", + path: "/new-route", + pageKey: "page3", + messages: { + errorMessage: "", + }, + }; + + const routes: Route[] = [ + { + id: "route1", + path: "/route1", + pageKey: "page1", + messages: { + errorMessage: "", + }, + }, + { + id: "route2", + path: "/route2", + pageKey: "page2", + messages: { + errorMessage: "", + }, + }, + ]; + + const updatedRoutes = addRoute(newRoute, routes); + + if (updatedRoutes) { + expect(updatedRoutes).toHaveLength(routes.length + 1); + expect(updatedRoutes[2]).toEqual(newRoute); + } + }); + + it("should add a new route as a child of an existing route", () => { + const newRoute: Route = { + id: "new-route", + path: "/new-route", + pageKey: "page3", + messages: { + errorMessage: "", + }, + }; + + const routes: Route[] = [ + { + id: "parent-route", + path: "/parent-route", + pageKey: "page3", + messages: { + errorMessage: "", + }, + children: [ + { + id: "child-route1", + path: "/child-route1", + pageKey: "page3", + messages: { + errorMessage: "", + }, + }, + { + id: "child-route2", + path: "/child-route2", + pageKey: "page3", + messages: { + errorMessage: "", + }, + }, + ], + }, + ]; + + const updatedRoutes = addRoute(newRoute, routes, "parent-route"); + if (updatedRoutes && updatedRoutes[0].children) { + expect(updatedRoutes).toHaveLength(routes.length); + expect(updatedRoutes[0].children).toHaveLength(3); + expect(updatedRoutes[0].children[2]).toBe(newRoute); + } + }); +}); diff --git a/client/apps/portal-administration/src/context/actions/find-route-router-action.test.ts b/client/apps/portal-administration/src/context/actions/find-route-router-action.test.ts new file mode 100644 index 000000000..22f2100e8 --- /dev/null +++ b/client/apps/portal-administration/src/context/actions/find-route-router-action.test.ts @@ -0,0 +1,69 @@ +import { test, expect } from "vitest"; +import { findRouteById } from "./router-actions"; +import { Route } from "../../types/router-config"; + +test("findRouteById should return the correct route", () => { + const childRoute = { + id: "3", + description: "Route 3", + path: "/route3", + pageKey: "route3", + messages: { + errorMessage: "Error in Route 3", + noPageMessage: "No page found for Route 3", + }, + children: undefined, + }; + const routes: Route[] = [ + { + id: "1", + description: "Route 1", + path: "/route1", + pageKey: "route1", + messages: { + errorMessage: "Error in Route 1", + noPageMessage: "No page found for Route 1", + }, + children: [ + { + id: "2", + description: "Route 2", + path: "/route2", + pageKey: "route2", + messages: { + errorMessage: "Error in Route 2", + noPageMessage: "No page found for Route 2", + }, + children: [ + { + id: "3", + description: "Route 3", + path: "/route3", + pageKey: "route3", + messages: { + errorMessage: "Error in Route 3", + noPageMessage: "No page found for Route 3", + }, + children: undefined, + }, + ], + }, + ], + }, + { + id: "4", + description: "Route 4", + path: "/route4", + pageKey: "route4", + messages: { + errorMessage: "Error in Route 4", + noPageMessage: "No page found for Route 4", + }, + children: undefined, + }, + ]; + + const result = findRouteById(routes, "3"); + + expect(result).toEqual(childRoute); +}); diff --git a/client/apps/portal-administration/src/context/actions/remove-route-router-action.test.ts b/client/apps/portal-administration/src/context/actions/remove-route-router-action.test.ts new file mode 100644 index 000000000..b11dfa2b9 --- /dev/null +++ b/client/apps/portal-administration/src/context/actions/remove-route-router-action.test.ts @@ -0,0 +1,92 @@ +import { describe, it, expect } from "vitest"; +import { removeRoute } from "./router-actions"; +import { Route } from "../../types/router-config"; + +describe("removeRoute", () => { + it("should remove a route from the router", () => { + // Arrange + const routes: Route[] = [ + { + id: "1", + description: "Route 1", + path: "/route1", + pageKey: "route1", + messages: { + errorMessage: "Error message for Route 1", + }, + }, + { + id: "2", + description: "Route 2", + path: "/route2", + pageKey: "route2", + messages: { + errorMessage: "Error message for Route 2", + noPageMessage: "No page message for Route 2", + }, + children: [ + { + id: "2.1", + description: "Route 2.1", + path: "/route2.1", + pageKey: "route2.1", + messages: { + errorMessage: "Error message for Route 2.1", + }, + }, + ], + }, + ]; + + // Act + const updatedRouter = removeRoute("1", routes); + + // Assert + if (updatedRouter) { + expect(updatedRouter).toHaveLength(1); + expect(updatedRouter).not.toContain(routes[0]); + } + }); + it("should remove a child route from the router", () => { + // Arrange + const routes: Route[] = [ + { + id: "1", + description: "Route 1", + path: "/route1", + pageKey: "route1", + messages: { + errorMessage: "Error message for Route 1", + }, + }, + { + id: "2", + description: "Route 2", + path: "/route2", + pageKey: "route2", + messages: { + errorMessage: "Error message for Route 2", + }, + children: [ + { + id: "2.1", + description: "Route 2.1", + path: "/route2.1", + pageKey: "route2.1", + messages: { + errorMessage: "Error message for Route 2.1", + }, + }, + ], + }, + ]; + + // Act + const updatedRouter = removeRoute("2.1", routes); + + // Assert + if (updatedRouter) { + expect(updatedRouter[1].children).toHaveLength(0); + } + }); +}); diff --git a/client/apps/portal-administration/src/context/actions/router-actions.ts b/client/apps/portal-administration/src/context/actions/router-actions.ts new file mode 100644 index 000000000..a54e64c10 --- /dev/null +++ b/client/apps/portal-administration/src/context/actions/router-actions.ts @@ -0,0 +1,164 @@ +import { uuidv4 } from 'uuidv7'; +import { Route, Router } from '../../types/router-config'; + +export type Actions = + | { + type: 'SET_ACTIVE_ROUTE'; + payload: { + id?: string; + }; + } + | { + type: 'TOGGLE_ROOT'; + } + | { + type: 'UPDATE_ROUTER'; + payload: Router; + } + | { + type: 'TOGGLE_CONFIG'; + } + | { + type: 'UPDATE_ROOT'; + payload: { + pageKey: string; + }; + } + | { + type: 'UPDATE_ROUTE_BY_FIELD'; + payload: { + id: string; + value: string; + }; + } + | { + type: 'UPDATE_ROUTE'; + payload: { + route?: Route; + }; + } + | { + type: 'CREATE_ROUTE'; + payload: { + id?: string; + route: Route; + }; + } + | { + type: 'REMOVE_ROUTE'; + payload: { + id: string; + }; + }; + +export const findRouteById = (routes?: Route[], id?: string): Route | undefined => { + const result = { route: undefined } as { route: Route | undefined }; + + routes?.forEach((route) => { + if (route.id === id) { + result.route = route; + } else if (!result.route) { + const data = findRouteById(route.children, id); + if (data) { + result.route = data; + } + } + }); + + return result.route; +}; + +export const addRoute = (newRoute: Route, routes?: Route[], id?: string) => { + if (!routes) return; + + if (id) { + return routes.reduce((acc, route, i) => { + if (route.id === id) { + const newRoutes = addRoute(newRoute, route.children || []); + if (newRoutes) { + route.children = [...newRoutes]; + } + } else if (route.children) { + const newRoutes = addRoute(newRoute, route.children, id); + if (newRoutes) { + route.children = [...newRoutes]; + } + } + + acc[i] = route; + return acc; + }, routes); + } + + return [...routes, newRoute]; +}; +export const updateRoute = (newRoute?: Route, routes?: Route[]) => { + if (!routes) return []; + + if (!newRoute) return routes; + return [ + ...routes.reduce((acc, route, i) => { + if (route.id === newRoute.id) { + acc[i] = newRoute; + } else { + const newRoutes = updateRoute(newRoute, route.children); + if (newRoutes) { + route.children = [...newRoutes]; + } + } + + return acc; + }, routes), + ]; +}; + +export const removeRoute = (id: string, routes?: Route[]) => { + if (!routes) return; + + const result = routes.reduce((acc, route, i) => { + if (route.id === id) { + return [...acc.filter((route) => route.id !== id)]; + } else if (route.children?.length && acc[i]) { + acc[i].children = removeRoute(id, route.children); + } + + return acc; + }, routes); + + return result; +}; + +export const createRoute = (): Route => { + return { + id: uuidv4(), + messages: { + errorMessage: '', + }, + description: '', + path: '', + pageKey: '', + }; +}; + +export const updateRouteByField = (id: string, value: string, route?: Route): Route => { + if (!route) { + return { + id: '', + messages: { + errorMessage: '', + }, + path: '', + description: '', + pageKey: '', + [id]: value, + }; + } + if (id.toLowerCase().includes('message')) { + return { + description: '', + ...route, + messages: { ...route.messages, [id]: value }, + }; + } + return { ...route, [id]: value }; +}; diff --git a/client/apps/portal-administration/src/context/actions/updarte-route-router-action.test.ts b/client/apps/portal-administration/src/context/actions/updarte-route-router-action.test.ts new file mode 100644 index 000000000..b0d33206e --- /dev/null +++ b/client/apps/portal-administration/src/context/actions/updarte-route-router-action.test.ts @@ -0,0 +1,107 @@ +import { describe, it, expect } from 'vitest'; +import { updateRoute } from './router-actions'; +import { Route } from '../../types/router-config'; + +describe('updateRoute', () => { + it('should return an empty array if routes is not provided', () => { + const result = updateRoute(undefined, undefined); + expect(result).toEqual([]); + }); + + it('should return the routes array if newRoute is not provided', () => { + const routes: Route[] = [ + { + id: '1', + description: undefined, + path: '/home', + pageKey: 'home', + messages: { + errorMessage: 'Error message 1', + }, + children: [], + }, + { + id: '2', + description: undefined, + path: '/about', + pageKey: 'about', + messages: { + errorMessage: 'Error message 2', + }, + children: [], + }, + ]; + const result = updateRoute(undefined, routes); + expect(result).toEqual(routes); + }); + + it('should update the route with the same id and return the updated routes array', () => { + const routes: Route[] = [ + { + children: [], + id: '1', + description: undefined, + path: '/about', + pageKey: 'about', + messages: { + errorMessage: 'Error message 1', + }, + }, + { + id: '2', + description: undefined, + path: '/about', + pageKey: 'about', + messages: { + errorMessage: 'Error message 1', + }, + children: [ + { + children: undefined, + id: '3', + description: undefined, + path: '/about', + pageKey: 'about', + messages: { + errorMessage: 'Error message 1', + }, + }, + ], + }, + ]; + const newRoute = { + children: undefined, + id: '3', + description: undefined, + path: '/3', + pageKey: '3', + messages: { + errorMessage: 'Error message 3', + }, + }; + const expected = [ + { + children: [], + id: '1', + description: undefined, + path: '/about', + pageKey: 'about', + messages: { + errorMessage: 'Error message 1', + }, + }, + { + id: '2', + description: undefined, + path: '/about', + pageKey: 'about', + messages: { + errorMessage: 'Error message 1', + }, + children: [newRoute], + }, + ]; + const result = updateRoute(newRoute, routes); + expect(result).toEqual(expected); + }); +}); diff --git a/client/apps/portal-administration/src/context/actions/update-route-field-router-action.test.ts b/client/apps/portal-administration/src/context/actions/update-route-field-router-action.test.ts new file mode 100644 index 000000000..fe87e8b76 --- /dev/null +++ b/client/apps/portal-administration/src/context/actions/update-route-field-router-action.test.ts @@ -0,0 +1,61 @@ +import { describe, it, expect } from "vitest"; +import { updateRouteByField } from "./router-actions"; + +describe("updateRouteByField", () => { + it("should return a new route object with the specified field updated", () => { + const route = { + id: "123", + messages: { + errorMessage: "Error", + }, + path: "/home", + pageKey: "home", + }; + + const updatedRoute = updateRouteByField("id", "456", route); + + expect(updatedRoute).toEqual({ + id: "456", + messages: { + errorMessage: "Error", + }, + path: "/home", + pageKey: "home", + }); + }); + + it("should return a new route object with the specified message field updated", () => { + const route = { + id: "123", + messages: { + errorMessage: "Error", + }, + path: "/home", + pageKey: "home", + }; + + const updatedRoute = updateRouteByField("errorMessage", "New Error", route); + + expect(updatedRoute).toEqual({ + id: "123", + messages: { + errorMessage: "New Error", + }, + path: "/home", + pageKey: "home", + }); + }); + + it("should return a new route object with the specified field added if route is not provided", () => { + const updatedRoute = updateRouteByField("id", "123"); + + expect(updatedRoute).toEqual({ + id: "123", + messages: { + errorMessage: "", + }, + path: "", + pageKey: "", + }); + }); +}); diff --git a/client/apps/portal-administration/src/context/mocs/routes.ts b/client/apps/portal-administration/src/context/mocs/routes.ts new file mode 100644 index 000000000..d05f2145f --- /dev/null +++ b/client/apps/portal-administration/src/context/mocs/routes.ts @@ -0,0 +1,40 @@ +import { uuidv4 } from "uuidv7"; + +export const mockRoutes = [ + { + id: uuidv4(), + path: "project/*", + pageKey: "project", + messages: { + errorMessage: "Fail to load project page", + }, + children: [ + { + id: uuidv4(), + messages: { + errorMessage: "Fail to load project page", + }, + path: ":contextId", + pageKey: "project", + }, + ], + }, + { + id: uuidv4(), + path: "facility/*", + pageKey: "facility", + messages: { + errorMessage: "Fail to load facility page", + }, + children: [ + { + id: uuidv4(), + messages: { + errorMessage: "Fail to load facility page", + }, + path: ":contextId", + pageKey: "facility", + }, + ], + }, +]; diff --git a/client/apps/portal-administration/src/context/reducers/router-reducer.ts b/client/apps/portal-administration/src/context/reducers/router-reducer.ts new file mode 100644 index 000000000..285491fb1 --- /dev/null +++ b/client/apps/portal-administration/src/context/reducers/router-reducer.ts @@ -0,0 +1,81 @@ +import { uuidv4 } from 'uuidv7'; +import { RouterConfigContextState } from '../RouterContext'; +import { + Actions, + findRouteById, + addRoute, + updateRouteByField, + updateRoute, + removeRoute, +} from '../actions/router-actions'; + +export const reducer = (state: RouterConfigContextState, action: Actions) => { + switch (action.type) { + case 'UPDATE_ROUTER': + return { + ...state, + root: action.payload?.root || { + pageKey: '', + messages: { + errorMessage: '', + }, + }, + routes: action.payload?.routes || [], + }; + case 'UPDATE_ROOT': + return { + ...state, + root: { + ...state.root, + pageKey: action.payload.pageKey, + }, + }; + case 'TOGGLE_ROOT': + return { + ...state, + rootActive: true, + activeRoute: undefined, + }; + case 'TOGGLE_CONFIG': + return { + ...state, + configActive: !state.configActive, + }; + case 'SET_ACTIVE_ROUTE': + const activeRoute = findRouteById(state.routes, action.payload?.id); + + return { + ...state, + activeRoute, + activeRouteControl: activeRoute, + rootActive: false, + }; + case 'CREATE_ROUTE': + const newRoute = + state.activeRoute?.id !== '' ? action.payload.route : { ...state.activeRoute, id: uuidv4() }; + return { + ...state, + routes: addRoute(newRoute, state.routes, action.payload.id) || [], + activeRoute: newRoute, + rootActive: false, + }; + case 'REMOVE_ROUTE': + return { + ...state, + routes: removeRoute(action.payload.id, state.routes) || [], + }; + case 'UPDATE_ROUTE_BY_FIELD': + return { + ...state, + activeRoute: updateRouteByField(action.payload.id, action.payload.value, state.activeRoute), + }; + case 'UPDATE_ROUTE': + const routes = updateRoute(action.payload.route, state.routes); + return { + ...state, + routes, + }; + default: + return state; + } +}; diff --git a/client/apps/portal-administration/src/hooks/use-active-onbaorded-context.ts b/client/apps/portal-administration/src/hooks/use-active-onbaorded-context.ts new file mode 100644 index 000000000..09ef62b24 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-active-onbaorded-context.ts @@ -0,0 +1,24 @@ +import { act, useMemo } from "react"; +import { usePortalContext } from "../context/PortalContext"; +import { useOnboardedContexts } from "./use-onboarded-context"; +import { useGetPortal } from "./use-portal-query"; + +export const useActiveOnboardedContext = () => { + const { activePortalId } = usePortalContext(); + const { isLoading: isLoadingPortalConfig, data: portalConfig } = + useGetPortal(activePortalId); + const { isLoading, data: onboardedContexts } = useOnboardedContexts(); + + const activeContexts = useMemo(() => { + if (!portalConfig || !onboardedContexts) return []; + return onboardedContexts.filter((context) => + portalConfig.contexts.map((c) => c.type).includes(context.type) + ); + }, [portalConfig, onboardedContexts]); + + return { + activeContexts, + isLoading: isLoading || isLoadingPortalConfig, + contextTypes: portalConfig?.contexts.map((c) => c.type), + }; +}; diff --git a/client/apps/portal-administration/src/hooks/use-add-app-with-context.ts b/client/apps/portal-administration/src/hooks/use-add-app-with-context.ts new file mode 100644 index 000000000..901dfe564 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-add-app-with-context.ts @@ -0,0 +1,104 @@ +import { + IHttpClient, + useHttpClient, +} from "@equinor/fusion-framework-react-app/http"; +import { useMutation } from "@tanstack/react-query"; +import { OnboardedContext, PortalApp } from "../types"; + +type ContextAppResult = { + appKey: string; + contextId: string; + status: "failed" | "success"; +}; + +export const useAddAppWithContext = (portalId?: string) => { + const client = useHttpClient("portal"); + + return useMutation({ + mutationFn: async ({ + appsSelection, + contextSelection, + }: { + appsSelection: PortalApp[]; + contextSelection: OnboardedContext[]; + }) => { + return addPortalAppsWithContexts( + client, + appsSelection, + contextSelection, + portalId + ); + }, + }); +}; + +const addPortalAppWithContext = async ( + client: IHttpClient, + contextId: string, + appKey: string, + portalId: string +) => { + const response = await client.fetch( + `api/portals/${portalId}/apps`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + appKey, + removeAppForContexts: true, + }), + } + ); + + if (!response.ok) { + return { appKey, contextId, status: "failed" } as ContextAppResult; + } + + return { appKey, status: "success" } as ContextAppResult; +}; + +const addPortalAppWithContexts = async ( + client: IHttpClient, + appKey: string, + contexts: OnboardedContext[], + portalId?: string +) => { + if (!portalId) return [] as ContextAppResult[]; + const results: ContextAppResult[] = []; + + for (const context of contexts) { + const result = await addPortalAppWithContext( + client, + context.contextId, + appKey, + portalId + ); + results.push(result); + } + + return results as ContextAppResult[]; +}; + +const addPortalAppsWithContexts = async ( + client: IHttpClient, + portalApps: PortalApp[], + contexts: OnboardedContext[], + portalId?: string +) => { + if (!portalId) return [] as ContextAppResult[]; + const results: ContextAppResult[] = []; + + for (const app of portalApps) { + const result = await addPortalAppWithContexts( + client, + app.appKey, + contexts, + portalId + ); + results.push(...result); + } + + return results as ContextAppResult[]; +}; diff --git a/client/apps/portal-administration/src/hooks/use-add-context.ts b/client/apps/portal-administration/src/hooks/use-add-context.ts new file mode 100644 index 000000000..0fe38a266 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-add-context.ts @@ -0,0 +1,53 @@ +import { + IHttpClient, + useHttpClient, +} from "@equinor/fusion-framework-react-app/http"; +import { useQueryClient, useMutation } from "@tanstack/react-query"; +import { useSnackBar } from "./use-snack-bar"; +import { FormattedError } from "../types"; + +import { formatError } from "../utils/error-utils"; + +export type AddContext = { + externalId: string; + type: string; + description: string; +}; + +export const useAddContext = () => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + + const { sendMessage } = useSnackBar(); + + return useMutation({ + mutationFn: async (data) => { + return await addContext(client, data); + }, + onError() { + sendMessage("Failed to add context", "Error"); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["create-portal"] }); + sendMessage("Add context success", "Info"); + }, + }); +}; + +const addContext = async (client: IHttpClient, body: AddContext) => { + const response = await client.fetch(`api/onboarded-contexts`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.text(); + return data; +}; diff --git a/client/apps/portal-administration/src/hooks/use-context-by-id.ts b/client/apps/portal-administration/src/hooks/use-context-by-id.ts new file mode 100644 index 000000000..4a95a7bd9 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-context-by-id.ts @@ -0,0 +1,12 @@ +import { useQuery } from "@tanstack/react-query"; +import { useResolver } from "./use-resolver"; + +export const useContextById = (id?: string) => { + const { getContextById } = useResolver(); + + return useQuery({ + queryKey: ["context", id], + queryFn: async () => await getContextById(id), + enabled: Boolean(id), + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-context-search.ts b/client/apps/portal-administration/src/hooks/use-context-search.ts new file mode 100644 index 000000000..2701008ee --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-context-search.ts @@ -0,0 +1,13 @@ +import { SearchableDropdownResult } from "@equinor/fusion-react-searchable-dropdown"; +import { useResolver } from "./use-resolver"; +import { useQuery } from "@tanstack/react-query"; + +export const useContextSearch = (searchText: string, types: string[]) => { + const { searchQuery } = useResolver(types); + + return useQuery({ + queryKey: ["contexts", ...types, searchText], + queryFn: async () => await searchQuery(searchText), + enabled: Boolean(searchText), + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-context-type-query.ts b/client/apps/portal-administration/src/hooks/use-context-type-query.ts new file mode 100644 index 000000000..adfbbc645 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-context-type-query.ts @@ -0,0 +1,51 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; + +import { ContextType, FormattedError } from "../types"; +import { useHttpClient } from "@equinor/fusion-framework-react-app/http"; +import { + createContextType, + getContextTypesQuery, + removeContextType, +} from "../query/context-type-query"; +import { ContextTypeInputs } from "../schema"; + +export const useGetContextTypes = () => { + const client = useHttpClient("portal-client"); + + return useQuery({ + queryKey: ["context-types"], + queryFn: ({ signal }) => getContextTypesQuery(client, signal), + }); +}; + +export const useCreateContextType = () => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + + return useMutation< + ContextTypeInputs, + FormattedError, + ContextTypeInputs, + ContextTypeInputs + >({ + mutationKey: ["create-context-type"], + mutationFn: (body) => createContextType(client, body), + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["create-context-type"] }); + queryClient.invalidateQueries({ queryKey: ["context-types"] }); + }, + }); +}; +export const useRemoveContextType = () => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (type) => removeContextType(client, type), + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["context-types"] }); + }, + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-onboard-apps.ts b/client/apps/portal-administration/src/hooks/use-onboard-apps.ts new file mode 100644 index 000000000..a1aa1bdfe --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-onboard-apps.ts @@ -0,0 +1,47 @@ +import { useMemo } from "react"; +import { useOnboardedApps } from "./use-onboarded-apps"; +import { useGetPortalApps } from "./use-portal-apps"; +import { useGetPortal } from "./use-portal-query"; +import { PortalApp } from "../types"; + +export const useOnboardApps = (portalId?: string) => { + const { data: onboardedApps, isLoading: onboardedAppsIsLoading } = + useOnboardedApps(); + const { data: portalApps, isLoading: portalAppsIsLoading } = + useGetPortalApps(portalId); + + const { data: portalData, isLoading: portalIsLoading } = + useGetPortal(portalId); + + const onboardAppsList = useMemo(() => { + if (!onboardedApps || !portalApps || !portalData) { + return []; + } + + const portalHasContext = portalData?.contexts.length > 0; + const portalContexts = portalData?.contexts; + + return onboardedApps.reduce((acc, app) => { + const isActive = Boolean( + portalApps.find((portalApp) => portalApp.key === app.appKey) + ); + + if ( + portalHasContext && + portalContexts.find((context) => + app.contexts.find((appContext) => appContext.type === context.type) + ) + ) { + acc.push({ ...app, isActive }); + } else if (!portalHasContext || app.contexts.length === 0) { + acc.push({ ...app, isActive }); + } + return acc; + }, [] as PortalApp[]); + }, [onboardedApps, portalApps, portalData]); + + return { + data: onboardAppsList, + isLoading: onboardedAppsIsLoading || portalAppsIsLoading || portalIsLoading, + }; +}; diff --git a/client/apps/portal-administration/src/hooks/use-onboarded-apps.ts b/client/apps/portal-administration/src/hooks/use-onboarded-apps.ts new file mode 100644 index 000000000..fcc017b4a --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-onboarded-apps.ts @@ -0,0 +1,118 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { FormattedError, PortalApp, PortalAppMutation } from '../types'; +import { useHttpClient } from '@equinor/fusion-framework-react-app/http'; +import { OnboardAppInputs } from '../schema/app'; +import { useSnackBar } from './use-snack-bar'; +import { editOnboardedApps } from '../query/onboarded-apps-queries'; +import { Result } from '../query/apps-queries'; +import { mutateOnboardedApps } from '../query/onboarded-apps-mutations'; + +export const useOnboardedApps = () => { + const client = useHttpClient('portal-client'); + + return useQuery({ + queryKey: ['onboarded-apps'], + queryFn: async () => await client.fetch('api/onboarded-apps').then((response) => response.json()), + }); +}; + +export const useAddOnboardedApp = () => { + const client = useHttpClient('portal-client'); + const { sendMessage } = useSnackBar(); + const queryClient = useQueryClient(); + return useMutation({ + mutationKey: ['onboard-app'], + mutationFn: async (body) => { + return await client + .fetch(`api/onboarded-apps`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }) + .then((response) => response.text()); + }, + onSuccess() { + sendMessage('App onboarded successful', 'Info'); + queryClient.invalidateQueries({ queryKey: ['onboarded-apps'] }); + }, + onError() { + sendMessage('Failed onboarding application', 'Error'); + }, + }); +}; + +export const useDeleteOnboardedApp = () => { + const client = useHttpClient('portal-client'); + const { sendMessage } = useSnackBar(); + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async (appKey) => { + const response = await ( + await client + ).fetch(`api/onboarded-apps/${appKey}`, { + method: 'DELETE', + }); + + if (response.ok) return response.ok; + + throw new Error('Failed delete application'); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ['onboarded-apps'] }); + sendMessage('Onboarded app successfully deleted', 'Info'); + }, + onError() { + sendMessage('Failed delete application', 'Error'); + }, + }); +}; + +export const useEditOnboardedApp = (appKey?: string) => { + const client = useHttpClient('portal-client'); + const queryClient = useQueryClient(); + return useMutation({ + mutationKey: ['onboarded-app', appKey], + mutationFn: async (body) => { + return await client + .fetch(`api/onboarded-apps/${appKey}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }) + .then((response) => response.json()); + }, + + onSettled() { + queryClient.invalidateQueries({ queryKey: ['onboarded-apps'] }); + }, + }); +}; + +export const useEditOnboardedApps = () => { + const client = useHttpClient('portal-client'); + const queryClient = useQueryClient(); + const { sendMessage } = useSnackBar(); + return useMutation< + Result[], + FormattedError, + PortalAppMutation[], + { prevApps: PortalAppMutation[]; newApps: PortalAppMutation[] } + >({ + mutationFn: async (apps) => editOnboardedApps(client, apps), + onMutate(apps) { + return mutateOnboardedApps(queryClient, apps); + }, + onError(_err, _apps, context) { + sendMessage('Apps failed to be updated', 'Error'); + queryClient.setQueryData(['onboarded-apps'], context?.prevApps || []); + }, + onSettled() { + queryClient.invalidateQueries({ queryKey: ['onboarded-apps'] }); + sendMessage('Apps updated successful', 'Info'); + }, + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-onboarded-context.ts b/client/apps/portal-administration/src/hooks/use-onboarded-context.ts new file mode 100644 index 000000000..56e69374a --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-onboarded-context.ts @@ -0,0 +1,67 @@ +import { useHttpClient } from "@equinor/fusion-framework-react-app/http"; +import { FormattedError, OnboardedContext } from "../types"; +import { + getOnboardedContextQuery, + onboardContext, + updateOnboardedContext, +} from "../query/onboarded-context"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useSnackBar } from "./use-snack-bar"; + +export const useOnboardedContexts = () => { + const client = useHttpClient("portal-client"); + + return useQuery({ + queryKey: ["onboarded-contexts"], + queryFn: ({ signal }) => getOnboardedContextQuery(client, signal), + }); +}; + +export const useEditOnboardContext = () => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + + const { sendMessage } = useSnackBar(); + + return useMutation< + string, + FormattedError, + OnboardedContext, + OnboardedContext + >({ + mutationKey: ["onboarded-context"], + mutationFn: (body) => updateOnboardedContext(client, body), + + onError() { + sendMessage("Context update failed", "Error"); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["onboarded-contexts"] }); + sendMessage("Context update successful", "Info"); + }, + }); +}; + +export const useOnboardContext = () => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + const { sendMessage } = useSnackBar(); + + return useMutation< + string, + FormattedError, + Pick, + string + >({ + mutationFn: (type) => onboardContext(client, type), + onError() { + sendMessage("Context creation failed", "Error"); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["context-types"] }); + sendMessage("Context onboarded successful", "Info"); + }, + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-portal-apps.ts b/client/apps/portal-administration/src/hooks/use-portal-apps.ts new file mode 100644 index 000000000..3df215fec --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-portal-apps.ts @@ -0,0 +1,85 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { AppManifestResponse, FormattedError, PortalApp } from "../types"; + +import { useHttpClient } from "@equinor/fusion-framework-react-app/http"; +import { + Result, + addPortalApps, + getPortalAppsById, + removePortalApps, +} from "../query/apps-queries"; +import { useSnackBar } from "./use-snack-bar"; +import { + mutateDeletePortalApps, + mutatePortalApps as mutateAddPortalApps, +} from "../query/apps-mutations"; + +export const useGetPortalApps = (portalId?: string) => { + const client = useHttpClient("portal-client"); + + return useQuery({ + queryKey: ["portal-apps", portalId], + queryFn: ({ signal }) => getPortalAppsById(client, portalId, signal), + enabled: Boolean(portalId), + }); +}; + +export const useAddPortalApps = (portalId?: string) => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + const { sendMessage } = useSnackBar(); + + return useMutation< + Result[], + FormattedError, + PortalApp[], + { prevApps: AppManifestResponse[]; newApps: AppManifestResponse[] } + >({ + mutationFn: (apps) => addPortalApps(client, apps, portalId), + onMutate: (apps) => { + return mutateAddPortalApps(queryClient, portalId, apps); + }, + onError(_err, _apps, context) { + sendMessage("Apps failed to be added", "Error"); + queryClient.setQueryData( + ["portal-apps", portalId], + context?.prevApps || [] + ); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["portal-apps", portalId] }); + sendMessage("Apps added successful", "Info"); + }, + }); +}; + +export const useRemovePortalApps = (portalId?: string) => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + const { sendMessage } = useSnackBar(); + + return useMutation< + Result[], + FormattedError, + PortalApp[], + { prevApps: AppManifestResponse[]; newApps: AppManifestResponse[] } + >({ + mutationFn: (apps) => removePortalApps(client, apps, portalId), + onMutate: (apps) => { + return mutateDeletePortalApps(queryClient, portalId, apps); + }, + onError: (_err, _apps, context) => { + sendMessage("Failed to remove apps from portal", "Error"); + queryClient.setQueryData( + ["portal-apps", portalId], + context?.prevApps || [] + ); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["portal-apps", portalId] }); + sendMessage("Apps removed successfully", "Info"); + }, + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-portal-config-query.ts b/client/apps/portal-administration/src/hooks/use-portal-config-query.ts new file mode 100644 index 000000000..ae0119a93 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-portal-config-query.ts @@ -0,0 +1,48 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { + FormattedError, + PortalConfiguration, + PortalConfigurationEditInput, +} from "../types"; +import { + getPortalConfigByIdQuery, + updatePortalConfigQuery, +} from "../query/portal-query"; + +import { useHttpClient } from "@equinor/fusion-framework-react-app/http"; +import { useSnackBar } from "./use-snack-bar"; + +export const useGetPortalConfiguration = (portalId?: string) => { + const client = useHttpClient("portal-client"); + + return useQuery({ + queryKey: ["portal-config", { portalId }], + queryFn: ({ signal }) => getPortalConfigByIdQuery(client, portalId, signal), + enabled: Boolean(portalId), + }); +}; + +export const useUpdatePortalConfig = () => { + const client = useHttpClient("portal-client"); + + const queryClient = useQueryClient(); + + const { sendMessage } = useSnackBar(); + + return useMutation< + boolean, + FormattedError, + PortalConfigurationEditInput, + PortalConfigurationEditInput + >({ + mutationKey: ["portal-config"], + mutationFn: (body) => updatePortalConfigQuery(client, body), + onError() { + sendMessage("Failed to update portal", "Error"); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["portal-config"] }); + sendMessage("Portal updated success", "Info"); + }, + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-portal-query.ts b/client/apps/portal-administration/src/hooks/use-portal-query.ts new file mode 100644 index 000000000..a235e31df --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-portal-query.ts @@ -0,0 +1,95 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { FormattedError, Portal } from '../types'; +import { + createPortalQuery, + deletePortalByIdQuery, + getPortalByIdQuery, + getPortalsQuery, + updatePortalQuery, +} from '../query/portal-query'; +import { PortalInputs } from '../schema'; +import { useHttpClient } from '@equinor/fusion-framework-react-app/http'; +import { useSnackBar } from './use-snack-bar'; +import { useNavigate } from 'react-router-dom'; + +export const useGetPortals = () => { + const client = useHttpClient('portal-client'); + + return useQuery({ + queryKey: ['portals'], + queryFn: ({ signal }) => getPortalsQuery(client, signal), + }); +}; + +export const useGetPortal = (portalId?: string) => { + const client = useHttpClient('portal-client'); + + return useQuery({ + queryKey: ['portal', { portalId }], + queryFn: ({ signal }) => getPortalByIdQuery(client, portalId, signal), + enabled: Boolean(portalId), + }); +}; + +export const useDeletePortal = () => { + const client = useHttpClient('portal-client'); + const queryClient = useQueryClient(); + + const { sendMessage } = useSnackBar(); + return useMutation({ + mutationFn: (portal) => deletePortalByIdQuery(client, portal?.id), + onError(_, portal) { + sendMessage( + `Failed to delete ${portal?.name || 'Portal'}. The Portal may have one or more applications enabled`, + 'Error' + ); + }, + onSuccess(_, portal) { + queryClient.invalidateQueries({ queryKey: ['portals'] }); + sendMessage(`Portal ${portal?.name} deleted successfully`, 'Info'); + }, + }); +}; + +export const useCreatePortal = () => { + const client = useHttpClient('portal-client'); + + const queryClient = useQueryClient(); + const navigate = useNavigate(); + const { sendMessage } = useSnackBar(); + + return useMutation({ + mutationKey: ['create-portal'], + mutationFn: (body) => createPortalQuery(client, body), + onError() { + sendMessage('Failed to create portal', 'Error'); + }, + onSuccess(_, portal) { + queryClient.invalidateQueries({ queryKey: ['create-portal'] }); + queryClient.invalidateQueries({ queryKey: ['portals'] }); + queryClient.invalidateQueries({ queryKey: ['portal'] }); + sendMessage(`Portal ${portal.name} was created successfully`, 'Info'); + navigate(`/portals?tab=table`); + }, + }); +}; + +export const useUpdatePortal = (portalId: string) => { + const client = useHttpClient('portal-client'); + + const queryClient = useQueryClient(); + + const { sendMessage } = useSnackBar(); + + return useMutation({ + mutationKey: ['portal', { portalId }], + mutationFn: (body) => updatePortalQuery(client, body), + onError() { + sendMessage('Failed to update portal', 'Error'); + }, + onSuccess() { + queryClient.invalidateQueries({ queryKey: ['portal'] }); + sendMessage('Portal updated success', 'Info'); + }, + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-portals-query.ts b/client/apps/portal-administration/src/hooks/use-portals-query.ts new file mode 100644 index 000000000..f0960b912 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-portals-query.ts @@ -0,0 +1,14 @@ +import { useQuery } from "@tanstack/react-query"; +import { useHttpClient } from "@equinor/fusion-framework-react-app/http"; + +import { Portal } from "../types"; + +export const usePortalsQuery = () => { + const client = useHttpClient("portal-client"); + + return useQuery({ + queryKey: ["portals"], + queryFn: async () => + await client.fetch("api/portals").then((res) => res.json()), + }); +}; diff --git a/client/apps/portal-administration/src/hooks/use-remove-app-from-context.ts b/client/apps/portal-administration/src/hooks/use-remove-app-from-context.ts new file mode 100644 index 000000000..38b44a024 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-remove-app-from-context.ts @@ -0,0 +1,104 @@ +import { + IHttpClient, + useHttpClient, +} from "@equinor/fusion-framework-react-app/http"; +import { useMutation } from "@tanstack/react-query"; +import { OnboardedContext, PortalApp } from "../types"; + +type ContextAppResult = { + appKey: string; + contextId: string; + status: "failed" | "success"; +}; + +export const useRemoveAppWithContext = (portalId?: string) => { + const client = useHttpClient("portal"); + + return useMutation({ + mutationFn: async ({ + appsSelection, + contextSelection, + }: { + appsSelection: PortalApp[]; + contextSelection: OnboardedContext[]; + }) => { + return addPortalAppsWithContexts( + client, + appsSelection, + contextSelection, + portalId + ); + }, + }); +}; + +const addPortalAppWithContext = async ( + client: IHttpClient, + contextId: string, + appKey: string, + portalId: string +) => { + const response = await client.fetch( + `api/portals/${portalId}/apps`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + appKey, + removeAppForContexts: true, + }), + } + ); + + if (!response.ok) { + return { appKey, contextId, status: "failed" } as ContextAppResult; + } + + return { appKey, status: "success" } as ContextAppResult; +}; + +const addPortalAppWithContexts = async ( + client: IHttpClient, + appKey: string, + contexts: OnboardedContext[], + portalId?: string +) => { + if (!portalId) return [] as ContextAppResult[]; + const results: ContextAppResult[] = []; + + for (const context of contexts) { + const result = await addPortalAppWithContext( + client, + context.contextId, + appKey, + portalId + ); + results.push(result); + } + + return results as ContextAppResult[]; +}; + +const addPortalAppsWithContexts = async ( + client: IHttpClient, + portalApps: PortalApp[], + contexts: OnboardedContext[], + portalId?: string +) => { + if (!portalId) return [] as ContextAppResult[]; + const results: ContextAppResult[] = []; + + for (const app of portalApps) { + const result = await addPortalAppWithContexts( + client, + app.appKey, + contexts, + portalId + ); + results.push(...result); + } + + return results as ContextAppResult[]; +}; diff --git a/client/apps/portal-administration/src/hooks/use-resise-observer.ts b/client/apps/portal-administration/src/hooks/use-resise-observer.ts new file mode 100644 index 000000000..0555380ce --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-resise-observer.ts @@ -0,0 +1,50 @@ +import { RefObject, useCallback, useLayoutEffect, useState } from "react"; +/** + * Hook to observe width and height + * @param ref Node that you want to observe size for + * @param callback Optional callback function that accesses the node + * @returns width and height for the observed node + */ +export const useResizeObserver = ( + ref: RefObject, + callback?: (entry: DOMRectReadOnly) => void +) => { + const [width, setWidth] = useState(0); + const [height, setHeight] = useState(0); + + const handleResize = useCallback( + (entries: ResizeObserverEntry[]) => { + if (!Array.isArray(entries)) { + return; + } + const entry = entries[0]; + setWidth(entry.contentRect.width); + setHeight(entry.contentRect.height); + + if (callback) { + callback(entry.contentRect); + } + }, + [callback] + ); + + useLayoutEffect(() => { + if (!ref.current) { + return; + } + let RO = new ResizeObserver((entries: ResizeObserverEntry[]) => + handleResize(entries) + ); + RO.observe(ref.current); + + // eslint-disable-next-line consistent-return + return () => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + RO.disconnect; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + RO = null; + }; + }, [ref]); + return [width, height]; +}; diff --git a/client/apps/portal-administration/src/hooks/use-resolver.ts b/client/apps/portal-administration/src/hooks/use-resolver.ts new file mode 100644 index 000000000..14bc2e897 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-resolver.ts @@ -0,0 +1,103 @@ +import { + SearchableDropdownResultItem, + SearchableDropdownResult, +} from "@equinor/fusion-react-searchable-dropdown"; +import { QueryContextResponse } from "@equinor/fusion-framework-module-services/context/query"; +import { ServicesModule } from "@equinor/fusion-framework-module-services"; +import { ContextApiClient } from "@equinor/fusion-framework-module-services/context"; +import { useFramework } from "@equinor/fusion-framework-react"; +import { useCallback, useEffect, useState } from "react"; + +const singleItem = (props: unknown): SearchableDropdownResultItem => { + return Object.assign({ id: "0", title: "Dummy title" }, props); +}; + +function contextResultMapped( + contexts: QueryContextResponse<"v1"> +): SearchableDropdownResult { + return contexts.map((context) => + singleItem({ + id: context.id, + title: context.title, + subTitle: context.type?.id, + }) + ); +} + +const minQueryLength = 3; + +export const useResolver = (type: string[] = []) => { + const [client, setClient] = useState | null>(null); + + const { modules } = useFramework<[ServicesModule]>(); + const ct = useFramework().modules.serviceDiscovery.createClient("context"); + useEffect(() => { + modules.services.createContextClient("json").then(setClient); + }, [modules.services, setClient]); + + const searchQuery = useCallback( + async (search: string): Promise => { + let searchResult: SearchableDropdownResult = []; + if (!client) { + return []; + } + + try { + if (!search || search.length < minQueryLength) { + searchResult.push( + singleItem({ + title: `Need ${minQueryLength - search.length} more chars`, + isDisabled: true, + }) + ); + return searchResult; + } + + const contexts = await client.query("v1", { + query: { search, filter: { type } }, + }); + + if (contexts[0] && !contexts[0].id) return searchResult; + // Structure as type + searchResult = contextResultMapped(contexts); + + if (searchResult.length === 0) { + searchResult.push( + singleItem({ title: "No matches...", isDisabled: true }) + ); + } + + return searchResult; + } catch (e) { + return [ + singleItem({ + title: "API Error", + subTitle: e, + isDisabled: true, + isError: true, + }), + ]; + } + }, + [client, type] + ); + + const getContextById = useCallback( + async (id?: string): Promise | undefined> => { + if (!client) { + return; + } + + try { + return await client.get("v1", { + id: id || "", + }); + } catch (e) { + return; + } + }, + [client, type] + ); + + return { searchQuery, getContextById }; +}; diff --git a/client/apps/portal-administration/src/hooks/use-snack-bar.ts b/client/apps/portal-administration/src/hooks/use-snack-bar.ts new file mode 100644 index 000000000..4834eff67 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-snack-bar.ts @@ -0,0 +1,33 @@ +import { useEffect, useState } from "react"; +import { BehaviorSubject } from "rxjs"; +import { uuidv7 } from "uuidv7"; + +export type Message = { + id: string; + type: string; + message: string; +}; + +const messages$ = new BehaviorSubject>({}); + +export const useSnackBar = () => { + const [messages, setMessages] = useState>({}); + + useEffect(() => { + const sub = messages$.subscribe(setMessages); + return () => sub.unsubscribe(); + }, []); + + const sendMessage = (message: string, type: string = "Info") => { + const id = uuidv7(); + messages$.next( + Object.assign({}, messages$.value, { [id]: { message, type, id } }) + ); + }; + + const removeMessage = (id: string) => { + delete messages$.value[id]; + }; + + return { sendMessage, removeMessage, messages, messages$ }; +}; diff --git a/client/apps/portal-administration/src/hooks/use-tabs.ts b/client/apps/portal-administration/src/hooks/use-tabs.ts new file mode 100644 index 000000000..f58014314 --- /dev/null +++ b/client/apps/portal-administration/src/hooks/use-tabs.ts @@ -0,0 +1,24 @@ +import { IconData } from '@equinor/eds-icons'; +import { FC, useEffect, useState } from 'react'; +import { useLocation } from 'react-router-dom'; + +type Tab = { key: Key; title: string; route: string; description: string | FC; icon?: IconData }; +export type TabsList = Tab[]; + +export const useTabs = (tabs: TabsList, defaultTabKey: Key) => { + const defaultTab = tabs.find((tab) => tab.key === defaultTabKey)!; + const [activeTab, setActiveTab] = useState>(defaultTab); + + const { pathname } = useLocation(); + + useEffect(() => { + const match = tabs.find((tab) => pathname.endsWith(tab.route)); + if (match) { + setActiveTab(match); + } else if (defaultTab) { + setActiveTab(defaultTab); + } + }, [pathname, tabs, defaultTab]); + + return { activeTab, setActiveTab }; +}; diff --git a/client/apps/portal-administration/src/index.ts b/client/apps/portal-administration/src/index.ts new file mode 100644 index 000000000..dbf3887ea --- /dev/null +++ b/client/apps/portal-administration/src/index.ts @@ -0,0 +1,21 @@ +import { createElement } from 'react'; +import { createRoot } from 'react-dom/client'; +import { makeComponent, ComponentRenderArgs } from '@equinor/fusion-framework-react-app'; + +import configure from './config'; + +import App from './App'; + +const appComponent = createElement(App); + +const createApp = (args: ComponentRenderArgs) => makeComponent(appComponent, args, configure); + +export default function (el: HTMLElement, args: ComponentRenderArgs) { + const app = createApp(args); + + const root = createRoot(el); + + root.render(createElement(app)); + + return () => root.unmount(); +} diff --git a/client/apps/portal-administration/src/pages/ContextConfig.tsx b/client/apps/portal-administration/src/pages/ContextConfig.tsx new file mode 100644 index 000000000..d5d3e4dc6 --- /dev/null +++ b/client/apps/portal-administration/src/pages/ContextConfig.tsx @@ -0,0 +1,27 @@ +import styled from 'styled-components'; +import { OnboardedContextsTable } from '../components/OnboardedContexts/OnboardedContextsTable'; + +import { Loading } from '../components/Loading'; +import { useOnboardedContexts } from '../hooks/use-onboarded-context'; +import { AddContext } from '../components/OnboardedContexts/AddContext'; + +const Style = { + Content: styled.div` + padding-top: 1rem; + width: 100%; + height: -webkit-fill-available; + `, +}; + +export const Context = () => { + const { isLoading, data: onboardedContexts } = useOnboardedContexts(); + + if (isLoading) return ; + + return ( + + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/ContextTypesPage.tsx b/client/apps/portal-administration/src/pages/ContextTypesPage.tsx new file mode 100644 index 000000000..d2e72f2e6 --- /dev/null +++ b/client/apps/portal-administration/src/pages/ContextTypesPage.tsx @@ -0,0 +1,18 @@ +import { styled } from 'styled-components'; +import { EditContextTypeForm } from '../components/OnboardedContexts/ContextType'; + +const Style = { + Content: styled.div` + padding-top: 1rem; + width: 100%; + height: -webkit-fill-available; + `, +}; + +export const ContextTypesPage = () => { + return ( + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/CreatePortal.tsx b/client/apps/portal-administration/src/pages/CreatePortal.tsx new file mode 100644 index 000000000..91cf07dcc --- /dev/null +++ b/client/apps/portal-administration/src/pages/CreatePortal.tsx @@ -0,0 +1,20 @@ +import styled from 'styled-components'; +import { CreatePortalForm } from '../components/Portals/CreatePortalForm'; + +const Style = { + Wrapper: styled.div` + display: flex; + padding: 1rem 0; + flex-direction: column; + width: -webkit-fill-available; + height: -webkit-fill-available; + `, +}; + +export const CreatePortal = () => { + return ( + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/EditPortal.tsx b/client/apps/portal-administration/src/pages/EditPortal.tsx new file mode 100644 index 000000000..62027798c --- /dev/null +++ b/client/apps/portal-administration/src/pages/EditPortal.tsx @@ -0,0 +1,46 @@ +import styled from 'styled-components'; + +import { useParams } from 'react-router-dom'; + +import { useGetPortal } from '../hooks/use-portal-query'; +import { useGetContextTypes } from '../hooks/use-context-type-query'; +import { Typography } from '@equinor/eds-core-react'; +import { Loading } from '../components/Loading'; +import { EditPortalForm } from '../components/Portal/EditPortalForm'; +import { Message } from '../components/Message'; + +const Style = { + Wrapper: styled.div` + gap: 1rem; + display: flex; + padding: 1rem 0; + flex-direction: column; + width: -webkit-fill-available; + height: -webkit-fill-available; + `, + Heading: styled(Typography)` + padding: 0.5rem 0; + `, +}; + +export const EditPortal = () => { + const { portalId } = useParams(); + + const { data: portal, isLoading: portalLoading } = useGetPortal(portalId); + + const { data: contextTypes, isLoading: contextTypeLoading } = useGetContextTypes(); + + if (portalLoading || contextTypeLoading) { + return ; + } + + if (!portalId || !portal || !contextTypes) { + return ; + } + + return ( + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/OnboardedAppsTable.tsx b/client/apps/portal-administration/src/pages/OnboardedAppsTable.tsx new file mode 100644 index 000000000..7573b3465 --- /dev/null +++ b/client/apps/portal-administration/src/pages/OnboardedAppsTable.tsx @@ -0,0 +1,31 @@ +import { styled } from 'styled-components'; +import { Loading } from '../components/Loading'; +import { useOnboardedApps } from '../hooks/use-onboarded-apps'; +import { AppsTable } from '../components/OnboardedApps/AppsTable'; +import { OnboardApp } from '../components/OnboardedApps/OnboardApp'; + +const Style = { + Content: styled.div` + padding-top: 1rem; + width: 100%; + height: -webkit-fill-available; + `, + Wrapper: styled.div` + display: flex; + flex-direction: column; + height: 100%; + `, +}; + +export const OnboardedApps = () => { + const { data, isLoading } = useOnboardedApps(); + + return ( + + + + {isLoading ? : } + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/Portal.tsx b/client/apps/portal-administration/src/pages/Portal.tsx new file mode 100644 index 000000000..4b8beb4a4 --- /dev/null +++ b/client/apps/portal-administration/src/pages/Portal.tsx @@ -0,0 +1,59 @@ +import { Outlet, useNavigate, useParams } from 'react-router-dom'; +import styled from 'styled-components'; +import { useEffect } from 'react'; +import { usePortalContext } from '../context/PortalContext'; +import { PageMessage } from '../components/PageMessage/PageMessage'; +import { useGetPortal } from '../hooks/use-portal-query'; +import { PortalHeader } from '../components/Portal/PortalHeader'; + +const Styles = { + Content: styled.div` + display: flex; + width: 100%; + height: 100%; + `, + Section: styled.section` + flex-direction: column; + padding: 1rem; + display: flex; + height: 100%; + `, + Wrapper: styled.div` + display: block; + overflow: hidden; + height: 100%; + `, +}; + +export const Portal = () => { + const { portalId } = useParams(); + const navigate = useNavigate(); + const { setActivePortalById, activePortalId } = usePortalContext(); + + useEffect(() => { + if (!portalId || portalId === 'undefined') { + navigate('portals'); + } else { + activePortalId !== portalId && setActivePortalById(portalId); + } + }, [portalId, activePortalId, setActivePortalById]); + + const { data: portal } = useGetPortal(portalId); + + if (!portalId) { + return ; + } + + return ( + + + + + + + + + ); +}; + +export default Portal; diff --git a/client/apps/portal-administration/src/pages/PortalApps.tsx b/client/apps/portal-administration/src/pages/PortalApps.tsx new file mode 100644 index 000000000..74546f02d --- /dev/null +++ b/client/apps/portal-administration/src/pages/PortalApps.tsx @@ -0,0 +1,39 @@ +import styled from 'styled-components'; + +import { useParams } from 'react-router-dom'; +import { useOnboardApps } from '../hooks/use-onboard-apps'; + +import { PortalAppTable } from '../components/PortalApps/PortalAppTable'; +import { Loading } from '../components/Loading'; + +const Style = { + Wrapper: styled.div` + height: calc(100% - 6rem); + width: 100%; + position: absolute; + `, + Content: styled.div` + width: -webkit-fill-available; + height: -webkit-fill-available; + `, +}; + +export const PortalApps = () => { + const { portalId } = useParams(); + + const { data: portalApps, isLoading } = useOnboardApps(portalId); + + if (!portalId) { + return <>No portalId provided; + } + + if (isLoading) { + return ; + } + + return ( + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/Portals.tsx b/client/apps/portal-administration/src/pages/Portals.tsx new file mode 100644 index 000000000..670968225 --- /dev/null +++ b/client/apps/portal-administration/src/pages/Portals.tsx @@ -0,0 +1,35 @@ +import styled from 'styled-components'; +import { Outlet } from 'react-router-dom'; +import { PortalsHeader } from '../components/Portals/PortalsHeader'; + +const Styles = { + Content: styled.div` + display: flex; + width: 100%; + height: 100%; + `, + Section: styled.section` + flex-direction: column; + padding: 1rem; + display: flex; + height: 100%; + `, + Wrapper: styled.div` + display: block; + overflow: hidden; + height: 100%; + `, +}; + +export const Portals = () => { + return ( + + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/PortalsList.tsx b/client/apps/portal-administration/src/pages/PortalsList.tsx new file mode 100644 index 000000000..9460a2e60 --- /dev/null +++ b/client/apps/portal-administration/src/pages/PortalsList.tsx @@ -0,0 +1,29 @@ +import { styled } from 'styled-components'; +import { Loading } from '../components/Loading'; +import { PortalTable } from '../components/Portals/PortalTable'; +import { usePortalsQuery } from '../hooks/use-portals-query'; + +const Style = { + Wrapper: styled.div` + height: calc(100% - 6rem); + width: 100%; + position: absolute; + `, + Content: styled.div` + width: 100%; + height: -webkit-fill-available; + `, +}; + +export const PortalList = () => { + const { isLoading, data: portalsData } = usePortalsQuery(); + + if (isLoading) { + return ; + } + return ( + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/Root.tsx b/client/apps/portal-administration/src/pages/Root.tsx new file mode 100644 index 000000000..9876c0945 --- /dev/null +++ b/client/apps/portal-administration/src/pages/Root.tsx @@ -0,0 +1,39 @@ +import { Outlet } from 'react-router-dom'; +import styled from 'styled-components'; +import SideMenu from '../components/SideMenu'; +import { PortalContextComponent } from '../context/PortalContext'; +import { Snack } from '../components/Snack'; + +const Styles = { + Content: styled.div` + flex: 1; + position: relative; + overflow: auto; + overflow-x: hidden; + `, + Section: styled.section` + display: flex; + height: inherit; + `, + Wrapper: styled.div` + display: block; + height: inherit; + width: 100%; + `, +}; + +export const Root = () => { + return ( + + + + + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/RouterConfig.tsx b/client/apps/portal-administration/src/pages/RouterConfig.tsx new file mode 100644 index 000000000..86a39754a --- /dev/null +++ b/client/apps/portal-administration/src/pages/RouterConfig.tsx @@ -0,0 +1,21 @@ +import { useParams } from 'react-router-dom'; +import { useGetPortal } from '../hooks/use-portal-query'; +import { Loading } from '../components/Loading'; + +import { RouterConfigContextComponent } from '../context/RouterContext'; +import { RouterTree } from '../components/Router/RouterTree'; +import { RouterEdit } from '../components/Router/RouterEdit'; + +export const RouterConfig = () => { + const { portalId } = useParams(); + const { data: portal, isLoading: portalIsLoading } = useGetPortal(portalId); + + if (portalIsLoading) return ; + + return ( + + + + + ); +}; diff --git a/client/apps/portal-administration/src/pages/Settings.tsx b/client/apps/portal-administration/src/pages/Settings.tsx new file mode 100644 index 000000000..8bb1384a5 --- /dev/null +++ b/client/apps/portal-administration/src/pages/Settings.tsx @@ -0,0 +1,36 @@ +import styled from 'styled-components'; + +import { Outlet } from 'react-router-dom'; +import { SettingsHeader } from '../components/Settings/SettingsHeader'; + +const Styles = { + Content: styled.div` + display: flex; + width: 100%; + height: inherit; + `, + Section: styled.section` + flex-direction: column; + padding: 1rem; + display: flex; + height: inherit; + `, + Wrapper: styled.div` + display: block; + overflow: hidden; + height: 100%; + `, +}; + +export const Settings = () => { + return ( + + + + + + + + + ); +}; diff --git a/client/apps/portal-administration/src/query/apps-mutations.ts b/client/apps/portal-administration/src/query/apps-mutations.ts new file mode 100644 index 000000000..a8019b28b --- /dev/null +++ b/client/apps/portal-administration/src/query/apps-mutations.ts @@ -0,0 +1,50 @@ +import { QueryClient } from "@tanstack/react-query"; +import { PortalApp, AppManifestResponse } from "../types"; + +export const mutatePortalApps = ( + queryClient: QueryClient, + portalId: string | undefined, + apps: PortalApp[] +) => { + queryClient.cancelQueries({ queryKey: ["portal-apps", portalId] }); + + const prevApps = + queryClient.getQueryData([ + "portal-apps", + portalId, + ]) || []; + + const newApps = [ + ...prevApps, + ...apps.map((a) => ({ + key: a.appKey, + contextTypes: a.contexts, + appManifest: { + key: a.appKey, + name: a.name, + description: a.description, + }, + })), + ] as AppManifestResponse[]; + + queryClient.setQueryData(["portal-apps", portalId], newApps); + return { prevApps, newApps }; +}; + +export const mutateDeletePortalApps = ( + queryClient: QueryClient, + portalId: string | undefined, + apps: PortalApp[] +) => { + queryClient.cancelQueries({ queryKey: ["portal-apps", portalId] }); + const prevApps = + queryClient.getQueryData([ + "portal-apps", + portalId, + ]) || []; + + const appKeys = apps.map((a) => a.appKey); + const newApps = prevApps?.filter((a) => !appKeys.includes(a.key)); + queryClient.setQueryData(["portal-apps", portalId], newApps); + return { prevApps, newApps }; +}; diff --git a/client/apps/portal-administration/src/query/apps-queries.ts b/client/apps/portal-administration/src/query/apps-queries.ts new file mode 100644 index 000000000..88e58a8b4 --- /dev/null +++ b/client/apps/portal-administration/src/query/apps-queries.ts @@ -0,0 +1,109 @@ +import { IHttpClient } from "@equinor/fusion-framework-react-app/http"; +import { formatError } from "../utils/error-utils"; +import { AppManifestResponse, PortalApp } from "../types"; + +export const getPortalAppsById = async ( + client: IHttpClient, + portalId?: string, + signal?: AbortSignal +) => { + const response = await client.fetch( + `api/portals/${portalId}/apps`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + signal, + } + ); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.json(); + return data as AppManifestResponse[]; +}; + +export type Result = { + appKey: string; + status: "failed" | "success"; +}; + +export const addPortalApp = async ( + client: IHttpClient, + appKey: string, + portalId: string +) => { + const response = await client.fetch( + `api/portals/${portalId}/apps`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + appKey, + removeAppForContexts: true, + }), + } + ); + + if (!response.ok) { + return { appKey, status: "failed" } as Result; + } + + return { appKey, status: "success" } as Result; +}; + +export const addPortalApps = async ( + client: IHttpClient, + portalApps: PortalApp[], + portalId?: string +) => { + if (!portalId) return [] as Result[]; + const results: Result[] = []; + + for (const app of portalApps) { + const result = await addPortalApp(client, app.appKey, portalId); + results.push(result); + } + + return results as Result[]; +}; + +export const removePortalApp = async ( + client: IHttpClient, + appKey: string, + portalId: string +) => { + const response = await client.fetch( + `api/portals/${portalId}/apps/${appKey}`, + { + method: "DELETE", + } + ); + + if (!response.ok) { + return { appKey, status: "failed" } as Result; + } + + return { appKey, status: "success" } as Result; +}; + +export const removePortalApps = async ( + client: IHttpClient, + portalApps: PortalApp[], + portalId?: string +) => { + if (!portalId) return [] as Result[]; + const results: Result[] = []; + + for (const app of portalApps) { + const result = await removePortalApp(client, app.appKey, portalId); + results.push(result); + } + + return results as Result[]; +}; diff --git a/client/apps/portal-administration/src/query/context-type-query.ts b/client/apps/portal-administration/src/query/context-type-query.ts new file mode 100644 index 000000000..d4954bd96 --- /dev/null +++ b/client/apps/portal-administration/src/query/context-type-query.ts @@ -0,0 +1,52 @@ +import { IHttpClient } from "@equinor/fusion-framework-module-http"; +import { formatError } from "../utils/error-utils"; +import { ContextType } from "../types"; +import { ContextTypeInputs } from "../schema"; + +export const getContextTypesQuery = async ( + client: IHttpClient, + signal?: AbortSignal +) => { + const response = await client.fetch(`api/context-types`, { + method: "GET", + signal, + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.json(); + return data as ContextType[]; +}; + +export const createContextType = async ( + client: IHttpClient, + body: ContextTypeInputs +) => { + const response = await client.fetch(`api/context-types`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.json(); + return data as ContextTypeInputs; +}; + +export const removeContextType = async (client: IHttpClient, type: string) => { + const response = await client.fetch(`api/context-types/${type}`, { + method: "DELETE", + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + return true; +}; diff --git a/client/apps/portal-administration/src/query/onboarded-apps-mutations.ts b/client/apps/portal-administration/src/query/onboarded-apps-mutations.ts new file mode 100644 index 000000000..6d7523bd9 --- /dev/null +++ b/client/apps/portal-administration/src/query/onboarded-apps-mutations.ts @@ -0,0 +1,19 @@ +import { QueryClient } from '@tanstack/react-query'; +import { PortalAppMutation } from '../types'; + +export const mutateOnboardedApps = (queryClient: QueryClient, apps: PortalAppMutation[]) => { + queryClient.cancelQueries({ queryKey: ['onboarded-apps'] }); + + const prevApps = queryClient.getQueryData(['onboarded-apps']) || []; + + const newApps = [ + ...prevApps, + ...apps.map((a) => ({ + key: a.appKey, + contextTypes: a.contextTypes, + })), + ] as PortalAppMutation[]; + + queryClient.setQueryData(['portal-apps'], newApps); + return { prevApps, newApps }; +}; diff --git a/client/apps/portal-administration/src/query/onboarded-apps-queries.ts b/client/apps/portal-administration/src/query/onboarded-apps-queries.ts new file mode 100644 index 000000000..e2cd9a447 --- /dev/null +++ b/client/apps/portal-administration/src/query/onboarded-apps-queries.ts @@ -0,0 +1,32 @@ +import { IHttpClient } from '@equinor/fusion-framework-module-http'; +import { PortalAppMutation } from '../types'; +import { Result } from './apps-queries'; + +export const editOnboardedApp = async (client: IHttpClient, app: PortalAppMutation) => { + const response = await client.fetch(`api/onboarded-apps/${app.appKey}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + contextTypes: app.contextTypes, + }), + }); + + if (!response.ok) { + return { appKey: app.appKey, status: 'failed' } as Result; + } + + return { appKey: app.appKey, status: 'success' } as Result; +}; + +export const editOnboardedApps = async (client: IHttpClient, onboardedApps: PortalAppMutation[]) => { + const results: Result[] = []; + console.log(onboardedApps); + for (const app of onboardedApps) { + const result = await editOnboardedApp(client, app); + results.push(result); + } + + return results as Result[]; +}; diff --git a/client/apps/portal-administration/src/query/onboarded-context.ts b/client/apps/portal-administration/src/query/onboarded-context.ts new file mode 100644 index 000000000..25e512350 --- /dev/null +++ b/client/apps/portal-administration/src/query/onboarded-context.ts @@ -0,0 +1,100 @@ +import { IHttpClient } from "@equinor/fusion-framework-react-app/http"; +import { formatError } from "../utils/error-utils"; +import { OnboardedContext } from "../types"; + +export const getOnboardedContextQuery = async ( + client: IHttpClient, + signal?: AbortSignal +) => { + const response = await client.fetch(`api/onboarded-contexts`, { + method: "GET", + signal, + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.json(); + return data as OnboardedContext[]; +}; + +export const searchFusionContexts = async ( + client: IHttpClient, + body: Pick +) => { + const response = await client.fetch(`api/onboarded-contexts`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.text(); + return data as string; +}; + +export const onboardContext = async ( + client: IHttpClient, + body: Pick +) => { + const response = await client.fetch(`api/onboarded-contexts`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.text(); + return data as string; +}; + +export const updateOnboardedContext = async ( + client: IHttpClient, + body: Pick +) => { + const response = await client.fetch( + `api/onboarded-contexts/${body.id}`, + { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + } + ); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.text(); + return data as string; +}; + +export const removeOnboardedContext = async ( + client: IHttpClient, + id: string +) => { + const response = await client.fetch( + `api/onboarded-contexts/${id}`, + { + method: "DELETE", + } + ); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + return true; +}; diff --git a/client/apps/portal-administration/src/query/portal-query.ts b/client/apps/portal-administration/src/query/portal-query.ts new file mode 100644 index 000000000..0fe5e7164 --- /dev/null +++ b/client/apps/portal-administration/src/query/portal-query.ts @@ -0,0 +1,119 @@ +import { IHttpClient } from '@equinor/fusion-framework-module-http'; +import { formatError } from '../utils/error-utils'; +import { Portal, PortalConfiguration, PortalConfigurationEditInput } from '../types'; +import { PortalInputs } from '../schema'; + +export const getPortalsQuery = async (client: IHttpClient, signal?: AbortSignal) => { + const response = await client.fetch(`api/portals`, { + method: 'GET', + signal, + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.json(); + return data as Portal[]; +}; + +export const createPortalQuery = async (client: IHttpClient, body: PortalInputs) => { + const response = await client.fetch(`api/portals`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + return await response.text(); +}; + +export const updatePortalQuery = async (client: IHttpClient, body: PortalInputs) => { + const response = await client.fetch(`api/portals/${body.id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + return response.ok; +}; +export const updatePortalConfigQuery = async (client: IHttpClient, body: PortalConfigurationEditInput) => { + const response = await client.fetch(`api/portals/${body.id}/configuration`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ router: JSON.stringify(body.router) }), + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + return response.ok; +}; + +export const getPortalConfigByIdQuery = async (client: IHttpClient, activePortalId?: string, signal?: AbortSignal) => { + const response = await client.fetch(`api/portals/${activePortalId}/configuration`, { + method: 'GET', + signal, + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const router = JSON.parse((await response.json()).router); + + return { router } as PortalConfiguration; +}; + +export const getPortalByIdQuery = async (client: IHttpClient, activePortalId?: string, signal?: AbortSignal) => { + const response = await client.fetch(`api/portals/${activePortalId}`, { + method: 'GET', + signal, + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.json(); + return data as Portal; +}; +export const deletePortalByIdQuery = async (client: IHttpClient, activePortalId?: string) => { + const response = await client.fetch(`api/portals/${activePortalId}`, { + method: 'DELETE', + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + return true; +}; + +export const getPortalAppsQuery = async (client: IHttpClient, activePortalId?: string, signal?: AbortSignal) => { + const response = await client.fetch(`api/portals/${activePortalId}/apps`, { + method: 'GET', + signal, + }); + + if (!response.ok) { + throw formatError(await response.json(), response.status); + } + + const data = await response.json(); + return data as any; +}; diff --git a/client/apps/portal-administration/src/routes.tsx b/client/apps/portal-administration/src/routes.tsx new file mode 100644 index 000000000..c7f6d5fe9 --- /dev/null +++ b/client/apps/portal-administration/src/routes.tsx @@ -0,0 +1,95 @@ +import { Navigate, RouteObject } from 'react-router-dom'; +import { Portals } from './pages/Portals'; +import { EditPortal } from './pages/EditPortal'; +import { RouterConfig } from './pages/RouterConfig'; +import { Context } from './pages/ContextConfig'; +import Portal from './pages/Portal'; +import { Settings } from './pages/Settings'; +import { PortalApps } from './pages/PortalApps'; +import { Root } from './pages/Root'; +import { ShowConfigPage } from './components/Portal/ShowConfig'; +import { PortalList } from './pages/PortalsList'; +import { CreatePortal } from './pages/CreatePortal'; + +import { OnboardedApps } from './pages/OnboardedAppsTable'; + +import { ContextTypesPage } from './pages/ContextTypesPage'; + +export const routes: RouteObject[] = [ + { + path: '/', + Component: Root, + children: [ + { + index: true, + Component: () => , + }, + { + path: 'settings/apps', + Component: Settings, + children: [ + { + index: true, + Component: OnboardedApps, + }, + ], + }, + { + Component: Settings, + path: 'settings/contexts', + children: [ + { + index: true, + Component: Context, + }, + { + path: 'types', + Component: ContextTypesPage, + }, + ], + }, + { + path: 'portals', + Component: Portals, + children: [ + { + index: true, + Component: PortalList, + }, + { + path: 'create', + Component: CreatePortal, + }, + ], + }, + { + path: 'portals/:portalId', + Component: Portal, + children: [ + { + path: 'overview', + Component: EditPortal, + }, + { + Component: RouterConfig, + path: 'router', + }, + { + Component: PortalApps, + path: 'apps', + }, + { + Component: Context, + path: 'context', + }, + { + Component: ShowConfigPage, + path: 'show', + }, + ], + }, + ], + }, +]; + +export default routes; diff --git a/client/apps/portal-administration/src/schema/app.ts b/client/apps/portal-administration/src/schema/app.ts new file mode 100644 index 000000000..f2248cffa --- /dev/null +++ b/client/apps/portal-administration/src/schema/app.ts @@ -0,0 +1,8 @@ +import { z } from "zod"; + +export const onboardAppInput = z.object({ + appKey: z.string().min(1, "Please Select application from the list").max(50), + contextTypes: z.array(z.string()), +}); + +export type OnboardAppInputs = z.infer; diff --git a/client/apps/portal-administration/src/schema/index.ts b/client/apps/portal-administration/src/schema/index.ts new file mode 100644 index 000000000..c4c02c2ba --- /dev/null +++ b/client/apps/portal-administration/src/schema/index.ts @@ -0,0 +1,34 @@ +import * as z from 'zod'; +export const contextTypeSchema = z.object({ + type: z.string().min(3, 'Context type description must contain at least 3 character(s)').max(30), +}); + +export type ContextTypeInputs = z.infer; + +const base = { + name: z.string().min(3, 'Short description must contain at least 3 character(s)').max(50), + shortName: z + .string() + .min(2, 'Short Name must contain at least 2 character(s)') + .max(150, 'Short Name can contain at most 300 character(s)'), + subtext: z + .string() + .min(3, 'Short Name must contain at least 3 character(s)') + .max(150, 'Short Name can contain at most 300 character(s)'), + description: z.string().max(500, 'Description can contain at most 300 character(s)').optional(), + icon: z.string().default(''), +}; + +export const portalInputSchema = z.object({ + ...base, + contextTypes: z.array(z.string()), +}); + +export const portalEditInputSchema = z.object({ + ...base, + id: z.string().uuid().optional(), + contextTypes: z.array(z.string()).optional(), +}); + +export type PortalCreateInputs = z.infer; +export type PortalInputs = z.infer; diff --git a/client/apps/portal-administration/src/schema/route.ts b/client/apps/portal-administration/src/schema/route.ts new file mode 100644 index 000000000..4639a450e --- /dev/null +++ b/client/apps/portal-administration/src/schema/route.ts @@ -0,0 +1,35 @@ +import { z } from "zod"; + +export const route = z + .object({ + path: z.string().min(1, "Please add path").max(50), + pageKey: z + .string() + .min(2, "Please add pageKey, min 2 characters long") + .max(50), + messages: z.object({ + errorMessage: z + .string() + .min(1, "Please add Error Message") + .max(200, "Error message to long."), + }), + description: z.string().optional(), + }) + .passthrough(); + +export type RouteInput = z.infer; + +export const rootInput = z.object({ + pageKey: z + .string() + .min(2, "Please add pageKey, min 2 characters long") + .max(50), + messages: z.object({ + errorMessage: z + .string() + .min(1, "Please add Error Message") + .max(200, "Error message to long."), + }), +}); + +export type RootInput = z.infer; diff --git a/client/apps/portal-administration/src/types/index.ts b/client/apps/portal-administration/src/types/index.ts new file mode 100644 index 000000000..8d1205e6e --- /dev/null +++ b/client/apps/portal-administration/src/types/index.ts @@ -0,0 +1,75 @@ +import { AppManifest } from '@equinor/fusion-framework-react-app'; +import { Router } from './router-config'; + +export type Portal = { + name: string; + shortName: string; + subtext: string; + id: string; + key: string; + type: string; + icon?: string; + description: string; + contexts: ContextType[]; +}; + +export type CreatePortal = Omit; + +export type PortalAppCreate = { + appKey: string; + removeAppFromContexts: boolean; +}; + +export type ContextType = { + type: string; +}; +export type OnboardedContext = { + title: string; + id: string; + contextId: string; + externalId: string; + type: string; + description: string; +}; + +export type Variant = 'Warning' | 'Error' | 'Info' | 'NoContent'; + +export type Message = { + type?: Variant; + title: string; + messages?: string[]; +}; + +export type FormattedError = { + status: number; +} & Message; + +export type PortalApp = { + name: string; + id: string; + appKey: string; + isLegacy: boolean; + description: string; + contexts: ContextType[]; + contextTypes: string[]; + appInformation: { icon: string }; + isActive?: boolean; +}; +export type PortalAppMutation = { + appKey: string; + contextTypes: string[]; +}; + +export type AppManifestResponse = { + key: string; + contextTypes: ContextType[]; + appManifest: AppManifest; +}; + +export type PortalConfiguration = { + router: Router; +}; + +export type PortalConfigurationEditInput = { + id: string; +} & PortalConfiguration; diff --git a/client/apps/portal-administration/src/types/router-config.ts b/client/apps/portal-administration/src/types/router-config.ts new file mode 100644 index 000000000..8c0434c7c --- /dev/null +++ b/client/apps/portal-administration/src/types/router-config.ts @@ -0,0 +1,24 @@ +export type RootRoute = { + pageKey: string; + messages: { + errorMessage: string; + noPageMessage?: string; + }; +}; + +export type Router = { + root: RootRoute; + routes: Route[]; +}; + +export type Route = { + id: string; + description?: string; + path: string; + pageKey: string; + messages: { + errorMessage: string; + noPageMessage?: string; + }; + children?: Route[]; +}; diff --git a/client/apps/portal-administration/src/types/utils.ts b/client/apps/portal-administration/src/types/utils.ts new file mode 100644 index 000000000..c93871d55 --- /dev/null +++ b/client/apps/portal-administration/src/types/utils.ts @@ -0,0 +1 @@ +export type PartialWithDefined = Partial & Pick; diff --git a/client/apps/portal-administration/src/utils/error-utils.ts b/client/apps/portal-administration/src/utils/error-utils.ts new file mode 100644 index 000000000..aa9a741c3 --- /dev/null +++ b/client/apps/portal-administration/src/utils/error-utils.ts @@ -0,0 +1,11 @@ +import { FormattedError } from "../types"; + +export const DEFAULT_ERROR: FormattedError = { + type: "Error", + title: "Generic Error", + status: -1, +}; + +export const formatError = (errorResponse: unknown, status: number) => { + return DEFAULT_ERROR; +}; diff --git a/client/apps/portal-administration/src/utils/syntaxHighlightJson.tsx b/client/apps/portal-administration/src/utils/syntaxHighlightJson.tsx new file mode 100644 index 000000000..5f04d0759 --- /dev/null +++ b/client/apps/portal-administration/src/utils/syntaxHighlightJson.tsx @@ -0,0 +1,69 @@ +import { useRef, useEffect } from 'react'; +import { styled } from 'styled-components'; + +export const CodeStyle = styled.pre` + background-color: #242a2d; + border: 2px solid #3a3d3e; + color: #ffffff; + padding: 1.5rem; + font-family: monospace; + max-height: -webkit-fill-available; + margin-bottom: 4rem; + overflow: auto; + .key { + color: rgb(156, 220, 254); + } + .string { + color: rgb(214, 157, 133); + } + .boolean { + color: rgb(86, 156, 214); + } + .null { + color: rgb(86, 156, 214); + } + .number { + color: rgb(184, 215, 163); + } +`; + +export const Code = ({ config }: { config: any }) => { + const ref = useRef(null); + + useEffect(() => { + if (ref.current) ref.current.innerHTML = syntaxHighlightJson(config); + }, [ref, config]); + + return ( + +
    ; +
    + ); +}; + +function syntaxHighlightJson(json: any) { + if (typeof json != 'string') { + json = JSON.stringify(json, null, 2); + } + + json = json.replace(/&/g, '&').replace(//g, '>'); + + return json.replace( + /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, + function (match: string) { + var cls = 'number'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'key'; + } else { + cls = 'string'; + } + } else if (/true|false/.test(match)) { + cls = 'boolean'; + } else if (/null/.test(match)) { + cls = 'null'; + } + return '' + match + ''; + } + ); +} diff --git a/client/apps/portal-administration/tsconfig.json b/client/apps/portal-administration/tsconfig.json new file mode 100644 index 000000000..8448b83e7 --- /dev/null +++ b/client/apps/portal-administration/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "rootDir": "src", + "baseUrl": "src", + "jsx": "react-jsx", + "strict": true, + "module": "ES2022", + "target": "ES6", + "incremental": true, + "removeComments": true, + "preserveConstEnums": true, + + "inlineSourceMap":true, + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "stripInternal": true, + "skipLibCheck": true, + "lib": [ + "esnext", + "dom", + "dom.iterable" + ], + "composite": true, + "outDir": "./dist", + }, + "include": [ + "./src", + ], + "exclude": [ + "node_modules", + "lib" + ] +} diff --git a/client/apps/portal-administration/vite.config.ts b/client/apps/portal-administration/vite.config.ts new file mode 100644 index 000000000..c067320be --- /dev/null +++ b/client/apps/portal-administration/vite.config.ts @@ -0,0 +1,35 @@ +import { defineConfig } from 'vite'; + +const fix = ` +var process = { + env: { + NODE_ENV: "production" + } +}; +var production = "production"; + +`; + +export const InjectProcessPlugin = { + name: 'rollup-plugin-metadata', + renderChunk: (code: any) => fix + code, +}; + +export default defineConfig({ + appType: 'custom', + build: { + emptyOutDir: true, + minify: false, + rollupOptions: { + plugins: [InjectProcessPlugin], + output: { + inlineDynamicImports: true, + }, + }, + lib: { + entry: './src/index.ts', + fileName: 'app-bundle', + formats: ['es'], + }, + }, +}); diff --git a/client/apps/portal-administration/yarn.lock b/client/apps/portal-administration/yarn.lock new file mode 100644 index 000000000..628907f6d --- /dev/null +++ b/client/apps/portal-administration/yarn.lock @@ -0,0 +1,5954 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ag-grid-community/client-side-row-model@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-community/client-side-row-model/-/client-side-row-model-31.2.1.tgz#7ee1e80e8de31d3e231a74c8267a9f849fe05d2b" + integrity sha512-EwW2Sj3DGboZ7kv1uvbVUVyumfzRMFCo3qgLwONwWNeLkQP+9EooUsDQmyzWT8nn1lBkSFyvolpxFfyS05pL2A== + dependencies: + "@ag-grid-community/core" "31.2.1" + tslib "^2.3.0" + +"@ag-grid-community/core@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-community/core/-/core-31.2.1.tgz#eefc018e39e22d82b53dbb4229d7330167ebe25a" + integrity sha512-tTDt8c6KykR+Y0cNwwbpokkhMmD1L1WVILPwZ0Z3lsSxSkmzGbTKSD2jOSvlw9vpPuAJpU0R5tMe1dfsEXO1YA== + dependencies: + tslib "^2.3.0" + +"@ag-grid-community/core@^32.1.0": + version "32.1.0" + resolved "https://registry.yarnpkg.com/@ag-grid-community/core/-/core-32.1.0.tgz#cbc50f00a63a3edc539d046fb712132c15092214" + integrity sha512-fHpgSZa/aBjg2DdOzooDxILFZqxmxP8vsjRfeZVtqby19mTKwNAclE7Z6rWzOA0GYjgN9s8JwLFcNA5pvfswMg== + dependencies: + ag-charts-types "10.1.0" + tslib "^2.3.0" + +"@ag-grid-community/csv-export@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-community/csv-export/-/csv-export-31.2.1.tgz#040a04b7cdc5ec23208e270b120790071a4a633e" + integrity sha512-3h9kd9LDgpHdO2aPcKI2qZT0dGEJMWE/oTRrpBIMQD66KMTRKVJouKulvCTgDVp9X0nGHWq00/2TpNpTcK5jDg== + dependencies: + "@ag-grid-community/core" "31.2.1" + tslib "^2.3.0" + +"@ag-grid-community/react@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-community/react/-/react-31.2.1.tgz#73c670f495b4753970b40ebdb0865a310d748c27" + integrity sha512-PDbvU965Zr6iE6QvEPeJpNRKvJfIv8z8gPWKuAyiUrQUowBjzFHe80XwSyOzYwWg1+79hJbGioPdBglLwLm0GQ== + dependencies: + prop-types "^15.8.1" + +"@ag-grid-community/react@^32.1.0": + version "32.1.0" + resolved "https://registry.yarnpkg.com/@ag-grid-community/react/-/react-32.1.0.tgz#98fde13b891c0b637b473b89dfea69ec3c3fe0fa" + integrity sha512-ObaMk+g5IpfuiHSNar56IhJ0dLKkHaeMQYI9H1JlJyf5+3IafY1DiuGZ5mZTU7GyfNBgmMuRWrUxwOyt0tp7Lw== + dependencies: + prop-types "^15.8.1" + +"@ag-grid-enterprise/column-tool-panel@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/column-tool-panel/-/column-tool-panel-31.2.1.tgz#b061a2ab34758ac20c4912eebfe5bea2c0fd6764" + integrity sha512-FoymPDDQz1B4XaYXaqarczbTwhbu3G4PkHzavcfMUcM8FqoqE0Mhhk4oAihR8gwRJrDwaGZ0C/OQcsaG6VY0wQ== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + "@ag-grid-enterprise/row-grouping" "31.2.1" + "@ag-grid-enterprise/side-bar" "31.2.1" + +"@ag-grid-enterprise/core@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/core/-/core-31.2.1.tgz#a0be8d3857d30a511c6f88581f09622733282959" + integrity sha512-So9U/bC41uBjNdg0pdJTYOkW9fFFRx7+2csOZkSuf2Y3dx9Zn8bAFCzNs1N3v0+XlNj8Ylsdi2isA6mjP9dIMQ== + dependencies: + "@ag-grid-community/core" "31.2.1" + +"@ag-grid-enterprise/excel-export@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/excel-export/-/excel-export-31.2.1.tgz#14554721bd78dd27998bf80b4a49a6d9a26bf07a" + integrity sha512-+lo3Kjc08kHyP5xLfErzF9xLrS4BohhfGXKaZ/HX803Yp8ptcFXXa+AYoBwx6ZAS0FHRCM8NR74I7Ef7CpW6OA== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-community/csv-export" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/filter-tool-panel@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/filter-tool-panel/-/filter-tool-panel-31.2.1.tgz#55ab4c9d2cecd3c3ef3285462bcb2af267f1af99" + integrity sha512-I0NwbLsbiuq18Vs6wFWrdRCrZeisLF9amGvnA8WqnBryd09Cqd8Yp40Ak9fxJopkgPtJd6h/amtF2/JRZN3LJw== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + "@ag-grid-enterprise/side-bar" "31.2.1" + +"@ag-grid-enterprise/master-detail@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/master-detail/-/master-detail-31.2.1.tgz#d88a25552b7d9d351bf0908d49f90636c056f894" + integrity sha512-AOxlQ0oFFClmGcZx7K3PYiAWcIIHDbBzCq9M4xWbflRFwPaSFwo3QwJIAF1/Js6pYXM/v869XkpqHQqXuf8KmQ== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/menu@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/menu/-/menu-31.2.1.tgz#07bca2da90748fd90a1d48bbfffc5318dc00d956" + integrity sha512-lOK6z+4yDyxpaDz9B4Te9au4VWxfW7H2CigVC84j5j9rKJF+u0niD9S93V5m1R6O2qCGaNeIEfqnqEywA+eH+g== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/column-tool-panel" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/multi-filter@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/multi-filter/-/multi-filter-31.2.1.tgz#cd6ed0d485a34aefa3cc6115384ca70b44fb6139" + integrity sha512-H9PJEaaVlhulP0D2Ij4JJyRxLX7t04ipmYmzI8KhRRA8cJpsy1K75h0U/VveHANCZpZyKIvxhOAjN2CffMdDLQ== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/range-selection@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/range-selection/-/range-selection-31.2.1.tgz#878291200270c58a13b721d42b4f159e59979528" + integrity sha512-GZc2mzXkbSqriaxZ17bdEeqmgoAtDsvOVvRgaV6nIU4sgh4s+/RSIhI5tWefLaogs0agCggcqghSVbCMq/lGrg== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/rich-select@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/rich-select/-/rich-select-31.2.1.tgz#3ba966c1e8962ce1eaf5d20ab45228a212ac1112" + integrity sha512-A7qK4hjqMxCNp4dkXjEAEPmJY7TZCBucxeM4YgXellG7AD1s3ReYOXw9vPj5fBWZYybEvNJwdpOju3PhG+cDHA== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/row-grouping@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/row-grouping/-/row-grouping-31.2.1.tgz#95a710704abda44e4832a178044fa65b367c2ae8" + integrity sha512-Sl7QPjrx4+4yJtNO/KKuTJjkg0JjSJmghY30kSjGmJA6+FEvlptnW6HKqVuKS/49lNd+GDL9oncug8t+b99ghA== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/server-side-row-model@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/server-side-row-model/-/server-side-row-model-31.2.1.tgz#cca32d80d55ee81fbcccba8d08a86573f7359a03" + integrity sha512-WL4hUj9IpO+aU8TUy/8M1soCsm7c9TDStLFWiW9zEXeC6P7696p/K1a1PqDUhmgC1TNKOQBW1ST/+FCfLxuUgw== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/set-filter@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/set-filter/-/set-filter-31.2.1.tgz#4c150f3358544d3bd14451917bb0d90378925834" + integrity sha512-jIGdKcWMDF4MYMdAgy1bY0LwLC3G66CFO1uMwRMp1fKw5R9W7cWk6LgbIpSV6Zxr+3bFOgSBhHPpyeHmMgduBQ== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/side-bar@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/side-bar/-/side-bar-31.2.1.tgz#f8540cf2cb610ec4e78a9e9bbe06453a58a27ee7" + integrity sha512-OLAyJLx5ZTgPmE/f0NljaV/MFUBa+Uy0VABPz+NELmRmuhGNj7m4CoiOBYPXdWlOWygZ4xuc3dFqYmMWZql8hg== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + +"@ag-grid-enterprise/status-bar@31.2.1": + version "31.2.1" + resolved "https://registry.yarnpkg.com/@ag-grid-enterprise/status-bar/-/status-bar-31.2.1.tgz#4e646e65399cfe5889a2aa999e5a816d032263d9" + integrity sha512-4StX8mOesVEozpTwR3hdifo3nJlG8TDzl3PTcSet1p/SnLVzTPxdtv43fw5ncXuzZaq+/YKoMl9EcCsf/DGQuQ== + dependencies: + "@ag-grid-community/core" "31.2.1" + "@ag-grid-enterprise/core" "31.2.1" + tslib "^2.3.0" + +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@azure/msal-browser@^2.21.0": + version "2.39.0" + resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-2.39.0.tgz#684fd3974c2628b2dffd04a4c8416a0945b42b69" + integrity sha512-kks/n2AJzKUk+DBqZhiD+7zeQGBl+WpSOQYzWy6hff3bU0ZrYFqr4keFLlzB5VKuKZog0X59/FGHb1RPBDZLVg== + dependencies: + "@azure/msal-common" "13.3.3" + +"@azure/msal-common@13.3.3": + version "13.3.3" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-13.3.3.tgz#b4963c9e5a164ed890b204becb036303ccf4f6ac" + integrity sha512-n278DdCXKeiWhLwhEL7/u9HRMyzhUXLefeajiknf6AmEedoiOiv2r5aRJ7LXdT3NGPyubkdIbthaJlVtmuEqvA== + +"@babel/code-frame@^7.22.13", "@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + +"@babel/compat-data@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.2.tgz#e41928bd33475305c586f6acbbb7e3ade7a6f7f5" + integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ== + +"@babel/core@^7.24.5": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77" + integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/helper-compilation-targets" "^7.25.2" + "@babel/helper-module-transforms" "^7.25.2" + "@babel/helpers" "^7.25.0" + "@babel/parser" "^7.25.0" + "@babel/template" "^7.25.0" + "@babel/traverse" "^7.25.2" + "@babel/types" "^7.25.2" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.0.tgz#f858ddfa984350bc3d3b7f125073c9af6988f18e" + integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== + dependencies: + "@babel/types" "^7.25.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" + integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== + dependencies: + "@babel/compat-data" "^7.25.2" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-module-imports@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-module-transforms@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" + integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== + dependencies: + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + "@babel/traverse" "^7.25.2" + +"@babel/helper-plugin-utils@^7.24.7": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" + integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== + +"@babel/helper-simple-access@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" + integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + +"@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== + +"@babel/helpers@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.0.tgz#e69beb7841cb93a6505531ede34f34e6a073650a" + integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw== + dependencies: + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.0" + +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.25.0", "@babel/parser@^7.25.3": + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.3.tgz#91fb126768d944966263f0657ab222a642b82065" + integrity sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw== + dependencies: + "@babel/types" "^7.25.2" + +"@babel/plugin-transform-react-jsx-self@^7.24.5": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz#66bff0248ea0b549972e733516ffad577477bdab" + integrity sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-react-jsx-source@^7.24.1": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz#1198aab2548ad19582013815c938d3ebd8291ee3" + integrity sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/runtime@^7.24.0", "@babel/runtime@^7.24.5", "@babel/runtime@^7.24.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.8.3": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.25.0": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" + integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" + integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" + +"@babel/traverse@^7.24.7", "@babel/traverse@^7.25.2": + version "7.25.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.3.tgz#f1b901951c83eda2f3e29450ce92743783373490" + integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/parser" "^7.25.3" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.2" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.25.0", "@babel/types@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.2.tgz#55fb231f7dc958cd69ea141a4c2997e819646125" + integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + +"@emotion/hash@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + +"@emotion/is-prop-valid@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337" + integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== + dependencies: + "@emotion/memoize" "^0.8.1" + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/unitless@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@equinor/eds-core-react@^0.40.1": + version "0.40.1" + resolved "https://registry.yarnpkg.com/@equinor/eds-core-react/-/eds-core-react-0.40.1.tgz#8a886398793d50829bcdb4b3c14034c1693c1a8d" + integrity sha512-WqF+OICoFteKod/sJhzMtfm8RlSTZpB4lvPKH0QJFKlqoiJm/b8Pp+1T45dNVhiHNLC8d+KmDtkLQ7svoonszw== + dependencies: + "@babel/runtime" "^7.24.7" + "@equinor/eds-icons" "^0.21.0" + "@equinor/eds-tokens" "0.9.2" + "@equinor/eds-utils" "0.8.5" + "@floating-ui/react" "^0.26.19" + "@internationalized/date" "^3.5.4" + "@react-aria/utils" "^3.24.1" + "@react-stately/calendar" "^3.5.1" + "@react-stately/datepicker" "^3.9.4" + "@react-types/shared" "^3.23.1" + "@tanstack/react-virtual" "3.8.2" + downshift "9.0.6" + react-aria "^3.33.1" + +"@equinor/eds-core-react@^0.41.2": + version "0.41.5" + resolved "https://registry.yarnpkg.com/@equinor/eds-core-react/-/eds-core-react-0.41.5.tgz#1e9d251372b11b5de2b1c599feeb89a74cfb6075" + integrity sha512-6Jo+jTWeWnEy7laRDEOOHTew9IAjrf58TVIeJ9YgwXBMjhapNuvEuG9lj3EhChBo6M0CLJ49LaIPoYskndlq1w== + dependencies: + "@babel/runtime" "^7.25.0" + "@equinor/eds-icons" "^0.21.0" + "@equinor/eds-tokens" "0.9.2" + "@equinor/eds-utils" "0.8.5" + "@floating-ui/react" "^0.26.22" + "@internationalized/date" "^3.5.5" + "@react-aria/utils" "^3.25.1" + "@react-stately/calendar" "^3.5.3" + "@react-stately/datepicker" "^3.10.1" + "@react-types/shared" "^3.24.1" + "@tanstack/react-virtual" "3.10.6" + downshift "9.0.8" + react-aria "^3.34.1" + +"@equinor/eds-icons@^0.19.1", "@equinor/eds-icons@^0.19.3": + version "0.19.3" + resolved "https://registry.yarnpkg.com/@equinor/eds-icons/-/eds-icons-0.19.3.tgz#08ce80c1ea6edf0b4144def73d1e5d0de392434f" + integrity sha512-Sh0W01PrwXPCi8/p9YKj0qKNtRU9R/xYJORinIzsNNRllpiu9wvuGAsQNE0gQaDDnrprsiRBH3+MdMSRXVs3Wg== + +"@equinor/eds-icons@^0.21.0": + version "0.21.0" + resolved "https://registry.yarnpkg.com/@equinor/eds-icons/-/eds-icons-0.21.0.tgz#9adb994d2cd74011474a6d354458ffedcf7afc2f" + integrity sha512-k2keACHou9h9D5QLfSBeojTApqbPCkHNBWplUA/B9FQv8FMCMSBbjJAo2L/3yAExMylQN9LdwKo81T2tijRXoA== + +"@equinor/eds-tokens@0.9.2", "@equinor/eds-tokens@^0.9.0", "@equinor/eds-tokens@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@equinor/eds-tokens/-/eds-tokens-0.9.2.tgz#21545ffbb16a22f3eb7370295d32276dcb655373" + integrity sha512-pDIFei0vsfN3GN12NKWqxskAkYBQd6+Dzjga2liuY81LfnlJs5g9NblamU9WY5w5YdVE5Z8FNjsMKDLs2JIWcw== + +"@equinor/eds-utils@0.8.5": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@equinor/eds-utils/-/eds-utils-0.8.5.tgz#04ad176a475b21790f5bee50eafdaf3ba5825577" + integrity sha512-4AwltyJg51rjBBB4a4g4dGh9JlR+9mc/1AvRsV+nJqdpjjUgDeVBXukLN8Dh2CgyX1+0q3iH3TWq7bwOzd7n5Q== + dependencies: + "@babel/runtime" "^7.24.0" + "@equinor/eds-tokens" "0.9.2" + +"@equinor/fusion-framework-app@^9.1.7": + version "9.1.7" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-app/-/fusion-framework-app-9.1.7.tgz#4c1e1717e67a0dd43c6669daaaf3bad0b9988882" + integrity sha512-O3Ov3cUuHQ8KauwgoF73ET8b2bwtKB5dF4INuySLx+hp9dFHgbMn6AA/3O8WdkaRVLdtdCEQoYEDIpRzOQZl1w== + dependencies: + "@equinor/fusion-framework" "^7.2.6" + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-framework-module-app" "^5.3.11" + "@equinor/fusion-framework-module-event" "^4.2.3" + "@equinor/fusion-framework-module-http" "^6.0.3" + "@equinor/fusion-framework-module-msal" "^3.1.4" + +"@equinor/fusion-framework-cli@^9.12.14": + version "9.12.14" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-cli/-/fusion-framework-cli-9.12.14.tgz#00fc345cf7c89044ea79d5922ec799dc437db3bd" + integrity sha512-F2JjWFWUa9jIowrk+fiDYTjrLSTQVf5h1wAyiJ0KjwrLO+L02We5ssSKFiLpBvoBqHyRW/NGbEPkhKoBPG+Ylg== + dependencies: + "@equinor/eds-core-react" "^0.41.2" + "@equinor/eds-icons" "^0.21.0" + "@equinor/eds-tokens" "^0.9.2" + "@equinor/fusion-framework-app" "^9.1.7" + "@equinor/fusion-framework-module-feature-flag" "^1.1.8" + "@equinor/fusion-framework-react-components-people-provider" "^1.4.6" + "@equinor/fusion-observable" "^8.4.1" + "@equinor/fusion-wc-chip" "^1.2.1" + "@equinor/fusion-wc-person" "^3.0.1" + "@types/adm-zip" "^0.5.0" + "@types/semver" "^7.5.0" + "@vitejs/plugin-react" "^4.0.4" + adm-zip "^0.5.10" + chalk "^5.3.0" + commander "^12.0.0" + deepmerge "^4.3.1" + express "^4.18.2" + express-rate-limit "^7.0.0" + find-up "^7.0.0" + http-proxy-middleware "^2.0.6" + is-mergeable-object "^1.1.1" + ora "^8.0.1" + portfinder "^1.0.32" + pretty-bytes "^6.1.1" + read-package-up "^11.0.0" + semver "^7.5.4" + vite "^5.4.3" + vite-plugin-environment "^1.1.3" + vite-plugin-restart "^0.4.0" + vite-tsconfig-paths "^4.2.0" + +"@equinor/fusion-framework-module-app@^5.3.11": + version "5.3.11" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-app/-/fusion-framework-module-app-5.3.11.tgz#550c673ffd1cf2c3dee7686bb90a4cd59e2d34ff" + integrity sha512-Aj5R2iOFAnXm+G2O20zZOpgLUq6Smbh8KLaQHAPEw8E2Clbjh66OaaSW3gL/eWJKuF9KMSO/HkWFbWniEV0Wow== + dependencies: + "@equinor/fusion-observable" "^8.4.1" + "@equinor/fusion-query" "^5.1.3" + immer "^9.0.16" + rxjs "^7.8.1" + +"@equinor/fusion-framework-module-bookmark@^1.2.11": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-bookmark/-/fusion-framework-module-bookmark-1.2.11.tgz#3c7682b314bf657825f3c69696f9b622da0d25a8" + integrity sha512-rnpLWAC7tfic44r+/CKFgh4nfeMHHSPPhhSzuRGZlBw/2Demc0BhhZK7cgwraTRCyQp1BwzO+IW4oRA/XCTWDQ== + dependencies: + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-observable" "^8.4.1" + "@equinor/fusion-query" "^5.1.3" + rxjs "^7.8.1" + +"@equinor/fusion-framework-module-context@^5.0.11": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-context/-/fusion-framework-module-context-5.0.11.tgz#9332886cc54c9722ade9a015b1eca452c1702e44" + integrity sha512-BmbUNRx+b23btVmhNEHV0l+1EkQQXoJjkImRdlsIKxcZmdLztqMq/vaXSRz2wEBkfvLIA4icJWEGOUIT6ge24g== + dependencies: + "@equinor/fusion-query" "^5.1.3" + fast-deep-equal "^3.1.3" + +"@equinor/fusion-framework-module-event@^4.2.3": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-event/-/fusion-framework-module-event-4.2.3.tgz#e828f5f79f82baf5d3f3429700cedeffd90cf286" + integrity sha512-v20bvQx0aGB9oXiXvP/7UTyvP9oUmXRgVkDW43CLmQXZwdB0l6ctvC6Gv3tm7GQjB+gPGLeCE0oH5lvvTVUxDg== + dependencies: + "@equinor/fusion-framework-module" "^4.3.4" + immer "^9.0.16" + +"@equinor/fusion-framework-module-feature-flag@^1.1.8": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-feature-flag/-/fusion-framework-module-feature-flag-1.1.8.tgz#2fba3be30a8d99b3fb9bdd08110c74e793b1fc63" + integrity sha512-DyupfC5cgh4k6Hp8PZvtyA3YtB5YDn9TmeMXhXwLx77spKc3Dr+e9CH3qzImiB9xXuZ+vmeEepW89YF7qVGtpg== + dependencies: + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-observable" "^8.4.1" + immer "^9.0.16" + rxjs "^7.8.1" + uuid "^10.0.0" + +"@equinor/fusion-framework-module-http@^6.0.3": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-http/-/fusion-framework-module-http-6.0.3.tgz#30923f69b992cf88fccb9abd425ddd69ef1159bb" + integrity sha512-nti+NRCpKlXk24bdK44MBulL3AMqmBFk1L3A+t+r4X/rAVWka8cDtlRgqbyMJxrNCYhC+atgqiRDfNd8pPClCA== + dependencies: + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-framework-module-msal" "^3.1.4" + rxjs "^7.8.1" + +"@equinor/fusion-framework-module-msal@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-msal/-/fusion-framework-module-msal-3.1.4.tgz#624db485802c77ed307d4f699a2ee4ff06f057d3" + integrity sha512-Ip4f0nb4FAobEGSX3h/bL0+gzsYVNyxyKM2uN+g5S1Nop4uThnQPQpgPpxW5+xmIRRt/1Z1RUNMUWVOQqAwwqQ== + dependencies: + "@azure/msal-browser" "^2.21.0" + "@equinor/fusion-framework-module" "^4.3.4" + +"@equinor/fusion-framework-module-navigation@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-navigation/-/fusion-framework-module-navigation-4.0.6.tgz#ad7e415db8d82d1e2f704c16521e8607c6245c5d" + integrity sha512-KkAqoGR068extJqcuLeJbTtkvtBWg9uZi8XpWz01NtJpgGyS43/7vYf2kUEOSsYCxHj5YBGcmpuzOdVLmLyuOw== + dependencies: + "@remix-run/router" "^1.8.0" + +"@equinor/fusion-framework-module-service-discovery@^7.1.13": + version "7.1.13" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-service-discovery/-/fusion-framework-module-service-discovery-7.1.13.tgz#eadda4e6b21f2011b46cf3fc3ec80ccc20803741" + integrity sha512-1DgQn3mAzt7QoXz6hz8Zjt+pqvWcw0yM/26GmGHhBRZ50Ulg5gFVKL0wZyhOTgpJfG69MQgEdoDuK4HvbNyuRQ== + dependencies: + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-framework-module-http" "^6.0.3" + "@equinor/fusion-query" "^5.1.3" + rxjs "^7.8.1" + +"@equinor/fusion-framework-module-services@^4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module-services/-/fusion-framework-module-services-4.1.3.tgz#f1cac1da9fc7335a85812a5fcef0f4ff26c969d4" + integrity sha512-B3A41eHrUOK+kD+ohaFTjDd6xdJpUPNEsQ7Nss8gV8OGMg2Gnkr0GuQ3CULchfF3xmNLGERZaEqgVKL6BEEHVg== + dependencies: + odata-query "^7.0.4" + +"@equinor/fusion-framework-module@^4.3.4": + version "4.3.4" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-module/-/fusion-framework-module-4.3.4.tgz#07eb5453e58f2814f4ba73ec045b0cffd3ad313a" + integrity sha512-wJEt6Za6JP9zyGVwfTdLw4d48Ianrp+HVOamv+L+2lfZJtWZREdWSdcz9z/JWig5klw1kyLhM89gEAVQX+E7fA== + dependencies: + rxjs "^7.8.1" + semver "^7.5.4" + +"@equinor/fusion-framework-react-app@^5.2.7": + version "5.2.7" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-react-app/-/fusion-framework-react-app-5.2.7.tgz#b7a9f56d04329ee58894ab2b4ab2d3e253a125ae" + integrity sha512-R6Iy38K9XU3b+XnS/rsmD7UJSrsrpfirF8MXFUWlgKLyXcACymgUkUFh6+Mrhae8mPC9Xp3N6STOubHdDNsQhw== + dependencies: + "@equinor/fusion-framework-app" "^9.1.7" + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-framework-module-app" "^5.3.11" + "@equinor/fusion-framework-module-navigation" "^4.0.6" + "@equinor/fusion-framework-react" "^7.2.1" + "@equinor/fusion-framework-react-module" "^3.1.5" + "@equinor/fusion-framework-react-module-http" "^6.0.3" + +"@equinor/fusion-framework-react-components-people-provider@^1.4.6": + version "1.4.6" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-react-components-people-provider/-/fusion-framework-react-components-people-provider-1.4.6.tgz#636a6d546c9ab78bea8bb0eaa9848a2ce320e2b4" + integrity sha512-jXy2D5uaxuAIpbl3TS8m+WpWXM0ZxY4nu1p3+tvHmDXEY3ijGQcD906tUcBKWuWV0QIUER/8I2IiWkf+iqbXxQ== + dependencies: + "@equinor/fusion-framework-module-services" "^4.1.3" + "@equinor/fusion-framework-react" "^7.2.1" + "@equinor/fusion-framework-react-module" "^3.1.5" + "@equinor/fusion-framework-react-module-bookmark" "^2.1.15" + "@equinor/fusion-query" "^5.1.3" + rxjs "^7.8.1" + +"@equinor/fusion-framework-react-module-bookmark@^2.1.15": + version "2.1.15" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-react-module-bookmark/-/fusion-framework-react-module-bookmark-2.1.15.tgz#5136ea29ba935ab9efe220df1aa59bf9e1729a4c" + integrity sha512-5QftONTJmcLf0zJPvSbJsbg4yklwUz48n9tWlIa47MbN3YV1vSYRS9TGym4cfykzS+fztSy63DOqPum453avKA== + dependencies: + "@equinor/fusion-framework-module-bookmark" "^1.2.11" + "@equinor/fusion-framework-module-context" "^5.0.11" + "@equinor/fusion-framework-react" "^7.2.1" + "@equinor/fusion-framework-react-module" "^3.1.5" + "@equinor/fusion-observable" "^8.4.1" + "@equinor/fusion-query" "^5.1.3" + +"@equinor/fusion-framework-react-module-http@^6.0.3": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-react-module-http/-/fusion-framework-react-module-http-6.0.3.tgz#512fe5ade865da684376ee991988bd15016036da" + integrity sha512-Po29yCf3Plllf2pUrzix4mTuuEstp/EMhP52gx7J6JbgI2sZ3f8COx8RpnP/sKvHaUdAK45WJY4MW/qT6wUVCw== + +"@equinor/fusion-framework-react-module@^3.1.5": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-react-module/-/fusion-framework-react-module-3.1.5.tgz#18d3367765259056c27278fcb7b822aa615741ac" + integrity sha512-4gju+hLN0BYqti+gbeeHp4uFipEGuO2az97OjRMTacY944X5x6qhVRY9pKO123OAvV/B+mzbk0pd+F9ytOo6Mw== + dependencies: + "@equinor/fusion-framework-module" "^4.3.4" + +"@equinor/fusion-framework-react@^7.2.1": + version "7.2.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework-react/-/fusion-framework-react-7.2.1.tgz#9ff95deb1c816478f3a06e64cf1cfe9601ecb85a" + integrity sha512-vgcE44ZyyZzcdxDNq2Ue8QYaVXxA65qhB2JTkb7wyJ75IBtLfInaBuvYGtFyWV1yXjVi+XbKFuWe17SOh6w9Dg== + dependencies: + "@equinor/fusion-framework" "^7.2.6" + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-framework-react-module" "^3.1.5" + "@equinor/fusion-framework-react-module-http" "^6.0.3" + "@equinor/fusion-observable" "^8.4.1" + rxjs "^7.8.1" + +"@equinor/fusion-framework@^7.2.6": + version "7.2.6" + resolved "https://registry.yarnpkg.com/@equinor/fusion-framework/-/fusion-framework-7.2.6.tgz#830ceb8c039a7a6bab76caa98b57931fadfc7f08" + integrity sha512-vxE8Sm8JIW8owBvkjPtGMw03KWD38ObZUzS2trQb0u8jKqj7sSjmbVRtO6u73oGjrYJMaco36+3uEl9SWTe4yA== + dependencies: + "@equinor/fusion-framework-module" "^4.3.4" + "@equinor/fusion-framework-module-context" "^5.0.11" + "@equinor/fusion-framework-module-event" "^4.2.3" + "@equinor/fusion-framework-module-http" "^6.0.3" + "@equinor/fusion-framework-module-msal" "^3.1.4" + "@equinor/fusion-framework-module-service-discovery" "^7.1.13" + "@equinor/fusion-framework-module-services" "^4.1.3" + rxjs "^7.8.1" + +"@equinor/fusion-log@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@equinor/fusion-log/-/fusion-log-1.1.0.tgz#aab344577cfcdb7b8918b6b4e231795183d92ee8" + integrity sha512-I0V55f8ONDzB7HlMrgiGUGYBYA08T6qEusEk5nNDTfMBeN94aMHD3TSEXZ4LlJTxPjk1UPn0l10cdD3bU7zTZA== + dependencies: + chalk "^5.3.0" + rxjs "^7.8.1" + +"@equinor/fusion-observable@^8.4.1": + version "8.4.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-observable/-/fusion-observable-8.4.1.tgz#e8d429904313d66339447731594ff9156a009e95" + integrity sha512-MZfZ9X3JGkpdVvO8THBLe6gdtF3kUI16t6COxEKKlpGnZiWUjFIR0ZKqu38q0ve+0u3h5DqV1lSa1qqbXFoDzg== + dependencies: + immer "^9.0.16" + rxjs "^7.8.1" + uuid "^10.0.0" + +"@equinor/fusion-query@^5.1.3": + version "5.1.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-query/-/fusion-query-5.1.3.tgz#429b9422498ccf0d0d7714e930c094fe59d3244a" + integrity sha512-NvJtuL3WBO4Qoy9LJCRmnR7cfq25d8eZ+4NnjB7U7gW1YDcP9IWGiSszPTsZ1n2zLtKDci7DpLUD0EVoC6I7Ag== + dependencies: + "@equinor/fusion-log" "^1.1.0" + "@equinor/fusion-observable" "^8.4.1" + immer "^9.0.16" + rxjs "^7.8.1" + uuid "^10.0.0" + +"@equinor/fusion-react-ag-grid-styles@^31.2.1": + version "31.2.4" + resolved "https://registry.yarnpkg.com/@equinor/fusion-react-ag-grid-styles/-/fusion-react-ag-grid-styles-31.2.4.tgz#63c364b1f5ad167724194e54eb0450adc0112e0a" + integrity sha512-hJ+2xtKmBedJwjKDGrQvcaPppX7/mrNel1XzlPU9DO4ZLiU6misACESqNq3gyiY1+ad7etH07v4EHWXJ3dw85w== + +"@equinor/fusion-react-searchable-dropdown@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-react-searchable-dropdown/-/fusion-react-searchable-dropdown-0.5.2.tgz#a139ac5465b366b1b44af3b1fbab78e07a33e458" + integrity sha512-spfXwfFBMyv8c8biX0tn3GJhzM5TOWoxTRBgNBbzuDZzBKZ8KpmdzzHth5EOgV7BqsiVGLtQheZBZP9rNI1G/A== + dependencies: + "@equinor/fusion-react-utils" "^2.1.1" + "@equinor/fusion-wc-icon" "^2.3.0" + "@equinor/fusion-wc-searchable-dropdown" "^3.7.2" + +"@equinor/fusion-react-side-sheet@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-react-side-sheet/-/fusion-react-side-sheet-1.3.3.tgz#73073e6cbd0aedd5466511b0b18c5696f77892b2" + integrity sha512-5ktA2VmrOT+3GprmHKsk5aE4WOMDb3IFMu9TbOunXZtSXpHbT8F2I5iBmtyp8W0dvOAIz5lgwF/hTEmt/Wz+YQ== + dependencies: + re-resizable "^6.9.11" + react-keyed-flatten-children "^3.0.0" + +"@equinor/fusion-react-styles@^0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-react-styles/-/fusion-react-styles-0.6.2.tgz#e6a3d6cc2036276d2b2a486f1380435daa954e67" + integrity sha512-cfyq1TCrXffsv4mekdIJyzocvkiHpga708o+W9RsgvMCv076qV1pIau1fLNmbXLpeCtMzEG0V9soIVKRylJ4uw== + dependencies: + "@equinor/fusion-wc-theme" "^1.1.0" + "@equinor/fusion-web-theme" "^0.1.10" + "@material-ui/styles" "^4.11.4" + clsx "^2.1.0" + +"@equinor/fusion-react-utils@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-react-utils/-/fusion-react-utils-2.1.1.tgz#05a8b49e473d2c881410418cd39d45530bae5e05" + integrity sha512-UU3afQMaKeiUseEfOwigTZqV0J6+2PTNFzqhOb0MAAwYsNthQWn77puHVjomsi4tbh8MsxqEIdq4303RA8x2lw== + dependencies: + date-fns "^3.2.0" + +"@equinor/fusion-wc-avatar@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-avatar/-/fusion-wc-avatar-3.2.3.tgz#2b95ee4dc5f535e28adc376df5157a7c7e3a1739" + integrity sha512-R4QrPz+lzIdYnc1s/6RixQb6MQ/sn1t1h+/P9MictC1bpxXaBKNA7XonxOXQyP9ivZHXLIZK8lNW6vtxiZXurQ== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-picture" "^3.1.1" + "@equinor/fusion-wc-ripple" "^1.1.1" + "@equinor/fusion-web-theme" "^0.1.10" + lit "3.2.0" + +"@equinor/fusion-wc-badge@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-badge/-/fusion-wc-badge-1.3.2.tgz#8252d0f9a50f9daf54fa31750fde97a20a5d9192" + integrity sha512-RnwtNC+USW388qFafoOxM+7EEmCgWC2sxbjlcyIfBlp0ladgMCEdSnJiSJL1Nb/Qdne7BJWQi3oAA9xnku4Rhg== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-icon" "^2.3.1" + "@equinor/fusion-web-theme" "^0.1.10" + lit "3.2.0" + +"@equinor/fusion-wc-button@^2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-button/-/fusion-wc-button-2.4.2.tgz#cfd002d83c7aaff3bc65963702534352e0dfc637" + integrity sha512-NPhY6GLO6MQnZLNnqtLrAbZrodm1ogsK65OL+VleN0NlYZzZ7i2li99itXSMSgXg5fit1YZ4ONonPzZ9BN4HFw== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-icon" "^2.3.1" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-button" "^0.27.0" + "@material/mwc-icon-button" "^0.27.0" + "@material/mwc-icon-button-toggle" "^0.27.0" + lit "3.2.0" + +"@equinor/fusion-wc-checkbox@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-checkbox/-/fusion-wc-checkbox-1.1.1.tgz#89510f4d6f058786d3cc82ca7c3e4cccb1ffec97" + integrity sha512-anLfHPuyO9VIsByGp5BAZEMo/wRy/YiCilnE0dlqi4AY5/DxfnjHkvMEinbQ9yeu2y3r/Mp3Oi6TBmYN4cIBXw== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-checkbox" "^0.27.0" + lit "3.1.2" + +"@equinor/fusion-wc-checkbox@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-checkbox/-/fusion-wc-checkbox-1.1.2.tgz#ae9bdcca168e18c57ff980205b1d23b7781a4ecb" + integrity sha512-lAD6yh4cvuTCNisiYjyB1BvGg566YkQFa9m+/hzIVIlQRk0UQn9/FHa8BB/DnAj9O/K6IrgRx7tabrXIDrzHUg== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-checkbox" "^0.27.0" + lit "3.2.0" + +"@equinor/fusion-wc-chip@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-chip/-/fusion-wc-chip-1.2.1.tgz#83bf353838496df091f3bdef24559c532e99bb5c" + integrity sha512-HdID9S+8GfHEN/unz1sa4szUN0DahsZnenVVInV34/l4xkGLeyXOjczHkRVrcO1P2ebY6spHn8eZDc5fOWzF1A== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-icon" "^2.3.0" + "@equinor/fusion-wc-ripple" "^1.1.0" + "@equinor/fusion-web-theme" "^0.1.10" + lit "3.1.2" + +"@equinor/fusion-wc-core@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-core/-/fusion-wc-core-2.0.0.tgz#ac362bd4d97a54d19f334630e6bd732b511bb190" + integrity sha512-yxUepfQhMIkKNYn2Vc73R6/cyvyO0hde3LXFitCCaa8QR9woK0UXZlxP+RwnEYzve528l9K1t7SnEsX6x5eyPg== + +"@equinor/fusion-wc-divider@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-divider/-/fusion-wc-divider-1.1.1.tgz#e44fa91a94699ed590ffe70c415b6cd42fc99e66" + integrity sha512-vM09tJy8yoGXVSwCVlptb1uu/9PeOON84vZiSmsuWySkNiDM3xpRARjLhT83XWW/rO7Y8oyM/3D61LVvX274gA== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + lit "3.1.2" + +"@equinor/fusion-wc-divider@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-divider/-/fusion-wc-divider-1.1.2.tgz#8638d0e352a142d92ae7ea50241d3e00028a1d7c" + integrity sha512-kb5kmq8S+aMqe+91RNHmJtjCg8ecrnB5DYrcm6RzucLicxL0NTwlLAJfy49xDR5kzt2laoyq6XsQ+4MqnlTbyw== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + lit "3.2.0" + +"@equinor/fusion-wc-icon@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-icon/-/fusion-wc-icon-2.3.0.tgz#f56870e3f35647c8ad120eb55d2017f141b636af" + integrity sha512-CRyIHnvmZ/WOzZwhsoxNL3DkN30wk7jskEa6i+YsiqFkV1xAGgMPQJjhmXI1jhewRoT4o09WcUjnLaYQ6CUdsQ== + dependencies: + "@equinor/eds-icons" "^0.19.1" + "@equinor/fusion-wc-core" "^2.0.0" + lit "3.0.2" + +"@equinor/fusion-wc-icon@^2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-icon/-/fusion-wc-icon-2.3.1.tgz#5e75ef22028cea043ca0cce383f21e6ccbe6a641" + integrity sha512-uwmlMWb0/ZOXzHgzFge7x3ZEWfDzvuHPhTfBe9gF4hCNE2ZpQU3TlQd/UZh4B6/0xVhdfAMdZyhAOmjW7OzDZA== + dependencies: + "@equinor/eds-icons" "^0.21.0" + "@equinor/fusion-wc-core" "^2.0.0" + lit "3.2.0" + +"@equinor/fusion-wc-list@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-list/-/fusion-wc-list-1.1.2.tgz#4647f14b2cf4ad20f39ae54e3d435196dfde92fa" + integrity sha512-oY8P7t/h/BMkK8h0CNKqvbvRk02OiIKxKwd5o5HmA3IKmBDrY49PvlEEVyhP5yjshbEfolIPnhe8tSeigKVbYA== + dependencies: + "@equinor/fusion-wc-checkbox" "^1.1.1" + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-divider" "^1.1.1" + "@equinor/fusion-wc-icon" "^2.3.0" + "@equinor/fusion-wc-radio" "^1.1.1" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-list" "^0.27.0" + lit "3.1.2" + +"@equinor/fusion-wc-list@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-list/-/fusion-wc-list-1.1.3.tgz#8e3003c803a1bc172d38dc81fc7453b99acf89c0" + integrity sha512-eKzpPA1/8k6uQu6/5ozfywJWHUBPcwOzcZbHz4/Rzu1fb5b932Eot/yUsacDRhnSigbgBvsOqU0phDp2OuV6yA== + dependencies: + "@equinor/fusion-wc-checkbox" "^1.1.2" + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-divider" "^1.1.2" + "@equinor/fusion-wc-icon" "^2.3.1" + "@equinor/fusion-wc-radio" "^1.1.2" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-list" "^0.27.0" + lit "3.2.0" + +"@equinor/fusion-wc-person@^3.0.1": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-person/-/fusion-wc-person-3.0.2.tgz#634fa242982d87bb8279a8203fba7a2dfc15e17a" + integrity sha512-ouexHJf1SLv8WAZj4evfb68hhjXb3pMji4q4Ag17e6S5wgpkvmoEI5LhyeAYdWEInC4flzdTiXJEl++zoE5EwQ== + dependencies: + "@equinor/fusion-wc-avatar" "^3.2.3" + "@equinor/fusion-wc-badge" "^1.3.2" + "@equinor/fusion-wc-button" "^2.4.2" + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-icon" "^2.3.1" + "@equinor/fusion-wc-list" "^1.1.3" + "@equinor/fusion-wc-searchable-dropdown" "^3.7.4" + "@equinor/fusion-wc-skeleton" "^2.1.2" + "@equinor/fusion-wc-textinput" "^1.1.2" + "@equinor/fusion-web-theme" "^0.1.10" + "@floating-ui/dom" "^1.6.10" + "@lit-labs/observers" "^2.0.3" + "@lit-labs/task" "^3.1.0" + lit "3.2.0" + +"@equinor/fusion-wc-picture@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-picture/-/fusion-wc-picture-3.1.1.tgz#a80565eed473444933170832b39fbef9f05e75ea" + integrity sha512-TeZd46sjyg43HHlbE4h9Ebk9wCBnif5j9XGodIdVTCaC7rLz2YEd7C6RS7vj3nS+goFIZmowiUUmg6gZemzY4w== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + lit "3.2.0" + +"@equinor/fusion-wc-radio@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-radio/-/fusion-wc-radio-1.1.1.tgz#4686def502187a4df9a2d2e8449fc3b7e3ef458f" + integrity sha512-Id5krecYRBFbeaIn0S22RNZzHiJ8ZSJnsaeXcqgjy61u4w88bguDaVmwH2kBO0kCG31HBJiBilvrs2YwnxdqzA== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-radio" "^0.27.0" + lit "3.1.2" + +"@equinor/fusion-wc-radio@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-radio/-/fusion-wc-radio-1.1.2.tgz#118a401978a7f3f6efccf14c1574ecb3dfb543ec" + integrity sha512-XO0rGD74dVQTtyI4GIjg1CuINbQ7DUUiNohvBWsYoLdG6TmvnCuO+2KfRNMdlwVTyog7Nm6qIl9agjQUOHQS0Q== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-radio" "^0.27.0" + lit "3.2.0" + +"@equinor/fusion-wc-ripple@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-ripple/-/fusion-wc-ripple-1.1.0.tgz#5c9827aa142926934ece9193f9747ffe64ecf762" + integrity sha512-eoWfj39NFnNhT4/stqw3x706pT68Kkc9oA6LIeOJW2H5rBKhJ/5vzMWwFo7CWPISd7jf52t/wlLF9Zfj0JXW7A== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@material/mwc-ripple" "^0.27.0" + lit "3.0.2" + +"@equinor/fusion-wc-ripple@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-ripple/-/fusion-wc-ripple-1.1.1.tgz#0cf949dd1d6b308703c75e053d671c253fbd648c" + integrity sha512-TuyBqTRekg7Kh+09+guD7P0HldGOkE7gicYF+rW1yfVFJGwCjBWQ+2EDqhImDPViRq5RWvE73Y8Ajayt/wO0Qw== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@material/mwc-ripple" "^0.27.0" + lit "3.2.0" + +"@equinor/fusion-wc-searchable-dropdown@^3.7.2": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-searchable-dropdown/-/fusion-wc-searchable-dropdown-3.7.3.tgz#d961e7c22ece8c961f52c0bcaf2649bf341834e1" + integrity sha512-2NzLqDK6zQpYTRNWYeemoY9Bz0O1HzG1bVjKZuFExCoSHThMeBXXaf5+WTWtkhpikSGU9GAjFMgDVGhQ0/8T0w== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-divider" "^1.1.1" + "@equinor/fusion-wc-icon" "^2.3.0" + "@equinor/fusion-wc-list" "^1.1.2" + "@equinor/fusion-wc-textinput" "^1.1.1" + "@equinor/fusion-web-theme" "^0.1.10" + "@lit-labs/task" "^3.1.0" + "@material/mwc-textfield" "^0.27.0" + "@types/uuid" "^9.0.8" + lit "3.1.2" + uuid "^9.0.0" + +"@equinor/fusion-wc-searchable-dropdown@^3.7.4": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-searchable-dropdown/-/fusion-wc-searchable-dropdown-3.7.4.tgz#63e0b948d2c6ffa1994f13ecb6d3448e0680ef15" + integrity sha512-ED34b/1f6Sg05TT5lUhakhZHGfWiLpMLy0PhAuO18BhWVpHMHikQeoaZU1P13he6ks/GCIXt+K+2/Y47nBi4Ng== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-divider" "^1.1.2" + "@equinor/fusion-wc-icon" "^2.3.1" + "@equinor/fusion-wc-list" "^1.1.3" + "@equinor/fusion-wc-textinput" "^1.1.2" + "@equinor/fusion-web-theme" "^0.1.10" + "@lit-labs/task" "^3.1.0" + "@material/mwc-textfield" "^0.27.0" + "@types/uuid" "^10.0.0" + lit "3.2.0" + uuid "^10.0.0" + +"@equinor/fusion-wc-skeleton@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-skeleton/-/fusion-wc-skeleton-2.1.2.tgz#f29922e46f8fe31409ca65d27b83fd0ce1e33cbe" + integrity sha512-LqrfUAg6BEqBi59kNs08UG+K7ESCvYJ6NMDIXI8EBTy1x2nt12D2JRXAE5zIeYU4+I084/zwKwt62Gx3yFtSkA== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + lit "3.2.0" + +"@equinor/fusion-wc-textinput@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-textinput/-/fusion-wc-textinput-1.1.1.tgz#f0f38c2c38821e984fdb5a7075e830f187c4ae1b" + integrity sha512-vEjbkiKulwTPesTl0mycNKtiA2/rZoJSJPlPZA1KmOwy6INDHaIP86QwfHiA3/nzqSAg8XRNcpZlLdN2XGr16g== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-icon" "^2.3.0" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-textfield" "^0.27.0" + lit "3.1.2" + +"@equinor/fusion-wc-textinput@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-textinput/-/fusion-wc-textinput-1.1.2.tgz#1ee1c16b821e089c5526dd07345e2404b92bc8d3" + integrity sha512-ZnN3nCCIvSJnfN6aLiE6Zr2euC0gSQB9X6R/2RxQYRPK++vRfbMH5gkafCJDDyS89A1WU0orDL7Ulgkq1XowMw== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-wc-icon" "^2.3.1" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/mwc-textfield" "^0.27.0" + lit "3.2.0" + +"@equinor/fusion-wc-theme@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@equinor/fusion-wc-theme/-/fusion-wc-theme-1.1.1.tgz#9fea0c6908b387473bfe97b21277d7c3bf4f57b2" + integrity sha512-zuiBp3pzVCwQtJ2zoejBdkdillx95R//NAw4rutYIwtrM/08V6J1T5OgFRY5w7nGwTjxL0D/KC3ZNrppG3wsVA== + dependencies: + "@equinor/fusion-wc-core" "^2.0.0" + "@equinor/fusion-web-theme" "^0.1.10" + "@material/theme" "^14.0.0" + lit "3.1.2" + +"@equinor/fusion-web-theme@^0.1.10": + version "0.1.10" + resolved "https://registry.yarnpkg.com/@equinor/fusion-web-theme/-/fusion-web-theme-0.1.10.tgz#b989f51cd3216df894c733fa0f80c6ef954dbe7f" + integrity sha512-/Yzfie73UvMoBMo35gmeHO+5nTty5EyemomcB5ZbEDyHFNIodgCL1JGm2KfrIwqez9w9CTneHjnJWvwhu9TM+w== + dependencies: + "@equinor/eds-tokens" "0.9.2" + csstype "^3.1.3" + +"@equinor/workspace-ag-grid@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@equinor/workspace-ag-grid/-/workspace-ag-grid-3.0.2.tgz#330be6f06d59e3c229f2b1c1f12ea22dbb56a0d4" + integrity sha512-m6A9FkbBZiKCyVXvtLZwHl/21NY/mTl+XNWuMbtpMJKBjsg7GSJrj0a6QlTorvHwltMBq5SCsSG0HTIyI2qNcg== + dependencies: + "@ag-grid-community/client-side-row-model" "31.2.1" + "@ag-grid-community/core" "31.2.1" + "@ag-grid-community/react" "31.2.1" + "@ag-grid-enterprise/column-tool-panel" "31.2.1" + "@ag-grid-enterprise/excel-export" "31.2.1" + "@ag-grid-enterprise/filter-tool-panel" "31.2.1" + "@ag-grid-enterprise/master-detail" "31.2.1" + "@ag-grid-enterprise/menu" "31.2.1" + "@ag-grid-enterprise/multi-filter" "31.2.1" + "@ag-grid-enterprise/range-selection" "31.2.1" + "@ag-grid-enterprise/rich-select" "31.2.1" + "@ag-grid-enterprise/row-grouping" "31.2.1" + "@ag-grid-enterprise/server-side-row-model" "31.2.1" + "@ag-grid-enterprise/set-filter" "31.2.1" + "@ag-grid-enterprise/side-bar" "31.2.1" + "@ag-grid-enterprise/status-bar" "31.2.1" + "@equinor/eds-tokens" "^0.9.0" + "@equinor/fusion-react-ag-grid-styles" "^31.2.1" + "@equinor/fusion-react-styles" "^0.6.2" + react ">= 18" + react-dom ">= 18" + +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@floating-ui/core@^1.6.0": + version "1.6.7" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.7.tgz#7602367795a390ff0662efd1c7ae8ca74e75fb12" + integrity sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g== + dependencies: + "@floating-ui/utils" "^0.2.7" + +"@floating-ui/dom@^1.0.0", "@floating-ui/dom@^1.6.10": + version "1.6.10" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.10.tgz#b74c32f34a50336c86dcf1f1c845cf3a39e26d6f" + integrity sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.7" + +"@floating-ui/react-dom@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.1.tgz#cca58b6b04fc92b4c39288252e285e0422291fb0" + integrity sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg== + dependencies: + "@floating-ui/dom" "^1.0.0" + +"@floating-ui/react@^0.26.19": + version "0.26.22" + resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.22.tgz#b46f645f9cd19a591da706aed24608c23cdb89a2" + integrity sha512-LNv4azPt8SpT4WW7Kku5JNVjLk2GcS0bGGjFTAgqOONRFo9r/aaGHHPpdiIuQbB1t8shmWyWqTTUDmZ9fcNshg== + dependencies: + "@floating-ui/react-dom" "^2.1.1" + "@floating-ui/utils" "^0.2.7" + tabbable "^6.0.0" + +"@floating-ui/react@^0.26.22": + version "0.26.23" + resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.23.tgz#28985e5ce482c34f347f28076f11267e47a933bd" + integrity sha512-9u3i62fV0CFF3nIegiWiRDwOs7OW/KhSUJDNx2MkQM3LbE5zQOY01sL3nelcVBXvX7Ovvo3A49I8ql+20Wg/Hw== + dependencies: + "@floating-ui/react-dom" "^2.1.1" + "@floating-ui/utils" "^0.2.7" + tabbable "^6.0.0" + +"@floating-ui/utils@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.7.tgz#d0ece53ce99ab5a8e37ebdfe5e32452a2bfc073e" + integrity sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA== + +"@formatjs/ecma402-abstract@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz#39197ab90b1c78b7342b129a56a7acdb8f512e17" + integrity sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g== + dependencies: + "@formatjs/intl-localematcher" "0.5.4" + tslib "^2.4.0" + +"@formatjs/fast-memoize@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b" + integrity sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA== + dependencies: + tslib "^2.4.0" + +"@formatjs/icu-messageformat-parser@2.7.8": + version "2.7.8" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz#f6d7643001e9bb5930d812f1f9a9856f30fa0343" + integrity sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA== + dependencies: + "@formatjs/ecma402-abstract" "2.0.0" + "@formatjs/icu-skeleton-parser" "1.8.2" + tslib "^2.4.0" + +"@formatjs/icu-skeleton-parser@1.8.2": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz#2252c949ae84ee66930e726130ea66731a123c9f" + integrity sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q== + dependencies: + "@formatjs/ecma402-abstract" "2.0.0" + tslib "^2.4.0" + +"@formatjs/intl-localematcher@0.5.4": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz#caa71f2e40d93e37d58be35cfffe57865f2b366f" + integrity sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g== + dependencies: + tslib "^2.4.0" + +"@hookform/resolvers@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.9.0.tgz#cf540ac21c6c0cd24a40cf53d8e6d64391fb753d" + integrity sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg== + +"@internationalized/date@^3.5.4", "@internationalized/date@^3.5.5": + version "3.5.5" + resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.5.5.tgz#7d34cb9da35127f98dd669fc926bb37e771e177f" + integrity sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ== + dependencies: + "@swc/helpers" "^0.5.0" + +"@internationalized/message@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@internationalized/message/-/message-3.1.4.tgz#4da041155829ffb57c9563fa7c99e2b94c8a5766" + integrity sha512-Dygi9hH1s7V9nha07pggCkvmRfDd3q2lWnMGvrJyrOwYMe1yj4D2T9BoH9I6MGR7xz0biQrtLPsqUkqXzIrBOw== + dependencies: + "@swc/helpers" "^0.5.0" + intl-messageformat "^10.1.0" + +"@internationalized/number@^3.5.3": + version "3.5.3" + resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.5.3.tgz#9fa060c1c4809f23fb3d38dd3f3d1ae4c87e95a8" + integrity sha512-rd1wA3ebzlp0Mehj5YTuTI50AQEx80gWFyHcQu+u91/5NgdwBecO8BH6ipPfE+lmQ9d63vpB3H9SHoIUiupllw== + dependencies: + "@swc/helpers" "^0.5.0" + +"@internationalized/string@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@internationalized/string/-/string-3.2.3.tgz#b0a8379e779a69e7874979714e27f2ae86761d3c" + integrity sha512-9kpfLoA8HegiWTeCbR2livhdVeKobCnVv8tlJ6M2jF+4tcMqDo94ezwlnrUANBWPgd8U7OXIHCk2Ov2qhk4KXw== + dependencies: + "@swc/helpers" "^0.5.0" + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@lit-labs/observers@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@lit-labs/observers/-/observers-2.0.3.tgz#a42a72cfa288dbd3065c7edb50313ad8d3ea6fe1" + integrity sha512-CeftEJ2TId9iohDJHLjUXiSBVndqjIBaALjeTt8OmgWLh2dnIzwlj4WtPCiJw15uR1s6D6wyCsw0AoJC5/9QXw== + dependencies: + "@lit/reactive-element" "^1.0.0 || ^2.0.0" + lit-html "^3.2.0" + +"@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0", "@lit-labs/ssr-dom-shim@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz#2f3a8f1d688935c704dbc89132394a41029acbb8" + integrity sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ== + +"@lit-labs/task@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@lit-labs/task/-/task-3.1.0.tgz#4821d2d5e0e0af0e18e57136bb39c2662811cbd9" + integrity sha512-zMlcUtZeHDT83IiT2+CJBSoFvWDLnPEezhOCgqjxW4DmRHlbgd7jdft97T6dw4S4RvIETfI7OOyvubCV/EzTlg== + dependencies: + "@lit/task" "^1.0.0" + +"@lit/reactive-element@^1.0.0 || ^2.0.0", "@lit/reactive-element@^2.0.0", "@lit/reactive-element@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-2.0.4.tgz#8f2ed950a848016383894a26180ff06c56ae001b" + integrity sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.2.0" + +"@lit/reactive-element@^1.3.0", "@lit/reactive-element@^1.6.0": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.6.3.tgz#25b4eece2592132845d303e091bad9b04cdcfe03" + integrity sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.0.0" + +"@lit/task@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@lit/task/-/task-1.0.1.tgz#7462aeaa973766822567f5ca90fe157404e8eb81" + integrity sha512-fVLDtmwCau8NywnFIXaJxsCZjzaIxnVq+cFRKYC1Y4tA4/0rMTvF6DLZZ2JE51BwzOluaKtgJX8x1QDsQtAaIw== + dependencies: + "@lit/reactive-element" "^1.0.0 || ^2.0.0" + +"@material-ui/styles@^4.11.4": + version "4.11.5" + resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.11.5.tgz#19f84457df3aafd956ac863dbe156b1d88e2bbfb" + integrity sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA== + dependencies: + "@babel/runtime" "^7.4.4" + "@emotion/hash" "^0.8.0" + "@material-ui/types" "5.1.0" + "@material-ui/utils" "^4.11.3" + clsx "^1.0.4" + csstype "^2.5.2" + hoist-non-react-statics "^3.3.2" + jss "^10.5.1" + jss-plugin-camel-case "^10.5.1" + jss-plugin-default-unit "^10.5.1" + jss-plugin-global "^10.5.1" + jss-plugin-nested "^10.5.1" + jss-plugin-props-sort "^10.5.1" + jss-plugin-rule-value-function "^10.5.1" + jss-plugin-vendor-prefixer "^10.5.1" + prop-types "^15.7.2" + +"@material-ui/types@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2" + integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A== + +"@material-ui/utils@^4.11.3": + version "4.11.3" + resolved "https://registry.yarnpkg.com/@material-ui/utils/-/utils-4.11.3.tgz#232bd86c4ea81dab714f21edad70b7fdf0253942" + integrity sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg== + dependencies: + "@babel/runtime" "^7.4.4" + prop-types "^15.7.2" + react-is "^16.8.0 || ^17.0.0" + +"@material/animation@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/animation/-/animation-14.0.0-canary.53b3cad2f.0.tgz#5610fca9ddfa240692ae1fc7098b5f29975dec93" + integrity sha512-GBuR4VmcTQW1D0lPXEosf5Giho72LLbyGIydWGtaEUtLJoive/D9kFkwTN4Fsyt9Kkl7hbhs35vrNe6QkAH4/Q== + dependencies: + tslib "^2.1.0" + +"@material/base@14.0.0-canary.53b3cad2f.0", "@material/base@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/base/-/base-14.0.0-canary.53b3cad2f.0.tgz#ada9928175c9a2f6db116e95854c3d72ab6846c3" + integrity sha512-UJKbXwZtkrA3sfQDmj8Zbw1Q3Tqtl6KdfVFws95Yf7TCUgTFzbZI/FSx1w7dVugQPOEnIBuZnzqZam/MtHkx4w== + dependencies: + tslib "^2.1.0" + +"@material/density@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/density/-/density-14.0.0-canary.53b3cad2f.0.tgz#a67e49fdbfc5347b8757ea14654197540762c20a" + integrity sha512-Eh/vZ3vVyqtpylg5Ci33qlgtToS4H1/ppd450Ib3tcdISIoodgijYY0w4XsRvrnZgbI/h/1STFdLxdzS0UNuFw== + dependencies: + tslib "^2.1.0" + +"@material/dom@14.0.0-canary.53b3cad2f.0", "@material/dom@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/dom/-/dom-14.0.0-canary.53b3cad2f.0.tgz#55613a2bf3d0ea64989ad77291f053b607256012" + integrity sha512-aR+rfncF6oi2ivdOlKSJI4UXwNzWV5rXM88MLDoSJF1D7lXxhAKhge+tMUBodWGV/q0+FnXLuVAa0WYTrKjo+A== + dependencies: + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/elevation@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/elevation/-/elevation-14.0.0-canary.53b3cad2f.0.tgz#f4eedead82ebe456643d482905c1c445e9f5b338" + integrity sha512-3h+EkR588RMZ5TSNQ4UeXD1FOBnL3ABQix0DQIGwtNJCqSMoPndT/oJEFvwQbTkZNDbFIKN9p1Q7/KuFPVY8Pw== + dependencies: + "@material/animation" "14.0.0-canary.53b3cad2f.0" + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/feature-targeting@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/feature-targeting/-/feature-targeting-14.0.0-canary.53b3cad2f.0.tgz#03f0048861ff737b46a77549dccb449650a14d9c" + integrity sha512-fn7Af3PRyARtNeYqtjxXmE3Y/dCpnpQVWWys57MqiGR/nvc6qpgOfJ6rOdcu/MrOysOE/oebTUDmDnTmwpe9Hw== + dependencies: + tslib "^2.1.0" + +"@material/feature-targeting@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@material/feature-targeting/-/feature-targeting-14.0.0.tgz#a6a878ae2be1f88d31b0bb95f05dbf5d486c4b3e" + integrity sha512-a5WGgHEq5lJeeNL5yevtgoZjBjXWy6+klfVWQEh8oyix/rMJygGgO7gEc52uv8fB8uAIoYEB3iBMOv8jRq8FeA== + dependencies: + tslib "^2.1.0" + +"@material/floating-label@14.0.0-canary.53b3cad2f.0", "@material/floating-label@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/floating-label/-/floating-label-14.0.0-canary.53b3cad2f.0.tgz#cdfb00ac092b455c49eb25558d3afb992a61f624" + integrity sha512-gHZUTTVKnP+Zjz4l9IT/G89NPmypn5FlTGLWKKqXbuQphr37rsKFR3Y80SJxULRyMDnAdKSxuZwiXLFKQz9KlA== + dependencies: + "@material/animation" "14.0.0-canary.53b3cad2f.0" + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/dom" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + "@material/typography" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/focus-ring@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/focus-ring/-/focus-ring-14.0.0-canary.53b3cad2f.0.tgz#3a0afc426cd898aa6fa045c5eef9bffb4a320e91" + integrity sha512-exPX5VrjQimipBwgcFDGRiEE783sOBgpkFui59A6i6iGvS2UrLHlYY2E65fyyyQnD1f/rv4Po1OOnCesE1kulg== + dependencies: + "@material/dom" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + +"@material/line-ripple@14.0.0-canary.53b3cad2f.0", "@material/line-ripple@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/line-ripple/-/line-ripple-14.0.0-canary.53b3cad2f.0.tgz#eb86f5a596b0f36e12a8a09492e074c25919ffe8" + integrity sha512-k8f8uuDwnSqZZ98CzbYtQVtxlp1ryUup9nd2uobo3kiqQNlQfXdGkVjuCXcla0OPiKFizNn7dS6Kl/j6L09XUA== + dependencies: + "@material/animation" "14.0.0-canary.53b3cad2f.0" + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/list@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/list/-/list-14.0.0-canary.53b3cad2f.0.tgz#0c0d0bdf3f9454a820e990fddb0abb1c42767f1c" + integrity sha512-mkMpltSKAYLBtFnTTCk/mQIDzwxF/VLh1gh59ehOtmRXt7FvTz83RoAa4tqe53hpVrbX4HoLDBu+vILhq/wkjw== + dependencies: + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/density" "14.0.0-canary.53b3cad2f.0" + "@material/dom" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/ripple" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + "@material/shape" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + "@material/typography" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/mwc-base@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-base/-/mwc-base-0.27.0.tgz#9bb282510b39168dcaa2d2c23aecdf91f6733c6e" + integrity sha512-oCWWtjbyQ52AaUbzINLGBKScIPyqhps2Y7c8t6Gu6fcFeDxhKXMV1Cqvtj/OMhtAt53XjHfD2XruWwYv3cYYUA== + dependencies: + "@material/base" "=14.0.0-canary.53b3cad2f.0" + "@material/dom" "=14.0.0-canary.53b3cad2f.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-button@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-button/-/mwc-button-0.27.0.tgz#192ab82eab8f7f4dcbf987d0af7bb808408d77d2" + integrity sha512-t5m2zfE93RNKHMjdsU67X6csFzuSG08VJKKvXVQ+BriGE3xBgzY5nZdmZXomFpaWjDENPAlyS4ppCFm6o+DILw== + dependencies: + "@material/mwc-icon" "^0.27.0" + "@material/mwc-ripple" "^0.27.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-checkbox@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-checkbox/-/mwc-checkbox-0.27.0.tgz#a299252df96045e9c37a67ff0d5c3f3469f27ae4" + integrity sha512-EY0iYZLwo8qaqMwR5da4fdn0xI0BZNAvKTcwoubYWpDDHlGxDcqwvjp/40ChGo3Q/zv8/4/A0Qp7cwapI82EkA== + dependencies: + "@material/mwc-base" "^0.27.0" + "@material/mwc-ripple" "^0.27.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-floating-label@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-floating-label/-/mwc-floating-label-0.27.0.tgz#7d2608b1fb91f99fda009021b1f8aad809b261b9" + integrity sha512-uLleloTxQ6dDShcZzqgqfC8otQY8DtGMO9HFQbAEncoFAWpAehcEonsuT/IUhMORN+c5un0P5WXwcZsInJb7og== + dependencies: + "@material/floating-label" "=14.0.0-canary.53b3cad2f.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-icon-button-toggle@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-icon-button-toggle/-/mwc-icon-button-toggle-0.27.0.tgz#1cbd3c59800f8fa0bb03a4efcf9f926c36b28012" + integrity sha512-PLozOm8m96vfPqTvugdCSC6V+sd337rdm/H2ZpnMbV+8gllfIkm1J02hv7rQ1O51ThrpMt4hd0URitIiEeuATg== + dependencies: + "@material/mwc-base" "^0.27.0" + "@material/mwc-icon-button" "^0.27.0" + "@material/mwc-ripple" "^0.27.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-icon-button@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-icon-button/-/mwc-icon-button-0.27.0.tgz#c7e6ba3c8130b017ced00c311c6667a6c7d6d569" + integrity sha512-wReiPa1UkLaCSPtpkAs1OGKEBtvqPnz9kzuY+RvN5ZQnpo3Uh7n3plHV4y/stsUBfrWtBCcOgYnCdNRaR/r2nQ== + dependencies: + "@material/mwc-ripple" "^0.27.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-icon@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-icon/-/mwc-icon-0.27.0.tgz#f25ecdd7fe54d810d7d655ba05251169f78b84fd" + integrity sha512-Sul44I37M9Ewynn0A9DjkEBrmll2VtNbth6Pxj7I1A/EAwEfaCrPvryyGqfIu1T2hTsRcaojzQx6QjF+B5QW9A== + dependencies: + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-line-ripple@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-line-ripple/-/mwc-line-ripple-0.27.0.tgz#91fdc3b2fc3a2cc93cedbbf2342dd8bab37a60a6" + integrity sha512-n9Xpt5g3RJEl9rvk14OP6dUNJUtsJA46beTQiep7ppO7IPVFLC1v/5sPpUzfNPUBsclSPxdBuNlCxsgcIYueUw== + dependencies: + "@material/line-ripple" "=14.0.0-canary.53b3cad2f.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-list@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-list/-/mwc-list-0.27.0.tgz#4871a4dc9d6b7dae38ad509f9d5973e293cbc1f3" + integrity sha512-oAhNQsBuAOgF3ENOIY8PeWjXsl35HoYaUkl0ixBQk8jJP2HIEf+MdbS5688y/UXxFbSjr0m//LfwR5gauEashg== + dependencies: + "@material/base" "=14.0.0-canary.53b3cad2f.0" + "@material/dom" "=14.0.0-canary.53b3cad2f.0" + "@material/list" "=14.0.0-canary.53b3cad2f.0" + "@material/mwc-base" "^0.27.0" + "@material/mwc-checkbox" "^0.27.0" + "@material/mwc-radio" "^0.27.0" + "@material/mwc-ripple" "^0.27.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-notched-outline@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-notched-outline/-/mwc-notched-outline-0.27.0.tgz#1c5539c6e485e27048404e24132051dad0a47407" + integrity sha512-IlqfQVaEd1RAHqhOG0Xk5JhTDgBe/P9og0pnACglK6bPE0vUhYKwibJiHcr4ACTPtGWHO9o92aktR+7AIEAKtQ== + dependencies: + "@material/mwc-base" "^0.27.0" + "@material/notched-outline" "=14.0.0-canary.53b3cad2f.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-radio@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-radio/-/mwc-radio-0.27.0.tgz#f05b69706626590725e5338705485ac44ea60875" + integrity sha512-+rSO9a373BgyMgQOM0Z8vVkuieobBylPJ8qpltytM+yGPj8+n+MtwRZyg+ry3WwEjYYDMP6GxZPHwLgWs6lMpQ== + dependencies: + "@material/mwc-base" "^0.27.0" + "@material/mwc-ripple" "^0.27.0" + "@material/radio" "=14.0.0-canary.53b3cad2f.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-ripple@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-ripple/-/mwc-ripple-0.27.0.tgz#1dff975d41151ed78285013a289a5dbaca769636" + integrity sha512-by0O8d8g3Rd96/sUB8hxy6MrDx1QTstqOsA64vqypWd526hMTBGRik08jTNap5sVIyrN9Vq17jb4NJLWQLnNHQ== + dependencies: + "@material/dom" "=14.0.0-canary.53b3cad2f.0" + "@material/mwc-base" "^0.27.0" + "@material/ripple" "=14.0.0-canary.53b3cad2f.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/mwc-textfield@^0.27.0": + version "0.27.0" + resolved "https://registry.yarnpkg.com/@material/mwc-textfield/-/mwc-textfield-0.27.0.tgz#07cdc6ec6b30ce5cb357a5381530689720c082ee" + integrity sha512-4/OEeEVAWWQ1DzpjeMLYLsa9HMlifOPjAvi0681Yj1g/RYJs5ONZS80HZ8HOT+efAOlZDugshgM4gdNS3I0XFQ== + dependencies: + "@material/floating-label" "=14.0.0-canary.53b3cad2f.0" + "@material/line-ripple" "=14.0.0-canary.53b3cad2f.0" + "@material/mwc-base" "^0.27.0" + "@material/mwc-floating-label" "^0.27.0" + "@material/mwc-line-ripple" "^0.27.0" + "@material/mwc-notched-outline" "^0.27.0" + "@material/textfield" "=14.0.0-canary.53b3cad2f.0" + lit "^2.0.0" + tslib "^2.0.1" + +"@material/notched-outline@14.0.0-canary.53b3cad2f.0", "@material/notched-outline@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/notched-outline/-/notched-outline-14.0.0-canary.53b3cad2f.0.tgz#e1959462acb4b94038e6aac598e45f9098c5d3da" + integrity sha512-3ByiPOC/wWQmFKfgJS98kb5/6v92n7uIfJ6v6sryKJlJCJn39qfpGcCM5RpRIws1RET1s1zBJT2JDwYeu/hM5A== + dependencies: + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/floating-label" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + "@material/shape" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/radio@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/radio/-/radio-14.0.0-canary.53b3cad2f.0.tgz#51ee17e301509d729aef85cc1b22762f504a21b9" + integrity sha512-V/AgWEOuHFoh9d4Gq1rqBZnKSGtMLQNh23Bwrv0c1FhPqFvUpwt9jR3SVwhJk5gvQQWGy9p3iiGc9QCJ+0+P8Q== + dependencies: + "@material/animation" "14.0.0-canary.53b3cad2f.0" + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/density" "14.0.0-canary.53b3cad2f.0" + "@material/dom" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/focus-ring" "14.0.0-canary.53b3cad2f.0" + "@material/ripple" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + "@material/touch-target" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/ripple@14.0.0-canary.53b3cad2f.0", "@material/ripple@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/ripple/-/ripple-14.0.0-canary.53b3cad2f.0.tgz#143454681b56ba42e979116903a3a1e4680249bf" + integrity sha512-6g2G62vd8DsMuIUSXlRrzb98qkZ4o8ZREknNwNP2zaLQEOkJ//4j9HaqDt98/3LIjUTY9UIVFTQENiMmlwKHYQ== + dependencies: + "@material/animation" "14.0.0-canary.53b3cad2f.0" + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/dom" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/rtl@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/rtl/-/rtl-14.0.0-canary.53b3cad2f.0.tgz#63216c4957992e39d1864eb0d07fa9194740f92a" + integrity sha512-f08LT0HSa0WYU+4Jz/tbm1TQ9Fcf2k+H6dPPYv0J1sZmX6hMgCEmNiUdUFLQFvszoXx2XrRi1/hIFjbz2e69Yg== + dependencies: + "@material/theme" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/shape@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/shape/-/shape-14.0.0-canary.53b3cad2f.0.tgz#60d2ba5ae2c428997cab78c65a29bcd6029f268a" + integrity sha512-RyjInLCNe+nI/ulKea0ZLHphXQDiDqYazS25SRn18g8Hoa5qGNaY5oOBncDXUYn3jm5oI5kFc9oif//kulkbjg== + dependencies: + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/textfield@=14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/textfield/-/textfield-14.0.0-canary.53b3cad2f.0.tgz#cd6ed02d9fa4669bf3fd4a26c5716ecaa8053072" + integrity sha512-Pla9Tr94Is18o97E/mqHKdkR24rPES9atGm3BlXrNzyr5tu6+h++RBbxy7V6IExcfl0MX+v9Gyqz7sPZzFtwMA== + dependencies: + "@material/animation" "14.0.0-canary.53b3cad2f.0" + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/density" "14.0.0-canary.53b3cad2f.0" + "@material/dom" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/floating-label" "14.0.0-canary.53b3cad2f.0" + "@material/line-ripple" "14.0.0-canary.53b3cad2f.0" + "@material/notched-outline" "14.0.0-canary.53b3cad2f.0" + "@material/ripple" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + "@material/shape" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + "@material/tokens" "14.0.0-canary.53b3cad2f.0" + "@material/typography" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/theme@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/theme/-/theme-14.0.0-canary.53b3cad2f.0.tgz#27863ec21c7c913b80b98a22f056dd3e75b85a0a" + integrity sha512-S06XAevDCDWMe+GgsEpITMS07imUidzadNaTbJsqssFajBLr53QWVZsG84BpjXKXoYvyEJvb0hX5U0lq6ip9UQ== + dependencies: + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/theme@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@material/theme/-/theme-14.0.0.tgz#cbcd7b2116220c44ef8a89c43b068b29d23456ea" + integrity sha512-6/SENWNIFuXzeHMPHrYwbsXKgkvCtWuzzQ3cUu4UEt3KcQ5YpViazIM6h8ByYKZP8A9d8QpkJ0WGX5btGDcVoA== + dependencies: + "@material/feature-targeting" "^14.0.0" + tslib "^2.1.0" + +"@material/tokens@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/tokens/-/tokens-14.0.0-canary.53b3cad2f.0.tgz#32e021323b1deb5fa6df7c08012f58d65ec4b5f2" + integrity sha512-myHFB7vac8zErA3qgkqmV+kpE+i9JEwc/6Yf0MOumDSpylJGw28QikpNC6eAVBK2EmPQTaFn20mqUxyud8dGqw== + dependencies: + "@material/elevation" "14.0.0-canary.53b3cad2f.0" + +"@material/touch-target@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/touch-target/-/touch-target-14.0.0-canary.53b3cad2f.0.tgz#c933f68f66bdcfb4c688cd4ee54b517dce4db389" + integrity sha512-d83e5vbqoLyL542yOTTp4TLVltddWiqbI/j1w/D9ipE30YKfe2EDN+CNJc32Zufh5IUfK41DsZdrN8fI9cL99A== + dependencies: + "@material/base" "14.0.0-canary.53b3cad2f.0" + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/rtl" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@material/typography@14.0.0-canary.53b3cad2f.0": + version "14.0.0-canary.53b3cad2f.0" + resolved "https://registry.yarnpkg.com/@material/typography/-/typography-14.0.0-canary.53b3cad2f.0.tgz#735414b1ce38864a2023a81c3e2cb98e1232ca3f" + integrity sha512-9J0k2fq7uyHsRzRqJDJLGmg3YzRpfRPtFDVeUH/xBcYoqpZE7wYw5Mb7s/l8eP626EtR7HhXhSPjvRTLA6NIJg== + dependencies: + "@material/feature-targeting" "14.0.0-canary.53b3cad2f.0" + "@material/theme" "14.0.0-canary.53b3cad2f.0" + tslib "^2.1.0" + +"@react-aria/breadcrumbs@^3.5.15": + version "3.5.15" + resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.15.tgz#c8ba91b36ec07b4c81bc6124461054a91d258217" + integrity sha512-KJ7678hwKbacz6dyY4aOJlgtV91PtuSnlWGR+AsK88WwHhpjjTjLLTSRepjbQ35GuQuoYokM4mmfaS/I0nblhw== + dependencies: + "@react-aria/i18n" "^3.12.1" + "@react-aria/link" "^3.7.3" + "@react-aria/utils" "^3.25.1" + "@react-types/breadcrumbs" "^3.7.7" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/breadcrumbs@^3.5.16": + version "3.5.16" + resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.16.tgz#bea4b38e2ac218d113be56294fc556f790db8581" + integrity sha512-OXLKKu4SmjnSaSHkk4kow5/aH/SzlHWPJt+Uq3xec9TwDOr/Ob8aeFVGFoY0HxfGozuQlUz+4e+d29vfA0jNWg== + dependencies: + "@react-aria/i18n" "^3.12.2" + "@react-aria/link" "^3.7.4" + "@react-aria/utils" "^3.25.2" + "@react-types/breadcrumbs" "^3.7.7" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/button@^3.9.7": + version "3.9.7" + resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.9.7.tgz#f839cb54d318d03cc3ec8bdcd31cca9a4046cd21" + integrity sha512-xwE6uatbbn3KbNSc0dyDnOo539HJM2cqCPfjiQGt8O9cFbpQSmx76Fj4WotU3BwT7ZVbcAC8D206CgF1C2cDcQ== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/toggle" "^3.7.6" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/button@^3.9.8": + version "3.9.8" + resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.9.8.tgz#bf0a54268e9b88b0aa18494e8453f2c4f70e129c" + integrity sha512-MdbMQ3t5KSCkvKtwYd/Z6sgw0v+r1VQFRYOZ4L53xOkn+u140z8vBpNeWKZh/45gxGv7SJn9s2KstLPdCWmIxw== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-stately/toggle" "^3.7.7" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/calendar@^3.5.10": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.10.tgz#749ac8baf44f7b4639b898dc9f4e80b5e905f4e4" + integrity sha512-5PokdIHAH+CAd6vMHFW9mg77I5tC0FQglYsCEI9ikhCnL5xlt3FmJjLtOs3UJQaWgrd4cdVd0oINpPafJ9ydhA== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/utils" "^3.25.1" + "@react-stately/calendar" "^3.5.3" + "@react-types/button" "^3.9.6" + "@react-types/calendar" "^3.4.8" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/calendar@^3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.11.tgz#da75da0eaf40a48d33a766b67fc342dc21deb21d" + integrity sha512-VLhBovLVu3uJXBkHbgEippmo/K58QLcc/tSJQ0aJUNyHsrvPgHEcj484cb+Uj/yOirXEIzaoW6WEvhcdKrb49Q== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/utils" "^3.25.2" + "@react-stately/calendar" "^3.5.4" + "@react-types/button" "^3.9.6" + "@react-types/calendar" "^3.4.9" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/checkbox@^3.14.5": + version "3.14.5" + resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.14.5.tgz#8e25a19a2cf6c28de603aebd77ec14f0f504333b" + integrity sha512-On8m66CNi1LvbDeDo355au0K66ayIjo0nDe4oe85aNsR/owyzz8hXNPAFuh98owQVMsKt4596FZICAVSMzzhJg== + dependencies: + "@react-aria/form" "^3.0.7" + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/toggle" "^3.10.6" + "@react-aria/utils" "^3.25.1" + "@react-stately/checkbox" "^3.6.7" + "@react-stately/form" "^3.0.5" + "@react-stately/toggle" "^3.7.6" + "@react-types/checkbox" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/checkbox@^3.14.6": + version "3.14.6" + resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.14.6.tgz#79050d5c491a8e16be42bc80188f72b6891c610f" + integrity sha512-LICY1PR3WsW/VbuLMjZbxo75+poeo3XCXGcUnk6hxMlWfp/Iy/XHVsHlGu9stRPKRF8BSuOGteaHWVn6IXfwtA== + dependencies: + "@react-aria/form" "^3.0.8" + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/toggle" "^3.10.7" + "@react-aria/utils" "^3.25.2" + "@react-stately/checkbox" "^3.6.8" + "@react-stately/form" "^3.0.5" + "@react-stately/toggle" "^3.7.7" + "@react-types/checkbox" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/combobox@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.10.1.tgz#8e964815471e09f794d314945b7f8fabf250858a" + integrity sha512-B0zjX66HEqjPFnunYR0quAqwVJ6U0ez1eqBp25/611Dtzh3JHUovQmTE0xGGTjRe6N6qJg0VHVr2eRO/D0A+Lw== + dependencies: + "@react-aria/i18n" "^3.12.1" + "@react-aria/listbox" "^3.13.1" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/menu" "^3.15.1" + "@react-aria/overlays" "^3.23.1" + "@react-aria/selection" "^3.19.1" + "@react-aria/textfield" "^3.14.7" + "@react-aria/utils" "^3.25.1" + "@react-stately/collections" "^3.10.9" + "@react-stately/combobox" "^3.9.1" + "@react-stately/form" "^3.0.5" + "@react-types/button" "^3.9.6" + "@react-types/combobox" "^3.12.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/combobox@^3.10.3": + version "3.10.3" + resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.10.3.tgz#39d79bdb97eb06aadae83553d7a708756e18fd2d" + integrity sha512-EdDwr2Rp1xy7yWjOYHt2qF1IpAtUrkaNKZJzlIw1XSwcqizQY6E8orNPdZr6ZwD6/tgujxF1N71JTKyffrR0Xw== + dependencies: + "@react-aria/i18n" "^3.12.2" + "@react-aria/listbox" "^3.13.3" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/menu" "^3.15.3" + "@react-aria/overlays" "^3.23.2" + "@react-aria/selection" "^3.19.3" + "@react-aria/textfield" "^3.14.8" + "@react-aria/utils" "^3.25.2" + "@react-stately/collections" "^3.10.9" + "@react-stately/combobox" "^3.9.2" + "@react-stately/form" "^3.0.5" + "@react-types/button" "^3.9.6" + "@react-types/combobox" "^3.12.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/datepicker@^3.11.1": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.11.1.tgz#0162ac24f5e46c798422e5cdbb23a1c2d41f1de3" + integrity sha512-yEEuDt/ynt7bTfd/9RD1EiLPysWhbgSYSpn5PHVz7I2XORvNPpyamyAgz3+oFiLFLC/zy0qrG7e6V1rvI1NBzw== + dependencies: + "@internationalized/date" "^3.5.5" + "@internationalized/number" "^3.5.3" + "@internationalized/string" "^3.2.3" + "@react-aria/focus" "^3.18.1" + "@react-aria/form" "^3.0.7" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/spinbutton" "^3.6.7" + "@react-aria/utils" "^3.25.1" + "@react-stately/datepicker" "^3.10.1" + "@react-stately/form" "^3.0.5" + "@react-types/button" "^3.9.6" + "@react-types/calendar" "^3.4.8" + "@react-types/datepicker" "^3.8.1" + "@react-types/dialog" "^3.5.12" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/datepicker@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.11.2.tgz#628f70ea532480421e7ebe1f0020856baee60639" + integrity sha512-6sbLln3VXSBcBRDgSACBzIzF/5KV5NlNOhZvXPFE6KqFw6GbevjZQTv5BNDXiwA3CQoawIRF7zgRvTANw8HkNA== + dependencies: + "@internationalized/date" "^3.5.5" + "@internationalized/number" "^3.5.3" + "@internationalized/string" "^3.2.3" + "@react-aria/focus" "^3.18.2" + "@react-aria/form" "^3.0.8" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/spinbutton" "^3.6.8" + "@react-aria/utils" "^3.25.2" + "@react-stately/datepicker" "^3.10.2" + "@react-stately/form" "^3.0.5" + "@react-types/button" "^3.9.6" + "@react-types/calendar" "^3.4.9" + "@react-types/datepicker" "^3.8.2" + "@react-types/dialog" "^3.5.12" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/dialog@^3.5.16": + version "3.5.16" + resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.16.tgz#f21d69886ce9d87c07903cc51551888445dadb8e" + integrity sha512-2clBSQQaoqCjAUkHnMA/noZ1ZnFbEVU67fL9M1QfokezAyLAlyCyD9XSed6+Td/Ncj80N3/Lax65XAlvWCyOlg== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/overlays" "^3.23.1" + "@react-aria/utils" "^3.25.1" + "@react-types/dialog" "^3.5.12" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/dialog@^3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.17.tgz#156c62be73ee5c1fb68d8cd59effa350f9d69970" + integrity sha512-lvfEgaqg922J1hurscqCS600OZQVitGtdpo81kAefJaUzMnCxzrYviyT96aaW0simHOlimbYF5js8lxBLZJRaw== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/overlays" "^3.23.2" + "@react-aria/utils" "^3.25.2" + "@react-types/dialog" "^3.5.12" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/dnd@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.7.1.tgz#091d42094fc8f47816075704b5b16a34da8b3a57" + integrity sha512-p3/pc8p2fGd4s+Qj4SfRPJjZFStuuXqRNyDQxd9AAFYUWcCQxwDOqtiTZmfvs7Hvl0PUuysHW6Q5v7ABRjVr7w== + dependencies: + "@internationalized/string" "^3.2.3" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/overlays" "^3.23.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/dnd" "^3.4.1" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/dnd@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.7.2.tgz#d42b83729f21902fe1614a1efd4d62f7918e57a8" + integrity sha512-NuE3EGqoBbe9aXAO9mDfbu4kMO7S4MCgkjkCqYi16TWfRUf38ajQbIlqodCx91b3LVN3SYvNbE3D4Tj5ebkljw== + dependencies: + "@internationalized/string" "^3.2.3" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/overlays" "^3.23.2" + "@react-aria/utils" "^3.25.2" + "@react-stately/dnd" "^3.4.2" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/focus@^3.18.1": + version "3.18.1" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.18.1.tgz#b54b88e78662549ddae917e3143723c8dd7a4e90" + integrity sha512-N0Cy61WCIv+57mbqC7hiZAsB+3rF5n4JKabxUmg/2RTJL6lq7hJ5N4gx75ymKxkN8GnVDwt4pKZah48Wopa5jw== + dependencies: + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + clsx "^2.0.0" + +"@react-aria/focus@^3.18.2": + version "3.18.2" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.18.2.tgz#93accfce59c8abbbb95589e65816a240cd16068a" + integrity sha512-Jc/IY+StjA3uqN73o6txKQ527RFU7gnG5crEl5Xy3V+gbYp2O5L3ezAo/E0Ipi2cyMbG6T5Iit1IDs7hcGu8aw== + dependencies: + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + clsx "^2.0.0" + +"@react-aria/form@^3.0.7": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@react-aria/form/-/form-3.0.7.tgz#767a6474a20d4206dca0fd5f5946656452ff59a9" + integrity sha512-VIsKP/KytJPOLRQl0NxWWS1bQELPBuW3vRjmmhBrtgPFmp0uCLhjPBkP6A4uIVj1E/JtAocyHN3DNq4+IJGQCg== + dependencies: + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/form" "^3.0.5" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/form@^3.0.8": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@react-aria/form/-/form-3.0.8.tgz#9d98040b44795052bddffd47741ed64b739dd070" + integrity sha512-8S2QiyUdAgK43M3flohI0R+2rTyzH088EmgeRArA8euvJTL16cj/oSOKMEgWVihjotJ9n6awPb43ZhKboyNsMg== + dependencies: + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-stately/form" "^3.0.5" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/grid@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.10.1.tgz#5eb81575c9f8d872b00e2c43e5167f5d9451f131" + integrity sha512-7dSgiYVQapBtPV4SIit+9fJ1qoEjtp+PXffJkWAPtGbg/jJ4b0jcVzykH7ARD4w/6jAJN/oVSfrKZqFPoLAd9w== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/selection" "^3.19.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/collections" "^3.10.9" + "@react-stately/grid" "^3.9.1" + "@react-stately/selection" "^3.16.1" + "@react-types/checkbox" "^3.8.3" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/grid@^3.10.3": + version "3.10.3" + resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.10.3.tgz#141cf19f2625912da9159e3bf20a49b23ca37786" + integrity sha512-l0r9mz05Gwjq3t6JOTNQOf+oAoWN0bXELPJtIr8m0XyXMPFCQe1xsTaX8igVQdrDmXyBc75RAWS0BJo2JF2fIA== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/selection" "^3.19.3" + "@react-aria/utils" "^3.25.2" + "@react-stately/collections" "^3.10.9" + "@react-stately/grid" "^3.9.2" + "@react-stately/selection" "^3.16.2" + "@react-types/checkbox" "^3.8.3" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/gridlist@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.9.1.tgz#02672b42f8b1c8df26521ef24b5722aee252da09" + integrity sha512-cue2KCI4WyVmL3j9tZx7xG7gUJ7UyRbawzRTcocJukOmpeoyRaw/robrIYK2Pd//GhRbIMAoo4iOyZk5j7vEww== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/grid" "^3.10.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/selection" "^3.19.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/collections" "^3.10.9" + "@react-stately/list" "^3.10.7" + "@react-stately/tree" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/gridlist@^3.9.3": + version "3.9.3" + resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.9.3.tgz#9c1f7cd48a6cbbbfeb660a09a1a938f670306c1c" + integrity sha512-bb9GnKKeuL6NljoVUcHxr9F0cy/2WDOXRYeMikTnviRw6cuX95oojrhFfCUvz2d6ID22Btrvh7LkE+oIPVuc+g== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/grid" "^3.10.3" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/selection" "^3.19.3" + "@react-aria/utils" "^3.25.2" + "@react-stately/collections" "^3.10.9" + "@react-stately/list" "^3.10.8" + "@react-stately/tree" "^3.8.4" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/i18n@^3.12.1": + version "3.12.1" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.12.1.tgz#2b170953867f14688c4dd17b2ab55a8ca8eba07d" + integrity sha512-0q3gyogF9Ekah+9LOo6tcfshxsk2Ope+KdbtFHJVhznedMxn6RpHGcVur5ImbQ1dYafA5CmjBUGJW70b56+BGA== + dependencies: + "@internationalized/date" "^3.5.5" + "@internationalized/message" "^3.1.4" + "@internationalized/number" "^3.5.3" + "@internationalized/string" "^3.2.3" + "@react-aria/ssr" "^3.9.5" + "@react-aria/utils" "^3.25.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/i18n@^3.12.2": + version "3.12.2" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.12.2.tgz#f1e63ddb5227bc1c8a17cd3475235851e428dd0b" + integrity sha512-PvEyC6JWylTpe8dQEWqQwV6GiA+pbTxHQd//BxtMSapRW3JT9obObAnb/nFhj3HthkUvqHyj0oO1bfeN+mtD8A== + dependencies: + "@internationalized/date" "^3.5.5" + "@internationalized/message" "^3.1.4" + "@internationalized/number" "^3.5.3" + "@internationalized/string" "^3.2.3" + "@react-aria/ssr" "^3.9.5" + "@react-aria/utils" "^3.25.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/interactions@^3.22.1": + version "3.22.1" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.22.1.tgz#f2219a100c886cee383da7be9ae05e9dd940d39a" + integrity sha512-5TLzQaDAQQ5C70yG8GInbO4wIylKY67RfTIIwQPGR/4n5OIjbUD8BOj3NuSsuZ/frUPaBXo1VEBBmSO23fxkjw== + dependencies: + "@react-aria/ssr" "^3.9.5" + "@react-aria/utils" "^3.25.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/interactions@^3.22.2": + version "3.22.2" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.22.2.tgz#88ab021326459513fb16cf752974471932ffb5d1" + integrity sha512-xE/77fRVSlqHp2sfkrMeNLrqf2amF/RyuAS6T5oDJemRSgYM3UoxTbWjucPhfnoW7r32pFPHHgz4lbdX8xqD/g== + dependencies: + "@react-aria/ssr" "^3.9.5" + "@react-aria/utils" "^3.25.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/label@^3.7.10": + version "3.7.10" + resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.10.tgz#5343c95da514bc448ad779b2fbec9f8dd550e0d1" + integrity sha512-e5XVHA+OUK0aIwr4nHcnIj0z1kUryGaJWYYD2OGkkIltyUCKmwpRqdx8LQYbO4HGsJhvC3hJgidFdGcQwHHPYw== + dependencies: + "@react-aria/utils" "^3.25.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/label@^3.7.11": + version "3.7.11" + resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.11.tgz#79cb5234dce68eb6eb011fa74de435e394cac2a8" + integrity sha512-REgejE5Qr8cXG/b8H2GhzQmjQlII/0xQW/4eDzydskaTLvA7lF5HoJUE6biYTquH5va38d8XlH465RPk+bvHzA== + dependencies: + "@react-aria/utils" "^3.25.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/link@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.7.3.tgz#a6170ed04c67e55dedf0eec1b699cfa168e9eb28" + integrity sha512-dOwzxzo7LF4djBfRC8GcIhuTpDkNUIMT6ykQRV1a3749kgrr10YLascsO/l66k60i2k0T2oClkzfefYEK6WZeA== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-types/link" "^3.5.7" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/link@^3.7.4": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.7.4.tgz#3ea250b2f81f4af518118eaf183553cc8f296e49" + integrity sha512-E8SLDuS9ssm/d42+3sDFNthfMcNXMUrT2Tq1DIZt22EsMcuEzmJ9B0P7bDP5RgvIw05xVGqZ20nOpU4mKTxQtA== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-types/link" "^3.5.7" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/listbox@^3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.13.1.tgz#3a59b2973baebb96f10e784f14c6ddf1312c2196" + integrity sha512-b5Nu+5d5shJbxpy4s6OXvMlMzm+PVbs3L6CtoHlsKe8cAlSWD340vPHCOGYLwZApIBewepOBvRWgeAF8IDI04w== + dependencies: + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/selection" "^3.19.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/collections" "^3.10.9" + "@react-stately/list" "^3.10.7" + "@react-types/listbox" "^3.5.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/listbox@^3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.13.3.tgz#e1c85f932d9f16c2b2121d326ff9975436fa8331" + integrity sha512-htluPyDfFtn66OEYaJdIaFCYH9wGCNk30vOgZrQkPul9F9Cjce52tTyPVR0ERsf14oCUsjjS5qgeq3dGidRqEw== + dependencies: + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/selection" "^3.19.3" + "@react-aria/utils" "^3.25.2" + "@react-stately/collections" "^3.10.9" + "@react-stately/list" "^3.10.8" + "@react-types/listbox" "^3.5.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/live-announcer@^3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@react-aria/live-announcer/-/live-announcer-3.3.4.tgz#97a5830ae7da8546b2d19311fe1606c5d5e0151c" + integrity sha512-w8lxs35QrRrn6pBNzVfyGOeqWdxeVKf9U6bXIVwhq7rrTqRULL8jqy8RJIMfIs1s8G5FpwWYjyBOjl2g5Cu1iA== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-aria/menu@^3.15.1": + version "3.15.1" + resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.15.1.tgz#d44196d268f731c7a1b6b4fb907419a7c3632060" + integrity sha512-ZBTMZiJ17j6t7epcsjd0joAzsMKO31KLJHPtWAEfk1JkBxrMoirISPN8O1CeK/uBX++VaWSrDZfFe1EjrOwKuA== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/overlays" "^3.23.1" + "@react-aria/selection" "^3.19.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/collections" "^3.10.9" + "@react-stately/menu" "^3.8.1" + "@react-stately/tree" "^3.8.3" + "@react-types/button" "^3.9.6" + "@react-types/menu" "^3.9.11" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/menu@^3.15.3": + version "3.15.3" + resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.15.3.tgz#e950fc19a65630a77c9aa5e15023445bcaf35e17" + integrity sha512-vvUmVjJwIg3h2r+7isQXTwlmoDlPAFBckHkg94p3afrT1kNOTHveTsaVl17mStx/ymIioaAi3PrIXk/PZXp1jw== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/overlays" "^3.23.2" + "@react-aria/selection" "^3.19.3" + "@react-aria/utils" "^3.25.2" + "@react-stately/collections" "^3.10.9" + "@react-stately/menu" "^3.8.2" + "@react-stately/tree" "^3.8.4" + "@react-types/button" "^3.9.6" + "@react-types/menu" "^3.9.11" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/meter@^3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.15.tgz#7a277636f8f03660134296dc067b614b59d52b98" + integrity sha512-OUAzgmfiyEvBF+h9NlG7s8jvrGNTqj/zAWyUWEh5FMEjKFrDfni6awwFoRs164QqmUvRBNC0/eKv3Ghd2GIkRA== + dependencies: + "@react-aria/progress" "^3.4.15" + "@react-types/meter" "^3.4.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/meter@^3.4.16": + version "3.4.16" + resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.16.tgz#fea02ce06ccef4042702de585bf5b71bf805824d" + integrity sha512-hJqKnEE6mmK2Psx5kcI7NZ44OfTg0Bp7DatQSQ4zZE4yhnykRRwxqSKjze37tPR63cCqgRXtQ5LISfBfG54c0Q== + dependencies: + "@react-aria/progress" "^3.4.16" + "@react-types/meter" "^3.4.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/numberfield@^3.11.5": + version "3.11.5" + resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.11.5.tgz#09582fadda67a908c83175949c0f5ebabbbdc1df" + integrity sha512-cfJzU7SWsksKiLjfubSj5lR18ebQ7IbYaMQZbxdpZSPOANHIiktaxjPK4Nz7cqZ+HZ/6tQEirpY0iqpLx35CSw== + dependencies: + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/spinbutton" "^3.6.7" + "@react-aria/textfield" "^3.14.7" + "@react-aria/utils" "^3.25.1" + "@react-stately/form" "^3.0.5" + "@react-stately/numberfield" "^3.9.5" + "@react-types/button" "^3.9.6" + "@react-types/numberfield" "^3.8.5" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/numberfield@^3.11.6": + version "3.11.6" + resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.11.6.tgz#f96d927adc8c35b6c36965f7adaf7abb3c81284e" + integrity sha512-nvEWiQcWRwj6O2JXmkXEeWoBX/GVZT9zumFJcew3XknGTWJUr3h2AOymIQFt9g4mpag8IgOFEpSIlwhtZHdp1A== + dependencies: + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/spinbutton" "^3.6.8" + "@react-aria/textfield" "^3.14.8" + "@react-aria/utils" "^3.25.2" + "@react-stately/form" "^3.0.5" + "@react-stately/numberfield" "^3.9.6" + "@react-types/button" "^3.9.6" + "@react-types/numberfield" "^3.8.5" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/overlays@^3.23.1": + version "3.23.1" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.23.1.tgz#64214e91251a0c005f93d3c769547cf8f3c8c5dd" + integrity sha512-qNV3pGThvRXjhdHCfqN9Eg4uD+nFm2DoK6d5e9LFd1+xCkKbT88afDBIcLmeG7fgfmukb1sNmzCJQJt8Svk54g== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/ssr" "^3.9.5" + "@react-aria/utils" "^3.25.1" + "@react-aria/visually-hidden" "^3.8.14" + "@react-stately/overlays" "^3.6.9" + "@react-types/button" "^3.9.6" + "@react-types/overlays" "^3.8.9" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/overlays@^3.23.2": + version "3.23.2" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.23.2.tgz#1413b4f7cb9e0d0f7c5b483da9115539fcf5ad5c" + integrity sha512-vjlplr953YAuJfHiP4O+CyrTlr6OaFgXAGrzWq4MVMjnpV/PT5VRJWYFHR0sUGlHTPqeKS4NZbi/xCSgl/3pGQ== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/ssr" "^3.9.5" + "@react-aria/utils" "^3.25.2" + "@react-aria/visually-hidden" "^3.8.15" + "@react-stately/overlays" "^3.6.10" + "@react-types/button" "^3.9.6" + "@react-types/overlays" "^3.8.9" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/progress@^3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.15.tgz#20a1d339a34cfc408c40ad74738a4fa978c8e9f5" + integrity sha512-wlx8pgEet3mlq5Skjy7yV1DfQiEg79tZtojpb5YGN2dIAH8sxClrKOSJRVce0fy9IXVCKrQxjQNXPNUIojK5Rg== + dependencies: + "@react-aria/i18n" "^3.12.1" + "@react-aria/label" "^3.7.10" + "@react-aria/utils" "^3.25.1" + "@react-types/progress" "^3.5.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/progress@^3.4.16": + version "3.4.16" + resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.16.tgz#78296ead8268867a0a7a4077ae94dc2440a010a8" + integrity sha512-RbDIFQg4+/LG+KYZeLAijt2zH7K2Gp0CY9RKWdho3nU5l3/w57Fa7NrfDGWtpImrt7bR2nRmXMA6ESfr7THfrg== + dependencies: + "@react-aria/i18n" "^3.12.2" + "@react-aria/label" "^3.7.11" + "@react-aria/utils" "^3.25.2" + "@react-types/progress" "^3.5.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/radio@^3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.10.6.tgz#e5ded29e604866bde49b536c1e146b2812b3cc38" + integrity sha512-Cr7kiTUWw+HOEdFHztqrFlSXvwuzOCTMbwNkziTyc9fualIX6UDilykND2ctfBgkM4qH7SgQt+SxAIwTdevsKg== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/form" "^3.0.7" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/utils" "^3.25.1" + "@react-stately/radio" "^3.10.6" + "@react-types/radio" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/radio@^3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.10.7.tgz#7c76548b6f08bfce7c48eba910799eb71b4b98c4" + integrity sha512-o2tqIe7xd1y4HeCBQfz/sXIwLJuI6LQbVoCQ1hgk/5dGhQ0LiuXohRYitGRl9zvxW8jYdgLULmOEDt24IflE8A== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/form" "^3.0.8" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/utils" "^3.25.2" + "@react-stately/radio" "^3.10.7" + "@react-types/radio" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/searchfield@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.7.7.tgz#4cfb5497f3192ea4a84653466dd862e1a23e40a7" + integrity sha512-2f087PCR8X5LYyLnvjCIOV27xjjTCkDFPnQaC7XSPCfzDYGM8utCR56JfZMqHnjcMnVNoiEg7EjSBBrh7I2bnQ== + dependencies: + "@react-aria/i18n" "^3.12.1" + "@react-aria/textfield" "^3.14.7" + "@react-aria/utils" "^3.25.1" + "@react-stately/searchfield" "^3.5.5" + "@react-types/button" "^3.9.6" + "@react-types/searchfield" "^3.5.7" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/searchfield@^3.7.8": + version "3.7.8" + resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.7.8.tgz#da263ba56a2a8d41f015ece7933b14e413630bd9" + integrity sha512-SsF5xwH8Us548QgzivvbM7nhFbw7pu23xnRRIuhlP3MwOR3jRUFh17NKxf3Z0jvrDv/u0xfm3JKHIgaUN0KJ2A== + dependencies: + "@react-aria/i18n" "^3.12.2" + "@react-aria/textfield" "^3.14.8" + "@react-aria/utils" "^3.25.2" + "@react-stately/searchfield" "^3.5.6" + "@react-types/button" "^3.9.6" + "@react-types/searchfield" "^3.5.8" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/select@^3.14.7": + version "3.14.7" + resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.14.7.tgz#8019c2b0b81360b17001798cf7db6d8b2c0001e7" + integrity sha512-qZy5oX6P8SGrdv4bHb8iVMIVv+vLuo7UwOJtsQ1FUORIsZmBEz0RyfgYdzlueMcZNoQ9JgLYtrK2e0h6AmJOlg== + dependencies: + "@react-aria/form" "^3.0.7" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/listbox" "^3.13.1" + "@react-aria/menu" "^3.15.1" + "@react-aria/selection" "^3.19.1" + "@react-aria/utils" "^3.25.1" + "@react-aria/visually-hidden" "^3.8.14" + "@react-stately/select" "^3.6.6" + "@react-types/button" "^3.9.6" + "@react-types/select" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/select@^3.14.9": + version "3.14.9" + resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.14.9.tgz#3daca97358e02858e5c5beacbc2e155e5a586caa" + integrity sha512-tiNgMyA2G9nKnFn3pB/lMSgidNToxSFU7r6l4OcG+Vyr63J7B/3dF2lTXq8IYhlfOR3K3uQkjroSx52CmC3NDw== + dependencies: + "@react-aria/form" "^3.0.8" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/listbox" "^3.13.3" + "@react-aria/menu" "^3.15.3" + "@react-aria/selection" "^3.19.3" + "@react-aria/utils" "^3.25.2" + "@react-aria/visually-hidden" "^3.8.15" + "@react-stately/select" "^3.6.7" + "@react-types/button" "^3.9.6" + "@react-types/select" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/selection@^3.19.1": + version "3.19.1" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.19.1.tgz#3fbbac4d3f8dc1711cb6523bef0d9e0c47a514cb" + integrity sha512-mbExvq2Omi60sTWFGjwcNz1ja2P8VDsxWAqSypHRTyqXhtgqbv8V/v8Gp+7BmVPH1YHcbhztl6rvUZTDOSszzw== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/selection" "^3.16.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/selection@^3.19.3": + version "3.19.3" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.19.3.tgz#407fb61af8b0956655baf664457ef293d844b1b8" + integrity sha512-GYoObXCXlmGK08hp7Qfl6Bk0U+bKP5YDWSsX+MzNjJsqzQSLm4S06tRB9ACM7gIo9dDCvL4IRxdSYTJAlJc6bw== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-stately/selection" "^3.16.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/separator@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.4.1.tgz#c8c643f9506b569ba2af7185761588a87ca73949" + integrity sha512-bZ+GQ936Y+WXAtsQjJdEMgYeqmqjhU90+wOlRGjmGdwf+/ht2yzBpeRuHEYUbE6F0iis/YoVc+b8ppAtPna/kA== + dependencies: + "@react-aria/utils" "^3.25.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/separator@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.4.2.tgz#4f9a40bd423bac4f3f4371d6eb050b6d1a944548" + integrity sha512-Xql9Kg3VlGesEUC7QheE+L5b3KgBv0yxiUU+/4JP8V2vfU/XSz4xmprHEeq7KVQVOetn38iiXU8gA5g26SEsUA== + dependencies: + "@react-aria/utils" "^3.25.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/slider@^3.7.10": + version "3.7.10" + resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.10.tgz#09474eb9f6d041bf1651dc663695843b34652061" + integrity sha512-QmBn87sDkncS/uhcrH0MxUN7bcEo8cHYcWk+gk7mibdIpyxyVDPKh7v7ZsosmAJLzjS0yb2ec1/Q5Oldfg1k/A== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/utils" "^3.25.1" + "@react-stately/slider" "^3.5.6" + "@react-types/shared" "^3.24.1" + "@react-types/slider" "^3.7.5" + "@swc/helpers" "^0.5.0" + +"@react-aria/slider@^3.7.11": + version "3.7.11" + resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.11.tgz#43bb0dd1e19218238ee72696514243de000315c1" + integrity sha512-2WAwjANXPsA2LHJ5nxxV4c7ihFAzz2spaBz8+FJ7MDYE7WroYnE8uAXElea1aGo+Lk0DTiAdepLpBkggqPNanw== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/utils" "^3.25.2" + "@react-stately/slider" "^3.5.7" + "@react-types/shared" "^3.24.1" + "@react-types/slider" "^3.7.5" + "@swc/helpers" "^0.5.0" + +"@react-aria/spinbutton@^3.6.7": + version "3.6.7" + resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.6.7.tgz#4c549039542e1215f68c791d5bb2d8be61b10979" + integrity sha512-OCimp4yXoFIgh6WAMOls5DDDRDRO75ZFic3YA6wLWTRNHxo1Lj8S90i1A6pakY6bi4hdBCKmj4DnFSNKAw1iWg== + dependencies: + "@react-aria/i18n" "^3.12.1" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/utils" "^3.25.1" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/spinbutton@^3.6.8": + version "3.6.8" + resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.6.8.tgz#5e44c02543b6669a8aa0b86f932183b7c3d573c5" + integrity sha512-OJMAYRIZ0WrWE+5tZsywrSg4t+aOwl6vl/e1+J64YcGMM+p+AKd61KGG5T0OgNSORXjoVIZOmj6wZ6Od4xfPMw== + dependencies: + "@react-aria/i18n" "^3.12.2" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/utils" "^3.25.2" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/ssr@^3.9.5": + version "3.9.5" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.5.tgz#775d84f51f90934ff51ae74eeba3728daac1a381" + integrity sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-aria/switch@^3.6.6": + version "3.6.6" + resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.6.6.tgz#da1ec971ad877ea9551f15a7d23d990075c62e34" + integrity sha512-+dZOX1utODlx5dC90DtwnXd9nvln9HxMffBj/gmMT1/cD/RmXfjvymfjTsTMwvHhqCew9yfpvod0ZWwj3BkLGw== + dependencies: + "@react-aria/toggle" "^3.10.6" + "@react-stately/toggle" "^3.7.6" + "@react-types/shared" "^3.24.1" + "@react-types/switch" "^3.5.5" + "@swc/helpers" "^0.5.0" + +"@react-aria/switch@^3.6.7": + version "3.6.7" + resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.6.7.tgz#47937f18935f8411fb2d19d7d3cde0a69ecfb05a" + integrity sha512-yBNvKylhc3ZRQ0+7mD0mIenRRe+1yb8YaqMMZr8r3Bf87LaiFtQyhRFziq6ZitcwTJz5LEWjBihxbSVvUrf49w== + dependencies: + "@react-aria/toggle" "^3.10.7" + "@react-stately/toggle" "^3.7.7" + "@react-types/shared" "^3.24.1" + "@react-types/switch" "^3.5.5" + "@swc/helpers" "^0.5.0" + +"@react-aria/table@^3.15.1": + version "3.15.1" + resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.15.1.tgz#908175bf2ad064fd0c7862ff49297b3c036dc920" + integrity sha512-jVDLxp6Y/9M6y45c1I6u6msJ9dBg2I7Cu/FlSaK6HthTpN23UXuGw1oWuAjbfqi31nVXHWBwjCZkGKTdMjLf5A== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/grid" "^3.10.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/utils" "^3.25.1" + "@react-aria/visually-hidden" "^3.8.14" + "@react-stately/collections" "^3.10.9" + "@react-stately/flags" "^3.0.3" + "@react-stately/table" "^3.12.1" + "@react-types/checkbox" "^3.8.3" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@react-types/table" "^3.10.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/table@^3.15.3": + version "3.15.3" + resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.15.3.tgz#665394bb3447a982b5543ad1e1498fcab3e4237a" + integrity sha512-nQCLjlEvyJHyuijHw8ESqnA9fxNJfQHx0WPcl08VDEb8VxcE/MVzSAIedSWaqjG5k9Oflz6o/F/zHtzw4AFAow== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/grid" "^3.10.3" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/live-announcer" "^3.3.4" + "@react-aria/utils" "^3.25.2" + "@react-aria/visually-hidden" "^3.8.15" + "@react-stately/collections" "^3.10.9" + "@react-stately/flags" "^3.0.3" + "@react-stately/table" "^3.12.2" + "@react-types/checkbox" "^3.8.3" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@react-types/table" "^3.10.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/tabs@^3.9.3": + version "3.9.3" + resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.9.3.tgz#77e9216ba93dbd5f1af17dca00a2229de0285766" + integrity sha512-J1KOCdx4eSyMMeNCvO8BIz8E8xez12B+cYbM4BbJzWlcfMboGYUnM0lvI8QSpFPa/H9LkAhp7BJnl9IZeIBzoA== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/selection" "^3.19.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/tabs" "^3.6.8" + "@react-types/shared" "^3.24.1" + "@react-types/tabs" "^3.3.9" + "@swc/helpers" "^0.5.0" + +"@react-aria/tabs@^3.9.5": + version "3.9.5" + resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.9.5.tgz#0c48160c386a9f64b0f8456635a82eec3e012849" + integrity sha512-aQZGAoOIg1B16qlvXIy6+rHbNBNVcWkGjOjeyvqTTPMjXt/FmElkICnqckI7MRJ1lTqzyppCOBitYOHSXRo8Uw== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/i18n" "^3.12.2" + "@react-aria/selection" "^3.19.3" + "@react-aria/utils" "^3.25.2" + "@react-stately/tabs" "^3.6.9" + "@react-types/shared" "^3.24.1" + "@react-types/tabs" "^3.3.9" + "@swc/helpers" "^0.5.0" + +"@react-aria/tag@^3.4.3": + version "3.4.3" + resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.4.3.tgz#7d59f4a863ca7fe75bd6f3e21bb328f4c684627d" + integrity sha512-BqXKazX9YHvt6+qzGTu770V0FqGVefzz03hmnV2IVb+zYchXBv3WYbWVy46s/D5zTePOAXdpitQHxqy5rh+hgw== + dependencies: + "@react-aria/gridlist" "^3.9.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/selection" "^3.19.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/list" "^3.10.7" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/tag@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.4.5.tgz#de39e72f050e9a2e8975a66a72d5d899b09224aa" + integrity sha512-iyJuATQ8t2cdLC7hiZm143eeZze/MtgxaMq0OewlI9TUje54bkw2Q+CjERdgisIo3Eemf55JJgylGrTcalEJAg== + dependencies: + "@react-aria/gridlist" "^3.9.3" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/selection" "^3.19.3" + "@react-aria/utils" "^3.25.2" + "@react-stately/list" "^3.10.8" + "@react-types/button" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/textfield@^3.14.7": + version "3.14.7" + resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.14.7.tgz#368c2da2e0596a1ebadc6d21df5da41f2c619feb" + integrity sha512-1cWCG6vkjlwJuRTXKbKl9P0Q/0Li5pnMafZqDDWfDOlkS5dFGxYG6QFfoaYp7N6XMoNkXiculnCssfrQ+8hWgA== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/form" "^3.0.7" + "@react-aria/label" "^3.7.10" + "@react-aria/utils" "^3.25.1" + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.2" + "@react-types/shared" "^3.24.1" + "@react-types/textfield" "^3.9.5" + "@swc/helpers" "^0.5.0" + +"@react-aria/textfield@^3.14.8": + version "3.14.8" + resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.14.8.tgz#76b8d01f2892022048e42f239e1c43c4b8d6cacc" + integrity sha512-FHEvsHdE1cMR2B7rlf+HIneITrC40r201oLYbHAp3q26jH/HUujzFBB9I20qhXjyBohMWfQLqJhSwhs1VW1RJQ== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/form" "^3.0.8" + "@react-aria/label" "^3.7.11" + "@react-aria/utils" "^3.25.2" + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.3" + "@react-types/shared" "^3.24.1" + "@react-types/textfield" "^3.9.6" + "@swc/helpers" "^0.5.0" + +"@react-aria/toggle@^3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.10.6.tgz#c0afba7bdf5263869b7169d97651b1ba746f84f9" + integrity sha512-AGlbtB1b8grrtjbiW5Au0LKYzxR83RHbHhaUkFwajyYRGyuEzr3Y03OiveoPB+DayA8Gz3H1ZVmW++8JZQOWHw== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/toggle" "^3.7.6" + "@react-types/checkbox" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/toggle@^3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.10.7.tgz#50f7af45e6b875e3ff42e9871db9f065d9910cb7" + integrity sha512-/RJQU8QlPZXRElZ3Tt10F5K5STgUBUGPpfuFUGuwF3Kw3GpPxYsA1YAVjxXz2MMGwS0+y6+U/J1xIs1AF0Jwzg== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-stately/toggle" "^3.7.7" + "@react-types/checkbox" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/tooltip@^3.7.6": + version "3.7.6" + resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.7.6.tgz#1e3a715a2d0a977bd4481d4ae6cc69de16e4f5a3" + integrity sha512-JvRAMTcMju/KBOtISjVKKtIDzG3J1r6xK+mZTvu6ArM7DdeMBM5A8Lwk0bJ8dhr+YybiM9rR3hoZv3/E7IIYVw== + dependencies: + "@react-aria/focus" "^3.18.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-stately/tooltip" "^3.4.11" + "@react-types/shared" "^3.24.1" + "@react-types/tooltip" "^3.4.11" + "@swc/helpers" "^0.5.0" + +"@react-aria/tooltip@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.7.7.tgz#5372c086af55d549461e3cd736beb136fffb5be5" + integrity sha512-UOTTDbbUz7OaE48VjNSWl+XQbYCUs5Gss4I3Tv1pfRLXzVtGYXv3ur/vRayvZR0xd12ANY26fZPNkSmCFpmiXw== + dependencies: + "@react-aria/focus" "^3.18.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-stately/tooltip" "^3.4.12" + "@react-types/shared" "^3.24.1" + "@react-types/tooltip" "^3.4.11" + "@swc/helpers" "^0.5.0" + +"@react-aria/utils@^3.24.1", "@react-aria/utils@^3.25.1": + version "3.25.1" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.25.1.tgz#f6530ce47aa28617924cc6868b4cf1c113a909c5" + integrity sha512-5Uj864e7T5+yj78ZfLnfHqmypLiqW2mN+nsdslog2z5ssunTqjolVeM15ootXskjISlZ7MojLpq97kIC4nlnAw== + dependencies: + "@react-aria/ssr" "^3.9.5" + "@react-stately/utils" "^3.10.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + clsx "^2.0.0" + +"@react-aria/utils@^3.25.2": + version "3.25.2" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.25.2.tgz#2cce329849617b2df6a34f0931abe431f60aaedc" + integrity sha512-GdIvG8GBJJZygB4L2QJP1Gabyn2mjFsha73I2wSe+o4DYeGWoJiMZRM06PyTIxLH4S7Sn7eVDtsSBfkc2VY/NA== + dependencies: + "@react-aria/ssr" "^3.9.5" + "@react-stately/utils" "^3.10.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + clsx "^2.0.0" + +"@react-aria/visually-hidden@^3.8.14": + version "3.8.14" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.14.tgz#ccfff3c5220b833ef811574b70751bac303b29c5" + integrity sha512-DV3yagbAgO4ywQTq6D/AxcIaTC8c77r/SxlIMhQBMQ6vScJWTCh6zFG55wmLe3NKqvRrowv1OstlmYfZQ4v/XA== + dependencies: + "@react-aria/interactions" "^3.22.1" + "@react-aria/utils" "^3.25.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/visually-hidden@^3.8.15": + version "3.8.15" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.15.tgz#8b0317621e1eab3e4188df1a0206f483b95cd8f2" + integrity sha512-l+sJ7xTdD5Sd6+rDNDaeJCSPnHOsI+BaJyApvb/YcVgHa7rB47lp6TXCWUCDItcPY4JqRGyeByRJVrtzBFTWCw== + dependencies: + "@react-aria/interactions" "^3.22.2" + "@react-aria/utils" "^3.25.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/calendar@^3.5.1", "@react-stately/calendar@^3.5.3": + version "3.5.3" + resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.5.3.tgz#7bfbeceac85a273ee71f80312c6c98939623148f" + integrity sha512-SRwsgszyc9FNcvkjqBe81e/tnjKpRqH+yTYpG0uI9NR1HfyddmhR3Y7QilWPcqQkq4SQb7pL68SkTPH2dX2dng== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-stately/utils" "^3.10.2" + "@react-types/calendar" "^3.4.8" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/calendar@^3.5.4": + version "3.5.4" + resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.5.4.tgz#847b2a2e5cf13a81b3344f1ef4e9a0d10138191e" + integrity sha512-R2011mtFSXIjzMXaA+CZ1sflPm9XkTBMqVk77Bnxso2ZsG7FUX8nqFmaDavxwTuHFC6OUexAGSMs8bP9KycTNg== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-stately/utils" "^3.10.3" + "@react-types/calendar" "^3.4.9" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/checkbox@^3.6.7": + version "3.6.7" + resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.6.7.tgz#d622c3cac9c1ad5e09746d354fe82fc37259659f" + integrity sha512-ZOaBNXXazpwkuKj5hk6FtGbXO7HoKEGXvf3p7FcHcIHyiEJ65GBvC7e7HwMc3jYxlBwtbebSpEcf3oFqI5dl3A== + dependencies: + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.2" + "@react-types/checkbox" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/checkbox@^3.6.8": + version "3.6.8" + resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.6.8.tgz#87e43cbf762fce8569e9b0fecd7e6213952e0aac" + integrity sha512-c8TWjU67XHHBCpqj6+FXXhQUWGr2Pil1IKggX81pkedhWiJl3/7+WHJuZI0ivGnRjp3aISNOG8UNVlBEjS9E8A== + dependencies: + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.3" + "@react-types/checkbox" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/collections@^3.10.9": + version "3.10.9" + resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.9.tgz#cdf23d46de30741e2f836b96d439cf095acf4d84" + integrity sha512-plyrng6hOQMG8LrjArMA6ts/DgWyXln3g90/hFNbqe/hdVYF53sDVsj8Jb+5LtoYTpiAlV6eOvy1XR0vPZUf8w== + dependencies: + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/combobox@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.9.1.tgz#2593c050b65c6c90b806fe17d5526b54a21f53bc" + integrity sha512-jmeKUKs0jK18NwDAlpu79ATufgxrc6Sn3ZMmI8KPVQ5sdPTjNlnDx6gTFyOOIa87axf/c6WYU7v3jxmcp+RDdg== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/form" "^3.0.5" + "@react-stately/list" "^3.10.7" + "@react-stately/overlays" "^3.6.9" + "@react-stately/select" "^3.6.6" + "@react-stately/utils" "^3.10.2" + "@react-types/combobox" "^3.12.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/combobox@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.9.2.tgz#18b39ea430ef520959a586053071e9d8146f73d0" + integrity sha512-ZsbAcD58IvxZqwYxg9d2gOf8R/k5RUB2TPUiGKD6wgWfEKH6SDzY3bgRByHGOyMCyJB62cHjih/ZShizNTguqA== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/form" "^3.0.5" + "@react-stately/list" "^3.10.8" + "@react-stately/overlays" "^3.6.10" + "@react-stately/select" "^3.6.7" + "@react-stately/utils" "^3.10.3" + "@react-types/combobox" "^3.12.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/datepicker@^3.10.1", "@react-stately/datepicker@^3.9.4": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.10.1.tgz#f4926f9b881fdb925220b9d78f6a64646f8aa4b5" + integrity sha512-KXr5cxLOLUYBf3wlDSKhvshsKOWpdV2flhS075V6dgC/EPBh7igBZGUXJ9AZzndT7Hx1w8v/ul6CIffxEJz1Nw== + dependencies: + "@internationalized/date" "^3.5.5" + "@internationalized/string" "^3.2.3" + "@react-stately/form" "^3.0.5" + "@react-stately/overlays" "^3.6.9" + "@react-stately/utils" "^3.10.2" + "@react-types/datepicker" "^3.8.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/datepicker@^3.10.2": + version "3.10.2" + resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.10.2.tgz#2023e5cfc71240e8557720f1c3dfbe03207083bf" + integrity sha512-pa5IZUw+49AyOnddwu4XwU2kI5eo/1thbiIVNHP8uDpbbBrBkquSk3zVFDAGX1cu/I1U2VUkt64U/dxgkwaMQw== + dependencies: + "@internationalized/date" "^3.5.5" + "@internationalized/string" "^3.2.3" + "@react-stately/form" "^3.0.5" + "@react-stately/overlays" "^3.6.10" + "@react-stately/utils" "^3.10.3" + "@react-types/datepicker" "^3.8.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/dnd@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.4.1.tgz#a91be9a01d8788970d4be1313a2a556bbb12c96e" + integrity sha512-EXPW1vKx3vNpMaXOpPKTOU1T4S+jqjllGFDyWD659Ql0lL9SQ5Y4IU/KmIK3T3yKkjps9xrMmCjLAkb75PH5zg== + dependencies: + "@react-stately/selection" "^3.16.1" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/dnd@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.4.2.tgz#5fa177a9de019ea6d07cba283a8a7dd76cd2512c" + integrity sha512-VrHmNoNdVGrx5JHdz/zewmN+N8rlZe+vL/iAOLmvQ74RRLEz8KDFnHdlhgKg1AZqaSg3JJ18BlHEkS7oL1n+tA== + dependencies: + "@react-stately/selection" "^3.16.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/flags@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@react-stately/flags/-/flags-3.0.3.tgz#53a58c0140d61575787127a762b7901b4a7fa896" + integrity sha512-/ha7XFA0RZTQsbzSPwu3KkbNMgbvuM0GuMTYLTBWpgBrovBNTM+QqI/PfZTdHg8PwCYF4H5Y8gjdSpdulCvJFw== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-stately/form@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@react-stately/form/-/form-3.0.5.tgz#653f603ddd8b74a8a126b426ebc17abd112b672b" + integrity sha512-J3plwJ63HQz109OdmaTqTA8Qhvl3gcYYK7DtgKyNP6mc/Me2Q4tl2avkWoA+22NRuv5m+J8TpBk4AVHUEOwqeQ== + dependencies: + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/grid@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.9.1.tgz#27b4a35e344891e3cf69ef7a3d7dc56979f117ec" + integrity sha512-LSVIcXO/cqwG0IgDSk2juDbpARBS1IzGnsTp/8vSOejMxq5MXrwxL5hUcqNczL8Ss6aLpELm42tCS0kPm3cMKw== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/selection" "^3.16.1" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/grid@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.9.2.tgz#b880ea037a9d8c7cd4302456acaf294700d41883" + integrity sha512-2gK//sqAqg2Xaq6UITTFQwFUJnBRgcW+cKBVbFt+F8d152xB6UwwTS/K79E5PUkOotwqZgTEpkrSFs/aVxCLpw== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/selection" "^3.16.2" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/list@^3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.7.tgz#cff58ca38103cdb770d3d9809273a77e6606759c" + integrity sha512-W5PG7uG5GQV2Q59vXJE7QLKHZIoUNEx+JmHrBUCMKUgyngSpKIIEDR/R/C1b6ZJ9jMqqZA68Zlnd5iK1/mBi1A== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/selection" "^3.16.1" + "@react-stately/utils" "^3.10.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/list@^3.10.8": + version "3.10.8" + resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.8.tgz#2192708df0ff53345356ba116d8676d4b36ff120" + integrity sha512-rHCiPLXd+Ry3ztR9DkLA5FPQeH4Zd4/oJAEDWJ77W3oBBOdiMp3ZdHDLP7KBRh17XGNLO/QruYoHWAQTPiMF4g== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/selection" "^3.16.2" + "@react-stately/utils" "^3.10.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/menu@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.8.1.tgz#f7c91aae721eb2678673ecb5161e5803fb55ce3a" + integrity sha512-HzAANHg+QUpyRok0CBIL/5qb+4TARteP0q9av2tKnQWPG91iJw84phJDJrmmY55uFFax4fxBgDM9dy1t12iKgQ== + dependencies: + "@react-stately/overlays" "^3.6.9" + "@react-types/menu" "^3.9.11" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/menu@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.8.2.tgz#e7ecd5ea179d38a5d543b8e1fb58e1cde24257a4" + integrity sha512-lt6hIHmSixMzkKx1rKJf3lbAf01EmEvvIlENL20GLiU9cRbpPnPJ1aJMZ5Ad5ygglA7wAemAx+daPhlTQfF2rg== + dependencies: + "@react-stately/overlays" "^3.6.10" + "@react-types/menu" "^3.9.11" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/numberfield@^3.9.5": + version "3.9.5" + resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.9.5.tgz#0a6869ead08c387cc6becefa06fc68353c5dc9b7" + integrity sha512-aWilyzrZOvkgntcXd6Kl+t1QiCbnajUCN8yll6/saByKpfuOf1k6AGYNQBJ0CO/5HyffPPdbFs+45sj4e3cdjA== + dependencies: + "@internationalized/number" "^3.5.3" + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.2" + "@react-types/numberfield" "^3.8.5" + "@swc/helpers" "^0.5.0" + +"@react-stately/numberfield@^3.9.6": + version "3.9.6" + resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.9.6.tgz#4c3a08c34844b44c9b2a8bcb52b8d23ac8846ef3" + integrity sha512-p2R9admGLI439qZzB39dyANhkruprJJtZwuoGVtxW/VD0ficw6BrPVqAaKG25iwKPkmveleh9p8o+yRqjGedcQ== + dependencies: + "@internationalized/number" "^3.5.3" + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.3" + "@react-types/numberfield" "^3.8.5" + "@swc/helpers" "^0.5.0" + +"@react-stately/overlays@^3.6.10": + version "3.6.10" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.10.tgz#949a0cde397b16e2bc7ad9908a181d94f6b72533" + integrity sha512-XxZ2qScT5JPwGk9qiVJE4dtVh3AXTcYwGRA5RsHzC26oyVVsegPqY2PmNJGblAh6Q57VyodoVUyebE0Eo5CzRw== + dependencies: + "@react-stately/utils" "^3.10.3" + "@react-types/overlays" "^3.8.9" + "@swc/helpers" "^0.5.0" + +"@react-stately/overlays@^3.6.9": + version "3.6.9" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.9.tgz#3eaea249e35f424c4354fbee75c7c6767776a877" + integrity sha512-4chfyzKw7P2UEainm0yzjUgYwG1ovBejN88eTrn+O62x5huuMCwe0cbMxmYh4y7IhRFSee3jIJd0SP0u/+i39w== + dependencies: + "@react-stately/utils" "^3.10.2" + "@react-types/overlays" "^3.8.9" + "@swc/helpers" "^0.5.0" + +"@react-stately/radio@^3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.10.6.tgz#2513757b5aa49aed5f0b95d3e3a4460dde2635c5" + integrity sha512-wiJuUUQ6LuEv0J1DQtkC0+Sed7tO6y3sIPeB+5uIxIIsUpxvNlDcqr+JOkrQm7gZmkmvcfotb5Gv5PqaIl1zKA== + dependencies: + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.2" + "@react-types/radio" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/radio@^3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.10.7.tgz#7933619a6c14eaab8fba4834286fb2cfeb8a55d6" + integrity sha512-ZwGzFR+sGd42DxRlDTp3G2vLZyhMVtgHkwv2BxazPHxPMvLO9yYl7+3PPNxAmhMB4tg2u9CrzffpGX2rmEJEXA== + dependencies: + "@react-stately/form" "^3.0.5" + "@react-stately/utils" "^3.10.3" + "@react-types/radio" "^3.8.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/searchfield@^3.5.5": + version "3.5.5" + resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.5.5.tgz#bcd6da5fd077baaa8ba35b5257f370f4ba9168fa" + integrity sha512-rKWIVNbxft5eGGxQ4CtcTKGXm2B1AuYSg6kLRQLq+VYspPNq3wfeMtVBeIdy4LNjWXsTmzs2b3o+zkFYdPqPPw== + dependencies: + "@react-stately/utils" "^3.10.2" + "@react-types/searchfield" "^3.5.7" + "@swc/helpers" "^0.5.0" + +"@react-stately/searchfield@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.5.6.tgz#d6f0bcad74eb1ca444505b9a265c83ea145355ea" + integrity sha512-gVzU0FeWiLYD8VOYRgWlk79Qn7b2eirqOnWhtI5VNuGN8WyNaCIuBp6SkXTW2dY8hs2Hzn8HlMbgy1MIc7130Q== + dependencies: + "@react-stately/utils" "^3.10.3" + "@react-types/searchfield" "^3.5.8" + "@swc/helpers" "^0.5.0" + +"@react-stately/select@^3.6.6": + version "3.6.6" + resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.6.6.tgz#fd01bc8cd47aebcddf07488b52d8250437ebbe1f" + integrity sha512-JEpBosWNSXRexE/iReATei1EiVdTIwOWlLcCGw6K7oC/5/f+OHMsh2Kkt/c/RzM/to3vgR+Wbbqwrb712AWgYQ== + dependencies: + "@react-stately/form" "^3.0.5" + "@react-stately/list" "^3.10.7" + "@react-stately/overlays" "^3.6.9" + "@react-types/select" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/select@^3.6.7": + version "3.6.7" + resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.6.7.tgz#83a6a63d9d11dcbdab32e6b354a5c65743550fd8" + integrity sha512-hCUIddw0mPxVy1OH6jhyaDwgNea9wESjf+MYdnnTG/abRB+OZv/dWScd87OjzVsHTHWcw7CN4ZzlJoXm0FJbKQ== + dependencies: + "@react-stately/form" "^3.0.5" + "@react-stately/list" "^3.10.8" + "@react-stately/overlays" "^3.6.10" + "@react-types/select" "^3.9.6" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/selection@^3.16.1": + version "3.16.1" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.16.1.tgz#00fd65d2abef48067cbb67ad1a7aee8e89bf25c2" + integrity sha512-qmnmYaXY7IhhzmIiInec1a/yPxlPSBHka6vrWddvt0S6zN7FU5cv6sm69ONUwYwLKSoaNHgOGvZhmsTzyV0O2A== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/utils" "^3.10.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/selection@^3.16.2": + version "3.16.2" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.16.2.tgz#9eeb5038ca2f0f1bc688363b3b75a2185d5af060" + integrity sha512-C4eSKw7BIZHJLPzwqGqCnsyFHiUIEyryVQZTJDt6d0wYBOHU6k1pW+Q4VhrZuzSv+IMiI2RkiXeJKc55f0ZXrg== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/utils" "^3.10.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/slider@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.5.6.tgz#691a14e5aace3208c3de14d3ad6e54d32f26519d" + integrity sha512-a7DZgpOVjQyGzMLPiVRCVHISPJX8E3bT+qbZpcRQN+F7T7wReOwUt2I8gQMosnnCGWgU6kdYk8snn0obXe70Fg== + dependencies: + "@react-stately/utils" "^3.10.2" + "@react-types/shared" "^3.24.1" + "@react-types/slider" "^3.7.5" + "@swc/helpers" "^0.5.0" + +"@react-stately/slider@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.5.7.tgz#115b9a28fbe260492aaa233bbc4ff0d7bb824766" + integrity sha512-gEIGTcpBLcXixd8LYiLc8HKrBiGQJltrrEGoOvvTP8KVItXQxmeL+JiSsh8qgOoUdRRpzmAoFNUKGEg2/gtN8A== + dependencies: + "@react-stately/utils" "^3.10.3" + "@react-types/shared" "^3.24.1" + "@react-types/slider" "^3.7.5" + "@swc/helpers" "^0.5.0" + +"@react-stately/table@^3.12.1": + version "3.12.1" + resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.12.1.tgz#fd12c2c43cf9225e0afd8f57583c3a7ff60d79b4" + integrity sha512-Cg3lXrWJNrYkD1gqRclMxq0GGiR+ygxdeAqk2jbbsmHU8RSQuzoO/RtUCw6WAKfQjAq4gE0E60TlAsGgCUdJGA== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/flags" "^3.0.3" + "@react-stately/grid" "^3.9.1" + "@react-stately/selection" "^3.16.1" + "@react-stately/utils" "^3.10.2" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@react-types/table" "^3.10.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/table@^3.12.2": + version "3.12.2" + resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.12.2.tgz#dee76a176d9842f0d250d337a3755a35c37c97d9" + integrity sha512-dUcsrdALylhWz6exqIoqtR/dnrzjIAptMyAUPT378Y/mCYs4PxKkHSvtPEQrZhdQS1ALIIgfeg9KUVIempoXPw== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/flags" "^3.0.3" + "@react-stately/grid" "^3.9.2" + "@react-stately/selection" "^3.16.2" + "@react-stately/utils" "^3.10.3" + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + "@react-types/table" "^3.10.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/tabs@^3.6.8": + version "3.6.8" + resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.8.tgz#c02d8f730d0a9fac9d80075636d62ca37bf3f7b2" + integrity sha512-pLRwnMmXk/IWvbIJYSO5hm3/PiJ/VzrQlwKr6dlOcrDOSVIZpTjnGWHd6mJSDoPiDyBThlN/k3+2pUFMEOAcfw== + dependencies: + "@react-stately/list" "^3.10.7" + "@react-types/shared" "^3.24.1" + "@react-types/tabs" "^3.3.9" + "@swc/helpers" "^0.5.0" + +"@react-stately/tabs@^3.6.9": + version "3.6.9" + resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.9.tgz#54169ec17baa882aed1b28a018b3b9bfb9b9cef6" + integrity sha512-YZDqZng3HrRX+uXmg6u78x73Oi24G5ICpiXVqDKKDkO333XCA5H8MWItiuPZkYB2h3SbaCaLqSobLkvCoWYpNQ== + dependencies: + "@react-stately/list" "^3.10.8" + "@react-types/shared" "^3.24.1" + "@react-types/tabs" "^3.3.9" + "@swc/helpers" "^0.5.0" + +"@react-stately/toggle@^3.7.6": + version "3.7.6" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.7.6.tgz#de31d74b9f9bd73350cf99ba582bc3cd79fa8c74" + integrity sha512-xRZyrjNVu1VCd1xpg5RwmNYs9fXb+JHChoUaRcBmGCCjsPD0R5uR3iNuE17RXJtWS3/8o9IJVn90+/7NW7boOg== + dependencies: + "@react-stately/utils" "^3.10.2" + "@react-types/checkbox" "^3.8.3" + "@swc/helpers" "^0.5.0" + +"@react-stately/toggle@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.7.7.tgz#5ff135b8e8a3d2f85a09d599af6fcfc9ccea22c3" + integrity sha512-AS+xB4+hHWa3wzYkbS6pwBkovPfIE02B9SnuYTe0stKcuejpWKo5L3QMptW0ftFYsW3ZPCXuneImfObEw2T01A== + dependencies: + "@react-stately/utils" "^3.10.3" + "@react-types/checkbox" "^3.8.3" + "@swc/helpers" "^0.5.0" + +"@react-stately/tooltip@^3.4.11": + version "3.4.11" + resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.11.tgz#9fac5c5cd891893b7ea9d7cf2f6f1ee148d0e570" + integrity sha512-r1ScIXau2LZ/lUUBQ5PI01S2TB2urF2zrPzNM2xgngFLlG2uTyfIgMga6/035quQQKd3Bd0qGigMvTgZ3GRGEg== + dependencies: + "@react-stately/overlays" "^3.6.9" + "@react-types/tooltip" "^3.4.11" + "@swc/helpers" "^0.5.0" + +"@react-stately/tooltip@^3.4.12": + version "3.4.12" + resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.12.tgz#a4020fb235ce63d09793299c892cbd8430ebc2ff" + integrity sha512-QKYT/cze7n9qaBsk7o5ais3jRfhYCzcVRfps+iys/W+/9FFbbhjfQG995Lwi6b+vGOHWfXxXpwmyIO2tzM1Iog== + dependencies: + "@react-stately/overlays" "^3.6.10" + "@react-types/tooltip" "^3.4.11" + "@swc/helpers" "^0.5.0" + +"@react-stately/tree@^3.8.3": + version "3.8.3" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.8.3.tgz#c92854f6b10b146f983759243b64cdcba0a1fb28" + integrity sha512-9sRQOxkK7ZMdtSTGHx0sMabHC39PEM4tMl+IdJKkmcp60bfsm3p6LHXhha3E58jwnZaemBfUrlQmTP/E26BbGw== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/selection" "^3.16.1" + "@react-stately/utils" "^3.10.2" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/tree@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.8.4.tgz#8fb6dcfeadd39183d7e776e4001fa2037d579a78" + integrity sha512-HFNclIXJ/3QdGQWxXbj+tdlmIX/XwCfzAMB5m26xpJ6HtJhia6dtx3GLfcdyHNjmuRbAsTBsAAnnVKBmNRUdIQ== + dependencies: + "@react-stately/collections" "^3.10.9" + "@react-stately/selection" "^3.16.2" + "@react-stately/utils" "^3.10.3" + "@react-types/shared" "^3.24.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/utils@^3.10.2": + version "3.10.2" + resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.10.2.tgz#09377f771592ff537c901aa64178cb3a004a916f" + integrity sha512-fh6OTQtbeQC0ywp6LJuuKs6tKIgFvt/DlIZEcIpGho6/oZG229UnIk6TUekwxnDbumuYyan6D9EgUtEMmT8UIg== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-stately/utils@^3.10.3": + version "3.10.3" + resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.10.3.tgz#ed1bf00a8419750fc11ccba73350b97e30f3f707" + integrity sha512-moClv7MlVSHpbYtQIkm0Cx+on8Pgt1XqtPx6fy9rQFb2DNc9u1G3AUVnqA17buOkH1vLxAtX4MedlxMWyRCYYA== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-types/breadcrumbs@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.7.tgz#35c2733e3387fb8800adffa4e412e245db5c5eec" + integrity sha512-ZmhXwD2LLzfEA2OvOCp/QvXu8A/Edsrn5q0qUDGsmOZj9SCVeT82bIv8P+mQnATM13mi2gyoik6102Jc1OscJA== + dependencies: + "@react-types/link" "^3.5.7" + "@react-types/shared" "^3.24.1" + +"@react-types/button@^3.9.6": + version "3.9.6" + resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.6.tgz#135fc465a3026f2c5005725b63cf7c3525be2306" + integrity sha512-8lA+D5JLbNyQikf8M/cPP2cji91aVTcqjrGpDqI7sQnaLFikM8eFR6l1ZWGtZS5MCcbfooko77ha35SYplSQvw== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/calendar@^3.4.8": + version "3.4.8" + resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.8.tgz#e9cc625d286b6a2df17e3d17a2c825b700f01f6c" + integrity sha512-KVampt/X4uJvWU0TsxIdgPdXIAUClGtxcDWHzuFRJ7YUYkA4rH8Lad0kQ1mVehnwOLpuba8j9GCYKorkbln0gw== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-types/shared" "^3.24.1" + +"@react-types/calendar@^3.4.9": + version "3.4.9" + resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.9.tgz#7f2372624996be4c78a431d4ed942acf9eb1da5b" + integrity sha512-O/PS9c21HgO9qzxOyZ7/dTccxabFZdF6tj3UED4DrBw7AN3KZ7JMzwzYbwHinOcO7nUcklGgNoAIHk45UAKR9g== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-types/shared" "^3.24.1" + +"@react-types/checkbox@^3.8.3": + version "3.8.3" + resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.8.3.tgz#331055cf283dfb01c6bbcb02355a20decab19ada" + integrity sha512-f4c1mnLEt0iS1NMkyZXgT3q3AgcxzDk7w6MSONOKydcnh0xG5L2oefY14DhVDLkAuQS7jThlUFwiAs+MxiO3MA== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/combobox@^3.12.1": + version "3.12.1" + resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.12.1.tgz#ab015d31c160aa0a21d696887ce81467c5996602" + integrity sha512-bd5YwHZWtgnJx4jGbplWbYzXj7IbO5w3IY5suNR7r891rx6IktquZ8GQwyYH0pQ/x+X5LdK2xI59i6+QC2PmlA== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/datepicker@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.8.1.tgz#2998a40f19cd5dbfd57ead6b45c748639a276990" + integrity sha512-ZpxHHVT3rmZ4YsYP4TWCZSMSfOUm+067mZyyGLmvHxg55eYmctiB4uMgrRCqDoeiSiOjtxad0VtpPjf6ftK1GQ== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-types/calendar" "^3.4.8" + "@react-types/overlays" "^3.8.9" + "@react-types/shared" "^3.24.1" + +"@react-types/datepicker@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.8.2.tgz#49883bd6885f7d3b32493e957087918d76d85d39" + integrity sha512-Ih4F0bNVGrEuwCD8XmmBAspuuOBsj/Svn/pDFtC2RyAZjXfWh+sI+n4XLz/sYKjvARh5TUI8GNy9smYS4vYXug== + dependencies: + "@internationalized/date" "^3.5.5" + "@react-types/calendar" "^3.4.9" + "@react-types/overlays" "^3.8.9" + "@react-types/shared" "^3.24.1" + +"@react-types/dialog@^3.5.12": + version "3.5.12" + resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.12.tgz#cba173e3a1ca7efd8859bd995389eaa90070e5ea" + integrity sha512-JmpQbSpXltqEyYfEwoqDolABIiojeExkqolHNdQlayIsfFuSxZxNwXZPOpz58Ri/iwv21JP7K3QF0Gb2Ohxl9w== + dependencies: + "@react-types/overlays" "^3.8.9" + "@react-types/shared" "^3.24.1" + +"@react-types/grid@^3.2.8": + version "3.2.8" + resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.8.tgz#1855586e309387edcc6a77bb675a624039e9831a" + integrity sha512-6PJrpukwMqlv3IhJSDkJuVbhHM8Oe6hd2supWqd9adMXrlSP7QHt9a8SgFcFblCCTx8JzUaA0PvY5sTudcEtOQ== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/link@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.7.tgz#298447339a5513a007d31c26cb0fd8ab611da2e1" + integrity sha512-2WyaVmm1qr9UrSG3Dq6iz+2ziuVp+DH8CsYZ9CA6aNNb6U18Hxju3LTPb4a5gM0eC7W0mQGNBmrgGlAdDZEJOw== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/listbox@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.5.1.tgz#e2a95fcb9593b37b5743c96208ea34f82c825752" + integrity sha512-n5bOgD9lgfK1qaLtag9WPnu151SwXBCNn/OgGY/Br9mWRl+nPUEYtFcPX+2VCld7uThf54kwrTmzlFnaraIlcw== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/menu@^3.9.11": + version "3.9.11" + resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.11.tgz#5208ece45f47464bc74f73499fdc14e89679d44f" + integrity sha512-IguQVF70d7aHXgWB1Rd2a/PiIuLZ2Nt7lyayJshLcy/NLOYmgpTmTyn2WCtlA5lTfQwmQrNFf4EvnWkeljJXdA== + dependencies: + "@react-types/overlays" "^3.8.9" + "@react-types/shared" "^3.24.1" + +"@react-types/meter@^3.4.3": + version "3.4.3" + resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.4.3.tgz#de886e64759c8200f2958277a4f73abdf463fc18" + integrity sha512-Y2fX5CTAPGRKxVSeepbeyN6/K+wlF9pMRcNxTSU2qDwdoFqNCtTWMcWuCsU/Y2L/zU0jFWu4x0Vo7WkrcsgcMA== + dependencies: + "@react-types/progress" "^3.5.6" + +"@react-types/numberfield@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.8.5.tgz#de489f8913451e299c3621e8d317e809e20e45af" + integrity sha512-LVWggkxwd1nyVZomXBPfQA1E4I4/i4PBifjcDs2AfcV7q5RE9D+DVIDXsYucVOBxPlDOxiAq/T9ypobspWSwHw== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/overlays@^3.8.9": + version "3.8.9" + resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.9.tgz#3b5ca1f645f0acb1fefd2cf045cac1d9fd8748d5" + integrity sha512-9ni9upQgXPnR+K9cWmbYWvm3ll9gH8P/XsEZprqIV5zNLMF334jADK48h4jafb1X9RFnj0WbHo6BqcSObzjTig== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/progress@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.6.tgz#bc6602e94d2a306a9bfaa118a584b996d95bb015" + integrity sha512-Nh43sjQ5adyN1bTHBPRaIPhXUdBqP0miYeJpeMY3V/KUl4qmouJLwDnccwFG4xLm6gBfYe22lgbbV7nAfNnuTQ== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/radio@^3.8.3": + version "3.8.3" + resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.8.3.tgz#68752dbc5ae3d60a20e285f37ed156d425efd4b6" + integrity sha512-fUVJt4Bb6jOReFqnhHVNxWXH7t6c60uSFfoPKuXt/xI9LL1i2jhpur0ggpTfIn3qLIAmNBU6bKBCWAdr4KjeVQ== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/searchfield@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.7.tgz#f95b5693f09ebb2b4b267a4bc149de2fdc2a1fbd" + integrity sha512-dyuPwNWGswRZfb4i50Q1Q3tCwTBxRLkrAxcMs+Rf2Rl4t93bawBdSdIQuvxu1KEhgd0EXA9ZUW53ZplqfVmtiw== + dependencies: + "@react-types/shared" "^3.24.1" + "@react-types/textfield" "^3.9.5" + +"@react-types/searchfield@^3.5.8": + version "3.5.8" + resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.8.tgz#88b7b0492b7d272fc8a98e8e322c410a48dc7556" + integrity sha512-EcdqalHNIC6BJoRfmqUhAvXRd3aHkWlV1cFCz57JJKgUEFYyXPNrXd1b73TKLzTXEk+X/D6LKV15ILYpEaxu8w== + dependencies: + "@react-types/shared" "^3.24.1" + "@react-types/textfield" "^3.9.6" + +"@react-types/select@^3.9.6": + version "3.9.6" + resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.9.6.tgz#234c94d2dd6f0f52d2dcbda3d3a2f54851507a98" + integrity sha512-cVSFR0eJLup/ht1Uto+y8uyLmHO89J6wNh65SIHb3jeVz9oLBAedP3YNI2qB+F9qFMUcA8PBSLXIIuT6gXzLgQ== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/shared@^3.23.1", "@react-types/shared@^3.24.1": + version "3.24.1" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.24.1.tgz#fa06cb681d144fce9c515d8bd296d81440a45d25" + integrity sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw== + +"@react-types/slider@^3.7.5": + version "3.7.5" + resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.7.5.tgz#62f71c5e51a013fe14ad84d3496a0fa281b5b3a7" + integrity sha512-bRitwQRQjQoOcKEdPMljnvm474dwrmsc6pdsVQDh/qynzr+KO9IHuYc3qPW53WVE2hMQJDohlqtCAWQXWQ5Vcg== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/switch@^3.5.5": + version "3.5.5" + resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.5.5.tgz#e9d37bf5d974f3cc201503b8d46c24105afa48f0" + integrity sha512-SZx1Bd+COhAOs/RTifbZG+uq/llwba7VAKx7XBeX4LeIz1dtguy5bigOBgFTMQi4qsIVCpybSWEEl+daj4XFPw== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/table@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.10.1.tgz#a44e871cd163d6838668ffd6821c604cf5fd307a" + integrity sha512-xsNh0Gm4GtNeSknZqkMsfGvc94fycmfhspGO+FzQKim2hB5k4yILwd+lHYQ2UKW6New9GVH/zN2Pd3v67IeZ2g== + dependencies: + "@react-types/grid" "^3.2.8" + "@react-types/shared" "^3.24.1" + +"@react-types/tabs@^3.3.9": + version "3.3.9" + resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.9.tgz#a23011bf8fe955461ae25339f4de5b91cd7ee5eb" + integrity sha512-3Q9kRVvg/qDyeJR/W1+C2z2OyvDWQrSLvOCvAezX5UKzww4rBEAA8OqBlyDwn7q3fiwrh/m64l6p+dbln+RdxQ== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/textfield@^3.9.5": + version "3.9.5" + resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.9.5.tgz#a9d906ccbe6e5d42f3158320c036e112ae8c61d0" + integrity sha512-0hwZI4WXSEStPzdltKwbNUZWlgHtwbxMWE0LfqIzEW8RB7DyBflYSKzLyTBFqwUZ8j3C1gWy9c9OPSeCOq792Q== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/textfield@^3.9.6": + version "3.9.6" + resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.9.6.tgz#11f5112a85d6a0f1f07470e470810045c5847591" + integrity sha512-0uPqjJh4lYp1aL1HL9IlV8Cgp8eT0PcsNfdoCktfkLytvvBPmox2Pfm57W/d0xTtzZu2CjxhYNTob+JtGAOeXA== + dependencies: + "@react-types/shared" "^3.24.1" + +"@react-types/tooltip@^3.4.11": + version "3.4.11" + resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.11.tgz#6d24fa33d3210400980aa5778f77bea6508588b4" + integrity sha512-WPikHQxeT5Lb09yJEaW6Ja3ecE0g1YM6ukWYS2v/iZLUPn5YlYrGytspuCYQNSh/u7suCz4zRLEHYCl7OCigjw== + dependencies: + "@react-types/overlays" "^3.8.9" + "@react-types/shared" "^3.24.1" + +"@remix-run/router@1.19.0", "@remix-run/router@^1.8.0": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.19.0.tgz#745dbffbce67f05386d57ca22c51dfd85c979593" + integrity sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA== + +"@rollup/rollup-android-arm-eabi@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz#c3f5660f67030c493a981ac1d34ee9dfe1d8ec0f" + integrity sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA== + +"@rollup/rollup-android-arm-eabi@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz#0412834dc423d1ff7be4cb1fc13a86a0cd262c11" + integrity sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg== + +"@rollup/rollup-android-arm64@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz#64161f0b67050023a3859e723570af54a82cff5c" + integrity sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ== + +"@rollup/rollup-android-arm64@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz#baf1a014b13654f3b9e835388df9caf8c35389cb" + integrity sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA== + +"@rollup/rollup-darwin-arm64@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz#25f3d57b1da433097cfebc89341b355901615763" + integrity sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q== + +"@rollup/rollup-darwin-arm64@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz#0a2c364e775acdf1172fe3327662eec7c46e55b1" + integrity sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q== + +"@rollup/rollup-darwin-x64@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz#d8ddaffb636cc2f59222c50316e27771e48966df" + integrity sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ== + +"@rollup/rollup-darwin-x64@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz#a972db75890dfab8df0da228c28993220a468c42" + integrity sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w== + +"@rollup/rollup-linux-arm-gnueabihf@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz#41bd4fcffa20fb84f3dbac6c5071638f46151885" + integrity sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA== + +"@rollup/rollup-linux-arm-gnueabihf@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz#1609d0630ef61109dd19a278353e5176d92e30a1" + integrity sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w== + +"@rollup/rollup-linux-arm-musleabihf@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz#842077c5113a747eb5686f19f2f18c33ecc0acc8" + integrity sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw== + +"@rollup/rollup-linux-arm-musleabihf@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz#3c1dca5f160aa2e79e4b20ff6395eab21804f266" + integrity sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w== + +"@rollup/rollup-linux-arm64-gnu@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz#65d1d5b6778848f55b7823958044bf3e8737e5b7" + integrity sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ== + +"@rollup/rollup-linux-arm64-gnu@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz#c2fe376e8b04eafb52a286668a8df7c761470ac7" + integrity sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw== + +"@rollup/rollup-linux-arm64-musl@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz#50eef7d6e24d0fe3332200bb666cad2be8afcf86" + integrity sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q== + +"@rollup/rollup-linux-arm64-musl@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz#e62a4235f01e0f66dbba587c087ca6db8008ec80" + integrity sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w== + +"@rollup/rollup-linux-powerpc64le-gnu@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz#8837e858f53c84607f05ad0602943e96d104c6b4" + integrity sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz#24b3457e75ee9ae5b1c198bd39eea53222a74e54" + integrity sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ== + +"@rollup/rollup-linux-riscv64-gnu@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz#c894ade2300caa447757ddf45787cca246e816a4" + integrity sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA== + +"@rollup/rollup-linux-riscv64-gnu@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz#38edfba9620fe2ca8116c97e02bd9f2d606bde09" + integrity sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg== + +"@rollup/rollup-linux-s390x-gnu@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz#5841e5390d4c82dd5cdf7b2c95a830e3c2f47dd3" + integrity sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg== + +"@rollup/rollup-linux-s390x-gnu@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz#a3bfb8bc5f1e802f8c76cff4a4be2e9f9ac36a18" + integrity sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ== + +"@rollup/rollup-linux-x64-gnu@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz#cc1f26398bf777807a99226dc13f47eb0f6c720d" + integrity sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew== + +"@rollup/rollup-linux-x64-gnu@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz#0dadf34be9199fcdda44b5985a086326344f30ad" + integrity sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw== + +"@rollup/rollup-linux-x64-musl@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz#1507465d9056e0502a590d4c1a00b4d7b1fda370" + integrity sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg== + +"@rollup/rollup-linux-x64-musl@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz#7b7deddce240400eb87f2406a445061b4fed99a8" + integrity sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg== + +"@rollup/rollup-win32-arm64-msvc@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz#86a221f01a2c248104dd0defb4da119f2a73642e" + integrity sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA== + +"@rollup/rollup-win32-arm64-msvc@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz#a0ca0c5149c2cfb26fab32e6ba3f16996fbdb504" + integrity sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ== + +"@rollup/rollup-win32-ia32-msvc@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz#8bc8f77e02760aa664694b4286d6fbea7f1331c5" + integrity sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A== + +"@rollup/rollup-win32-ia32-msvc@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz#aae2886beec3024203dbb5569db3a137bc385f8e" + integrity sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw== + +"@rollup/rollup-win32-x64-msvc@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz#601fffee719a1e8447f908aca97864eec23b2784" + integrity sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg== + +"@rollup/rollup-win32-x64-msvc@4.21.2": + version "4.21.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz#e4291e3c1bc637083f87936c333cdbcad22af63b" + integrity sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA== + +"@swc/helpers@^0.5.0": + version "0.5.12" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.12.tgz#37aaca95284019eb5d2207101249435659709f4b" + integrity sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g== + dependencies: + tslib "^2.4.0" + +"@tanstack/query-core@5.51.21": + version "5.51.21" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.51.21.tgz#a510469c6c30d3de2a8b8798e340169a4b0fd08f" + integrity sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw== + +"@tanstack/query-devtools@5.51.16": + version "5.51.16" + resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.51.16.tgz#d855d00e7939c1a442c2e8ae3ad1a5bd603d003b" + integrity sha512-ajwuq4WnkNCMj/Hy3KR8d3RtZ6PSKc1dD2vs2T408MdjgKzQ3klVoL6zDgVO7X+5jlb5zfgcO3thh4ojPhfIaw== + +"@tanstack/react-query-devtools@^5.51.23": + version "5.51.23" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.51.23.tgz#2e5428a0ade3b15ec13dd39cb2e833dfa50d580b" + integrity sha512-XpHrdyfUPGULIyJ1K7UvhAcK+KjMJdw4NjmRjryoj3XEgfAU5qU1rz8gIFvGc3gTGT07yIseGo7GEll/ICfJfQ== + dependencies: + "@tanstack/query-devtools" "5.51.16" + +"@tanstack/react-query@^5.51.23": + version "5.51.23" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.51.23.tgz#83c223f4cb6054b206de8856b73ca7e41a63ba1f" + integrity sha512-CfJCfX45nnVIZjQBRYYtvVMIsGgWLKLYC4xcUiYEey671n1alvTZoCBaU9B85O8mF/tx9LPyrI04A6Bs2THv4A== + dependencies: + "@tanstack/query-core" "5.51.21" + +"@tanstack/react-virtual@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.10.6.tgz#f90f97d50a8d83dcd3c3a2d425aadbb55d4837db" + integrity sha512-xaSy6uUxB92O8mngHZ6CvbhGuqxQ5lIZWCBy+FjhrbHmOwc6BnOnKkYm2FsB1/BpKw/+FVctlMbEtI+F6I1aJg== + dependencies: + "@tanstack/virtual-core" "3.10.6" + +"@tanstack/react-virtual@3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.8.2.tgz#0901ac7a8ab0ffe06f15e8317f0f56e1523b6580" + integrity sha512-g78+DA29K0ByAfDkuibfLQqDshf8Aha/zcyEZ+huAX/yS/TWj/CUiEY4IJfDrFacdxIFmsLm0u4VtsLSKTngRw== + dependencies: + "@tanstack/virtual-core" "3.8.2" + +"@tanstack/virtual-core@3.10.6": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.6.tgz#babe3989b2344a5f12fc64129f9bbed5d3402999" + integrity sha512-1giLc4dzgEKLMx5pgKjL6HlG5fjZMgCjzlKAlpr7yoUtetVPELgER1NtephAI910nMwfPTHNyWKSFmJdHkz2Cw== + +"@tanstack/virtual-core@3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.8.2.tgz#e4413c2eb822d80666cfeb8a5354427c7458579f" + integrity sha512-ffpN6kTaPGwQPoWMcBAHbdv2ZCpj1SugldoYAcY0C4xH+Pej1KCOEUisNeEgbUnXOp8Y/4q6wGPu2tFHthOIQw== + +"@types/adm-zip@^0.5.0": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@types/adm-zip/-/adm-zip-0.5.5.tgz#4588042726aa5f351d7ea88232e4a952f60e7c1a" + integrity sha512-YCGstVMjc4LTY5uK9/obvxBya93axZOVOyf2GSUulADzmLhYE45u2nAssCs/fWBs1Ifq5Vat75JTPwd5XZoPJw== + dependencies: + "@types/node" "*" + +"@types/babel__core@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" + integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== + dependencies: + "@babel/types" "^7.20.7" + +"@types/estree@1.0.5", "@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/http-proxy@^1.17.8": + version "1.17.15" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.15.tgz#12118141ce9775a6499ecb4c01d02f90fc839d36" + integrity sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "22.2.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.2.0.tgz#7cf046a99f0ba4d628ad3088cb21f790df9b0c5b" + integrity sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ== + dependencies: + undici-types "~6.13.0" + +"@types/normalize-package-data@^2.4.3": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== + +"@types/prop-types@*": + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + +"@types/react-dom@^18.2.7": + version "18.3.0" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0" + integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^18.2.20": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" + integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/semver@^7.5.0": + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== + +"@types/stylis@4.2.5": + version "4.2.5" + resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.5.tgz#1daa6456f40959d06157698a653a9ab0a70281df" + integrity sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw== + +"@types/trusted-types@^2.0.2": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + +"@types/uuid@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d" + integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== + +"@types/uuid@^9.0.8": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + +"@vitejs/plugin-react@^4.0.4": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz#d0be6594051ded8957df555ff07a991fb618b48e" + integrity sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg== + dependencies: + "@babel/core" "^7.24.5" + "@babel/plugin-transform-react-jsx-self" "^7.24.5" + "@babel/plugin-transform-react-jsx-source" "^7.24.1" + "@types/babel__core" "^7.20.5" + react-refresh "^0.14.2" + +"@vitest/expect@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.0.5.tgz#f3745a6a2c18acbea4d39f5935e913f40d26fa86" + integrity sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA== + dependencies: + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + tinyrainbow "^1.2.0" + +"@vitest/pretty-format@2.0.5", "@vitest/pretty-format@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" + integrity sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/runner@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.0.5.tgz#89197e712bb93513537d6876995a4843392b2a84" + integrity sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig== + dependencies: + "@vitest/utils" "2.0.5" + pathe "^1.1.2" + +"@vitest/snapshot@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.0.5.tgz#a2346bc5013b73c44670c277c430e0334690a162" + integrity sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew== + dependencies: + "@vitest/pretty-format" "2.0.5" + magic-string "^0.30.10" + pathe "^1.1.2" + +"@vitest/spy@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.0.5.tgz#590fc07df84a78b8e9dd976ec2090920084a2b9f" + integrity sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA== + dependencies: + tinyspy "^3.0.0" + +"@vitest/utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.0.5.tgz#6f8307a4b6bc6ceb9270007f73c67c915944e926" + integrity sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ== + dependencies: + "@vitest/pretty-format" "2.0.5" + estree-walker "^3.0.3" + loupe "^3.1.1" + tinyrainbow "^1.2.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +adm-zip@^0.5.10: + version "0.5.15" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.15.tgz#c2c9b3d4f3b1c911e72b2394e84fd91bcc81e08e" + integrity sha512-jYPWSeOA8EFoZnucrKCNihqBjoEGQSU4HKgHYQgKNEQ0pQF9a/DYuo/+fAxY76k4qe75LUlLWpAM1QWcBMTOKw== + +ag-charts-types@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/ag-charts-types/-/ag-charts-types-10.1.0.tgz#f265665f6b92742bb0bc2dcfab319b21e6d78749" + integrity sha512-pk9ft8hbgTXJ/thI/SEUR1BoauNplYExpcHh7tMOqVikoDsta1O15TB1ZL4XWnl4TPIzROBmONKsz7d8a2HBuQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== + +async@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.23.1: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + dependencies: + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cac@^6.7.14: + version "6.7.14" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +camelize@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== + +caniuse-lite@^1.0.30001646: + version "1.0.30001651" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz#52de59529e8b02b1aedcaaf5c05d9e23c0c28138" + integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== + +chai@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.1.tgz#f035d9792a22b481ead1c65908d14bb62ec1c82c" + integrity sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +check-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== + +cli-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" + integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== + dependencies: + restore-cursor "^4.0.0" + +cli-spinners@^2.9.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + +clsx@^1.0.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + +clsx@^2.0.0, clsx@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +commander@^12.0.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== + +compute-scroll-into-view@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz#753f11d972596558d8fe7c6bcbc8497690ab4c87" + integrity sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-color-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== + +css-to-react-native@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32" + integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^4.0.2" + +css-vendor@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" + integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== + dependencies: + "@babel/runtime" "^7.8.3" + is-in-browser "^1.0.2" + +csstype@3.1.3, csstype@^3.0.2, csstype@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +csstype@^2.5.2: + version "2.6.21" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e" + integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w== + +date-fns@^3.2.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf" + integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.5: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== + +deepmerge@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +downshift@9.0.6: + version "9.0.6" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-9.0.6.tgz#a842e59741ac5e789e80be852609a2738b85e85f" + integrity sha512-lkqWh0eb34XuH+3z3/BH/LGVRV7ur0rielSlxtlQKsjAFF/wc/c0wsM9phUGXyzK2g1QWHoNHQyc+vVAheI17Q== + dependencies: + "@babel/runtime" "^7.24.5" + compute-scroll-into-view "^3.1.0" + prop-types "^15.8.1" + react-is "18.2.0" + tslib "^2.6.2" + +downshift@9.0.8: + version "9.0.8" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-9.0.8.tgz#a7fea7c522e31d72ccee7947fa8069ec5e7c30fb" + integrity sha512-59BWD7+hSUQIM1DeNPLirNNnZIO9qMdIK5GQ/Uo8q34gT4B78RBlb9dhzgnh0HfQTJj4T/JKYD8KoLAlMWnTsA== + dependencies: + "@babel/runtime" "^7.24.5" + compute-scroll-into-view "^3.1.0" + prop-types "^15.8.1" + react-is "18.2.0" + tslib "^2.6.2" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.5.4: + version "1.5.6" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.6.tgz#c81d9938b5a877314ad370feb73b4e5409b36abd" + integrity sha512-jwXWsM5RPf6j9dPYzaorcBSUg6AiqocPEyMpkchkvntaH9HGfOOMZwxMJjDY/XEs3T5dM7uyH1VhRMkqUU9qVw== + +emoji-regex@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.3.0.tgz#76998b9268409eb3dae3de989254d456e70cfe23" + integrity sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + +express-rate-limit@^7.0.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-7.4.0.tgz#5db412b8de83fa07ddb40f610c585ac8c1dab988" + integrity sha512-v1204w3cXu5gCDmAvgvzI6qjzZzoMWKnyVDk3ACgfswTQLYiGen+r8w0VnXnGMmzEN/g8fwIQ4JrFFd4ZP6ssg== + +express@^4.18.2: + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up-simple@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-up-simple/-/find-up-simple-1.0.0.tgz#21d035fde9fdbd56c8f4d2f63f32fd93a1cfc368" + integrity sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw== + +find-up@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-7.0.0.tgz#e8dec1455f74f78d888ad65bf7ca13dd2b4e66fb" + integrity sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g== + dependencies: + locate-path "^7.2.0" + path-exists "^5.0.0" + unicorn-magic "^0.1.0" + +follow-redirects@^1.0.0: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-east-asian-width@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e" + integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA== + +get-func-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globrex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" + integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hosted-git-info@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.2.tgz#9b751acac097757667f30114607ef7b661ff4f17" + integrity sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w== + dependencies: + lru-cache "^10.0.1" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy-middleware@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + +hyphenate-style-name@^1.0.3: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz#1797bf50369588b47b72ca6d5e65374607cf4436" + integrity sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +immer@^9.0.16: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + +index-to-position@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/index-to-position/-/index-to-position-0.1.2.tgz#e11bfe995ca4d8eddb1ec43274488f3c201a7f09" + integrity sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g== + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +intl-messageformat@^10.1.0: + version "10.5.14" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.14.tgz#e5bb373f8a37b88fbe647d7b941f3ab2a37ed00a" + integrity sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w== + dependencies: + "@formatjs/ecma402-abstract" "2.0.0" + "@formatjs/fast-memoize" "2.2.0" + "@formatjs/icu-messageformat-parser" "2.7.8" + tslib "^2.4.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-in-browser@^1.0.2, is-in-browser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" + integrity sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== + +is-interactive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" + integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== + +is-mergeable-object@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-mergeable-object/-/is-mergeable-object-1.1.1.tgz#faaa3ed1cfce87d6f7d2f5885e92cc30af3e2ebf" + integrity sha512-CPduJfuGg8h8vW74WOxHtHmtQutyQBzR+3MjQ6iDHIYdbOnm1YC7jv43SqCoU8OPGTJD4nibmiryA4kmogbGrA== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-unicode-supported@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" + integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== + +is-unicode-supported@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz#fdf32df9ae98ff6ab2cedc155a5a6e895701c451" + integrity sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jss-plugin-camel-case@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz#27ea159bab67eb4837fa0260204eb7925d4daa1c" + integrity sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw== + dependencies: + "@babel/runtime" "^7.3.1" + hyphenate-style-name "^1.0.3" + jss "10.10.0" + +jss-plugin-default-unit@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz#db3925cf6a07f8e1dd459549d9c8aadff9804293" + integrity sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + +jss-plugin-global@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz#1c55d3c35821fab67a538a38918292fc9c567efd" + integrity sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + +jss-plugin-nested@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz#db872ed8925688806e77f1fc87f6e62264513219" + integrity sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + tiny-warning "^1.0.2" + +jss-plugin-props-sort@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz#67f4dd4c70830c126f4ec49b4b37ccddb680a5d7" + integrity sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + +jss-plugin-rule-value-function@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz#7d99e3229e78a3712f78ba50ab342e881d26a24b" + integrity sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + tiny-warning "^1.0.2" + +jss-plugin-vendor-prefixer@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz#c01428ef5a89f2b128ec0af87a314d0c767931c7" + integrity sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg== + dependencies: + "@babel/runtime" "^7.3.1" + css-vendor "^2.0.8" + jss "10.10.0" + +jss@10.10.0, jss@^10.5.1: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss/-/jss-10.10.0.tgz#a75cc85b0108c7ac8c7b7d296c520a3e4fbc6ccc" + integrity sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw== + dependencies: + "@babel/runtime" "^7.3.1" + csstype "^3.0.2" + is-in-browser "^1.1.3" + tiny-warning "^1.0.2" + +lit-element@^3.3.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.3.3.tgz#10bc19702b96ef5416cf7a70177255bfb17b3209" + integrity sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.1.0" + "@lit/reactive-element" "^1.3.0" + lit-html "^2.8.0" + +lit-element@^4.0.0, lit-element@^4.0.4, lit-element@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-4.1.0.tgz#cea3eb25f15091e3fade07c4d917fa6aaf56ba7d" + integrity sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.2.0" + "@lit/reactive-element" "^2.0.4" + lit-html "^3.2.0" + +lit-html@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.8.0.tgz#96456a4bb4ee717b9a7d2f94562a16509d39bffa" + integrity sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q== + dependencies: + "@types/trusted-types" "^2.0.2" + +lit-html@^3.0.0, lit-html@^3.1.2, lit-html@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-3.2.0.tgz#cb09071a8a1f5f0850873f9143f18f0260be1fda" + integrity sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA== + dependencies: + "@types/trusted-types" "^2.0.2" + +lit@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lit/-/lit-3.0.2.tgz#e22e90c2cbcc3f37bf3c2558df66f3af4331c9cf" + integrity sha512-ZoVUPGgXOQocP4OvxehEOBmC4rWB4cRYDPaz7aFmH8DFytsCi/NeACbr4C6vNPGDEC07BrhUos7uVNayDKLQ2Q== + dependencies: + "@lit/reactive-element" "^2.0.0" + lit-element "^4.0.0" + lit-html "^3.0.0" + +lit@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lit/-/lit-3.1.2.tgz#f276258e8a56593f1d834a5fd00a7eb5e891ae73" + integrity sha512-VZx5iAyMtX7CV4K8iTLdCkMaYZ7ipjJZ0JcSdJ0zIdGxxyurjIn7yuuSxNBD7QmjvcNJwr0JS4cAdAtsy7gZ6w== + dependencies: + "@lit/reactive-element" "^2.0.4" + lit-element "^4.0.4" + lit-html "^3.1.2" + +lit@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lit/-/lit-3.2.0.tgz#2189d72bccbc335f733a67bfbbd295f015e68e05" + integrity sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw== + dependencies: + "@lit/reactive-element" "^2.0.4" + lit-element "^4.1.0" + lit-html "^3.2.0" + +lit@^2.0.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit/-/lit-2.8.0.tgz#4d838ae03059bf9cafa06e5c61d8acc0081e974e" + integrity sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA== + dependencies: + "@lit/reactive-element" "^1.6.0" + lit-element "^3.3.0" + lit-html "^2.8.0" + +locate-path@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + +lodash@^4.17.14: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-6.0.0.tgz#bb95e5f05322651cac30c0feb6404f9f2a8a9439" + integrity sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw== + dependencies: + chalk "^5.3.0" + is-unicode-supported "^1.3.0" + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loupe@^3.1.0, loupe@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.1.tgz#71d038d59007d890e3247c5db97c1ec5a92edc54" + integrity sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw== + dependencies: + get-func-name "^2.0.1" + +lru-cache@^10.0.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +magic-string@^0.30.10: + version "0.30.11" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954" + integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2, micromatch@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + +normalize-package-data@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.2.tgz#a7bc22167fe24025412bcff0a9651eb768b03506" + integrity sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g== + dependencies: + hosted-git-info "^7.0.0" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + +npm-run-path@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== + dependencies: + path-key "^4.0.0" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + +odata-query@^7.0.4: + version "7.0.6" + resolved "https://registry.yarnpkg.com/odata-query/-/odata-query-7.0.6.tgz#10f4ba102d05e5bbb469aaee25096c66ef039351" + integrity sha512-xwUxFikiVt8mO9LlOzLj7fZ/7ljDTkxN6FxPnEin8/KW3SaVdfOnYuwDphZ6tbwOyc5Lzp5QGhu8FYpLK5vLQA== + dependencies: + tslib "^2.4.0" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +ora@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-8.0.1.tgz#6dcb9250a629642cbe0d2df3a6331ad6f7a2af3e" + integrity sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ== + dependencies: + chalk "^5.3.0" + cli-cursor "^4.0.0" + cli-spinners "^2.9.2" + is-interactive "^2.0.0" + is-unicode-supported "^2.0.0" + log-symbols "^6.0.0" + stdin-discarder "^0.2.1" + string-width "^7.0.0" + strip-ansi "^7.1.0" + +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + +parse-json@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-8.1.0.tgz#91cdc7728004e955af9cb734de5684733b24a717" + integrity sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA== + dependencies: + "@babel/code-frame" "^7.22.13" + index-to-position "^0.1.2" + type-fest "^4.7.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + +picocolors@^1.0.0, picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +portfinder@^1.0.32: + version "1.0.32" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" + integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== + dependencies: + async "^2.6.4" + debug "^3.2.7" + mkdirp "^0.5.6" + +postcss-value-parser@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@8.4.38: + version "8.4.38" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + +postcss@^8.4.40: + version "8.4.41" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" + integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + +postcss@^8.4.43: + version "8.4.45" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.45.tgz#538d13d89a16ef71edbf75d895284ae06b79e603" + integrity sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + +pretty-bytes@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz#38cd6bb46f47afbf667c202cfc754bffd2016a3b" + integrity sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ== + +prop-types@^15.7.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +re-resizable@^6.9.11: + version "6.9.17" + resolved "https://registry.yarnpkg.com/re-resizable/-/re-resizable-6.9.17.tgz#78e4349934ff24a8fcb4b6b5a43ff9ed5f319d2a" + integrity sha512-OBqd1BwVXpEJJn/yYROG+CbeqIDBWIp6wathlpB0kzZWWZIY1gPTsgK2yJEui5hOvkCdC2mcexF2V3DZVfLq2g== + +react-aria@^3.33.1: + version "3.34.1" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.34.1.tgz#a4cfa4abdd2882196fbadbded6ef87b02a1790f7" + integrity sha512-vA4BP+SWjFFRfOTQcNJtIp9gKlxuC7kPUXQK9fuNA+2K4mJdIc9mBnmwXQiLl/eAthMf43fD4fETfY9SiCm1Zg== + dependencies: + "@internationalized/string" "^3.2.3" + "@react-aria/breadcrumbs" "^3.5.15" + "@react-aria/button" "^3.9.7" + "@react-aria/calendar" "^3.5.10" + "@react-aria/checkbox" "^3.14.5" + "@react-aria/combobox" "^3.10.1" + "@react-aria/datepicker" "^3.11.1" + "@react-aria/dialog" "^3.5.16" + "@react-aria/dnd" "^3.7.1" + "@react-aria/focus" "^3.18.1" + "@react-aria/gridlist" "^3.9.1" + "@react-aria/i18n" "^3.12.1" + "@react-aria/interactions" "^3.22.1" + "@react-aria/label" "^3.7.10" + "@react-aria/link" "^3.7.3" + "@react-aria/listbox" "^3.13.1" + "@react-aria/menu" "^3.15.1" + "@react-aria/meter" "^3.4.15" + "@react-aria/numberfield" "^3.11.5" + "@react-aria/overlays" "^3.23.1" + "@react-aria/progress" "^3.4.15" + "@react-aria/radio" "^3.10.6" + "@react-aria/searchfield" "^3.7.7" + "@react-aria/select" "^3.14.7" + "@react-aria/selection" "^3.19.1" + "@react-aria/separator" "^3.4.1" + "@react-aria/slider" "^3.7.10" + "@react-aria/ssr" "^3.9.5" + "@react-aria/switch" "^3.6.6" + "@react-aria/table" "^3.15.1" + "@react-aria/tabs" "^3.9.3" + "@react-aria/tag" "^3.4.3" + "@react-aria/textfield" "^3.14.7" + "@react-aria/tooltip" "^3.7.6" + "@react-aria/utils" "^3.25.1" + "@react-aria/visually-hidden" "^3.8.14" + "@react-types/shared" "^3.24.1" + +react-aria@^3.34.1: + version "3.34.3" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.34.3.tgz#4477aa8843beec1d3cf0853214753fcc47299662" + integrity sha512-wSprEI5EojDFCm357MxnKAxJZN68OYIt6UH6N0KCo6MEUAVZMbhMSmGYjw/kLK4rI7KrbJDqGqUMQkwc93W9Ng== + dependencies: + "@internationalized/string" "^3.2.3" + "@react-aria/breadcrumbs" "^3.5.16" + "@react-aria/button" "^3.9.8" + "@react-aria/calendar" "^3.5.11" + "@react-aria/checkbox" "^3.14.6" + "@react-aria/combobox" "^3.10.3" + "@react-aria/datepicker" "^3.11.2" + "@react-aria/dialog" "^3.5.17" + "@react-aria/dnd" "^3.7.2" + "@react-aria/focus" "^3.18.2" + "@react-aria/gridlist" "^3.9.3" + "@react-aria/i18n" "^3.12.2" + "@react-aria/interactions" "^3.22.2" + "@react-aria/label" "^3.7.11" + "@react-aria/link" "^3.7.4" + "@react-aria/listbox" "^3.13.3" + "@react-aria/menu" "^3.15.3" + "@react-aria/meter" "^3.4.16" + "@react-aria/numberfield" "^3.11.6" + "@react-aria/overlays" "^3.23.2" + "@react-aria/progress" "^3.4.16" + "@react-aria/radio" "^3.10.7" + "@react-aria/searchfield" "^3.7.8" + "@react-aria/select" "^3.14.9" + "@react-aria/selection" "^3.19.3" + "@react-aria/separator" "^3.4.2" + "@react-aria/slider" "^3.7.11" + "@react-aria/ssr" "^3.9.5" + "@react-aria/switch" "^3.6.7" + "@react-aria/table" "^3.15.3" + "@react-aria/tabs" "^3.9.5" + "@react-aria/tag" "^3.4.5" + "@react-aria/textfield" "^3.14.8" + "@react-aria/tooltip" "^3.7.7" + "@react-aria/utils" "^3.25.2" + "@react-aria/visually-hidden" "^3.8.15" + "@react-types/shared" "^3.24.1" + +"react-dom@>= 18", react-dom@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react-hook-form@^7.52.2: + version "7.52.2" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.52.2.tgz#ff40f4776250b86ddfcde6be68d34aa82b1c60fe" + integrity sha512-pqfPEbERnxxiNMPd0bzmt1tuaPcVccywFDpyk2uV5xCIBphHV5T8SVnX9/o3kplPE1zzKt77+YIoq+EMwJp56A== + +react-is@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +"react-is@^16.8.0 || ^17.0.0": + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-is@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +react-keyed-flatten-children@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-keyed-flatten-children/-/react-keyed-flatten-children-3.0.0.tgz#b6ad0bde437d3ab86c8af3a1902d164be2a29d67" + integrity sha512-tSH6gvOyQjt3qtjG+kU9sTypclL1672yjpVufcE3aHNM0FhvjBUQZqsb/awIux4zEuVC3k/DP4p0GdTT/QUt/Q== + dependencies: + react-is "^18.2.0" + +react-refresh@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== + +react-router-dom@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.26.0.tgz#8debe13295c58605c04f93018d659a763245e58c" + integrity sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ== + dependencies: + "@remix-run/router" "1.19.0" + react-router "6.26.0" + +react-router@6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.26.0.tgz#d5af4c46835b202348ef2b7ddacd32a2db539fde" + integrity sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg== + dependencies: + "@remix-run/router" "1.19.0" + +"react@>= 18", react@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +read-package-up@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/read-package-up/-/read-package-up-11.0.0.tgz#71fb879fdaac0e16891e6e666df22de24a48d5ba" + integrity sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ== + dependencies: + find-up-simple "^1.0.0" + read-pkg "^9.0.0" + type-fest "^4.6.0" + +read-pkg@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-9.0.1.tgz#b1b81fb15104f5dbb121b6bbdee9bbc9739f569b" + integrity sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA== + dependencies: + "@types/normalize-package-data" "^2.4.3" + normalize-package-data "^6.0.0" + parse-json "^8.0.0" + type-fest "^4.6.0" + unicorn-magic "^0.1.0" + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +restore-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" + integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +rollup@^4.13.0: + version "4.20.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.20.0.tgz#f9d602161d29e178f0bf1d9f35f0a26f83939492" + integrity sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.20.0" + "@rollup/rollup-android-arm64" "4.20.0" + "@rollup/rollup-darwin-arm64" "4.20.0" + "@rollup/rollup-darwin-x64" "4.20.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.20.0" + "@rollup/rollup-linux-arm-musleabihf" "4.20.0" + "@rollup/rollup-linux-arm64-gnu" "4.20.0" + "@rollup/rollup-linux-arm64-musl" "4.20.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.20.0" + "@rollup/rollup-linux-riscv64-gnu" "4.20.0" + "@rollup/rollup-linux-s390x-gnu" "4.20.0" + "@rollup/rollup-linux-x64-gnu" "4.20.0" + "@rollup/rollup-linux-x64-musl" "4.20.0" + "@rollup/rollup-win32-arm64-msvc" "4.20.0" + "@rollup/rollup-win32-ia32-msvc" "4.20.0" + "@rollup/rollup-win32-x64-msvc" "4.20.0" + fsevents "~2.3.2" + +rollup@^4.20.0: + version "4.21.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.21.2.tgz#f41f277a448d6264e923dd1ea179f0a926aaf9b7" + integrity sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.21.2" + "@rollup/rollup-android-arm64" "4.21.2" + "@rollup/rollup-darwin-arm64" "4.21.2" + "@rollup/rollup-darwin-x64" "4.21.2" + "@rollup/rollup-linux-arm-gnueabihf" "4.21.2" + "@rollup/rollup-linux-arm-musleabihf" "4.21.2" + "@rollup/rollup-linux-arm64-gnu" "4.21.2" + "@rollup/rollup-linux-arm64-musl" "4.21.2" + "@rollup/rollup-linux-powerpc64le-gnu" "4.21.2" + "@rollup/rollup-linux-riscv64-gnu" "4.21.2" + "@rollup/rollup-linux-s390x-gnu" "4.21.2" + "@rollup/rollup-linux-x64-gnu" "4.21.2" + "@rollup/rollup-linux-x64-musl" "4.21.2" + "@rollup/rollup-win32-arm64-msvc" "4.21.2" + "@rollup/rollup-win32-ia32-msvc" "4.21.2" + "@rollup/rollup-win32-x64-msvc" "4.21.2" + fsevents "~2.3.2" + +rxjs@^7.8.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.5, semver@^7.5.4: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallowequal@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +siginfo@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" + integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== + +signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.18" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz#22aa922dcf2f2885a6494a261f2d8b75345d0326" + integrity sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ== + +stackback@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" + integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +std-env@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" + integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== + +stdin-discarder@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stdin-discarder/-/stdin-discarder-0.2.2.tgz#390037f44c4ae1a1ae535c5fe38dc3aba8d997be" + integrity sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ== + +string-width@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" + integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== + dependencies: + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" + +strip-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +styled-components@^6.1.1: + version "6.1.12" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.12.tgz#0d9d511aacfb9052936146dcc2856559e6fae4df" + integrity sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA== + dependencies: + "@emotion/is-prop-valid" "1.2.2" + "@emotion/unitless" "0.8.1" + "@types/stylis" "4.2.5" + css-to-react-native "3.2.0" + csstype "3.1.3" + postcss "8.4.38" + shallowequal "1.1.0" + stylis "4.3.2" + tslib "2.6.2" + +stylis@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.2.tgz#8f76b70777dd53eb669c6f58c997bf0a9972e444" + integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tabbable@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" + integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== + +tiny-warning@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +tinybench@^2.8.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" + integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== + +tinypool@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.0.tgz#a68965218e04f4ad9de037d2a1cd63cda9afb238" + integrity sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ== + +tinyrainbow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" + integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== + +tinyspy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.0.tgz#cb61644f2713cd84dee184863f4642e06ddf0585" + integrity sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tsconfck@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.1.tgz#c7284913262c293b43b905b8b034f524de4a3162" + integrity sha512-00eoI6WY57SvZEVjm13stEVE90VkEdJAFGgpFLTsZbJyW/LwFQ7uQxJHWpZ2hzSWgCPKc9AnBnNP+0X7o3hAmQ== + +tslib@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + +type-fest@^4.6.0, type-fest@^4.7.1: + version "4.24.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.24.0.tgz#28d18f2d2afb020e46f6d1236e944d7aa4f92dde" + integrity sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@^5.1.3: + version "5.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== + +undici-types@~6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5" + integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== + +unicorn-magic@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4" + integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" + integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== + +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +uuidv7@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uuidv7/-/uuidv7-1.0.1.tgz#43c8d4329a2a1b403c8815c03f4770e531ae0151" + integrity sha512-2noB909GbI352dKfASOY6VHHl59KvevZ1FF8gCAXCwDyrt2kkZhuFbczF9udqTfeejiRYEmO4wzUZ0WhVP+IUA== + +validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +vite-node@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.0.5.tgz#36d909188fc6e3aba3da5fc095b3637d0d18e27b" + integrity sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q== + dependencies: + cac "^6.7.14" + debug "^4.3.5" + pathe "^1.1.2" + tinyrainbow "^1.2.0" + vite "^5.0.0" + +vite-plugin-environment@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/vite-plugin-environment/-/vite-plugin-environment-1.1.3.tgz#d01a04abb2f69730a4866c9c9db51d3dab74645b" + integrity sha512-9LBhB0lx+2lXVBEWxFZC+WO7PKEyE/ykJ7EPWCq95NEcCpblxamTbs5Dm3DLBGzwODpJMEnzQywJU8fw6XGGGA== + +vite-plugin-restart@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/vite-plugin-restart/-/vite-plugin-restart-0.4.1.tgz#c015447987beec52db4317372f513b949743dcbd" + integrity sha512-MYhDFaa2HMoSavr/2pShj6toKVFso+zqF6FAdWGC8JSIrsNig+4giy9EzoSySgGRJvsnbwZXKdjAvn8ag8rUkA== + dependencies: + micromatch "^4.0.7" + +vite-tsconfig-paths@^4.2.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz#321f02e4b736a90ff62f9086467faf4e2da857a9" + integrity sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA== + dependencies: + debug "^4.1.1" + globrex "^0.1.2" + tsconfck "^3.0.3" + +vite@^5.0.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.0.tgz#11dca8a961369ba8b5cae42d068c7ad684d5370f" + integrity sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.40" + rollup "^4.13.0" + optionalDependencies: + fsevents "~2.3.3" + +vite@^5.4.3: + version "5.4.3" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.3.tgz#771c470e808cb6732f204e1ee96c2ed65b97a0eb" + integrity sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" + optionalDependencies: + fsevents "~2.3.3" + +vitest@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.0.5.tgz#2f15a532704a7181528e399cc5b754c7f335fd62" + integrity sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@vitest/expect" "2.0.5" + "@vitest/pretty-format" "^2.0.5" + "@vitest/runner" "2.0.5" + "@vitest/snapshot" "2.0.5" + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + debug "^4.3.5" + execa "^8.0.1" + magic-string "^0.30.10" + pathe "^1.1.2" + std-env "^3.7.0" + tinybench "^2.8.0" + tinypool "^1.0.0" + tinyrainbow "^1.2.0" + vite "^5.0.0" + vite-node "2.0.5" + why-is-node-running "^2.3.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +why-is-node-running@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04" + integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w== + dependencies: + siginfo "^2.0.0" + stackback "0.0.2" + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yocto-queue@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" + integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== + +zod@^3.23.8: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== diff --git a/client/lerna.json b/client/lerna.json index 0f7bc4ffc..e7e8edc79 100644 --- a/client/lerna.json +++ b/client/lerna.json @@ -2,7 +2,8 @@ "$schema": "node_modules/lerna/schemas/lerna-schema.json", "npmClient": "yarn", "packages": [ - "packages/**" + "packages/**", + "apps/**" ], "version": "7.1.1" -} \ No newline at end of file +} diff --git a/client/package.json b/client/package.json index 0b6e57613..e78b385b4 100644 --- a/client/package.json +++ b/client/package.json @@ -105,4 +105,4 @@ "workspaces": [ "packages/**" ] -} +} \ No newline at end of file diff --git a/client/packages/core/src/app/hooks/use-app-loader.ts b/client/packages/core/src/app/hooks/use-app-loader.ts index 36aef15f9..9bba2ad27 100644 --- a/client/packages/core/src/app/hooks/use-app-loader.ts +++ b/client/packages/core/src/app/hooks/use-app-loader.ts @@ -28,7 +28,9 @@ export const useAppLoader = (appKey: string) => { appRef.current = createAppElement(); // Generate basename for application regex extracts /apps/:appKey - const [basename] = window.location.pathname.match(/\/?apps\/[a-z|-]+\//g) ?? ['']; + const [basename] = window.location.pathname.match(/\/?apps\/[a-z|-]+\//g) ?? [ + window.location.pathname, + ]; try { //Casting to se if manifest is for fusion legacy application diff --git a/client/packages/core/src/modules/portal-config/configurator.ts b/client/packages/core/src/modules/portal-config/configurator.ts index 038c924f4..fa4951035 100644 --- a/client/packages/core/src/modules/portal-config/configurator.ts +++ b/client/packages/core/src/modules/portal-config/configurator.ts @@ -30,19 +30,19 @@ export const createDefaultClient = (httpClient: IHttpClient): IClient => { export class PortalConfigConfigurator extends BaseConfigBuilder { public setConfig(config: { portalId: string; portalEnv: string }) { - this._set('base', () => config); + this._set('base', async () => config); } public setClient(client: IClient) { - this._set('client', () => client); + this._set('client', async () => client); } public setRoutes(client: PortalRoutes) { - this._set('portalConfig.routes', () => client); + this._set('portalConfig.routes', async () => client); } public setPortalConfig(config: PortalState) { - this._set('portalConfig', () => config); + this._set('portalConfig', async () => config); } /** diff --git a/client/packages/portal-client/src/components/portal-router/PortalRouter.tsx b/client/packages/portal-client/src/components/portal-router/PortalRouter.tsx index 847dd5812..79b33eb7f 100644 --- a/client/packages/portal-client/src/components/portal-router/PortalRouter.tsx +++ b/client/packages/portal-client/src/components/portal-router/PortalRouter.tsx @@ -42,6 +42,7 @@ const routes = (portalRoutes: PortalRoutes | undefined): RouteObject[] => { element: , errorElement: , }, + ...pages, { path: '/apps/:appKey', element: , @@ -54,7 +55,6 @@ const routes = (portalRoutes: PortalRoutes | undefined): RouteObject[] => { ], errorElement: , }, - ...pages, { path: `/aka/*`, element: , diff --git a/client/packages/portal-client/src/lib/portal-framework-config.tsx b/client/packages/portal-client/src/lib/portal-framework-config.tsx index c0dfdeb36..fa054eaeb 100644 --- a/client/packages/portal-client/src/lib/portal-framework-config.tsx +++ b/client/packages/portal-client/src/lib/portal-framework-config.tsx @@ -81,6 +81,22 @@ export function createPortalFramework(portalConfig: PortalConfig) { }, ], }, + { + path: 'admin/*', + pageKey: 'portal-administration', + messages: { + errorMessage: 'Fail to load portal administration page', + }, + children: [ + { + messages: { + errorMessage: 'Fail to load portal administration page', + }, + path: ':portalId', + pageKey: 'portal-administration', + }, + ], + }, ], }); }); @@ -135,7 +151,7 @@ export function createPortalFramework(portalConfig: PortalConfig) { enableFeatureFlagging(config, (builder) => { builder.addPlugin( - createLocalStoragePlugin([ + createLocalStoragePlugin([ { key: 'project-prediction', title: 'Allocated Projects', diff --git a/client/packages/portal-ui/src/header/Icon.tsx b/client/packages/portal-ui/src/header/Icon.tsx index 802089315..892c13371 100644 --- a/client/packages/portal-ui/src/header/Icon.tsx +++ b/client/packages/portal-ui/src/header/Icon.tsx @@ -1,61 +1,63 @@ import styled from 'styled-components'; -const Wrapper = styled.div` - /* padding: 0.2rem; */ +const Wrapper = styled.span` > svg { width: 35px; } `; -export function PortalIcon() { - return ( - - - - - - - - - - - - - - - - - - - - ); +export function PortalIcon({ icon }: { icon?: string }) { + if (!icon) { + return ( + + + + + + + + + + + + + + + + + + + + ); + } + return ; } diff --git a/client/packages/portal-ui/src/header/Logo.tsx b/client/packages/portal-ui/src/header/Logo.tsx index 0dcbf27ab..01b09ad72 100644 --- a/client/packages/portal-ui/src/header/Logo.tsx +++ b/client/packages/portal-ui/src/header/Logo.tsx @@ -27,7 +27,7 @@ export function PortalLogo({ onClick }: PortalLogoProps): JSX.Element { return ( - + {portal?.name} diff --git a/client/packages/ui/src/components/message/Message.tsx b/client/packages/ui/src/components/message/Message.tsx index 423d825a2..ae14d1eb9 100644 --- a/client/packages/ui/src/components/message/Message.tsx +++ b/client/packages/ui/src/components/message/Message.tsx @@ -96,7 +96,7 @@ export const Message = ({ title, messages, type = 'Info', children }: PropsWithC - + {title} diff --git a/client/yarn.lock b/client/yarn.lock index e0519e1e9..f838ec224 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -8752,10 +8752,10 @@ strong-log-transformer@2.1.0, strong-log-transformer@^2.1.0: minimist "^1.2.0" through "^2.3.4" -styled-components@5.3.6: - version "5.3.6" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.6.tgz#27753c8c27c650bee9358e343fc927966bfd00d1" - integrity sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg== +styled-components@5.3.11: + version "5.3.11" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.11.tgz#9fda7bf1108e39bf3f3e612fcc18170dedcd57a8" + integrity sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/traverse" "^7.4.5"