From 42cedca9d22995403a9fef26453cf67c6e4b8b37 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 28 Jul 2024 20:07:48 +0530 Subject: [PATCH 001/110] refactor: Fix JSON decoding issues in generate_docs_for_chunk function --- commit/api/generate_documentation.py | 13 +++++++++---- .../components/features/api_viewer/APIDetails.tsx | 13 ++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/commit/api/generate_documentation.py b/commit/api/generate_documentation.py index fbb04be..4cf9337 100644 --- a/commit/api/generate_documentation.py +++ b/commit/api/generate_documentation.py @@ -12,7 +12,6 @@ def generate_docs_for_apis(api_definitions): for chunk in chunks: chunk_docs = generate_docs_for_chunk(chunk) - # print("Chunk Docs:", chunk_docs) if chunk_docs: all_docs.extend(chunk_docs) else: @@ -68,7 +67,7 @@ def generate_docs_for_chunk(api_chunk): "- **Examples**: Code examples demonstrating how to use the function (enclosed in triple backticks ``````).\n\n" "The response should be a valid JSON list of objects formatted as follows: " "{function_name: , path: , documentation: }.\n" - "Ensure the response is in JSON format only, enclosed in triple backticks, and does not include `---`." + "Ensure the response is in valid JSON format only, enclosed in triple backticks, and does not include `---`." ) } ] @@ -89,7 +88,7 @@ def generate_docs_for_chunk(api_chunk): return cleaned_response # If cleaned_response is a string, attempt to decode it as JSON elif isinstance(cleaned_response, str): - return json.loads(cleaned_response) + return json.loads(cleaned_response, strict=False) else: # Handle other unexpected types if necessary print("Unexpected type of cleaned_response:", type(cleaned_response)) @@ -97,6 +96,12 @@ def generate_docs_for_chunk(api_chunk): except json.JSONDecodeError as e: print("JSON Decode Error:", e) print("Cleaned Response:\n", cleaned_response) - return [] + try: + # Attempt to fix common issues like single quotes or trailing commas + cleaned_response = cleaned_response.replace("'", '"') + return json.loads(cleaned_response, strict=False) + except json.JSONDecodeError as e: + print("Second JSON Decode Error:", e) + return [] # return cleaned_response \ No newline at end of file diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 545d9ae..f953736 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -189,10 +189,21 @@ export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: } export const Documentation = ({ documentation }: { documentation: string }) => { + console.log('documentation', documentation) + + const renderContent = () => { + if (typeof documentation === 'string') { + return {documentation}; + } else if (typeof documentation === 'object' && documentation !== null && !Array.isArray(documentation)) { + return
{JSON.stringify(documentation, null, 2)}
; + } else { + return
Invalid documentation format
; + } + }; return (
- {documentation} + {renderContent()}
) } From 7d8122c8d525c85df668175f3896dc8bc18a8d93 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 2 Aug 2024 11:47:49 +0530 Subject: [PATCH 002/110] refactor: Add allow_guest parameter to generate_bruno_file function --- commit/api/bruno.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commit/api/bruno.py b/commit/api/bruno.py index 4f5e258..88eb96a 100644 --- a/commit/api/bruno.py +++ b/commit/api/bruno.py @@ -1,6 +1,6 @@ import frappe -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def generate_bruno_file(data, return_type='download'): request_data = frappe.parse_json(data) """ From 2865d8c84e5639144f083c19b4d13e257a6a0781 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 2 Aug 2024 16:06:02 +0530 Subject: [PATCH 003/110] refactor: Update UI layout and styling in ERDDoctypeAndAppModal, YourAppAPIExplorer, APIExplorer, YourApps, and ProjectCard components --- .../features/meta_apps/YourAppAPIExplorer.tsx | 10 +++++----- .../src/components/features/projects/APIExplorer.tsx | 10 +++++----- .../components/features/projects/ViewERDAppDialog.tsx | 10 ++++++---- .../pages/features/erd/meta/ERDDoctypeAndAppModal.tsx | 2 +- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx index 1942488..60f5a07 100644 --- a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx +++ b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx @@ -54,11 +54,11 @@ export const ViewAPIExplorerContent = ({ data }: { data: AppsData[] }) => { }, [branch, navigate]) return ( - + - Select Apps + Select App - Select the apps to view API's + Select the app to view API's setBranch(value)} className="flex flex-col space-y-1" > @@ -89,9 +89,9 @@ export const ViewAPIExplorerCard = ({ app }: ViewAPIExplorerProps) => {
  • -
    { @@ -23,7 +24,7 @@ export const ViewERDDialogContent = ({ data }: { data: ProjectData[] }) => { } return ( - + Select Apps @@ -60,8 +61,9 @@ export const ViewERDProjectCard = ({ project, apps, setApps }: ViewERDProjectCar return (
  • -
    +
    +

    {project.display_name}

    + + * + **/ +export const FormElement = ({ name, label, children, tooltip, ...props }: FormElementProps) => { + + const { errors } = useFormState() + + /** + * The name can be a path like `items.0.item_code` so we need to split it + * and then get the error message from the errors object + * */ + let error: Record = errors + const path = name.split('.') + + for (let i = 0; i < path.length; i++) { + error = error?.[path[i]] + } + + return ( + +
    + {label &&
    +
    + } + {children} + {tooltip && {tooltip}} + {error && + {error.message} + + } +
    +
    + ) +}; diff --git a/dashboard/src/components/common/Forms/FormControl/index.ts b/dashboard/src/components/common/Forms/FormControl/index.ts new file mode 100644 index 0000000..c797cde --- /dev/null +++ b/dashboard/src/components/common/Forms/FormControl/index.ts @@ -0,0 +1,2 @@ +export * from './Control' +export * from './FormElement' \ No newline at end of file diff --git a/dashboard/src/components/common/Label/Label.tsx b/dashboard/src/components/common/Label/Label.tsx new file mode 100644 index 0000000..3149d2a --- /dev/null +++ b/dashboard/src/components/common/Label/Label.tsx @@ -0,0 +1,16 @@ +import { FormLabel } from "@/components/ui/form" +import { LabelProps } from "@radix-ui/react-label" + +interface FormLabelProps extends LabelProps { + label: string +} + +export const Label = ({ label, ...props }: FormLabelProps) => { + + return ( + + {label} + + + ) +} \ No newline at end of file diff --git a/dashboard/src/components/common/Label/index.ts b/dashboard/src/components/common/Label/index.ts new file mode 100644 index 0000000..d0ac8fd --- /dev/null +++ b/dashboard/src/components/common/Label/index.ts @@ -0,0 +1 @@ +export { Label } from './Label' \ No newline at end of file From ac91f31d2726f5d5761474e92f6ffe5f06cef10a Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:36:27 +0530 Subject: [PATCH 007/110] refactor: passed open to modal for reset the form when form get open --- .../src/components/features/projects/AddMenuButton.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dashboard/src/components/features/projects/AddMenuButton.tsx b/dashboard/src/components/features/projects/AddMenuButton.tsx index 9dbd797..6e14c03 100644 --- a/dashboard/src/components/features/projects/AddMenuButton.tsx +++ b/dashboard/src/components/features/projects/AddMenuButton.tsx @@ -59,13 +59,13 @@ export const AddMenuButton = ({ mutate }: { - + - + - + ) From c5614e264b0b97c8ec112ec338caf8fe537f945d Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:37:22 +0530 Subject: [PATCH 008/110] refactor:Use of FormElement Component in this modals --- .../projects/Branch/CreateBranchModal.tsx | 66 ++++++++------- .../features/projects/Org/CreateOrgModal.tsx | 80 +++++++++++-------- .../projects/Projects/CreateProjectModal.tsx | 80 +++++++++++-------- 3 files changed, 131 insertions(+), 95 deletions(-) diff --git a/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx b/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx index 6595189..b35344a 100644 --- a/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx +++ b/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx @@ -1,15 +1,15 @@ import { DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { FormProvider, useForm, SubmitHandler } from "react-hook-form" import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" import { Button } from '@/components/ui/button' import { ProjectData } from "../Projects" import { useToast } from "@/components/ui/use-toast" import { useFrappeCreateDoc, useFrappeEventListener } from "frappe-react-sdk" import { KeyedMutator } from "swr" -import { useState } from "react" +import { useEffect, useState } from "react" import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner" import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown" +import { FormElement } from "@/components/common/Forms/FormControl" type FormFields = { project: string, @@ -21,9 +21,10 @@ export interface BranchProps { message: ProjectData[]; }> setOpen: React.Dispatch> + open: boolean } -const CreateBranchModal = ({ mutate, setOpen }: BranchProps) => { +const CreateBranchModal = ({ mutate, setOpen, open }: BranchProps) => { const [desc, setDesc] = useState() const [eventLoading, setEventLoading] = useState(false) @@ -96,39 +97,50 @@ const CreateBranchModal = ({ mutate, setOpen }: BranchProps) => { }) } + useEffect(() => { + methods.reset() + }, [open]) + return ( - Add Branch. + Add Branch {error && } {creationError && }
    - - - - - -
    -
    {desc}
    - -
    -
    +
    + + + + + + + +
    +
    {desc}
    + +
    +
    +
    diff --git a/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx b/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx index c52f348..fc51ba8 100644 --- a/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx +++ b/dashboard/src/components/features/projects/Org/CreateOrgModal.tsx @@ -2,13 +2,14 @@ import { Button } from '@/components/ui/button' import { DialogHeader, DialogTitle, DialogContent, DialogFooter } from '@/components/ui/dialog' import { FormProvider, SubmitHandler, useForm } from 'react-hook-form' import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" import { useFrappeCreateDoc } from 'frappe-react-sdk' import { useToast } from '@/components/ui/use-toast' import { ProjectData } from '../Projects' import { KeyedMutator } from 'swr' import { ErrorBanner } from '@/components/common/ErrorBanner/ErrorBanner' import { SpinnerLoader } from '@/components/common/FullPageLoader/SpinnerLoader' +import { FormElement } from '@/components/common/Forms/FormControl' +import { useEffect } from 'react' type FormFields = { organization_name: string, @@ -19,10 +20,11 @@ type FormFields = { interface CreateOrgModalProps { mutate: KeyedMutator<{ message: ProjectData[]; }> onClose: () => void + open: boolean } -const CreateOrgModal = ({ mutate, onClose }: CreateOrgModalProps) => { +const CreateOrgModal = ({ mutate, onClose, open }: CreateOrgModalProps) => { const { toast } = useToast() const methods = useForm() @@ -40,6 +42,10 @@ const CreateOrgModal = ({ mutate, onClose }: CreateOrgModalProps) => { })) } + useEffect(() => { + methods.reset() + }, [open]) + return ( @@ -48,39 +54,43 @@ const CreateOrgModal = ({ mutate, onClose }: CreateOrgModalProps) => { {error && }
    - - - - - - - - - +
    + + + + + + + + + + + + +
    diff --git a/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx b/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx index 969e5fd..f68c9a9 100644 --- a/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx +++ b/dashboard/src/components/features/projects/Projects/CreateProjectModal.tsx @@ -2,12 +2,13 @@ import { DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/compon import { useFrappeCreateDoc } from "frappe-react-sdk" import { FormProvider, SubmitHandler, useForm } from "react-hook-form" import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" import { Button } from '@/components/ui/button' import { useToast } from "@/components/ui/use-toast" import { ProjectData } from "../Projects" import { KeyedMutator } from "swr" import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown" +import { FormElement } from "@/components/common/Forms/FormControl" +import { useEffect } from "react" export type FormFields = { org: string, @@ -18,9 +19,10 @@ export type FormFields = { interface CreateProjectModalProps { mutate: KeyedMutator<{ message: ProjectData[]; }>, onClose: VoidFunction + open: boolean } -const CreateProjectModal = ({ mutate, onClose }: CreateProjectModalProps) => { +const CreateProjectModal = ({ mutate, onClose, open }: CreateProjectModalProps) => { const { toast } = useToast() const methods = useForm() @@ -40,6 +42,9 @@ const CreateProjectModal = ({ mutate, onClose }: CreateProjectModalProps) => { }) } + useEffect(() => { + methods.reset() + }, [open]) return ( @@ -48,37 +53,46 @@ const CreateProjectModal = ({ mutate, onClose }: CreateProjectModalProps) => {
    - - - - - - - - - - - +
    + + + + + + + + + + + + + + + +
    From 97b8339cbc3ec0359535539c4035904a0c139430 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:37:29 +0530 Subject: [PATCH 009/110] refactor: Update UI layout and styling in multiple components --- .../projects/Branch/ManageBranchItem.tsx | 280 ++++++++++-------- 1 file changed, 149 insertions(+), 131 deletions(-) diff --git a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx index 5f013e4..3af3949 100644 --- a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx +++ b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx @@ -1,151 +1,169 @@ -import { Button } from '@/components/ui/button' -import { toast } from '@/components/ui/use-toast' -import { convertFrappeTimestampToTimeAgo } from '@/components/utils/dateconversion' -import { CommitProjectBranch } from '@/types/commit/CommitProjectBranch' -import { useFrappeDeleteDoc, useFrappePostCall, useFrappeUpdateDoc } from 'frappe-react-sdk' -import { AiOutlineDelete } from 'react-icons/ai' -import { IoMdSync } from 'react-icons/io' -import { ProjectData } from '../Projects' -import { KeyedMutator } from 'swr' +import { Button } from '@/components/ui/button'; +import { toast } from '@/components/ui/use-toast'; +import { convertFrappeTimestampToTimeAgo } from '@/components/utils/dateconversion'; +import { CommitProjectBranch } from '@/types/commit/CommitProjectBranch'; +import { useFrappeDeleteDoc, useFrappePostCall, useFrappeUpdateDoc } from 'frappe-react-sdk'; +import { AiOutlineDelete } from 'react-icons/ai'; +import { IoMdSync } from 'react-icons/io'; +import { ProjectData } from '../Projects'; +import { KeyedMutator } from 'swr'; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { Controller, FormProvider, useForm } from 'react-hook-form' -import { Label } from '@/components/ui/label' -import { useState } from 'react' - +import { Controller, FormProvider, useForm } from 'react-hook-form'; +import { Label } from '@/components/ui/label'; +import { useState } from 'react'; const ManageBranchItem = ({ branch, mutate }: { branch: CommitProjectBranch, mutate: KeyedMutator<{ message: ProjectData[]; }> }) => { - const { call, loading, reset: callReset } = useFrappePostCall<{ message: any }>('commit.commit.doctype.commit_project_branch.commit_project_branch.fetch_repo') - + const { call, loading: syncLoading, reset: callReset } = useFrappePostCall<{ message: any }>('commit.commit.doctype.commit_project_branch.commit_project_branch.fetch_repo'); + const { deleteDoc, loading: deleteLoading, reset } = useFrappeDeleteDoc(); + const { updateDoc } = useFrappeUpdateDoc(); + const [open, setOpen] = useState(false); - const { deleteDoc, reset, loading: deleteLoading } = useFrappeDeleteDoc() + const methods = useForm({ + defaultValues: { + frequency: branch.frequency, + }, + }); const handleDelete = () => { deleteDoc("Commit Project Branch", branch.name) .then(() => { - mutate() - reset() - }).then(() => toast({ - description: "Branch Deleted Successfully", - duration: 1500 - })) - } + mutate(); + reset(); + toast({ + description: "Branch Deleted Successfully", + duration: 1500, + }); + }); + }; const handleSync = () => { - call({ - doc: {}, - name: branch.name, - }).then(() => { - mutate() - callReset() - }).then(() => toast({ - description: "Branch Synced!", - duration: 1500 - })) - } - - const methods = useForm({ - defaultValues: { - frequency : branch.frequency - } - }) - - const { control, reset: formReset } = methods - - const { updateDoc } = useFrappeUpdateDoc() + call({ doc: {}, name: branch.name }) + .then(() => { + mutate(); + callReset(); + toast({ + description: "Branch Synced!", + duration: 1500, + }); + }); + }; const onSubmit = (data: CommitProjectBranch) => { updateDoc("Commit Project Branch", branch.name, data) .then(() => { - mutate() - formReset({ frequency: data.frequency }) - }).then(() => { + mutate(); + methods.reset({ frequency: data.frequency }); toast({ description: `Branch ${branch.branch_name} will be updated ${data.frequency}`, - duration: 2000 - }) - setOpen(false) - } - ) - - } - - - const [open, setOpen] = useState(false); + duration: 2000, + }); + setOpen(false); + }); + }; return ( -
  • -
    - {branch.branch_name} -
    - Last synced {convertFrappeTimestampToTimeAgo(branch.last_fetched)} -
    -
    -
    - - - - - - - -
    -
    - - ( - - )} - /> -
    -
    - -
    -
    -
    -
    -
    - +
  • + +
    + + +
    -
  • - ) -} - -export default ManageBranchItem - - + + ); +}; + +const BranchInfo = ({ branch }: { branch: CommitProjectBranch }) => ( +
    + {branch.branch_name} + Last synced {convertFrappeTimestampToTimeAgo(branch.last_fetched)} +
    +); + +const SyncButton = ({ loading, onSync }: { loading: boolean, onSync: () => void }) => ( + +); + +const FrequencyPopover = ({ open, setOpen, methods, onSubmit, control, frequency }: { + open: boolean, + setOpen: (open: boolean) => void, + methods: any, + onSubmit: any, + control: any, + frequency: string | undefined +}) => ( + + + + + + +
    +
    + + ( + + )} + /> +
    +
    + +
    +
    +
    +
    +
    +); + +const DeleteButton = ({ loading, onDelete }: { loading: boolean, onDelete: () => void }) => ( + +); + +export default ManageBranchItem; From 2a107107de5a096861d2f0f08ab15842a1b7a5fb Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 9 Aug 2024 16:37:53 +0530 Subject: [PATCH 010/110] refactor:Make pages responsive and svg file added --- dashboard/src/assets/api.svg | 1 + dashboard/src/assets/erd.svg | 341 ++++++++++++++++++ .../features/meta_apps/YourAppAPIExplorer.tsx | 43 ++- .../features/meta_apps/YourApps.tsx | 78 ++-- .../features/projects/APIExplorer.tsx | 31 +- .../components/features/projects/Projects.tsx | 53 ++- .../projects/Projects/ProjectCard.tsx | 99 +++-- .../features/projects/ViewERDButton.tsx | 81 +++++ 8 files changed, 587 insertions(+), 140 deletions(-) create mode 100644 dashboard/src/assets/api.svg create mode 100644 dashboard/src/assets/erd.svg create mode 100644 dashboard/src/components/features/projects/ViewERDButton.tsx diff --git a/dashboard/src/assets/api.svg b/dashboard/src/assets/api.svg new file mode 100644 index 0000000..17728fa --- /dev/null +++ b/dashboard/src/assets/api.svg @@ -0,0 +1 @@ + diff --git a/dashboard/src/assets/erd.svg b/dashboard/src/assets/erd.svg new file mode 100644 index 0000000..6461be4 --- /dev/null +++ b/dashboard/src/assets/erd.svg @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx index 60f5a07..f6d355e 100644 --- a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx +++ b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx @@ -4,11 +4,13 @@ import { useNavigate } from "react-router-dom" import { AppsData } from "./YourApps" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" -import { AiOutlineApi } from "react-icons/ai" import { useCallback, useState } from "react" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card" +import { MdKeyboardArrowRight } from "react-icons/md" +import api from '../../../assets/api.svg' export const YourAppAPIExplorer = () => { @@ -28,15 +30,36 @@ export const YourAppAPIExplorer = () => { if (data && data.message) { return ( - - - - - - + +
    + + Explore your API's + + +
    + Explore and interact with your site installed apps whitelisted API's effortlessly + using our API Explorer. +
    +
    + + + + + + + + + +
    +
    + API +
    +
    ) } } diff --git a/dashboard/src/components/features/meta_apps/YourApps.tsx b/dashboard/src/components/features/meta_apps/YourApps.tsx index e2bff95..9d26140 100644 --- a/dashboard/src/components/features/meta_apps/YourApps.tsx +++ b/dashboard/src/components/features/meta_apps/YourApps.tsx @@ -1,13 +1,10 @@ import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { Avatar, AvatarFallback } from "@/components/ui/avatar" -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardDescription, CardTitle } from "@/components/ui/card" import { AvatarImage } from "@radix-ui/react-avatar" import { useFrappeGetCall } from "frappe-react-sdk" import { useMemo } from "react" -import { BsDatabase } from "react-icons/bs" -import { useNavigate } from "react-router-dom" import { YourAppAPIExplorer } from "./YourAppAPIExplorer" +import { ViewERDButtonForSiteApps } from "../projects/ViewERDButton" export interface AppsData { app_name: string @@ -19,7 +16,6 @@ export interface AppsData { } export const YourApps = () => { - const navigate = useNavigate() const { data, error, isLoading } = useFrappeGetCall<{ message: AppsData[] }>('commit.api.meta_data.get_installed_apps', {}, 'get_installed_apps', { keepPreviousData: true, @@ -37,25 +33,24 @@ export const YourApps = () => { if (data && data.message) { return ( -
    -
    - -
    +
    +
    +
    + -
    -
    -
    - {data.message.map((app: AppsData) => { - return - })} +
    +
    +
    Projects
    +
    +
    + {data.message.map((org: AppsData) => { + return ( + + ) + })} +
    +
    ) @@ -64,32 +59,25 @@ export const YourApps = () => { const AppsCard = ({ app }: { app: AppsData }) => { - const appNameInitials = useMemo(() => { - return app.app_name.split('_').map((word) => word[0]).join('').toUpperCase() - }, [app]) + return app.app_name.split('_').map((word) => word[0]).join('').toUpperCase(); + }, [app]); return ( - - -
    - - - {appNameInitials} +
    +
    + + + {appNameInitials} -
    -
    -
    - {app.app_name} -
    - {app.app_publisher} +
    +
    {app.app_name}
    +
    + {app.app_description}
    +
    {app.app_publisher}
    - - {app.app_description} - -
    - - - ) -} \ No newline at end of file +
    +
    + ); +}; \ No newline at end of file diff --git a/dashboard/src/components/features/projects/APIExplorer.tsx b/dashboard/src/components/features/projects/APIExplorer.tsx index 4a24615..85bda45 100644 --- a/dashboard/src/components/features/projects/APIExplorer.tsx +++ b/dashboard/src/components/features/projects/APIExplorer.tsx @@ -3,13 +3,15 @@ import { Button } from "@/components/ui/button" import { useFrappeGetCall } from "frappe-react-sdk" import { ProjectData, ProjectWithBranch } from "./Projects" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" -import { AiOutlineApi } from "react-icons/ai" import { useCallback, useState } from "react" import { useNavigate } from "react-router-dom" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { CommitProjectBranch } from "@/types/commit/CommitProjectBranch" import { Label } from "@/components/ui/label" +import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card" +import { MdKeyboardArrowRight } from "react-icons/md" +import api from '../../../assets/api.svg' export const APIExplorer = () => { const { data, error, isLoading } = useFrappeGetCall<{ message: ProjectData[] }>('commit.api.commit_project.commit_project.get_project_list_with_branches', {}, 'get_project_list_with_branches', { @@ -28,15 +30,36 @@ export const APIExplorer = () => { if (data && data.message) { return ( + +
    + + Explore your API's + + +
    + Explore and interact with your whitelisted API's effortlessly + using our API Explorer. +
    +
    + + - + +
    +
    + API +
    +
    ) } return null diff --git a/dashboard/src/components/features/projects/Projects.tsx b/dashboard/src/components/features/projects/Projects.tsx index 97e78e9..78f8df6 100644 --- a/dashboard/src/components/features/projects/Projects.tsx +++ b/dashboard/src/components/features/projects/Projects.tsx @@ -1,15 +1,12 @@ import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; -import { Button } from "@/components/ui/button"; -import { Dialog, DialogTrigger } from "@/components/ui/dialog"; import { CommitProject } from "@/types/commit/CommitProject"; import { useFrappeGetCall } from "frappe-react-sdk"; -import { BsDatabase } from "react-icons/bs"; -import { ViewERDDialogContent } from "./ViewERDAppDialog"; import { isSystemManager } from "@/utils/roles"; import { CommitProjectBranch } from "@/types/commit/CommitProjectBranch"; import { AddMenuButton } from "./AddMenuButton"; import { APIExplorer } from "./APIExplorer"; import ProjectCard from "./Projects/ProjectCard"; +import { ViewERDButton } from "./ViewERDButton"; export interface ProjectWithBranch extends CommitProject { @@ -18,6 +15,7 @@ export interface ProjectWithBranch extends CommitProject { export interface ProjectData extends CommitProjectBranch { projects: ProjectWithBranch[]; organization_name: string; + github_org: string; image: string; name: string; about: string; @@ -48,32 +46,31 @@ export const Projects = () => { if (data && data.message) { return ( -
    -
    -
    - {isCreateAccess && } +
    +
    +
    + - - - - - -
    -
    - {data.message.map((org: ProjectData) => { - const orgName = org.organization_name; - return org.projects.map((project) => ( - - )); - })} +
    +
    +
    Projects
    + {isCreateAccess && } +
    +
    + {data.message.map((org: ProjectData) => { + const orgName = org.organization_name; + return org.projects.map((project) => ( + + )); + })} +
    diff --git a/dashboard/src/components/features/projects/Projects/ProjectCard.tsx b/dashboard/src/components/features/projects/Projects/ProjectCard.tsx index 7b1bb4d..f342f5b 100644 --- a/dashboard/src/components/features/projects/Projects/ProjectCard.tsx +++ b/dashboard/src/components/features/projects/Projects/ProjectCard.tsx @@ -1,10 +1,4 @@ import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardTitle, -} from "@/components/ui/card"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { AiOutlineDelete } from "react-icons/ai"; import { AlertDialog } from "@/components/ui/alert-dialog"; @@ -25,9 +19,10 @@ export interface ProjectCardProps { message: ProjectData[]; }> orgName: string + githubOrg: string } -const ProjectCard = ({ project, mutate, orgName }: ProjectCardProps) => { +const ProjectCard = ({ project, mutate, orgName, githubOrg }: ProjectCardProps) => { const appNameInitials = useMemo(() => { return project.display_name[0].toUpperCase() @@ -39,54 +34,52 @@ const ProjectCard = ({ project, mutate, orgName }: ProjectCardProps) => { const [openDeleteDialogModal, setOpenDeleteDialogModal] = useState(false) - return ( - - -
    -
    - - - - {appNameInitials} - - -
    -
    -
    -
    - {project.display_name} -
    - {orgName} -
    -
    - {isCreateAccess && - - - - - {project.branches.length > 0 && - { setOpenManageModal(true) }}> - <> - - Manage Branches - - - } - setOpenDeleteDialogModal(true)}> - - Delete Project - + const openGithubRepo = () => { + window.open(`https://github.com/${githubOrg}/${project.repo_name}`, '_blank') + } - - } -
    - - - {project.description} - + return ( +
    +
    + + + + {appNameInitials} + + +
    +
    {project.display_name}
    +
    + {project.description}
    +
    {orgName}
    - +
    +
    + {isCreateAccess && ( + + + + + + {project.branches.length > 0 && ( + { setOpenManageModal(true) }}> + <> + + Manage Branches + + + )} + setOpenDeleteDialogModal(true)}> + + Delete Project + + + + )} +
    @@ -95,7 +88,7 @@ const ProjectCard = ({ project, mutate, orgName }: ProjectCardProps) => { - +
    ); } diff --git a/dashboard/src/components/features/projects/ViewERDButton.tsx b/dashboard/src/components/features/projects/ViewERDButton.tsx new file mode 100644 index 0000000..482b710 --- /dev/null +++ b/dashboard/src/components/features/projects/ViewERDButton.tsx @@ -0,0 +1,81 @@ +import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card"; +import { Dialog, DialogTrigger } from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { ViewERDDialogContent } from "./ViewERDAppDialog"; +import { ProjectData } from "./Projects"; +import { MdKeyboardArrowRight } from "react-icons/md"; +import { useNavigate } from "react-router-dom"; +import erd from '../../../assets/erd.svg' + +export const ViewERDButton = ({ data }: { data: ProjectData[] }) => { + return ( + +
    + + Visualize your database + + +
    Analyze and understand the relationships between your doctypes with an interactive Entity Relationship Diagram (ERD).
    +
    + + + + + + + + +
    +
    + ERD Diagram +
    +
    + ); +}; + +export const ViewERDButtonForSiteApps = () => { + + const navigate = useNavigate() + + return ( + +
    + + Visualize your site database + + +
    Analyze and understand the relationships between your doctypes with an interactive Entity Relationship Diagram (ERD).
    +
    + + + +
    +
    + ERD Diagram +
    +
    + ); +} \ No newline at end of file From c2bbd88baa15e356a74f00402b7c7d1d72851713 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 12 Aug 2024 10:30:27 +0530 Subject: [PATCH 011/110] refactor: ERD svg file --- dashboard/src/assets/erd.svg | 382 ++++------------------------------- 1 file changed, 44 insertions(+), 338 deletions(-) diff --git a/dashboard/src/assets/erd.svg b/dashboard/src/assets/erd.svg index 6461be4..c669beb 100644 --- a/dashboard/src/assets/erd.svg +++ b/dashboard/src/assets/erd.svg @@ -1,341 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + From eee413c9a08021bc5db13d1ebb0c644ebed04209 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 30 Aug 2024 11:02:13 +0530 Subject: [PATCH 012/110] refactor: Update UI layout and styling in multiple components make it responsive --- .../projects/Branch/CreateBranchModal.tsx | 7 +- .../projects/Branch/ManageBranchItem.tsx | 104 +++++++++++++++--- .../projects/Branch/ManageBranchModal.tsx | 6 +- .../features/projects/Org/CreateOrgModal.tsx | 4 +- .../projects/Projects/CreateProjectModal.tsx | 4 +- .../projects/Projects/DeleteProjectModal.tsx | 4 +- .../features/projects/ViewERDAppDialog.tsx | 4 +- 7 files changed, 103 insertions(+), 30 deletions(-) diff --git a/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx b/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx index b35344a..c6717a4 100644 --- a/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx +++ b/dashboard/src/components/features/projects/Branch/CreateBranchModal.tsx @@ -102,10 +102,9 @@ const CreateBranchModal = ({ mutate, setOpen, open }: BranchProps) => { }, [open]) return ( - - - Add Branch - + + + Add Branch {error && } {creationError && } diff --git a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx index 3af3949..0c6a19c 100644 --- a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx +++ b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx @@ -11,13 +11,16 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Controller, FormProvider, useForm } from 'react-hook-form'; import { Label } from '@/components/ui/label'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; +import { HiOutlineDotsVertical } from "react-icons/hi"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; const ManageBranchItem = ({ branch, mutate }: { branch: CommitProjectBranch, mutate: KeyedMutator<{ message: ProjectData[]; }> }) => { const { call, loading: syncLoading, reset: callReset } = useFrappePostCall<{ message: any }>('commit.commit.doctype.commit_project_branch.commit_project_branch.fetch_repo'); const { deleteDoc, loading: deleteLoading, reset } = useFrappeDeleteDoc(); const { updateDoc } = useFrappeUpdateDoc(); const [open, setOpen] = useState(false); + const [isSmallScreen, setIsSmallScreen] = useState(false); const methods = useForm({ defaultValues: { @@ -25,6 +28,19 @@ const ManageBranchItem = ({ branch, mutate }: { branch: CommitProjectBranch, mut }, }); + useEffect(() => { + const handleResize = () => { + setIsSmallScreen(window.innerWidth < 840); // Tailwind's 'sm' breakpoint + }; + + handleResize(); // Initial check + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + }; + }, []); + const handleDelete = () => { deleteDoc("Commit Project Branch", branch.name) .then(() => { @@ -66,16 +82,37 @@ const ManageBranchItem = ({ branch, mutate }: { branch: CommitProjectBranch, mut
  • - - - + {isSmallScreen ? ( +
    + + +
    + ) : ( + <> + + + + + )}
  • ); @@ -91,7 +128,7 @@ const BranchInfo = ({ branch }: { branch: CommitProjectBranch }) => ( const SyncButton = ({ loading, onSync }: { loading: boolean, onSync: () => void }) => ( @@ -133,7 +170,9 @@ const FrequencyPopover = ({ open, setOpen, methods, onSubmit, control, frequency render={({ field }) => ( setSearchQuery(e.target.value)} className="h-8" value={searchQuery} /> +
    + {filteredData && filteredData?.length > 0 ? filteredData?.map((command: CommandResponse) => ) + :
    No commands found
    } +
    +
    + + + + + + + ) +} + +const CommandComponent = ({ name, help }: CommandResponse) => { + + return ( +
    + +
    + {`bench ${name}`} +
    + +
    +
    + {help} +
    +
    + ) +} \ No newline at end of file From 60207fdb8e4d6834ede661b456d4b290de1950a1 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Sep 2024 15:29:47 +0530 Subject: [PATCH 024/110] Refactor: Update APIList component to use HiOutlineCommandLine icon for commands button --- dashboard/src/components/features/api_viewer/APIList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dashboard/src/components/features/api_viewer/APIList.tsx b/dashboard/src/components/features/api_viewer/APIList.tsx index 85fa8eb..48e5a3b 100644 --- a/dashboard/src/components/features/api_viewer/APIList.tsx +++ b/dashboard/src/components/features/api_viewer/APIList.tsx @@ -3,11 +3,11 @@ import { Dialog, DialogTrigger } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { APIData } from "@/types/APIData" -import { EyeIcon } from "@heroicons/react/24/outline" import { useEffect, useMemo, useState } from "react" import { AiOutlineBranches } from "react-icons/ai" import { GoPackage } from "react-icons/go" import { CommandContent } from "../commands/CommandsContent" +import { HiOutlineCommandLine } from "react-icons/hi2"; export interface APIListProps { apiList: APIData[] @@ -53,7 +53,7 @@ export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, s From 002d808415c48cf5678f37a403eff620217ac530 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Sep 2024 16:05:51 +0530 Subject: [PATCH 025/110] refactor:show clickable link if help text content link --- .../features/commands/CommandsContent.tsx | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/dashboard/src/components/features/commands/CommandsContent.tsx b/dashboard/src/components/features/commands/CommandsContent.tsx index ce6f6a6..195111c 100644 --- a/dashboard/src/components/features/commands/CommandsContent.tsx +++ b/dashboard/src/components/features/commands/CommandsContent.tsx @@ -39,33 +39,51 @@ export const CommandContent = ({ app, app_path }: CommandContentProps) => { Commands - View commands for {app} + View bench commands for {app} app {isLoading && }
    -
    -
    +
    +
    setSearchQuery(e.target.value)} className="h-8" value={searchQuery} />
    - {filteredData && filteredData?.length > 0 ? filteredData?.map((command: CommandResponse) => ) - :
    No commands found
    } + + {filteredData && filteredData?.length > 0 ?
    + {filteredData?.map((command: CommandResponse) => )} +
    :
    No commands found
    }
    - - - +
    +
    Total {filteredData?.length} Command(s)
    + + + +
    ) } const CommandComponent = ({ name, help }: CommandResponse) => { + // Regular expression to detect URLs + const urlRegex = /(https?:\/\/[^\s]+)/g; + + // Function to wrap links in anchor tags + const renderHelpText = (text: string) => { + const parts = text.split(urlRegex); + return parts.map((part, index) => { + if (urlRegex.test(part)) { + return {part}; + } + return part; + }); + }; return ( -
    +
    {`bench ${name}`} @@ -74,8 +92,8 @@ const CommandComponent = ({ name, help }: CommandResponse) => { `bench ${name}` } className="h-6 w-6 hover:bg-gray-300" /> -
    - {help} +
    + {renderHelpText(help)}
    ) From b2839dc4667407b8e7ffb10536374f073b7f3440 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Sep 2024 16:12:18 +0530 Subject: [PATCH 026/110] fix:show mandatory fields --- dashboard/src/components/features/api_viewer/APIDetails.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 1c83881..78d4b51 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -160,7 +160,7 @@ export const ParametersTable = ({ parameters }: { parameters?: Argument[] }) => {parameters?.map((parameter) => ( - {parameter.argument} + {parameter.argument}{parameter.argument && parameter.default ? '' : *} {parameter.type ? parameter.type : '-'} {parameter.default ? parameter.default : '-'} From 5e42a08b42f80dc284c3b8a4ca3e027ce6f9a7e4 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Sep 2024 16:24:28 +0530 Subject: [PATCH 027/110] Refactor: Update ParametersTable component to show mandatory fields --- .../src/components/features/api_viewer/APIDetails.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 78d4b51..3e26c80 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -158,13 +158,16 @@ export const ParametersTable = ({ parameters }: { parameters?: Argument[] }) => - {parameters?.map((parameter) => ( + {parameters?.map((parameter) => { + const isMandatory = parameter.argument !== '' && parameter.argument && !parameter.default + return ( - {parameter.argument}{parameter.argument && parameter.default ? '' : *} + {parameter.argument}{isMandatory ? * : ''} {parameter.type ? parameter.type : '-'} {parameter.default ? parameter.default : '-'} - ))} + ) + })} ) From 19cbe3682d6c9bd3d69037c82485e0f78c98b0c4 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Sep 2024 16:39:48 +0530 Subject: [PATCH 028/110] Refactor: Update APIExplorer components to include Bench Commands --- .../src/components/features/meta_apps/YourAppAPIExplorer.tsx | 5 ++--- dashboard/src/components/features/projects/APIExplorer.tsx | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx index ed77efa..05aa70c 100644 --- a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx +++ b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx @@ -33,12 +33,11 @@ export const YourAppAPIExplorer = () => {
    - Explore your API's + Explore your API's and Bench Commands
    - Explore and interact with your site installed apps whitelisted API's effortlessly - using our API Explorer. + Effortlessly explore and interact with the whitelisted API's and Bench commands of your site's installed apps using our API Explorer.
    diff --git a/dashboard/src/components/features/projects/APIExplorer.tsx b/dashboard/src/components/features/projects/APIExplorer.tsx index 63feda4..c3c027f 100644 --- a/dashboard/src/components/features/projects/APIExplorer.tsx +++ b/dashboard/src/components/features/projects/APIExplorer.tsx @@ -33,12 +33,11 @@ export const APIExplorer = () => {
    - Explore your API's + Explore your API's and Bench Commands
    - Explore and interact with your whitelisted API's effortlessly - using our API Explorer. + Effortlessly explore and interact with your whitelisted API's and Bench commands using our API Explorer.
    From d749cd560ef0432e57b54f4fd91f1818b0a3938c Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Sep 2024 16:44:15 +0530 Subject: [PATCH 029/110] Refactor: Change return type of 'ret' variable in get_project_app_commands function --- commit/api/get_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commit/api/get_commands.py b/commit/api/get_commands.py index 8f754e3..218a4ec 100644 --- a/commit/api/get_commands.py +++ b/commit/api/get_commands.py @@ -16,7 +16,7 @@ def get_project_app_commands(app: str, app_path: str = None) -> dict: return frappe.throw('You do not have permission to access this resource', frappe.PermissionError) return get_site_app_commands(app) else: - ret = {} + ret = [] try: if app_path: # Add the app's directory to the Python path From 8aaac5710e39f929fa71116463cd53fc7f25e28a Mon Sep 17 00:00:00 2001 From: Sumit Jain <59503001+sumitjain236@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:06:54 +0530 Subject: [PATCH 030/110] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 195edcd..48ebeef 100644 --- a/README.md +++ b/README.md @@ -12,5 +12,3 @@ Go ahead and create a fresh new bench - `bench get-app https://github.com/The-commit-company/commit` - `bench new-site ` - `bench --site install-app commit` - -Commit will now be accessible on https://:8000/commit. From 7e6ff1a13ac6d8138bc86517506a35df8eaa07c6 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 23 Sep 2024 14:47:54 +0530 Subject: [PATCH 031/110] Refactor: Add tooltip to display available bench commands in APIList component --- .../features/api_viewer/APIList.tsx | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/dashboard/src/components/features/api_viewer/APIList.tsx b/dashboard/src/components/features/api_viewer/APIList.tsx index 48e5a3b..0ca836e 100644 --- a/dashboard/src/components/features/api_viewer/APIList.tsx +++ b/dashboard/src/components/features/api_viewer/APIList.tsx @@ -8,6 +8,7 @@ import { AiOutlineBranches } from "react-icons/ai" import { GoPackage } from "react-icons/go" import { CommandContent } from "../commands/CommandsContent" import { HiOutlineCommandLine } from "react-icons/hi2"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" export interface APIListProps { apiList: APIData[] @@ -50,15 +51,24 @@ export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, s

    {branch_name}

    - - - - - - + + + + + + + + + + + + Click to view available bench commands in this app + + +
    From a799be76be61abe24907a99d72583848ed4ef0ed Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 23 Sep 2024 14:48:14 +0530 Subject: [PATCH 032/110] Refactor: Add tooltip and API call functionality to APIDetails component --- .../features/APIClient/APIClientContent.tsx | 275 ++++++++++++++++++ .../features/api_viewer/APIDetails.tsx | 29 +- 2 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 dashboard/src/components/features/APIClient/APIClientContent.tsx diff --git a/dashboard/src/components/features/APIClient/APIClientContent.tsx b/dashboard/src/components/features/APIClient/APIClientContent.tsx new file mode 100644 index 0000000..e75aee1 --- /dev/null +++ b/dashboard/src/components/features/APIClient/APIClientContent.tsx @@ -0,0 +1,275 @@ +import CopyButton from "@/components/common/CopyToClipboard/CopyToClipboard" +import { Button } from "@/components/ui/button" +import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog" +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" +import { Input } from "@/components/ui/input" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { Argument } from "@/types/APIData" +import { DialogClose } from "@radix-ui/react-dialog" +import { FrappeConfig, FrappeContext } from "frappe-react-sdk" +import { useCallback, useContext, useEffect, useState } from "react" +import { useForm } from "react-hook-form" +import { BsArrowRight } from "react-icons/bs" +import { FaCaretDown } from "react-icons/fa" +import { IoAdd } from "react-icons/io5"; + + +export interface APIClientContentProps { + endpoint: string + parameters?: Argument[] +} + +export const APIClientContent = ({ endpoint, parameters }: APIClientContentProps) => { + + const [requestType, setRequestType] = useState<"GET" | "POST">('GET') + + // create state of parameters which is Record where key is parameter name and value is parameter value and key is one of the argument of parameters + + const [parameterValues, setParameterValues] = useState>({}) + + const { setValue, reset } = useForm() + + const [paramsType, setParamsType] = useState<'params' | 'form-data'>('params') + + const [response, setResponse] = useState({}) + + const onParamsTypeChange = useCallback((type: 'params' | 'form-data') => { + if (type === 'params') { + setParamsType('params') + if (parameters) { + const initialParameterValues: Record = {} + parameters.forEach((parameter) => { + setValue(parameter.argument, '') + initialParameterValues[parameter.argument] = '' + }) + // setParameterValues(initialParameterValues) + } else { + // setParameterValues({}) + reset({}) + + } + } else { + setParamsType('form-data') + // setParameterValues({}) + reset({}) + } + }, [parameters]) + + useEffect(() => { + if (parameters) { + // const initialParameterValues: Record = {} + // parameters.forEach((parameter) => { + // initialParameterValues[parameter.argument] = '' + // }) + // setParameterValues(initialParameterValues) + parameters.forEach((parameter) => { + setValue(parameter.argument, '') + }) + + } + }, [parameters]) + + const { call } = useContext(FrappeContext) as FrappeConfig + + const returnString = (value: any) => { + try { + // If it's a string but contains JSON-like structure, attempt to parse it + const parsedValue = JSON.parse(value); + + if (Array.isArray(parsedValue)) { + return JSON.stringify(parsedValue); // Convert array to string + } else if (typeof parsedValue === 'object' && parsedValue !== null) { + return JSON.stringify(parsedValue); // Convert object to string + } + } catch (error) { + // If JSON.parse fails, it's not a JSON string, continue to the next checks + } + + // Check if it's already a string + if (typeof value === 'string') { + return value; // Return the string as it is + } + + // Check if it's an array + if (Array.isArray(value)) { + return JSON.stringify(value); // Convert array to string + } + + // Check if it's an object + if (typeof value === 'object' && value !== null) { + return JSON.stringify(value); // Convert object to string + } + + // If it's not string, array, or object, return the string representation of the value + return String(value); + } + + const onAPIRequest = () => { + // filter out those parameters which are empty + + const filteredParameterValues = Object.keys(parameterValues).reduce((acc, key) => { + if (parameterValues[key] !== '') { + // check if value is string if it not if it is list or object then convert it to string using JSON.stringify + acc[key] = returnString(parameterValues[key]) + } + return acc + }, {} as Record) + if (requestType === 'GET') { + // call get api with endpoint and parameterValues + call.get(endpoint, filteredParameterValues).then((response) => { + setResponse(response) + }).catch((error) => { + setResponse(error) + }) + } else { + // call post api with endpoint and parameterValues + call.post(endpoint, filteredParameterValues).then((response) => { + setResponse(response) + }).catch((error) => { + setResponse(error) + }) + } + } + + return ( + + + API Request + + Easily test and interact with your API endpoints. + +
    +
    + + + + + + setRequestType('GET')}> + GET + + setRequestType('POST')}> + POST + + + +
    + + +
    +
    +
    +
    +
    + + + + + + onParamsTypeChange('params')}> + Params + + onParamsTypeChange('form-data')}> + Form Data + + + +
    +
    + + + + + Key + + + Value + + + + + {paramsType === 'params' ? + parameters?.filter((params) => params.argument !== '')?.map((parameter) => ( + + {parameter.argument}{parameter.default ? null : *} + + setParameterValues({ ...parameterValues, [parameter.argument]: e.target.value })} + className="h-8" + /> + + + )) : parameterValues && Object.keys(parameterValues).map((key) => ( + + + setParameterValues({ ...parameterValues, [e.target.value]: parameterValues[key] })} + className="h-8" + /> + + + setParameterValues({ ...parameterValues, [key]: e.target.value })} + className="h-8" + /> + + + )) + } + +
    + {/* {paramsType === 'form-data' &&
    + +
    } */} +
    +
    +
    + +
    + +
    +
    +                                    {
    +                                        JSON.stringify(response, null, 2)
    +                                    }
    +                                
    +
    +
    +
    +
    +
    + + + + + +
    + ) +} \ No newline at end of file diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 3e26c80..3cf0c12 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -11,6 +11,10 @@ import { useFrappeGetCall } from "frappe-react-sdk" import { useMemo } from "react" import { MdOutlineFileDownload } from "react-icons/md" import Markdown from "react-markdown" +import { AiOutlineThunderbolt } from "react-icons/ai" +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" +import { Dialog, DialogTrigger } from "@/components/ui/dialog" +import { APIClientContent } from "../APIClient/APIClientContent" export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string }) => { @@ -98,7 +102,30 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
    Endpoint :
    {data?.api_path}
    - +
    + + {viewerType === 'app' && + + + + + + + + + + + Click to make an API call to this endpoint + + + } +
    From cbc9707b4745990b3ffb1c41a654e3ca9500485b Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 23 Sep 2024 20:19:05 +0530 Subject: [PATCH 033/110] Refactor: support for formData --- .../features/APIClient/APIClientContent.tsx | 274 +++++++++--------- 1 file changed, 141 insertions(+), 133 deletions(-) diff --git a/dashboard/src/components/features/APIClient/APIClientContent.tsx b/dashboard/src/components/features/APIClient/APIClientContent.tsx index e75aee1..0413c3d 100644 --- a/dashboard/src/components/features/APIClient/APIClientContent.tsx +++ b/dashboard/src/components/features/APIClient/APIClientContent.tsx @@ -8,7 +8,7 @@ import { Argument } from "@/types/APIData" import { DialogClose } from "@radix-ui/react-dialog" import { FrappeConfig, FrappeContext } from "frappe-react-sdk" import { useCallback, useContext, useEffect, useState } from "react" -import { useForm } from "react-hook-form" +import { FormProvider, useForm } from "react-hook-form" import { BsArrowRight } from "react-icons/bs" import { FaCaretDown } from "react-icons/fa" import { IoAdd } from "react-icons/io5"; @@ -23,45 +23,35 @@ export const APIClientContent = ({ endpoint, parameters }: APIClientContentProps const [requestType, setRequestType] = useState<"GET" | "POST">('GET') - // create state of parameters which is Record where key is parameter name and value is parameter value and key is one of the argument of parameters + const methods = useForm() - const [parameterValues, setParameterValues] = useState>({}) - - const { setValue, reset } = useForm() + const { setValue, reset, register, handleSubmit, watch } = useForm() const [paramsType, setParamsType] = useState<'params' | 'form-data'>('params') const [response, setResponse] = useState({}) + const data = watch() + const onParamsTypeChange = useCallback((type: 'params' | 'form-data') => { if (type === 'params') { setParamsType('params') if (parameters) { - const initialParameterValues: Record = {} parameters.forEach((parameter) => { setValue(parameter.argument, '') - initialParameterValues[parameter.argument] = '' }) - // setParameterValues(initialParameterValues) } else { - // setParameterValues({}) reset({}) } } else { setParamsType('form-data') - // setParameterValues({}) reset({}) } }, [parameters]) useEffect(() => { if (parameters) { - // const initialParameterValues: Record = {} - // parameters.forEach((parameter) => { - // initialParameterValues[parameter.argument] = '' - // }) - // setParameterValues(initialParameterValues) parameters.forEach((parameter) => { setValue(parameter.argument, '') }) @@ -104,26 +94,27 @@ export const APIClientContent = ({ endpoint, parameters }: APIClientContentProps return String(value); } - const onAPIRequest = () => { - // filter out those parameters which are empty - - const filteredParameterValues = Object.keys(parameterValues).reduce((acc, key) => { - if (parameterValues[key] !== '') { + const onSubmit = (data: any) => { + const filteredParameterValues = Object.keys(data).reduce((acc, key) => { + if (data[key] !== '') { // check if value is string if it not if it is list or object then convert it to string using JSON.stringify - acc[key] = returnString(parameterValues[key]) + acc[key] = returnString(data[key]) } return acc }, {} as Record) + + const paramsData = handleFormData(filteredParameterValues) + if (requestType === 'GET') { // call get api with endpoint and parameterValues - call.get(endpoint, filteredParameterValues).then((response) => { + call.get(endpoint, paramsData).then((response) => { setResponse(response) }).catch((error) => { setResponse(error) }) } else { // call post api with endpoint and parameterValues - call.post(endpoint, filteredParameterValues).then((response) => { + call.post(endpoint, paramsData).then((response) => { setResponse(response) }).catch((error) => { setResponse(error) @@ -131,145 +122,162 @@ export const APIClientContent = ({ endpoint, parameters }: APIClientContentProps } } + const handleFormData = (data: any) => { + if (paramsType === 'form-data') { + const formData = new FormData() + Object.keys(data).forEach((key) => { + if (key.startsWith('key-')) { + formData.append(data[key], data[key.replace('key', 'value')]) + } + }) + return formData + } + else { + return Object.keys(data)?.filter((key) => !(key.includes('key') || key.includes('value'))).reduce((acc, key) => { + acc[key] = data[key] + return acc + }, {} as Record) + } + } + return ( - - - API Request - - Easily test and interact with your API endpoints. - -
    -
    - - - + + + setRequestType('GET')}> + GET + + setRequestType('POST')}> + POST + + + +
    + + - - - setRequestType('GET')}> - GET - - setRequestType('POST')}> - POST - - - -
    - - -
    -
    -
    -
    -
    - - - - - - onParamsTypeChange('params')}> - Params - - onParamsTypeChange('form-data')}> - Form Data - - -
    -
    - - - - - Key - - - Value - - - - - {paramsType === 'params' ? - parameters?.filter((params) => params.argument !== '')?.map((parameter) => ( + +
    +
    +
    + + + + + + onParamsTypeChange('params')}> + Params + + onParamsTypeChange('form-data')}> + Form Data + + + +
    +
    +
    + + + + Key + + + Value + + + + + {paramsType === 'params' ? parameters?.filter((params) => params.argument !== '')?.map((parameter) => ( {parameter.argument}{parameter.default ? null : *} setParameterValues({ ...parameterValues, [parameter.argument]: e.target.value })} + {...register(parameter.argument)} className="h-8" /> - )) : parameterValues && Object.keys(parameterValues).map((key) => ( + )) : data && Object.keys(data)?.filter((key) => key.startsWith('key-')).map((key) => ( setParameterValues({ ...parameterValues, [e.target.value]: parameterValues[key] })} + {...register(key)} className="h-8" /> setParameterValues({ ...parameterValues, [key]: e.target.value })} + {...register(key.replace('key', 'value'))} className="h-8" /> - )) + ))} + +
    + {paramsType === 'form-data' &&
    + +
    } +
    +
    +
    + +
    + +
    +
    +                                        {
    +                                            JSON.stringify(response, null, 2)
                                             }
    -                                    
    -                                
    -                                {/* {paramsType === 'form-data' && 
    - -
    } */} +
    +
    -
    - -
    - -
    -
    -                                    {
    -                                        JSON.stringify(response, null, 2)
    -                                    }
    -                                
    -
    +
    + Note: Please use double quotes (") for parameters instead of single quotes (').
    -
    - - - - - - - + + + + + + + + ) } \ No newline at end of file From c90f382a597e1a6489f5b1fb9e31bbe2c752d8ea Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 23 Sep 2024 20:34:48 +0530 Subject: [PATCH 034/110] Refactor: Reset form data in APIClientContent component --- .../src/components/features/APIClient/APIClientContent.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dashboard/src/components/features/APIClient/APIClientContent.tsx b/dashboard/src/components/features/APIClient/APIClientContent.tsx index 0413c3d..45e55e1 100644 --- a/dashboard/src/components/features/APIClient/APIClientContent.tsx +++ b/dashboard/src/components/features/APIClient/APIClientContent.tsx @@ -59,6 +59,10 @@ export const APIClientContent = ({ endpoint, parameters }: APIClientContentProps } }, [parameters]) + useEffect(() => { + reset({}) + },[]) + const { call } = useContext(FrappeContext) as FrappeConfig const returnString = (value: any) => { From c87dad04324e6ada7031195056c13cd0e50582af Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 24 Sep 2024 12:33:59 +0530 Subject: [PATCH 035/110] fix:open app selection modal if apps is not present in location.state --- dashboard/src/pages/features/erd/ERDViewer.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/dashboard/src/pages/features/erd/ERDViewer.tsx b/dashboard/src/pages/features/erd/ERDViewer.tsx index 318d4af..000c5b6 100644 --- a/dashboard/src/pages/features/erd/ERDViewer.tsx +++ b/dashboard/src/pages/features/erd/ERDViewer.tsx @@ -23,9 +23,9 @@ export const ERDViewer = () => { const location = useLocation() - const { apps } = location.state as { apps: string[] } + const { apps } = location.state as { apps: string[] } || {} - const [selectedApps, setSelectedApps] = useState(apps) + const [selectedApps, setSelectedApps] = useState(apps ?? []) const [erdDoctypes, setERDDocTypes] = useState<{ doctype: string, project_branch: string }[]>([]) @@ -39,6 +39,12 @@ export const ERDViewer = () => { }, []) + useEffect(() => { + if (!apps) { + setOpen(true) + } + }, [apps]) + const flowRef = useRef(null) return ( @@ -113,6 +119,12 @@ export const ModuleDoctypeListDrawer = ({ open, setOpen, apps, setSelectedApps, setOpenDialog(false) } + useEffect(() => { + if (apps.length === 0) { + setOpenDialog(true) + } + }, []) + return ( <> @@ -145,7 +157,7 @@ export const ModuleDoctypeListDrawer = ({ open, setOpen, apps, setSelectedApps, : null} - {apps.length ? : null} +
    From 95a35879a2b8d239873b9b30c6fbf0df50b3fd03 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 24 Sep 2024 13:39:49 +0530 Subject: [PATCH 036/110] Refactor: Simplify getting commands from app module --- commit/api/get_commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commit/api/get_commands.py b/commit/api/get_commands.py index 218a4ec..b64187a 100644 --- a/commit/api/get_commands.py +++ b/commit/api/get_commands.py @@ -56,8 +56,8 @@ def get_site_app_commands(app: str) -> dict: # Call get_commands if it is a callable command_list = [] - if hasattr(app_command_module, 'get_commands') and callable(getattr(app_command_module, 'get_commands')): - commands_from_function = app_command_module.get_commands() + if hasattr(app_command_module, 'commands'): + commands_from_function = app_command_module.commands if commands_from_function: for command_instance in commands_from_function: help_text = getattr(command_instance, 'help', 'No help text available') From 2f58fc3fb8f274366ec5f31dd5bb56cea2df5d58 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 24 Sep 2024 17:06:34 +0530 Subject: [PATCH 037/110] Refactor: Add padding to command name in CommandComponent --- dashboard/src/components/features/commands/CommandsContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/components/features/commands/CommandsContent.tsx b/dashboard/src/components/features/commands/CommandsContent.tsx index 195111c..eb1bebd 100644 --- a/dashboard/src/components/features/commands/CommandsContent.tsx +++ b/dashboard/src/components/features/commands/CommandsContent.tsx @@ -85,7 +85,7 @@ const CommandComponent = ({ name, help }: CommandResponse) => { return (
    -
    +
    {`bench ${name}`}
    Date: Wed, 25 Sep 2024 16:02:36 +0530 Subject: [PATCH 038/110] feat:API for generating documentation for code_snippet --- commit/api/generate_documentation.py | 59 +++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/commit/api/generate_documentation.py b/commit/api/generate_documentation.py index 4cf9337..43a39df 100644 --- a/commit/api/generate_documentation.py +++ b/commit/api/generate_documentation.py @@ -2,6 +2,7 @@ import re from commit.commit.doctype.open_ai_settings.open_ai_settings import open_ai_call import frappe +from commit.api.api_explorer import get_file_content_from_path def generate_docs_for_apis(api_definitions): @@ -104,4 +105,60 @@ def generate_docs_for_chunk(api_chunk): print("Second JSON Decode Error:", e) return [] - # return cleaned_response \ No newline at end of file + # return cleaned_response + +def generate_documentation_for_api_snippet(api_path:str,code_snippet:str): + messages = [ + { + "role": "system", + "content": ( + "You are an expert documentation generator. Create detailed and comprehensive documentation " + "for the code provided below in Markdown format. Each function should have the following sections:\n\n" + "- # [Function Name] (as heading 1)\n" + "- ## Description\n Provide a detailed description of what the function does and what it is used for.\n" + "- ## Parameters\n List of parameters with their types, descriptions, and indicate which are mandatory or optional.\n" + "- ## Return Type\n Specify the type and description of the return value.\n" + "- ## Examples\n Provide code examples demonstrating how to use the function, enclosed in triple backticks (``````).\n\n" + "The response should be a valid JSON formatted as follows: " + "{function_name: , path: , documentation: }.\n" + "Ensure the response is in valid JSON format only, and does not include `---`." + ) + } + ] + + user_message = f"api path: {api_path}, code:\n{code_snippet}" + if not code_snippet: + return [] + messages.append({"role": "user", "content": user_message}) + + response_text = open_ai_call(messages) + + cleaned_response = response_text + + try: + # Check if cleaned_response is already a list (or the expected type) + if isinstance(cleaned_response, list): + return cleaned_response + # If cleaned_response is a string, attempt to decode it as JSON + elif isinstance(cleaned_response, str): + return json.loads(cleaned_response, strict=False) + else: + # Handle other unexpected types if necessary + print("Unexpected type of cleaned_response:", type(cleaned_response)) + return [] + except json.JSONDecodeError as e: + print("JSON Decode Error:", e) + print("Cleaned Response:\n", cleaned_response) + try: + # Attempt to fix common issues like single quotes or trailing commas + cleaned_response = cleaned_response.replace("'", '"') + return json.loads(cleaned_response, strict=False) + except json.JSONDecodeError as e: + print("Second JSON Decode Error:", e) + return [] + +@frappe.whitelist() +def get_documentation_for_api(project_branch: str, file_path: str,block_start: int, block_end: int,endpoint:str,viewer_type:str = 'app'): + code_snippet = get_file_content_from_path(project_branch, file_path,block_start, block_end,viewer_type) + api_path = endpoint + return generate_documentation_for_api_snippet(api_path, code_snippet) \ No newline at end of file From fdfafc9fc242012838fc35ce8d7889db66c5a3a0 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Wed, 25 Sep 2024 16:03:15 +0530 Subject: [PATCH 039/110] Refactor: Update APIDetails component to include Meta Documentation tab --- .../features/api_viewer/APIDetails.tsx | 40 +----- .../documentation/APIDocumentation.tsx | 122 ++++++++++++++++++ 2 files changed, 128 insertions(+), 34 deletions(-) create mode 100644 dashboard/src/components/features/documentation/APIDocumentation.tsx diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 3e26c80..c8f32e3 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -10,7 +10,7 @@ import { XMarkIcon } from "@heroicons/react/24/outline" import { useFrappeGetCall } from "frappe-react-sdk" import { useMemo } from "react" import { MdOutlineFileDownload } from "react-icons/md" -import Markdown from "react-markdown" +import { APIDocumentationOfSiteApp, Documentation } from "../documentation/APIDocumentation" export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string }) => { @@ -18,19 +18,6 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set return endpointData.find((endpoint: APIData) => endpoint.name === selectedEndpoint) }, [endpointData, selectedEndpoint]) - const tabs = [ - { - name: 'Parameters', content: - }, - { - name: 'Code', content: - }, - { - name: 'Bruno', content: - }, - ] - data?.documentation && tabs.push({ name: 'Documentation', content: }) - const requestTypeBgColor = (requestType: string) => { switch (requestType) { case 'GET': @@ -120,12 +107,13 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
    - + Parameters Code Bruno {data?.documentation && Documentation} + {viewerType === 'app' && Documentation} @@ -139,6 +127,9 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set {data?.documentation && } + {viewerType === 'app' && + + }
    ) @@ -210,25 +201,6 @@ export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: ) } -export const Documentation = ({ documentation }: { documentation: string }) => { - console.log('documentation', documentation) - - const renderContent = () => { - if (typeof documentation === 'string') { - return {documentation}; - } else if (typeof documentation === 'object' && documentation !== null && !Array.isArray(documentation)) { - return
    {JSON.stringify(documentation, null, 2)}
    ; - } else { - return
    Invalid documentation format
    ; - } - }; - - return ( -
    - {renderContent()} -
    - ) -} export const Bruno = ({ doc }: { doc: APIData }) => { diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx new file mode 100644 index 0000000..4e0bd2b --- /dev/null +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -0,0 +1,122 @@ +import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; +import { SpinnerLoader } from "@/components/common/FullPageLoader/SpinnerLoader"; +import { Button } from "@/components/ui/button"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; +import { APIData } from "@/types/APIData"; +import { useFrappePostCall } from "frappe-react-sdk"; +import { useMemo, useState } from "react"; +import { MdOutlineRocketLaunch } from "react-icons/md"; +import Markdown from "react-markdown"; +import MDEditor from '@uiw/react-md-editor'; +import { FiEdit, FiSave } from "react-icons/fi"; + + +export const Documentation = ({ documentation }: { documentation: string }) => { + + const renderContent = () => { + if (typeof documentation === 'string') { + return {documentation}; + } else if (typeof documentation === 'object' && documentation !== null && !Array.isArray(documentation)) { + return
    {JSON.stringify(documentation, null, 2)}
    ; + } else { + return
    Invalid documentation format
    ; + } + }; + + return ( +
    + {renderContent()} +
    + ) +} + +export interface DocumentationResponse { + function_name: string, + path: string, + documentation: string +} +export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string }) => { + + const { call, error, loading } = useFrappePostCall('commit.api.generate_documentation.get_documentation_for_api') + + const [edit, setEdit] = useState(false) + + const [documentation, setDocumentation] = useState() + + const generateDocumentation = () => { + call({ + project_branch: project_branch, + file_path: file_path, + block_start: apiData.block_start ?? 0, + block_end: apiData.block_end ?? 0, + endpoint: endPoint + }).then((res) => { + setDocumentation(res.message) + setEdit(true) + }) + } + + const onDocumentationChange = (value: string) => { + setDocumentation((documentation) => { + return { + function_name: documentation?.function_name ?? endPoint?.split('.').pop() ?? '', + path: documentation?.path ?? endPoint, + documentation: value + } + }) + } + + const previewMode = useMemo(() => { + return edit ? 'live' : 'preview' + }, [edit]) + + const SaveEditButton = () => { + if (edit) { + // code for saving the documentation + + } else { + setEdit(true) + } + } + + return ( +
    + {error && } +
    +
    + + + + + + + Generate Documentation for this API + + + + + + + + + + {edit ? 'Save Documentation' : 'Edit Documentation'} + + + +
    + onDocumentationChange(value ?? '')} + style={{ minHeight: 'calc(100vh - 24rem)', overflowY: 'auto', margin: 8, padding: 4 }} + /> +
    +
    + ) +} \ No newline at end of file From f327f730016d5cf4ebf07671da2b2978d6fe7bf7 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Wed, 25 Sep 2024 16:03:20 +0530 Subject: [PATCH 040/110] feat: Add @uiw/react-md-editor package to dependencies --- dashboard/package.json | 1 + dashboard/yarn.lock | 490 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 487 insertions(+), 4 deletions(-) diff --git a/dashboard/package.json b/dashboard/package.json index 86e0a58..7a48bb0 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -36,6 +36,7 @@ "@radix-ui/react-toast": "^1.1.4", "@radix-ui/react-tooltip": "^1.0.6", "@tanstack/react-table": "^8.9.3", + "@uiw/react-md-editor": "^4.0.4", "cal-sans": "^1.0.1", "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index 28e53fa..95d7659 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -261,6 +261,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.14.6", "@babel/runtime@^7.17.2": + 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/runtime@^7.24.5": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" @@ -1707,6 +1714,13 @@ resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.14.tgz#319b63ad6df705ee2a65a73ef042c8271e696613" integrity sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg== +"@types/hast@^2.0.0": + version "2.3.10" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.10.tgz#5c9d9e0b304bbb8879b857225c5ebab2d81d7643" + integrity sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw== + dependencies: + "@types/unist" "^2" + "@types/hast@^3.0.0": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" @@ -1740,6 +1754,11 @@ dependencies: undici-types "~5.26.4" +"@types/prismjs@^1.0.0": + version "1.26.4" + resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.4.tgz#1a9e1074619ce1d7322669e5b46fbe823925103a" + integrity sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg== + "@types/prop-types@*": version "15.7.12" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" @@ -1770,6 +1789,40 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== +"@uiw/copy-to-clipboard@~1.0.12": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@uiw/copy-to-clipboard/-/copy-to-clipboard-1.0.17.tgz#86f501ddc8a6db0b45e6899bcd9d48e0b78f233e" + integrity sha512-O2GUHV90Iw2VrSLVLK0OmNIMdZ5fgEg4NhvtwINsX+eZ/Wf6DWD0TdsK9xwV7dNRnK/UI2mQtl0a2/kRgm1m1A== + +"@uiw/react-markdown-preview@^5.0.6": + version "5.1.3" + resolved "https://registry.yarnpkg.com/@uiw/react-markdown-preview/-/react-markdown-preview-5.1.3.tgz#edbffb9e3dde910e6bc862e8d17019c838b265f0" + integrity sha512-jV02wO4XHWFk54kz7sLqOkdPgJLttSfKLyen47XgjcyGgQXU2I4WJBygmdpV2AT9m/MiQ8qrN1Y+E5Syv9ZDpw== + dependencies: + "@babel/runtime" "^7.17.2" + "@uiw/copy-to-clipboard" "~1.0.12" + react-markdown "~9.0.1" + rehype-attr "~3.0.1" + rehype-autolink-headings "~7.1.0" + rehype-ignore "^2.0.0" + rehype-prism-plus "2.0.0" + rehype-raw "^7.0.0" + rehype-rewrite "~4.0.0" + rehype-slug "~6.0.0" + remark-gfm "~4.0.0" + remark-github-blockquote-alert "^1.0.0" + unist-util-visit "^5.0.0" + +"@uiw/react-md-editor@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@uiw/react-md-editor/-/react-md-editor-4.0.4.tgz#142c42eb722035d60c1b71209e1d89b34d9fc4d4" + integrity sha512-JH9nDXXRhJtWPP4yE61VE+9ryFo9tg9v7KMwGfJCnaOOKuLF1MR3l/MNsiJCGkRjUwyto5WrU7kBSq8ODJEtYw== + dependencies: + "@babel/runtime" "^7.14.6" + "@uiw/react-markdown-preview" "^5.0.6" + rehype "~13.0.0" + rehype-prism-plus "~2.0.0" + "@ungap/structured-clone@^1.0.0", "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" @@ -1925,6 +1978,11 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bcp-47-match@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/bcp-47-match/-/bcp-47-match-2.0.3.tgz#603226f6e5d3914a581408be33b28a53144b09d0" + integrity sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ== + binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" @@ -1939,6 +1997,11 @@ bl@^5.0.0: inherits "^2.0.4" readable-stream "^3.4.0" +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2197,6 +2260,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +css-selector-parser@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-3.0.5.tgz#9b636ebccf7c4bcce5c1ac21ae27de9f01180ae9" + integrity sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -2332,6 +2400,11 @@ diff@^5.0.0, diff@^5.1.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== +direction@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/direction/-/direction-2.0.1.tgz#71800dd3c4fa102406502905d3866e65bdebb985" + integrity sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA== + dlv@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" @@ -2754,6 +2827,11 @@ get-stream@^6.0.1: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +github-slugger@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-2.0.0.tgz#52cf2f9279a21eb6c59dd385b410f0c0adda8f1a" + integrity sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2830,6 +2908,18 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +hast-util-from-html@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz#485c74785358beb80c4ba6346299311ac4c49c82" + integrity sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw== + dependencies: + "@types/hast" "^3.0.0" + devlop "^1.1.0" + hast-util-from-parse5 "^8.0.0" + parse5 "^7.0.0" + vfile "^6.0.0" + vfile-message "^4.0.0" + hast-util-from-parse5@^8.0.0: version "8.0.1" resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz#654a5676a41211e14ee80d1b1758c399a0327651" @@ -2844,6 +2934,34 @@ hast-util-from-parse5@^8.0.0: vfile-location "^5.0.0" web-namespaces "^2.0.0" +hast-util-has-property@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz#4e595e3cddb8ce530ea92f6fc4111a818d8e7f93" + integrity sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-heading-rank@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz#2d5c6f2807a7af5c45f74e623498dd6054d2aba8" + integrity sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-is-element@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz#6e31a6532c217e5b533848c7e52c9d9369ca0932" + integrity sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-parse-selector@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz#25ab00ae9e75cbc62cf7a901f68a247eade659e2" + integrity sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA== + dependencies: + "@types/hast" "^2.0.0" + hast-util-parse-selector@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" @@ -2870,6 +2988,45 @@ hast-util-raw@^9.0.0: web-namespaces "^2.0.0" zwitch "^2.0.0" +hast-util-select@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hast-util-select/-/hast-util-select-6.0.2.tgz#f1e6c583ab6227cb510383471328734342bd1d1c" + integrity sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + bcp-47-match "^2.0.0" + comma-separated-tokens "^2.0.0" + css-selector-parser "^3.0.0" + devlop "^1.0.0" + direction "^2.0.0" + hast-util-has-property "^3.0.0" + hast-util-to-string "^3.0.0" + hast-util-whitespace "^3.0.0" + not "^0.1.0" + nth-check "^2.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + unist-util-visit "^5.0.0" + zwitch "^2.0.0" + +hast-util-to-html@^9.0.0: + version "9.0.3" + resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz#a9999a0ba6b4919576a9105129fead85d37f302b" + integrity sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^3.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + hast-util-to-jsx-runtime@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz#3ed27caf8dc175080117706bf7269404a0aa4f7c" @@ -2904,6 +3061,13 @@ hast-util-to-parse5@^8.0.0: web-namespaces "^2.0.0" zwitch "^2.0.0" +hast-util-to-string@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz#2a131948b4b1b26461a2c8ac876e2c88d02946bd" + integrity sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA== + dependencies: + "@types/hast" "^3.0.0" + hast-util-whitespace@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" @@ -2911,6 +3075,17 @@ hast-util-whitespace@^3.0.0: dependencies: "@types/hast" "^3.0.0" +hastscript@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-7.2.0.tgz#0eafb7afb153d047077fa2a833dc9b7ec604d10b" + integrity sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^3.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + hastscript@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-8.0.0.tgz#4ef795ec8dee867101b9f23cc830d4baf4fd781a" @@ -3301,6 +3476,16 @@ mdast-util-find-and-replace@^2.0.0: unist-util-is "^5.0.0" unist-util-visit-parents "^5.0.0" +mdast-util-find-and-replace@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz#a6fc7b62f0994e973490e45262e4bc07607b04e0" + integrity sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA== + dependencies: + "@types/mdast" "^4.0.0" + escape-string-regexp "^5.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + mdast-util-from-markdown@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz#9421a5a247f10d31d2faed2a30df5ec89ceafcf0" @@ -3347,6 +3532,17 @@ mdast-util-gfm-autolink-literal@^1.0.0: mdast-util-find-and-replace "^2.0.0" micromark-util-character "^1.0.0" +mdast-util-gfm-autolink-literal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz#abd557630337bd30a6d5a4bd8252e1c2dc0875d5" + integrity sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ== + dependencies: + "@types/mdast" "^4.0.0" + ccount "^2.0.0" + devlop "^1.0.0" + mdast-util-find-and-replace "^3.0.0" + micromark-util-character "^2.0.0" + mdast-util-gfm-footnote@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz#ce5e49b639c44de68d5bf5399877a14d5020424e" @@ -3356,6 +3552,17 @@ mdast-util-gfm-footnote@^1.0.0: mdast-util-to-markdown "^1.3.0" micromark-util-normalize-identifier "^1.0.0" +mdast-util-gfm-footnote@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz#25a1753c7d16db8bfd53cd84fe50562bd1e6d6a9" + integrity sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.1.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + mdast-util-gfm-strikethrough@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz#5470eb105b483f7746b8805b9b989342085795b7" @@ -3364,6 +3571,15 @@ mdast-util-gfm-strikethrough@^1.0.0: "@types/mdast" "^3.0.0" mdast-util-to-markdown "^1.3.0" +mdast-util-gfm-strikethrough@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz#d44ef9e8ed283ac8c1165ab0d0dfd058c2764c16" + integrity sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + mdast-util-gfm-table@^1.0.0: version "1.0.7" resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz#3552153a146379f0f9c4c1101b071d70bbed1a46" @@ -3374,6 +3590,17 @@ mdast-util-gfm-table@^1.0.0: mdast-util-from-markdown "^1.0.0" mdast-util-to-markdown "^1.3.0" +mdast-util-gfm-table@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz#7a435fb6223a72b0862b33afbd712b6dae878d38" + integrity sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + markdown-table "^3.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + mdast-util-gfm-task-list-item@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz#b280fcf3b7be6fd0cc012bbe67a59831eb34097b" @@ -3382,6 +3609,16 @@ mdast-util-gfm-task-list-item@^1.0.0: "@types/mdast" "^3.0.0" mdast-util-to-markdown "^1.3.0" +mdast-util-gfm-task-list-item@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz#e68095d2f8a4303ef24094ab642e1047b991a936" + integrity sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + mdast-util-gfm@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz#e92f4d8717d74bdba6de57ed21cc8b9552e2d0b6" @@ -3395,6 +3632,19 @@ mdast-util-gfm@^2.0.0: mdast-util-gfm-task-list-item "^1.0.0" mdast-util-to-markdown "^1.0.0" +mdast-util-gfm@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz#3f2aecc879785c3cb6a81ff3a243dc11eca61095" + integrity sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw== + dependencies: + mdast-util-from-markdown "^2.0.0" + mdast-util-gfm-autolink-literal "^2.0.0" + mdast-util-gfm-footnote "^2.0.0" + mdast-util-gfm-strikethrough "^2.0.0" + mdast-util-gfm-table "^2.0.0" + mdast-util-gfm-task-list-item "^2.0.0" + mdast-util-to-markdown "^2.0.0" + mdast-util-mdx-expression@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz#4968b73724d320a379110d853e943a501bfd9d87" @@ -3575,6 +3825,16 @@ micromark-extension-gfm-autolink-literal@^1.0.0: micromark-util-symbol "^1.0.0" micromark-util-types "^1.0.0" +micromark-extension-gfm-autolink-literal@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz#6286aee9686c4462c1e3552a9d505feddceeb935" + integrity sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-extension-gfm-footnote@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz#05e13034d68f95ca53c99679040bc88a6f92fe2e" @@ -3589,6 +3849,20 @@ micromark-extension-gfm-footnote@^1.0.0: micromark-util-types "^1.0.0" uvu "^0.5.0" +micromark-extension-gfm-footnote@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz#4dab56d4e398b9853f6fe4efac4fc9361f3e0750" + integrity sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw== + dependencies: + devlop "^1.0.0" + micromark-core-commonmark "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-extension-gfm-strikethrough@^1.0.0: version "1.0.7" resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz#c8212c9a616fa3bf47cb5c711da77f4fdc2f80af" @@ -3601,6 +3875,18 @@ micromark-extension-gfm-strikethrough@^1.0.0: micromark-util-types "^1.0.0" uvu "^0.5.0" +micromark-extension-gfm-strikethrough@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz#86106df8b3a692b5f6a92280d3879be6be46d923" + integrity sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw== + dependencies: + devlop "^1.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-classify-character "^2.0.0" + micromark-util-resolve-all "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-extension-gfm-table@^1.0.0: version "1.0.7" resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz#dcb46074b0c6254c3fc9cc1f6f5002c162968008" @@ -3612,6 +3898,17 @@ micromark-extension-gfm-table@^1.0.0: micromark-util-types "^1.0.0" uvu "^0.5.0" +micromark-extension-gfm-table@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz#5cadedfbb29fca7abf752447967003dc3b6583c9" + integrity sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-extension-gfm-tagfilter@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz#aa7c4dd92dabbcb80f313ebaaa8eb3dac05f13a7" @@ -3619,6 +3916,13 @@ micromark-extension-gfm-tagfilter@^1.0.0: dependencies: micromark-util-types "^1.0.0" +micromark-extension-gfm-tagfilter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz#f26d8a7807b5985fba13cf61465b58ca5ff7dc57" + integrity sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg== + dependencies: + micromark-util-types "^2.0.0" + micromark-extension-gfm-task-list-item@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz#b52ce498dc4c69b6a9975abafc18f275b9dde9f4" @@ -3630,6 +3934,17 @@ micromark-extension-gfm-task-list-item@^1.0.0: micromark-util-types "^1.0.0" uvu "^0.5.0" +micromark-extension-gfm-task-list-item@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz#bcc34d805639829990ec175c3eea12bb5b781f2c" + integrity sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-extension-gfm@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz#e517e8579949a5024a493e49204e884aa74f5acf" @@ -3644,6 +3959,20 @@ micromark-extension-gfm@^2.0.0: micromark-util-combine-extensions "^1.0.0" micromark-util-types "^1.0.0" +micromark-extension-gfm@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz#3e13376ab95dd7a5cfd0e29560dfe999657b3c5b" + integrity sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w== + dependencies: + micromark-extension-gfm-autolink-literal "^2.0.0" + micromark-extension-gfm-footnote "^2.0.0" + micromark-extension-gfm-strikethrough "^2.0.0" + micromark-extension-gfm-table "^2.0.0" + micromark-extension-gfm-tagfilter "^2.0.0" + micromark-extension-gfm-task-list-item "^2.0.0" + micromark-util-combine-extensions "^2.0.0" + micromark-util-types "^2.0.0" + micromark-factory-destination@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz#eb815957d83e6d44479b3df640f010edad667b9f" @@ -4124,6 +4453,11 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== +not@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/not/-/not-0.1.0.tgz#c9691c1746c55dcfbe54cbd8bd4ff041bc2b519d" + integrity sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA== + 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" @@ -4131,6 +4465,13 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +nth-check@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -4234,6 +4575,11 @@ parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-numeric-range@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz#7c63b61190d61e4d53a1197f0c83c47bb670ffa3" + integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ== + parse5@^7.0.0: version "7.1.2" resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" @@ -4436,7 +4782,7 @@ react-is@^16.13.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-markdown@^9.0.1: +react-markdown@^9.0.1, react-markdown@~9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-9.0.1.tgz#c05ddbff67fd3b3f839f8c648e6fb35d022397d1" integrity sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg== @@ -4564,11 +4910,71 @@ recast@^0.23.2: tiny-invariant "^1.3.3" tslib "^2.0.1" +refractor@^4.8.0: + version "4.8.1" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42" + integrity sha512-/fk5sI0iTgFYlmVGYVew90AoYnNMP6pooClx/XKqyeeCQXrL0Kvgn8V0VEht5ccdljbzzF1i3Q213gcntkRExg== + dependencies: + "@types/hast" "^2.0.0" + "@types/prismjs" "^1.0.0" + hastscript "^7.0.0" + parse-entities "^4.0.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== +rehype-attr@~3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/rehype-attr/-/rehype-attr-3.0.3.tgz#36b9c3d2bd91708f0c56080bc3005cba60dec4a7" + integrity sha512-Up50Xfra8tyxnkJdCzLBIBtxOcB2M1xdeKe1324U06RAvSjYm7ULSeoM+b/nYPQPVd7jsXJ9+39IG1WAJPXONw== + dependencies: + unified "~11.0.0" + unist-util-visit "~5.0.0" + +rehype-autolink-headings@~7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz#531087e155d9df053944923efd47d99728f3b196" + integrity sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw== + dependencies: + "@types/hast" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + hast-util-heading-rank "^3.0.0" + hast-util-is-element "^3.0.0" + unified "^11.0.0" + unist-util-visit "^5.0.0" + +rehype-ignore@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/rehype-ignore/-/rehype-ignore-2.0.2.tgz#1212335d3c8bd86422c15d4a4e5afaabc0488802" + integrity sha512-BpAT/3lU9DMJ2siYVD/dSR0A/zQgD6Fb+fxkJd4j+wDVy6TYbYpK+FZqu8eM9EuNKGvi4BJR7XTZ/+zF02Dq8w== + dependencies: + hast-util-select "^6.0.0" + unified "^11.0.0" + unist-util-visit "^5.0.0" + +rehype-parse@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-9.0.0.tgz#3949faeec6f466ec57774215661e0d75469195d9" + integrity sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw== + dependencies: + "@types/hast" "^3.0.0" + hast-util-from-html "^2.0.0" + unified "^11.0.0" + +rehype-prism-plus@2.0.0, rehype-prism-plus@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/rehype-prism-plus/-/rehype-prism-plus-2.0.0.tgz#75b1e2d0dd7496125987a1732cb7d560de02a0fd" + integrity sha512-FeM/9V2N7EvDZVdR2dqhAzlw5YI49m9Tgn7ZrYJeYHIahM6gcXpH0K1y2gNnKanZCydOMluJvX2cB9z3lhY8XQ== + dependencies: + hast-util-to-string "^3.0.0" + parse-numeric-range "^1.3.0" + refractor "^4.8.0" + rehype-parse "^9.0.0" + unist-util-filter "^5.0.0" + unist-util-visit "^5.0.0" + rehype-raw@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4" @@ -4578,6 +4984,45 @@ rehype-raw@^7.0.0: hast-util-raw "^9.0.0" vfile "^6.0.0" +rehype-rewrite@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/rehype-rewrite/-/rehype-rewrite-4.0.2.tgz#7b094bb586dfda83333994cb3dbb01cb1e8c361d" + integrity sha512-rjLJ3z6fIV11phwCqHp/KRo8xuUCO8o9bFJCNw5o6O2wlLk6g8r323aRswdGBQwfXPFYeSuZdAjp4tzo6RGqEg== + dependencies: + hast-util-select "^6.0.0" + unified "^11.0.3" + unist-util-visit "^5.0.0" + +rehype-slug@~6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-6.0.0.tgz#1d21cf7fc8a83ef874d873c15e6adaee6344eaf1" + integrity sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A== + dependencies: + "@types/hast" "^3.0.0" + github-slugger "^2.0.0" + hast-util-heading-rank "^3.0.0" + hast-util-to-string "^3.0.0" + unist-util-visit "^5.0.0" + +rehype-stringify@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-10.0.0.tgz#2031cf6fdd0355393706f0474ec794c75e5492f2" + integrity sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ== + dependencies: + "@types/hast" "^3.0.0" + hast-util-to-html "^9.0.0" + unified "^11.0.0" + +rehype@~13.0.0: + version "13.0.1" + resolved "https://registry.yarnpkg.com/rehype/-/rehype-13.0.1.tgz#56384ba83955e2f3aa7eca1975b406c67d9dbd5e" + integrity sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg== + dependencies: + "@types/hast" "^3.0.0" + rehype-parse "^9.0.0" + rehype-stringify "^10.0.0" + unified "^11.0.0" + remark-gfm@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-3.0.1.tgz#0b180f095e3036545e9dddac0e8df3fa5cfee54f" @@ -4588,6 +5033,25 @@ remark-gfm@^3.0.1: micromark-extension-gfm "^2.0.0" unified "^10.0.0" +remark-gfm@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-4.0.0.tgz#aea777f0744701aa288b67d28c43565c7e8c35de" + integrity sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-gfm "^3.0.0" + micromark-extension-gfm "^3.0.0" + remark-parse "^11.0.0" + remark-stringify "^11.0.0" + unified "^11.0.0" + +remark-github-blockquote-alert@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/remark-github-blockquote-alert/-/remark-github-blockquote-alert-1.2.1.tgz#adb58d7fb57e96bc5a53674167f130029d1cb3c0" + integrity sha512-qNf2mSAoZgh3Cl23/9Y1L7S4Kbf9NsdHvYK398ab/52yEsDPDU5I4cuTcgDRrdIX7Ltc6RK+KCLRtWkbFnL6Dg== + dependencies: + unist-util-visit "^5.0.0" + remark-parse@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-11.0.0.tgz#aa60743fcb37ebf6b069204eb4da304e40db45a1" @@ -4609,6 +5073,15 @@ remark-rehype@^11.0.0: unified "^11.0.0" vfile "^6.0.0" +remark-stringify@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-11.0.0.tgz#4c5b01dd711c269df1aaae11743eb7e2e7636fd3" + integrity sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-to-markdown "^2.0.0" + unified "^11.0.0" + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -5057,7 +5530,7 @@ unified@^10.0.0: trough "^2.0.0" vfile "^5.0.0" -unified@^11.0.0: +unified@^11.0.0, unified@^11.0.3, unified@~11.0.0: version "11.0.5" resolved "https://registry.yarnpkg.com/unified/-/unified-11.0.5.tgz#f66677610a5c0a9ee90cab2b8d4d66037026d9e1" integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA== @@ -5070,6 +5543,15 @@ unified@^11.0.0: trough "^2.0.0" vfile "^6.0.0" +unist-util-filter@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/unist-util-filter/-/unist-util-filter-5.0.1.tgz#f9f3a0bdee007e040964c274dda27bac663d0a39" + integrity sha512-pHx7D4Zt6+TsfwylH9+lYhBhzyhEnCXs/lbq/Hstxno5z4gVdyc2WEW0asfjGKPyG4pEKrnBv5hdkO6+aRnQJw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + unist-util-is@^5.0.0: version "5.2.1" resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9" @@ -5138,7 +5620,7 @@ unist-util-visit@^4.0.0: unist-util-is "^5.0.0" unist-util-visit-parents "^5.1.1" -unist-util-visit@^5.0.0: +unist-util-visit@^5.0.0, unist-util-visit@~5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== @@ -5350,7 +5832,7 @@ zustand@^4.4.1: dependencies: use-sync-external-store "1.2.0" -zwitch@^2.0.0: +zwitch@^2.0.0, zwitch@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== From 8f449d5701bfe3bde1d81390bbf8f6a900b94fe6 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Wed, 25 Sep 2024 16:44:25 +0530 Subject: [PATCH 041/110] Refactor: Remove unnecessary code in Header component and adjust styling in Overview component --- dashboard/src/components/common/Header.tsx | 13 ------------- dashboard/src/pages/overview/Overview.tsx | 4 ++-- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/dashboard/src/components/common/Header.tsx b/dashboard/src/components/common/Header.tsx index e166546..f60b0fc 100644 --- a/dashboard/src/components/common/Header.tsx +++ b/dashboard/src/components/common/Header.tsx @@ -1,8 +1,5 @@ import { Link } from 'react-router-dom' import CommitLogo from '../../assets/commit-logo.png' -import { Button } from "@/components/ui/button" -import { GitHubLogoIcon } from '@radix-ui/react-icons' - export const Header = ({ text }: { text?: string }) => { return ( @@ -13,16 +10,6 @@ export const Header = ({ text }: { text?: string }) => { {text &&

    {text}

    }
    -
    - - -
    ) } \ No newline at end of file diff --git a/dashboard/src/pages/overview/Overview.tsx b/dashboard/src/pages/overview/Overview.tsx index af8c453..64090d7 100644 --- a/dashboard/src/pages/overview/Overview.tsx +++ b/dashboard/src/pages/overview/Overview.tsx @@ -9,9 +9,9 @@ export const Overview = () => { const areAppsAvailable = isSystemAppAvailable() return ( -
    +
    - {areAppsAvailable ? + {areAppsAvailable ? Projects Site Apps From c11cae779fe05ca5dbdffdc7be10a3b06329cc50 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Wed, 25 Sep 2024 16:45:02 +0530 Subject: [PATCH 042/110] chore:Styling and layout fix --- .../features/api_viewer/APIDetails.tsx | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 3cf0c12..ba2ac51 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -8,12 +8,12 @@ import { web_url } from "@/config/socket" import { APIData, Argument } from "@/types/APIData" import { XMarkIcon } from "@heroicons/react/24/outline" import { useFrappeGetCall } from "frappe-react-sdk" -import { useMemo } from "react" +import { useMemo, useState } from "react" import { MdOutlineFileDownload } from "react-icons/md" import Markdown from "react-markdown" import { AiOutlineThunderbolt } from "react-icons/ai" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" -import { Dialog, DialogTrigger } from "@/components/ui/dialog" +import { Dialog } from "@/components/ui/dialog" import { APIClientContent } from "../APIClient/APIClientContent" export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string }) => { @@ -65,11 +65,13 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set } } + const [apiOpen, setApiOpen] = useState(false) + return (
    -

    API Details

    +

    {data?.name}

    {data?.allow_guest || data?.xss_safe ?
    {data?.allow_guest && Allow Guest @@ -94,33 +96,27 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
    -
    -
    Name :
    -
    {data?.name}
    -
    -
    +
    Endpoint :
    -
    -
    {data?.api_path}
    +
    +
    + {data?.api_path} +
    +
    +
    {viewerType === 'app' && - - - - - - - - - + + + + Click to make an API call to this endpoint @@ -167,6 +163,9 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set } + + +
    ) } @@ -224,7 +223,7 @@ export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: {isLoading &&
    } - +
    @@ -286,7 +285,7 @@ export const Bruno = ({ doc }: { doc: APIData }) => { {isLoading &&
    } - +
    +
    +
    - - - - - ) From 01121d220d3040f273786fac0f76ba63eb53713d Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 27 Sep 2024 15:53:57 +0530 Subject: [PATCH 044/110] wip --- commit/api/generate_documentation.py | 14 ++-- .../features/api_viewer/APIDetails.tsx | 84 ++++--------------- .../features/api_viewer/APIList.tsx | 36 +++----- .../documentation/APIDocumentation.tsx | 37 ++++---- 4 files changed, 59 insertions(+), 112 deletions(-) diff --git a/commit/api/generate_documentation.py b/commit/api/generate_documentation.py index 43a39df..2bef1de 100644 --- a/commit/api/generate_documentation.py +++ b/commit/api/generate_documentation.py @@ -61,11 +61,11 @@ def generate_docs_for_chunk(api_chunk): "content": ( "You are an expert documentation generator. Create detailed and comprehensive documentation " "for the code provided below in Markdown format. Each function should have the following sections:\n\n" - "- **(api[Function Name])**\n" - "- **Description**: Detailed description of what the function does and what it is used for \n" - "- **Parameters**: List of parameters with their types, descriptions, and indicate which are mandatory or optional\n" - "- **Return Type**: Type and description of the return value\n" - "- **Examples**: Code examples demonstrating how to use the function (enclosed in triple backticks ``````).\n\n" + "- # [Function Name] (as heading 1)\n" + "- ## Description: Detailed description of what the function does and what it is used for \n" + "- ## Parameters: List of parameters with their types, descriptions, and indicate which are mandatory or optional\n" + "- ## Return Type: Type and description of the return value\n" + "- ## Examples: Code examples demonstrating how to use the function (enclosed using
     and  Tags`).\n\n"
                     "The response should be a valid JSON list of objects formatted as follows: "
                     "{function_name: , path: , documentation: }.\n"
                     "Ensure the response is in valid JSON format only, enclosed in triple backticks, and does not include `---`."
    @@ -77,8 +77,6 @@ def generate_docs_for_chunk(api_chunk):
             user_message = f"function name: {api['function_name']}, path: {api['path']}, code:\n{api['code']}"
             messages.append({"role": "user", "content": user_message})
     
    -    # print("Raw Response:\n", response_text)  # Log raw response for debugging
    -
         response_text = open_ai_call(messages)
     
         cleaned_response = clean_response(response_text)
    @@ -103,7 +101,7 @@ def generate_docs_for_chunk(api_chunk):
                 return json.loads(cleaned_response, strict=False)
             except json.JSONDecodeError as e:
                 print("Second JSON Decode Error:", e)
    -            return []
    +            return generate_docs_for_chunk(api_chunk)
     
         # return cleaned_response
     
    diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx
    index cf7651f..89dec49 100644
    --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx
    +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx
    @@ -8,21 +8,14 @@ import { web_url } from "@/config/socket"
     import { APIData, Argument } from "@/types/APIData"
     import { XMarkIcon } from "@heroicons/react/24/outline"
     import { useFrappeGetCall } from "frappe-react-sdk"
    -import { useMemo, useState } from "react"
    +import { useMemo } from "react"
     import { MdOutlineFileDownload } from "react-icons/md"
    -import Markdown from "react-markdown"
    -import { AiOutlineThunderbolt } from "react-icons/ai"
    -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
    -import { Dialog } from "@/components/ui/dialog"
    -import { APIClientContent } from "../APIClient/APIClientContent"
    -import { APIDocumentationOfSiteApp, Documentation } from "../documentation/APIDocumentation"
    +import { APIDocumentationOfSiteApp } from "../documentation/APIDocumentation"
     
     export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string }) => {
    -
         const data = useMemo(() => {
             return endpointData.find((endpoint: APIData) => endpoint.name === selectedEndpoint)
         }, [endpointData, selectedEndpoint])
    -
         const requestTypeBgColor = (requestType: string) => {
             switch (requestType) {
                 case 'GET':
    @@ -37,7 +30,6 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
                     return 'bg-gray-100'
             }
         }
    -
         const requestTypeBorderColor = (requestType: string) => {
             switch (requestType) {
                 case 'GET':
    @@ -52,14 +44,11 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
                     return 'ring-gray-600/20'
             }
         }
    -
    -    const [apiOpen, setApiOpen] = useState(false)
    -
         return (
             
    -

    {data?.name}

    +

    API Details

    {data?.allow_guest || data?.xss_safe ?
    {data?.allow_guest && Allow Guest @@ -84,32 +73,15 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
    -
    +
    +
    Name :
    +
    {data?.name}
    +
    +
    Endpoint :
    -
    -
    -
    - {data?.api_path} -
    - -
    -
    - {viewerType === 'app' && - - - - - - Click to make an API call to this endpoint - - - } -
    +
    +
    {data?.api_path}
    +
    @@ -130,14 +102,12 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
    - Parameters Code Bruno - {data?.documentation && Documentation} - {viewerType === 'app' && Documentation} + Documentation @@ -148,23 +118,14 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set - {data?.documentation && - - } - {viewerType === 'app' && - - } + + + - - -
    ) } - - export const ParametersTable = ({ parameters }: { parameters?: Argument[] }) => { - return ( A list of parameters that can be used in the API @@ -190,10 +151,7 @@ export const ParametersTable = ({ parameters }: { parameters?: Argument[] }) =>
    ) } - - export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: { apiData: APIData, project_branch: string, file_path: string, viewerType: string }) => { - const { data, error, isLoading } = useFrappeGetCall<{ message: { file_content: string } }>('commit.api.api_explorer.get_file_content_from_path', { project_branch: project_branch, file_path: file_path, @@ -207,7 +165,6 @@ export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: const copyValue = () => { const content = JSON.parse(JSON.stringify(data?.message?.file_content ?? []) ?? '[]') return content?.join('') - } return (
    @@ -215,7 +172,7 @@ export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: {isLoading &&
    } - +
    @@ -227,17 +184,13 @@ export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }:
    ) } - - export const Bruno = ({ doc }: { doc: APIData }) => { - const rest = useMemo(() => { if (doc) { const { allow_guest, xss_safe, documentation, block_end, block_start, index, ...rest } = doc return rest } }, [doc]) - const { data, error, isLoading } = useFrappeGetCall('commit.api.bruno.generate_bruno_file', { data: JSON.stringify(rest), type: 'copy' @@ -245,20 +198,17 @@ export const Bruno = ({ doc }: { doc: APIData }) => { revalidateOnFocus: false, revalidateIfStale: false, }) - const copyValue = () => { const content = JSON.parse(JSON.stringify(data ?? '') ?? '[]') return content - } - return (
    {error && } {isLoading &&
    } - +
    - - - - - - - - - - - - Click to view available bench commands in this app - - - + + + + + +
    @@ -93,13 +83,13 @@ export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, s
    {/* fixed height container */}
    - +
    ) } -export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint }: { list: APIData[], setSelectedEndpoint: (endpoint: string) => void, selectedEndpoint?: string }) => { +export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint, searchQuery }: { list: APIData[], setSelectedEndpoint: (endpoint: string) => void, selectedEndpoint?: string, searchQuery?: string }) => { return (
      @@ -138,8 +128,8 @@ export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint }: { list
    {/* create a div which is at fixed location and should be stick bottom which will show total list count at right corner of same w as above ul*/} {list.length &&
    -

    Total {list.length} API's

    +

    {list.length} API's {searchQuery ? "found" : ''}

    }
    ) -} +} \ No newline at end of file diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx index 4e0bd2b..e6c612c 100644 --- a/dashboard/src/components/features/documentation/APIDocumentation.tsx +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -9,6 +9,7 @@ import { MdOutlineRocketLaunch } from "react-icons/md"; import Markdown from "react-markdown"; import MDEditor from '@uiw/react-md-editor'; import { FiEdit, FiSave } from "react-icons/fi"; +import { isSystemManager } from "@/utils/roles"; export const Documentation = ({ documentation }: { documentation: string }) => { @@ -35,13 +36,24 @@ export interface DocumentationResponse { path: string, documentation: string } -export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string }) => { +export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint, viewerType }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string, viewerType: string }) => { + + const renderContent = () => { + // return string by type checking + if (typeof apiData?.documentation === 'string') { + return apiData.documentation + } else if (typeof apiData?.documentation === 'object' && apiData?.documentation !== null && !Array.isArray(apiData?.documentation)) { + return JSON.stringify(apiData?.documentation, null, 2) + } else { + return '' + } + } const { call, error, loading } = useFrappePostCall('commit.api.generate_documentation.get_documentation_for_api') const [edit, setEdit] = useState(false) - const [documentation, setDocumentation] = useState() + const [documentation, setDocumentation] = useState(renderContent()) const generateDocumentation = () => { call({ @@ -49,21 +61,16 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, file_path: file_path, block_start: apiData.block_start ?? 0, block_end: apiData.block_end ?? 0, - endpoint: endPoint + endpoint: endPoint, + viewer_type: viewerType }).then((res) => { - setDocumentation(res.message) + setDocumentation(res.message?.documentation ?? '') setEdit(true) }) } const onDocumentationChange = (value: string) => { - setDocumentation((documentation) => { - return { - function_name: documentation?.function_name ?? endPoint?.split('.').pop() ?? '', - path: documentation?.path ?? endPoint, - documentation: value - } - }) + setDocumentation(value) } const previewMode = useMemo(() => { @@ -79,11 +86,13 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, } } + const isCreateAccess = isSystemManager(); + return (
    {error && }
    -
    + {isCreateAccess &&
    @@ -109,9 +118,9 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, -
    +
    } onDocumentationChange(value ?? '')} style={{ minHeight: 'calc(100vh - 24rem)', overflowY: 'auto', margin: 8, padding: 4 }} From 16adedb68e54bcdae3147729a56a049c26683fb5 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 27 Sep 2024 18:08:00 +0530 Subject: [PATCH 045/110] refactor:added last updated timestamp to each documentation --- commit/api/api_explorer.py | 1 + commit/api/generate_documentation.py | 10 ++++---- .../features/api_viewer/APIDetails.tsx | 2 +- .../documentation/APIDocumentation.tsx | 23 +++++++++++++++---- dashboard/src/types/APIData.ts | 1 + 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/commit/api/api_explorer.py b/commit/api/api_explorer.py index ef457cb..dc4001d 100644 --- a/commit/api/api_explorer.py +++ b/commit/api/api_explorer.py @@ -18,6 +18,7 @@ def get_apis_for_project(project_branch: str): for doc in documentation: if doc.get("function_name") == api.get("name") and doc.get("path") == api.get("api_path"): api["documentation"] = doc.get("documentation") + api["last_updated"] = doc.get("last_updated") break app_name, organization, app_logo = frappe.db.get_value("Commit Project", branch_doc.project, ["app_name", "org", "image"]) diff --git a/commit/api/generate_documentation.py b/commit/api/generate_documentation.py index 2bef1de..3e0e68f 100644 --- a/commit/api/generate_documentation.py +++ b/commit/api/generate_documentation.py @@ -67,14 +67,14 @@ def generate_docs_for_chunk(api_chunk): "- ## Return Type: Type and description of the return value\n" "- ## Examples: Code examples demonstrating how to use the function (enclosed using
     and  Tags`).\n\n"
                     "The response should be a valid JSON list of objects formatted as follows: "
    -                "{function_name: , path: , documentation: }.\n"
    +                "{function_name: , path: , last_updated:, documentation: }.\n"
                     "Ensure the response is in valid JSON format only, enclosed in triple backticks, and does not include `---`."
                 )
             }
         ]
    -
    +    last_updated = frappe.utils.now()
         for api in api_chunk:
    -        user_message = f"function name: {api['function_name']}, path: {api['path']}, code:\n{api['code']}"
    +        user_message = f"function name: {api['function_name']}, path: {api['path']}, last_updated:{last_updated} ,code:\n{api['code']}"
             messages.append({"role": "user", "content": user_message})
     
         response_text = open_ai_call(messages)
    @@ -118,13 +118,13 @@ def generate_documentation_for_api_snippet(api_path:str,code_snippet:str):
                     "- ## Return Type\n Specify the type and description of the return value.\n"
                     "- ## Examples\n Provide code examples demonstrating how to use the function, enclosed in triple backticks (``````).\n\n"
                     "The response should be a valid JSON formatted as follows: "
    -                "{function_name: , path: , documentation: }.\n"
    +                "{function_name: , path: , last_updated:, documentation: }.\n"
                     "Ensure the response is in valid JSON format only, and does not include `---`."
                 )
             }
         ]
         
    -    user_message = f"api path: {api_path}, code:\n{code_snippet}"
    +    user_message = f"api path: {api_path}, last_updated:{frappe.utils.now()}, code:\n{code_snippet}"
         if not code_snippet:
             return []
         messages.append({"role": "user", "content": user_message})
    diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx
    index 89dec49..46ab477 100644
    --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx
    +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx
    @@ -79,7 +79,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
                             
    Endpoint :
    -
    +
    {data?.api_path}
    diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx index e6c612c..8d1bbd9 100644 --- a/dashboard/src/components/features/documentation/APIDocumentation.tsx +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -10,6 +10,8 @@ import Markdown from "react-markdown"; import MDEditor from '@uiw/react-md-editor'; import { FiEdit, FiSave } from "react-icons/fi"; import { isSystemManager } from "@/utils/roles"; +import { IoMdClose } from "react-icons/io"; +import { convertFrappeTimestampToTimeAgo } from "@/components/utils/dateconversion"; export const Documentation = ({ documentation }: { documentation: string }) => { @@ -92,8 +94,10 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path,
    {error && }
    - {isCreateAccess &&
    - +
    +
    Last Docs Updated - {convertFrappeTimestampToTimeAgo(apiData?.last_updated)}
    + {isCreateAccess &&
    + {!edit && } @@ -113,17 +120,23 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, {edit ? : } - + {edit ? 'Save Documentation' : 'Edit Documentation'}
    } +
    onDocumentationChange(value ?? '')} - style={{ minHeight: 'calc(100vh - 24rem)', overflowY: 'auto', margin: 8, padding: 4 }} + style={{ + minHeight: (apiData?.last_updated || isCreateAccess) ? 'calc(100vh - 24rem)' : 'calc(100vh - 21rem)', + overflowY: 'auto', margin: 8, padding: 4 + }} />
    diff --git a/dashboard/src/types/APIData.ts b/dashboard/src/types/APIData.ts index e982dcb..3fac31a 100644 --- a/dashboard/src/types/APIData.ts +++ b/dashboard/src/types/APIData.ts @@ -13,6 +13,7 @@ export interface APIData { block_start: number block_end: number documentation?: string + last_updated: string } export interface Argument { From f70a6d94afcf0de245be3cf515c1e42b35381c47 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 27 Sep 2024 18:08:14 +0530 Subject: [PATCH 046/110] refactor: Update APIViewer and AppAPIViewer components - Add useEffect and useRef hooks to handle URL query parameters - Update selected endpoint based on URL query parameter - Update URL search params when selected endpoint changes - Adjust width of APIList and APIDetails components based on selected endpoint --- .../features/api_viewer/APIList.tsx | 47 +++++++++++++--- .../pages/features/api_viewer/APIViewer.tsx | 55 +++++++++++++++---- .../features/api_viewer/AppAPIViewer.tsx | 38 +++++++++++-- 3 files changed, 115 insertions(+), 25 deletions(-) diff --git a/dashboard/src/components/features/api_viewer/APIList.tsx b/dashboard/src/components/features/api_viewer/APIList.tsx index 019c9be..fefa419 100644 --- a/dashboard/src/components/features/api_viewer/APIList.tsx +++ b/dashboard/src/components/features/api_viewer/APIList.tsx @@ -3,7 +3,7 @@ import { Dialog, DialogTrigger } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { APIData } from "@/types/APIData" -import { useEffect, useMemo, useState } from "react" +import { useEffect, useMemo, useRef, useState } from "react" import { AiOutlineBranches } from "react-icons/ai" import { GoPackage } from "react-icons/go" import { CommandContent } from "../commands/CommandsContent" @@ -16,9 +16,10 @@ export interface APIListProps { setSelectedEndpoint: (endpoint: string) => void selectedEndpoint?: string path_to_folder: string + listRef?: React.RefObject } -export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, selectedEndpoint, path_to_folder }: APIListProps) => { +export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, selectedEndpoint, path_to_folder, listRef }: APIListProps) => { const [searchQuery, setSearchQuery] = useState('') const [requestTypeFilter, setRequestTypeFilter] = useState('All') @@ -33,7 +34,18 @@ export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, s }, [searchQuery, apiList, requestTypeFilter]) useEffect(() => { - setSelectedEndpoint(filterList[0]?.name ?? '') + const searchParams = new URLSearchParams(window.location.search) + const endpointFromURL = searchParams.get('api') + if (endpointFromURL) { + if (filterList.map((api) => api.name).includes(endpointFromURL)) { + setSelectedEndpoint(endpointFromURL) + } else { + setSelectedEndpoint(filterList[0]?.name ?? '') + } + } + else { + setSelectedEndpoint(filterList[0]?.name ?? '') + } }, [filterList, setSelectedEndpoint]) return ( @@ -83,16 +95,28 @@ export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, s
    {/* fixed height container */}
    - +
    ) } -export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint, searchQuery }: { list: APIData[], setSelectedEndpoint: (endpoint: string) => void, selectedEndpoint?: string, searchQuery?: string }) => { +export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint, searchQuery, listRef }: { list: APIData[], setSelectedEndpoint: (endpoint: string) => void, selectedEndpoint?: string, searchQuery?: string, listRef?: React.RefObject }) => { + + const itemRefs = useRef<(HTMLLIElement | null)[]>([]); + + useEffect(() => { + if (listRef?.current && selectedEndpoint) { + const selectedElement = itemRefs?.current?.find(item => item?.dataset.endpoint === selectedEndpoint); + if (selectedElement) { + selectedElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + } + }, []); + return ( -
    -
      +
      +
        {list.length === 0 && (

        Sorry we couldn't find what you were looking for.

        @@ -100,7 +124,12 @@ export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint, searchQu
        )} {list.map((person: APIData, index: number) => ( -
      • setSelectedEndpoint(person.name)}> +
      • { + if (el) { + el.dataset.endpoint = person.name; + itemRefs.current[index] = el; + } + }} className={`flex justify-between gap-x-6 p-2 hover:bg-gray-100 cursor-pointer group ${selectedEndpoint === person.name ? 'bg-gray-100' : ''} `} onClick={() => setSelectedEndpoint(person.name)}>

        {person.name}

        @@ -127,7 +156,7 @@ export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint, searchQu ))}
      {/* create a div which is at fixed location and should be stick bottom which will show total list count at right corner of same w as above ul*/} - {list.length &&
      + {list.length &&

      {list.length} API's {searchQuery ? "found" : ''}

      }
      diff --git a/dashboard/src/pages/features/api_viewer/APIViewer.tsx b/dashboard/src/pages/features/api_viewer/APIViewer.tsx index a7a7bd5..65f78d1 100644 --- a/dashboard/src/pages/features/api_viewer/APIViewer.tsx +++ b/dashboard/src/pages/features/api_viewer/APIViewer.tsx @@ -1,9 +1,9 @@ import { APIDetails } from "@/components/features/api_viewer/APIDetails" import { APIList } from "@/components/features/api_viewer/APIList" -import { useState } from "react" +import { useEffect, useRef, useState } from "react" import { useFrappeGetCall } from "frappe-react-sdk" import { APIData } from "@/types/APIData" -import { useParams } from "react-router-dom" +import { useNavigate, useParams } from "react-router-dom" import { Header } from "@/components/common/Header" import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner" @@ -33,14 +33,46 @@ export const APIViewerContainer = () => { export const APIViewer = ({ projectBranch }: { projectBranch: string }) => { const [selectedendpoint, setSelectedEndpoint] = useState('') + const navigate = useNavigate() - const { data, isLoading, error } = useFrappeGetCall<{ message: GetAPIResponse }>('commit.api.api_explorer.get_apis_for_project', { - project_branch: projectBranch - }, undefined, { - revalidateOnFocus: false, - revalidateIfStale: false, - onSuccess: (d: { message: GetAPIResponse }) => setSelectedEndpoint(d.message.apis[0].name) - }) + const listRef = useRef(null); + + // Fetch the query parameters from the URL + useEffect(() => { + const searchParams = new URLSearchParams(window.location.search) + const endpointFromURL = searchParams.get('api') + + // Set selected endpoint from URL if available + if (endpointFromURL) { + setSelectedEndpoint(endpointFromURL) + } + }, []) + + // Update the URL search params when selectedEndpoint changes + useEffect(() => { + if (selectedendpoint) { + const searchParams = new URLSearchParams(window.location.search) + searchParams.set('api', selectedendpoint) + navigate({ search: searchParams.toString() }, { replace: true }) + } + }, [selectedendpoint, navigate]) + + const { data, isLoading, error } = useFrappeGetCall<{ message: GetAPIResponse }>( + 'commit.api.api_explorer.get_apis_for_project', + { + project_branch: projectBranch + }, + undefined, + { + revalidateOnFocus: false, + revalidateIfStale: false, + onSuccess: (d: { message: GetAPIResponse }) => { + if (!selectedendpoint) { + setSelectedEndpoint(d.message.apis[0].name) + } + } + } + ) if (isLoading) { return @@ -51,7 +83,7 @@ export const APIViewer = ({ projectBranch }: { projectBranch: string }) => {
      {error && } {data &&
      -
      +
      { setSelectedEndpoint={setSelectedEndpoint} selectedEndpoint={selectedendpoint} path_to_folder={data?.message.path_to_folder} + listRef={listRef} />
      {selectedendpoint && (
      { export const AppAPIViewer = ({ appName }: { appName: string }) => { const [selectedendpoint, setSelectedEndpoint] = useState('') + const navigate = useNavigate() + + const listRef = useRef(null); + + // Fetch the query parameters from the URL + useEffect(() => { + const searchParams = new URLSearchParams(window.location.search) + const endpointFromURL = searchParams.get('api') + + // Set selected endpoint from URL if available + if (endpointFromURL) { + setSelectedEndpoint(endpointFromURL) + } + }, []) + + // Update the URL search params when selectedEndpoint changes + useEffect(() => { + if (selectedendpoint) { + const searchParams = new URLSearchParams(window.location.search) + searchParams.set('api', selectedendpoint) + navigate({ search: searchParams.toString() }, { replace: true }) + } + }, [selectedendpoint, navigate]) const { data, isLoading, error } = useFrappeGetCall<{ message: GetAPIResponse }>('commit.api.meta_data.get_apis_for_app', { app_name: appName }, undefined, { revalidateIfStale: false, revalidateOnFocus: false, - onSuccess: (d: { message: GetAPIResponse }) => setSelectedEndpoint(d.message.apis?.[0]?.name) + onSuccess: (d: { message: GetAPIResponse }) => { + if (!selectedendpoint) { + setSelectedEndpoint(d.message.apis[0].name) + } + } }) if (isLoading) { @@ -44,7 +71,7 @@ export const AppAPIViewer = ({ appName }: { appName: string }) => {
      {error && } {data &&
      -
      +
      { setSelectedEndpoint={setSelectedEndpoint} selectedEndpoint={selectedendpoint} path_to_folder="" + listRef={listRef} />
      @@ -59,7 +87,7 @@ export const AppAPIViewer = ({ appName }: { appName: string }) => { {selectedendpoint && (
      From d374b4d6ce6aa09cadfead32dbadac6589065946 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 27 Sep 2024 19:01:42 +0530 Subject: [PATCH 047/110] fix:position from sticky to fixed --- dashboard/src/pages/features/erd/ERDViewer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/pages/features/erd/ERDViewer.tsx b/dashboard/src/pages/features/erd/ERDViewer.tsx index 000c5b6..9f4c542 100644 --- a/dashboard/src/pages/features/erd/ERDViewer.tsx +++ b/dashboard/src/pages/features/erd/ERDViewer.tsx @@ -178,7 +178,7 @@ export const ModuleDoctypeListDrawer = ({ open, setOpen, apps, setSelectedApps,
      -
      +
      From f2b332b7253ccfff36208ca14793d4a8ff7a5e26 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 27 Sep 2024 19:01:51 +0530 Subject: [PATCH 048/110] refactor: Simplify APIDocumentation component and extract AllButton component --- .../documentation/APIDocumentation.tsx | 77 +++++++++++-------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx index 8d1bbd9..3da8d0d 100644 --- a/dashboard/src/components/features/documentation/APIDocumentation.tsx +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -94,39 +94,12 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path,
      {error && }
      -
      -
      Last Docs Updated - {convertFrappeTimestampToTimeAgo(apiData?.last_updated)}
      - {isCreateAccess &&
      - {!edit && - - - - - - Generate Documentation for this API - - - } - {edit && } - - - - - - - {edit ? 'Save Documentation' : 'Edit Documentation'} - - - -
      } -
      + {apiData?.last_updated ?
      +
      + Last Docs Updated - {convertFrappeTimestampToTimeAgo(apiData?.last_updated)} +
      + {isCreateAccess && } +
      : (isCreateAccess && )}
      ) +} + +export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveEditButton }: { generateDocumentation: () => void, loading: boolean, edit: boolean, setEdit: (value: boolean) => void, SaveEditButton: () => void }) => { + + return ( +
      +
      + {!edit && + + + + + + Generate Documentation for this API + + + } + {edit && } + + + + + + + {edit ? 'Save Documentation' : 'Edit Documentation'} + + + +
      +
      + ) } \ No newline at end of file From 446c364a9adb0a759cb3dd136327fee8eb210453 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 29 Sep 2024 13:03:18 +0530 Subject: [PATCH 049/110] feat: Add Commit Branch Documentation doctype and related files --- .../commit_branch_documentation/__init__.py | 0 .../commit_branch_documentation.js | 8 +++ .../commit_branch_documentation.json | 52 +++++++++++++++++++ .../commit_branch_documentation.py | 9 ++++ .../test_commit_branch_documentation.py | 9 ++++ 5 files changed, 78 insertions(+) create mode 100644 commit/commit/doctype/commit_branch_documentation/__init__.py create mode 100644 commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.js create mode 100644 commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.json create mode 100644 commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.py create mode 100644 commit/commit/doctype/commit_branch_documentation/test_commit_branch_documentation.py diff --git a/commit/commit/doctype/commit_branch_documentation/__init__.py b/commit/commit/doctype/commit_branch_documentation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.js b/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.js new file mode 100644 index 0000000..79e7e2d --- /dev/null +++ b/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, The Commit Company and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Commit Branch Documentation", { +// refresh(frm) { + +// }, +// }); diff --git a/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.json b/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.json new file mode 100644 index 0000000..a09a825 --- /dev/null +++ b/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.json @@ -0,0 +1,52 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "field:app", + "creation": "2024-09-29 12:24:08.997955", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "app", + "documentation" + ], + "fields": [ + { + "fieldname": "app", + "fieldtype": "Data", + "in_list_view": 1, + "label": "App", + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "documentation", + "fieldtype": "JSON", + "label": "Documentation" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-09-29 12:29:40.251915", + "modified_by": "Administrator", + "module": "commit", + "name": "Commit Branch Documentation", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.py b/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.py new file mode 100644 index 0000000..c84c245 --- /dev/null +++ b/commit/commit/doctype/commit_branch_documentation/commit_branch_documentation.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class CommitBranchDocumentation(Document): + pass diff --git a/commit/commit/doctype/commit_branch_documentation/test_commit_branch_documentation.py b/commit/commit/doctype/commit_branch_documentation/test_commit_branch_documentation.py new file mode 100644 index 0000000..cc8937a --- /dev/null +++ b/commit/commit/doctype/commit_branch_documentation/test_commit_branch_documentation.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestCommitBranchDocumentation(FrappeTestCase): + pass From b2958acd813b0042de301da8362818a123e1c3b3 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 29 Sep 2024 13:04:19 +0530 Subject: [PATCH 050/110] chore: Update SpinnerLoader component to accept style prop and pass mutate to APIDetails --- .../src/components/common/FullPageLoader/SpinnerLoader.tsx | 7 +++++-- .../src/components/features/api_viewer/APIDetails.tsx | 4 ++-- dashboard/src/pages/features/api_viewer/APIViewer.tsx | 3 ++- dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/dashboard/src/components/common/FullPageLoader/SpinnerLoader.tsx b/dashboard/src/components/common/FullPageLoader/SpinnerLoader.tsx index f5088f3..56f000e 100644 --- a/dashboard/src/components/common/FullPageLoader/SpinnerLoader.tsx +++ b/dashboard/src/components/common/FullPageLoader/SpinnerLoader.tsx @@ -45,14 +45,17 @@ export const AsyncSpinnerLoader: React.FC = ({ export interface SpinnerLoaderProps { className?: string; + style?: React.CSSProperties; } -export const SpinnerLoader = ({ className }: SpinnerLoaderProps) => { +export const SpinnerLoader = ({ className, style }: SpinnerLoaderProps) => { return (
      + role="status" + style={style} + >
      ) } \ No newline at end of file diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 46ab477..799f6cf 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -12,7 +12,7 @@ import { useMemo } from "react" import { MdOutlineFileDownload } from "react-icons/md" import { APIDocumentationOfSiteApp } from "../documentation/APIDocumentation" -export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string }) => { +export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType, mutate }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string, mutate: () => void }) => { const data = useMemo(() => { return endpointData.find((endpoint: APIData) => endpoint.name === selectedEndpoint) }, [endpointData, selectedEndpoint]) @@ -119,7 +119,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set - +
      diff --git a/dashboard/src/pages/features/api_viewer/APIViewer.tsx b/dashboard/src/pages/features/api_viewer/APIViewer.tsx index 65f78d1..288c462 100644 --- a/dashboard/src/pages/features/api_viewer/APIViewer.tsx +++ b/dashboard/src/pages/features/api_viewer/APIViewer.tsx @@ -57,7 +57,7 @@ export const APIViewer = ({ projectBranch }: { projectBranch: string }) => { } }, [selectedendpoint, navigate]) - const { data, isLoading, error } = useFrappeGetCall<{ message: GetAPIResponse }>( + const { data, isLoading, error, mutate } = useFrappeGetCall<{ message: GetAPIResponse }>( 'commit.api.api_explorer.get_apis_for_project', { project_branch: projectBranch @@ -106,6 +106,7 @@ export const APIViewer = ({ projectBranch }: { projectBranch: string }) => { selectedEndpoint={selectedendpoint} setSelectedEndpoint={setSelectedEndpoint} viewerType="project" + mutate={mutate} />
      )} diff --git a/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx b/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx index 127d4e2..e11bd33 100644 --- a/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx +++ b/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx @@ -49,7 +49,7 @@ export const AppAPIViewer = ({ appName }: { appName: string }) => { } }, [selectedendpoint, navigate]) - const { data, isLoading, error } = useFrappeGetCall<{ message: GetAPIResponse }>('commit.api.meta_data.get_apis_for_app', { + const { data, isLoading, error, mutate } = useFrappeGetCall<{ message: GetAPIResponse }>('commit.api.meta_data.get_apis_for_app', { app_name: appName }, undefined, { revalidateIfStale: false, @@ -89,7 +89,7 @@ export const AppAPIViewer = ({ appName }: { appName: string }) => { className={`fixed z-10 right-0 w-[80vw] h-full bg-white shadow-lg transition-transform transform ${selectedendpoint ? 'translate-x-0' : 'translate-x-full' } md:relative md:translate-x-0 sm:w-[55%]`} > - +
      )}
      } From 068e488e20b7b7ab52c71f36d55e66bb086ac88d Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 29 Sep 2024 13:07:37 +0530 Subject: [PATCH 051/110] feat:save documentation for project_branch or site_app --- commit/api/generate_documentation.py | 82 ++++++++++++++++++- .../documentation/APIDocumentation.tsx | 55 ++++++------- 2 files changed, 105 insertions(+), 32 deletions(-) diff --git a/commit/api/generate_documentation.py b/commit/api/generate_documentation.py index 3e0e68f..a11d08d 100644 --- a/commit/api/generate_documentation.py +++ b/commit/api/generate_documentation.py @@ -159,4 +159,84 @@ def generate_documentation_for_api_snippet(api_path:str,code_snippet:str): def get_documentation_for_api(project_branch: str, file_path: str,block_start: int, block_end: int,endpoint:str,viewer_type:str = 'app'): code_snippet = get_file_content_from_path(project_branch, file_path,block_start, block_end,viewer_type) api_path = endpoint - return generate_documentation_for_api_snippet(api_path, code_snippet) \ No newline at end of file + return generate_documentation_for_api_snippet(api_path, code_snippet) + +@frappe.whitelist() +def save_documentation(project_branch:str,endpoint:str,documentation:str,viewer_type:str = 'app'): + # Save the documentation to the project branch + # 1. Check for viewer_type app or project + # 2. If viewer_type is app, then check the document is already present in Commit Branch Documentation doctype + # 3. If document present then loop over documentation check if the function_name and path matches then update the documentation else create a new dict and append to the documentation + # 4. If document not present then create a new document and append the documentation + # 5. If viewer_type is project then check the document is already present in Commit Project Branch doctype + # 6. If document present then loop over documentation check if the function_name and path matches then update the documentation else create a new dict and append to the documentation + # 7. If document not present then create a new document and append the documentation + + if viewer_type == "app": + # Check if the document is already present in Commit Branch Documentation doctype + save_documentation_for_site_app(project_branch, endpoint, documentation) + else: + save_documentation_for_project_branch(project_branch, endpoint, documentation) + +def save_documentation_for_project_branch(project_branch:str,endpoint:str,documentation:str): + + doc = frappe.get_doc("Commit Project Branch", project_branch) + docs = json.loads(doc.documentation) if doc.documentation else {} + apis = docs.get("apis", []) + + # apis is list of dict with keys function_name, path, last_updated, documentation + # loop over apis and check if function_name and path matches then update the documentation else create a new dict and append to the documentation + found = False + for api in apis: + if api.get("function_name") == endpoint.split(".")[-1] and api.get("path") == endpoint: + api["documentation"] = documentation + api["last_updated"] = frappe.utils.now() + found = True + break + if not found: + apis.append({ + "function_name": endpoint.split(".")[-1], + "path": endpoint, + "last_updated": frappe.utils.now(), + "documentation": documentation + }) + + doc.documentation = json.dumps({"apis": apis}) + doc.save() + +def save_documentation_for_site_app(project_branch:str,endpoint:str,documentation:str): + + if frappe.db.exists("Commit Branch Documentation",project_branch): + doc = frappe.get_doc("Commit Branch Documentation", project_branch) + docs = json.loads(doc.documentation) if doc.documentation else {} + apis = docs.get("apis", []) + + # apis is list of dict with keys function_name, path, last_updated, documentation + # loop over apis and check if function_name and path matches then update the documentation else create a new dict and append to the documentation + found = False + for api in apis: + if api.get("function_name") == endpoint.split(".")[-1] and api.get("path") == endpoint: + api["documentation"] = documentation + api["last_updated"] = frappe.utils.now() + found = True + break + if not found: + apis.append({ + "function_name": endpoint.split(".")[-1], + "path": endpoint, + "last_updated": frappe.utils.now(), + "documentation": documentation + }) + doc.documentation = json.dumps({"apis": apis}) + doc.save() + else: + # Create a new document and append the documentation + doc = frappe.new_doc("Commit Branch Documentation") + doc.app = project_branch + doc.documentation = json.dumps({"apis": [{ + "function_name": endpoint.split(".")[-1], + "path": endpoint, + "last_updated": frappe.utils.now(), + "documentation": documentation + }]}) + doc.save() \ No newline at end of file diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx index 3da8d0d..cb4ee62 100644 --- a/dashboard/src/components/features/documentation/APIDocumentation.tsx +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -4,41 +4,20 @@ import { Button } from "@/components/ui/button"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { APIData } from "@/types/APIData"; import { useFrappePostCall } from "frappe-react-sdk"; -import { useMemo, useState } from "react"; +import { useCallback, useMemo, useState } from "react"; import { MdOutlineRocketLaunch } from "react-icons/md"; -import Markdown from "react-markdown"; import MDEditor from '@uiw/react-md-editor'; import { FiEdit, FiSave } from "react-icons/fi"; import { isSystemManager } from "@/utils/roles"; import { IoMdClose } from "react-icons/io"; import { convertFrappeTimestampToTimeAgo } from "@/components/utils/dateconversion"; - -export const Documentation = ({ documentation }: { documentation: string }) => { - - const renderContent = () => { - if (typeof documentation === 'string') { - return {documentation}; - } else if (typeof documentation === 'object' && documentation !== null && !Array.isArray(documentation)) { - return
      {JSON.stringify(documentation, null, 2)}
      ; - } else { - return
      Invalid documentation format
      ; - } - }; - - return ( -
      - {renderContent()} -
      - ) -} - export interface DocumentationResponse { function_name: string, path: string, documentation: string } -export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint, viewerType }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string, viewerType: string }) => { +export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint, viewerType, mutate }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string, viewerType: string, mutate: () => void }) => { const renderContent = () => { // return string by type checking @@ -79,14 +58,25 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, return edit ? 'live' : 'preview' }, [edit]) - const SaveEditButton = () => { + const { call: saveCall } = useFrappePostCall('commit.api.generate_documentation.save_documentation') + + const SaveEditButton = useCallback(() => { if (edit) { // code for saving the documentation + saveCall({ + project_branch: project_branch, + endpoint: endPoint, + documentation: documentation ?? '', + viewer_type: viewerType + }).then(() => { + mutate() + setEdit(false) + }) } else { setEdit(true) } - } + }, [edit, documentation, project_branch, endPoint, viewerType]) const isCreateAccess = isSystemManager(); @@ -94,12 +84,12 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path,
      {error && }
      - {apiData?.last_updated ?
      + {apiData?.last_updated ?
      Last Docs Updated - {convertFrappeTimestampToTimeAgo(apiData?.last_updated)}
      - {isCreateAccess && } -
      : (isCreateAccess && )} + {isCreateAccess && } +
      : (isCreateAccess && )} void, loading: boolean, edit: boolean, setEdit: (value: boolean) => void, SaveEditButton: () => void }) => { +export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveEditButton, renderContent, setDocumentation }: { generateDocumentation: () => void, loading: boolean, edit: boolean, setEdit: (value: boolean) => void, SaveEditButton: () => void, renderContent: () => string, setDocumentation: (value: string | undefined) => void }) => { return (
      @@ -125,7 +115,7 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE @@ -134,7 +124,10 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE } - {edit && } From c98a8f0a5588436a7245f651010ba81d07aa48bf Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 29 Sep 2024 13:08:07 +0530 Subject: [PATCH 052/110] feat:get saved documentation for site app is exists --- commit/commit/code_analysis/apis.py | 36 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/commit/commit/code_analysis/apis.py b/commit/commit/code_analysis/apis.py index d8d44f5..2c1d3bd 100644 --- a/commit/commit/code_analysis/apis.py +++ b/commit/commit/code_analysis/apis.py @@ -1,5 +1,7 @@ import os import ast +import frappe +import json other_decorators = [ '@cache_source', @@ -33,7 +35,7 @@ def find_all_occurrences_of_whitelist(path: str, app_name: str): # if file.endswith('party.py'): indexes,line_nos,no_of_occurrences = find_indexes_of_whitelist(file_content, no_of_occurrences) api_count += no_of_occurrences - apis = get_api_details(file, file_content, indexes,line_nos, path) + apis = get_api_details(app_name, file, file_content, indexes,line_nos, path) api_details.extend(apis) return api_details @@ -109,7 +111,7 @@ def is_in_string_or_comment(file_content, index): return indexes, line_nos, actual_count -def get_api_details(file, file_content: str, indexes: list,line_nos:list, path: str): +def get_api_details(app_name, file, file_content: str, indexes: list,line_nos:list, path: str): ''' Get details of the API ''' @@ -118,7 +120,7 @@ def get_api_details(file, file_content: str, indexes: list,line_nos:list, path: whitelist_details = get_whitelist_details(file_content, index) api_details = get_api_name(file_content, index) other_decorators = get_other_decorators(file_content, index, api_details.get('def_index')) - apis.append({ + obj = { **api_details, **whitelist_details, 'other_decorators': other_decorators, @@ -127,7 +129,11 @@ def get_api_details(file, file_content: str, indexes: list,line_nos:list, path: 'block_end': find_function_end_lines(file_content,api_details.get('name','')), 'file': file, 'api_path': file.replace(path, '').replace('\\', '/').replace('.py', '').replace('/', '.')[1:] + '.' + api_details.get('name') - }) + } + documentation, last_updated = get_documentation_from_branch_documentation(app_name, obj.get('name'), obj.get('api_path')) + obj['documentation'] = documentation + obj['last_updated'] = last_updated + apis.append(obj) return apis @@ -286,4 +292,24 @@ def get_decorators(node): decorator_name = get_decorator_name(decorator) if decorator_name is not None: decorators.append(decorator_name) - return decorators \ No newline at end of file + return decorators + +def get_documentation_from_branch_documentation(app_name:str, name: str, api_path: str): + ''' + Get documentation from the Commit Branch Documentation + ''' + if frappe.db.exists('Commit Branch Documentation',app_name): + branch_documentation = frappe.get_doc('Commit Branch Documentation', app_name) + docs = json.loads(branch_documentation.documentation) if branch_documentation.documentation else {} + apis = docs.get("apis", []) + documentation = '' + last_updated = '' + for api in apis: + if api.get("function_name") == name and api.get("path") == api_path: + documentation = api.get("documentation") + last_updated = api.get("last_updated") + break + return documentation, last_updated + else: + return '', '' + \ No newline at end of file From 3c96d672df84f025e7ccec06fefcb03e10049067 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 29 Sep 2024 13:32:35 +0530 Subject: [PATCH 053/110] chore: API client and documentation components --- .../features/APIClient/APIClientContent.tsx | 1 - .../features/api_viewer/APIDetails.tsx | 51 ++++++++++++++----- .../documentation/APIDocumentation.tsx | 4 +- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/dashboard/src/components/features/APIClient/APIClientContent.tsx b/dashboard/src/components/features/APIClient/APIClientContent.tsx index 9024319..08c95cd 100644 --- a/dashboard/src/components/features/APIClient/APIClientContent.tsx +++ b/dashboard/src/components/features/APIClient/APIClientContent.tsx @@ -110,7 +110,6 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten }, {} as Record) const paramsData = handleFormData(filteredParameterValues) - console.log('paramsData', paramsData, filteredParameterValues) if (requestType === 'GET') { // call get api with endpoint and parameterValues diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 799f6cf..a4662a4 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -8,9 +8,13 @@ import { web_url } from "@/config/socket" import { APIData, Argument } from "@/types/APIData" import { XMarkIcon } from "@heroicons/react/24/outline" import { useFrappeGetCall } from "frappe-react-sdk" -import { useMemo } from "react" +import { useMemo, useState } from "react" import { MdOutlineFileDownload } from "react-icons/md" import { APIDocumentationOfSiteApp } from "../documentation/APIDocumentation" +import { Dialog } from "@/components/ui/dialog" +import { APIClientContent } from "../APIClient/APIClientContent" +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" +import { AiOutlineThunderbolt } from "react-icons/ai" export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType, mutate }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string, mutate: () => void }) => { const data = useMemo(() => { @@ -44,11 +48,14 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set return 'ring-gray-600/20' } } + + const [apiOpen, setApiOpen] = useState(false) + return (
      -

      API Details

      +

      {data?.name}

      {data?.allow_guest || data?.xss_safe ?
      {data?.allow_guest && Allow Guest @@ -73,20 +80,33 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
      -
      -
      Name :
      -
      {data?.name}
      -
      -
      +
      Endpoint :
      -
      -
      {data?.api_path}
      - +
      +
      +
      {data?.api_path}
      + +
      + {viewerType === 'app' && + + + + + + Click to make an API call to this endpoint + + + }
      -
      +
      Req. Types :
      -
      +
      {data?.request_types.map((type: string, idx: number) => ( {type} @@ -122,6 +142,9 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set + + +
      ) } @@ -172,7 +195,7 @@ export const CodeSnippet = ({ apiData, project_branch, file_path, viewerType }: {isLoading &&
      } - +
      @@ -208,7 +231,7 @@ export const Bruno = ({ doc }: { doc: APIData }) => { {isLoading &&
      } - +
      - + Generate Documentation for this API From 60c62238a4a70793c5f06b18541acd027d1e5f3d Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 4 Oct 2024 11:19:41 +0530 Subject: [PATCH 057/110] fix: Handle ModuleNotFoundError in get_site_app_commands function andf PermissionError --- commit/api/get_commands.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/commit/api/get_commands.py b/commit/api/get_commands.py index b64187a..f4d84f6 100644 --- a/commit/api/get_commands.py +++ b/commit/api/get_commands.py @@ -12,7 +12,7 @@ def get_project_app_commands(app: str, app_path: str = None) -> dict: ''' if not app_path or app_path == '': # Check the permissions of the user - if not frappe.has_permission('System Manager'): + if not is_system_manager(): return frappe.throw('You do not have permission to access this resource', frappe.PermissionError) return get_site_app_commands(app) else: @@ -52,8 +52,14 @@ def get_project_app_commands(app: str, app_path: str = None) -> dict: @frappe.whitelist() def get_site_app_commands(app: str) -> dict: - app_command_module = importlib.import_module(f"{app}.commands") + try: + app_command_module = importlib.import_module(f"{app}.commands") # Call get_commands if it is a callable + except ModuleNotFoundError as e: + if e.name == f"{app}.commands": + return [] + traceback.print_exc() + return [] command_list = [] if hasattr(app_command_module, 'commands'): @@ -68,3 +74,8 @@ def get_site_app_commands(app: str) -> dict: } command_list.append(obj) return command_list + +def is_system_manager(): + user = frappe.session.user + roles = frappe.get_roles(user) + return 'System Manager' in roles From 6fed939361b7f1b359caec24f1fd53d05247212a Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 4 Oct 2024 11:30:19 +0530 Subject: [PATCH 058/110] fix:endpoint max Character length --- dashboard/src/components/features/api_viewer/APIDetails.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index a4662a4..3245c83 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -55,7 +55,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
      -

      {data?.name}

      +

      {data?.name}

      {data?.allow_guest || data?.xss_safe ?
      {data?.allow_guest && Allow Guest @@ -84,7 +84,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set
      Endpoint :
      -
      {data?.api_path}
      +
      {data?.api_path}
      {viewerType === 'app' && From c836d8d0634ed540882cf16e9fbd9920b0290563 Mon Sep 17 00:00:00 2001 From: Aditya Pardeshi <69710507+Pardeshi-Aditya@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:18:17 +0530 Subject: [PATCH 059/110] Update README.md Update header and stats --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 48ebeef..fde67ea 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,31 @@ +

      + + Commit logo + + +

      commit

      +

      Developer tooling for the Frappeverse 🪐 +
      +
      + Install on Frappe Cloud» +
      +
      + Learn More » +
      +
      + Issues + . + Sponsor Us! +

      +

      +

      + + license + + Github Stars + Commits-per-month +

      + # [commit](https://commit.frappe.cloud/) Born out of a need to improve developer tooling for Frappe, "Commit" allows you to visualize your app's database schema and view all it's APIs - improving developer productivity and security of your critical applications. From a64bf8ecabe85b64955ba6ffa6de28d47db6ee34 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 29 Oct 2024 17:38:21 +0530 Subject: [PATCH 060/110] chore:Publish status added --- commit/api/api_explorer.py | 4 ++++ commit/commit/code_analysis/apis.py | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/commit/api/api_explorer.py b/commit/api/api_explorer.py index dc4001d..6d83a60 100644 --- a/commit/api/api_explorer.py +++ b/commit/api/api_explorer.py @@ -19,6 +19,10 @@ def get_apis_for_project(project_branch: str): if doc.get("function_name") == api.get("name") and doc.get("path") == api.get("api_path"): api["documentation"] = doc.get("documentation") api["last_updated"] = doc.get("last_updated") + api["is_published"] = doc.get("is_published", 0) + api["published_on"] = doc.get("published_on", None) + api["published_by"] = doc.get("published_by", None) + api['publish_id'] = doc.get('publish_id', None) break app_name, organization, app_logo = frappe.db.get_value("Commit Project", branch_doc.project, ["app_name", "org", "image"]) diff --git a/commit/commit/code_analysis/apis.py b/commit/commit/code_analysis/apis.py index 2c1d3bd..1c97c73 100644 --- a/commit/commit/code_analysis/apis.py +++ b/commit/commit/code_analysis/apis.py @@ -130,9 +130,13 @@ def get_api_details(app_name, file, file_content: str, indexes: list,line_nos:li 'file': file, 'api_path': file.replace(path, '').replace('\\', '/').replace('.py', '').replace('/', '.')[1:] + '.' + api_details.get('name') } - documentation, last_updated = get_documentation_from_branch_documentation(app_name, obj.get('name'), obj.get('api_path')) + documentation, last_updated, is_published, published_on, publish_by, publish_id = get_documentation_from_branch_documentation(app_name, obj.get('name'), obj.get('api_path')) obj['documentation'] = documentation obj['last_updated'] = last_updated + obj['is_published'] = is_published + obj['published_on'] = published_on + obj['publish_by'] = publish_by + obj['publish_id'] = publish_id apis.append(obj) return apis @@ -304,12 +308,20 @@ def get_documentation_from_branch_documentation(app_name:str, name: str, api_pat apis = docs.get("apis", []) documentation = '' last_updated = '' + is_published = '' + published_on = '' + publish_by = '' + publish_id = '' for api in apis: if api.get("function_name") == name and api.get("path") == api_path: documentation = api.get("documentation") last_updated = api.get("last_updated") + is_published = api.get("is_published",0) + published_on = api.get("published_on", None) + publish_by = api.get("publish_by", None) + publish_id = api.get("publish_id", None) break - return documentation, last_updated + return documentation, last_updated, is_published, published_on, publish_by, publish_id else: return '', '' \ No newline at end of file From d1e40c087f05610b4cef75cc5e29ac86fd81ad2b Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 29 Oct 2024 18:20:54 +0530 Subject: [PATCH 061/110] feat:Check Component --- .../src/components/common/Checkbox/Check.tsx | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 dashboard/src/components/common/Checkbox/Check.tsx diff --git a/dashboard/src/components/common/Checkbox/Check.tsx b/dashboard/src/components/common/Checkbox/Check.tsx new file mode 100644 index 0000000..62c8fe0 --- /dev/null +++ b/dashboard/src/components/common/Checkbox/Check.tsx @@ -0,0 +1,33 @@ +import { Controller, UseControllerProps, useFormContext } from "react-hook-form" +import { CheckboxProps } from "@radix-ui/react-checkbox" +import { Checkbox } from "@/components/ui/checkbox" + +export interface CheckProps extends CheckboxProps { + name: string + label: string, + rules?: UseControllerProps['rules'] + controllerProps?: Partial> + alignWithLabel?: boolean +} + +export const Check = ({ name, label, controllerProps, alignWithLabel = false, rules, ...props }: CheckProps) => { + + const { control } = useFormContext() + + return ( +
      + ( + + )} + {...controllerProps} + /> + +
      + ) +} \ No newline at end of file From c71daa37383e7fe4cc13767a64ab1565a961ad12 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 29 Oct 2024 19:54:31 +0530 Subject: [PATCH 062/110] feat: Add Commit Docs related files - Added test_commit_docs.py for CommitDocs doctype - Added commit_docs.py for CommitDocs doctype - Added commit_docs_page.js for CommitDocsPage doctype - Added commit_docs_page.py for CommitDocsPage doctype - Added commit_docs_group_item.py for CommitDocsGroupItem doctype - Added commit_docs_footer_item.py for CommitDocsFooterItem doctype - Added commit_docs_topbar_item.py for CommitDocsTopbarItem doctype - Added commit_docs_page.json for CommitDocsPage doctype - Added test_commit_docs_page.py for CommitDocsPage doctype - Added commit_docs_footer_item.json for CommitDocsFooterItem doctype - Added commit_docs.js for CommitDocs doctype - Added commit_docs_group_item.json for CommitDocsGroupItem doctype - Added commit_docs_topbar_item.json for CommitDocsTopbarItem doctype --- commit/commit/doctype/commit_docs/__init__.py | 0 .../commit/doctype/commit_docs/commit_docs.js | 50 ++++++ .../doctype/commit_docs/commit_docs.json | 142 ++++++++++++++++++ .../commit/doctype/commit_docs/commit_docs.py | 9 ++ .../doctype/commit_docs/test_commit_docs.py | 9 ++ .../commit_docs_footer_item/__init__.py | 0 .../commit_docs_footer_item.json | 56 +++++++ .../commit_docs_footer_item.py | 9 ++ .../commit_docs_group_item/__init__.py | 0 .../commit_docs_group_item.json | 62 ++++++++ .../commit_docs_group_item.py | 9 ++ .../doctype/commit_docs_page/__init__.py | 0 .../commit_docs_page/commit_docs_page.js | 8 + .../commit_docs_page/commit_docs_page.json | 40 +++++ .../commit_docs_page/commit_docs_page.py | 9 ++ .../commit_docs_page/test_commit_docs_page.py | 30 ++++ .../commit_docs_topbar_item/__init__.py | 0 .../commit_docs_topbar_item.json | 72 +++++++++ .../commit_docs_topbar_item.py | 9 ++ .../documentation/APIDocumentation.tsx | 117 ++++++++++++++- 20 files changed, 627 insertions(+), 4 deletions(-) create mode 100644 commit/commit/doctype/commit_docs/__init__.py create mode 100644 commit/commit/doctype/commit_docs/commit_docs.js create mode 100644 commit/commit/doctype/commit_docs/commit_docs.json create mode 100644 commit/commit/doctype/commit_docs/commit_docs.py create mode 100644 commit/commit/doctype/commit_docs/test_commit_docs.py create mode 100644 commit/commit/doctype/commit_docs_footer_item/__init__.py create mode 100644 commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.json create mode 100644 commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.py create mode 100644 commit/commit/doctype/commit_docs_group_item/__init__.py create mode 100644 commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.json create mode 100644 commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.py create mode 100644 commit/commit/doctype/commit_docs_page/__init__.py create mode 100644 commit/commit/doctype/commit_docs_page/commit_docs_page.js create mode 100644 commit/commit/doctype/commit_docs_page/commit_docs_page.json create mode 100644 commit/commit/doctype/commit_docs_page/commit_docs_page.py create mode 100644 commit/commit/doctype/commit_docs_page/test_commit_docs_page.py create mode 100644 commit/commit/doctype/commit_docs_topbar_item/__init__.py create mode 100644 commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json create mode 100644 commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.py diff --git a/commit/commit/doctype/commit_docs/__init__.py b/commit/commit/doctype/commit_docs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/commit/commit/doctype/commit_docs/commit_docs.js b/commit/commit/doctype/commit_docs/commit_docs.js new file mode 100644 index 0000000..f9ef7e5 --- /dev/null +++ b/commit/commit/doctype/commit_docs/commit_docs.js @@ -0,0 +1,50 @@ +// Copyright (c) 2024, The Commit Company and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Commit Docs', { + onload_post_render: function (frm) { + frm.trigger('set_parent_label_options'); + }, + + set_parent_label_options: function (frm) { + frm.fields_dict.navbar_items.grid.update_docfield_property( + 'parent_label', + 'options', + frm.events.get_parent_options(frm, 'navbar_items') + ); + }, + + get_parent_options: function (frm, table_field) { + var items = frm.doc[table_field] || []; + var main_items = ['']; + for (var i in items) { + var d = items[i]; + if (!d.url && d.label) { + main_items.push(d.label); + } + } + return main_items.join('\n'); + }, +}); + +frappe.ui.form.on('Commit Docs Topbar Item', { + navbar_delete(frm) { + frm.events.set_parent_label_options(frm); + }, + + navbar_add(frm, cdt, cdn) { + frm.events.set_parent_label_options(frm); + }, + + parent_label: function (frm, doctype, name) { + frm.events.set_parent_label_options(frm); + }, + + url: function (frm, doctype, name) { + frm.events.set_parent_label_options(frm); + }, + + label: function (frm, doctype, name) { + frm.events.set_parent_label_options(frm); + }, +}); diff --git a/commit/commit/doctype/commit_docs/commit_docs.json b/commit/commit/doctype/commit_docs/commit_docs.json new file mode 100644 index 0000000..f4c7693 --- /dev/null +++ b/commit/commit/doctype/commit_docs/commit_docs.json @@ -0,0 +1,142 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "field:header", + "creation": "2024-10-29 18:30:47.336889", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "header", + "route", + "section_break_camv", + "sidebar", + "logo_section", + "light_mode_logo", + "night_mode_logo", + "navbar_tab", + "navbar_items", + "footer_tab", + "twitter_url", + "linkedin", + "github", + "raven", + "footer" + ], + "fields": [ + { + "fieldname": "header", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Header", + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "route", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Route", + "reqd": 1 + }, + { + "fieldname": "navbar_tab", + "fieldtype": "Tab Break", + "label": "Navbar" + }, + { + "fieldname": "footer_tab", + "fieldtype": "Tab Break", + "label": "Footer" + }, + { + "fieldname": "logo_section", + "fieldtype": "Section Break", + "label": "Logo" + }, + { + "fieldname": "light_mode_logo", + "fieldtype": "Attach Image", + "label": "Light Mode Logo" + }, + { + "fieldname": "night_mode_logo", + "fieldtype": "Attach Image", + "label": "Night Mode Logo" + }, + { + "fieldname": "navbar_items", + "fieldtype": "Table", + "label": "Navbar Items", + "options": "Commit Docs Topbar Item" + }, + { + "description": "Add Twitter URL", + "fieldname": "twitter_url", + "fieldtype": "Data", + "label": "Twitter ", + "options": "URL" + }, + { + "description": "Add LinkedIn URL", + "fieldname": "linkedin", + "fieldtype": "Data", + "label": "LinkedIn ", + "options": "URL" + }, + { + "description": "Add Github URL", + "fieldname": "github", + "fieldtype": "Data", + "label": "Github", + "options": "URL" + }, + { + "description": "Add Raven URL", + "fieldname": "raven", + "fieldtype": "Data", + "label": "Raven", + "options": "URL" + }, + { + "fieldname": "footer", + "fieldtype": "Table", + "label": "Footer", + "options": "Commit Docs Footer Item" + }, + { + "fieldname": "section_break_camv", + "fieldtype": "Section Break" + }, + { + "fieldname": "sidebar", + "fieldtype": "Table", + "label": "Sidebar", + "options": "Commit Docs Group Item" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-10-29 19:51:08.985705", + "modified_by": "Administrator", + "module": "commit", + "name": "Commit Docs", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py new file mode 100644 index 0000000..0fe2063 --- /dev/null +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class CommitDocs(Document): + pass diff --git a/commit/commit/doctype/commit_docs/test_commit_docs.py b/commit/commit/doctype/commit_docs/test_commit_docs.py new file mode 100644 index 0000000..16a9eec --- /dev/null +++ b/commit/commit/doctype/commit_docs/test_commit_docs.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestCommitDocs(FrappeTestCase): + pass diff --git a/commit/commit/doctype/commit_docs_footer_item/__init__.py b/commit/commit/doctype/commit_docs_footer_item/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.json b/commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.json new file mode 100644 index 0000000..086ee0e --- /dev/null +++ b/commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.json @@ -0,0 +1,56 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-10-29 19:31:34.844227", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "parent_label", + "label", + "url", + "hide_on_footer" + ], + "fields": [ + { + "fieldname": "parent_label", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Parent Label", + "reqd": 1 + }, + { + "fieldname": "label", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Label", + "reqd": 1 + }, + { + "fieldname": "url", + "fieldtype": "Data", + "in_list_view": 1, + "label": "URL", + "options": "URL", + "reqd": 1 + }, + { + "default": "0", + "fieldname": "hide_on_footer", + "fieldtype": "Check", + "label": "Hide on Footer" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-10-29 19:32:27.468415", + "modified_by": "Administrator", + "module": "commit", + "name": "Commit Docs Footer Item", + "owner": "Administrator", + "permissions": [], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.py b/commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.py new file mode 100644 index 0000000..731271e --- /dev/null +++ b/commit/commit/doctype/commit_docs_footer_item/commit_docs_footer_item.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class CommitDocsFooterItem(Document): + pass diff --git a/commit/commit/doctype/commit_docs_group_item/__init__.py b/commit/commit/doctype/commit_docs_group_item/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.json b/commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.json new file mode 100644 index 0000000..f2324d2 --- /dev/null +++ b/commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.json @@ -0,0 +1,62 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-10-29 19:41:29.822737", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "parent_label", + "docs_page", + "hide_on_sidebar", + "badge", + "badge_color" + ], + "fields": [ + { + "fieldname": "parent_label", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Parent Label", + "reqd": 1 + }, + { + "fieldname": "docs_page", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Docs Page", + "options": "Commit Docs Page", + "reqd": 1 + }, + { + "default": "0", + "fieldname": "hide_on_sidebar", + "fieldtype": "Check", + "label": "Hide on Sidebar" + }, + { + "description": "This is badge field, eg: GET , POST etc.", + "fieldname": "badge", + "fieldtype": "Data", + "label": "Badge" + }, + { + "description": "Add Tailwind colours like red, green etc.", + "fieldname": "badge_color", + "fieldtype": "Data", + "label": "Badge Color" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-10-29 19:49:34.523154", + "modified_by": "Administrator", + "module": "commit", + "name": "Commit Docs Group Item", + "owner": "Administrator", + "permissions": [], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.py b/commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.py new file mode 100644 index 0000000..04eb61e --- /dev/null +++ b/commit/commit/doctype/commit_docs_group_item/commit_docs_group_item.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class CommitDocsGroupItem(Document): + pass diff --git a/commit/commit/doctype/commit_docs_page/__init__.py b/commit/commit/doctype/commit_docs_page/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.js b/commit/commit/doctype/commit_docs_page/commit_docs_page.js new file mode 100644 index 0000000..e1c023a --- /dev/null +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, The Commit Company and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Commit Docs Page", { +// refresh(frm) { + +// }, +// }); diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.json b/commit/commit/doctype/commit_docs_page/commit_docs_page.json new file mode 100644 index 0000000..dd54795 --- /dev/null +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.json @@ -0,0 +1,40 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-10-29 19:39:29.842455", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "section_break_4vr2" + ], + "fields": [ + { + "fieldname": "section_break_4vr2", + "fieldtype": "Section Break" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-10-29 19:39:29.842455", + "modified_by": "Administrator", + "module": "commit", + "name": "Commit Docs Page", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.py b/commit/commit/doctype/commit_docs_page/commit_docs_page.py new file mode 100644 index 0000000..fa190b8 --- /dev/null +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class CommitDocsPage(Document): + pass diff --git a/commit/commit/doctype/commit_docs_page/test_commit_docs_page.py b/commit/commit/doctype/commit_docs_page/test_commit_docs_page.py new file mode 100644 index 0000000..8f60b81 --- /dev/null +++ b/commit/commit/doctype/commit_docs_page/test_commit_docs_page.py @@ -0,0 +1,30 @@ +# Copyright (c) 2024, The Commit Company and Contributors +# See license.txt + +# import frappe +from frappe.tests import IntegrationTestCase, UnitTestCase + + +# On IntegrationTestCase, the doctype test records and all +# link-field test record depdendencies are recursively loaded +# Use these module variables to add/remove to/from that list +EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] +IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] + + +class TestCommitDocsPage(UnitTestCase): + """ + Unit tests for CommitDocsPage. + Use this class for testing individual functions and methods. + """ + + pass + + +class TestCommitDocsPage(IntegrationTestCase): + """ + Integration tests for CommitDocsPage. + Use this class for testing interactions between multiple components. + """ + + pass diff --git a/commit/commit/doctype/commit_docs_topbar_item/__init__.py b/commit/commit/doctype/commit_docs_topbar_item/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json new file mode 100644 index 0000000..049d1a0 --- /dev/null +++ b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json @@ -0,0 +1,72 @@ +{ + "actions": [], + "creation": "2024-10-29 18:42:47.854478", + "default_view": "List", + "doctype": "DocType", + "document_type": "Other", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "label", + "url", + "open_in_new_tab", + "right", + "column_break_5", + "parent_label" + ], + "fields": [ + { + "fieldname": "label", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Label", + "print_width": "120px", + "width": "120px" + }, + { + "description": "Link to the page you want to open. Leave blank if you want to make it a group parent.", + "fieldname": "url", + "fieldtype": "Data", + "in_list_view": 1, + "label": "URL", + "print_width": "200px", + "width": "200px" + }, + { + "default": "0", + "depends_on": "eval:doc.url", + "fieldname": "open_in_new_tab", + "fieldtype": "Check", + "label": "Open URL in a New Tab" + }, + { + "default": "1", + "fieldname": "right", + "fieldtype": "Check", + "label": "Align Right" + }, + { + "fieldname": "column_break_5", + "fieldtype": "Column Break" + }, + { + "description": "If you set this, this Item will come in a drop-down under the selected parent.", + "fieldname": "parent_label", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Parent Label" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-10-29 19:17:18.340314", + "modified_by": "Administrator", + "module": "commit", + "name": "Commit Docs Topbar Item", + "owner": "Administrator", + "permissions": [], + "sort_field": "creation", + "sort_order": "ASC", + "states": [] +} \ No newline at end of file diff --git a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.py b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.py new file mode 100644 index 0000000..024b9f3 --- /dev/null +++ b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, The Commit Company and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class CommitDocsTopbarItem(Document): + pass diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx index 5ced456..113c79b 100644 --- a/dashboard/src/components/features/documentation/APIDocumentation.tsx +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -4,13 +4,21 @@ import { Button } from "@/components/ui/button"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { APIData } from "@/types/APIData"; import { useFrappePostCall } from "frappe-react-sdk"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { MdOutlineRocketLaunch } from "react-icons/md"; import MDEditor from '@uiw/react-md-editor'; import { FiEdit, FiSave } from "react-icons/fi"; import { isSystemManager } from "@/utils/roles"; import { IoMdClose } from "react-icons/io"; import { convertFrappeTimestampToTimeAgo } from "@/components/utils/dateconversion"; +import { AiOutlineGlobal } from "react-icons/ai"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; +import { useToast } from "@/components/ui/use-toast"; +import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; +import { FormElement } from "@/components/common/Forms/FormControl"; +import { Input } from "@/components/ui/input"; +import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown"; +import { Check } from "@/components/common/Checkbox/Check"; export interface DocumentationResponse { function_name: string, @@ -80,6 +88,8 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, const isCreateAccess = isSystemManager(); + const [open, setOpen] = useState(false) + return (
      {error && } @@ -88,8 +98,8 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path,
      Last Docs Updated - {convertFrappeTimestampToTimeAgo(apiData?.last_updated)}
      - {isCreateAccess && } -
      : (isCreateAccess && )} + {isCreateAccess && } +
      : (isCreateAccess && )}
      + + +
      ) } -export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveEditButton, renderContent, setDocumentation }: { generateDocumentation: () => void, loading: boolean, edit: boolean, setEdit: (value: boolean) => void, SaveEditButton: () => void, renderContent: () => string, setDocumentation: (value: string | undefined) => void }) => { +export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveEditButton, renderContent, setDocumentation, setOpen, data }: { generateDocumentation: () => void, loading: boolean, edit: boolean, setEdit: (value: boolean) => void, SaveEditButton: () => void, renderContent: () => string, setDocumentation: (value: string | undefined) => void, setOpen: (value: boolean) => void, data: APIData }) => { return (
      + + + +
      + +
      +
      + + {data?.documentation ? 'Publish Documentation.' : 'Generate / Save the Documentation to Publish.'} + +
      +
      {!edit && @@ -145,4 +172,86 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE
      ) +} + +export interface PublishDocumentationFormFields { + page_name: string, + module_name: string, + live: boolean, + documentation: string +} + +export const PublishDocumentationDialog = ({ open, setOpen, project_branch, endPoint, viewerType, mutate, documentation }: { open: boolean, setOpen: (value: boolean) => void, project_branch: string, endPoint: string, viewerType: string, mutate: () => void, documentation: string }) => { + + const { toast } = useToast() + const methods = useForm({ + defaultValues: { + page_name: '', + module_name: '', + live: true, + documentation: documentation + } + }) + + const { call, reset, loading, error } = useFrappePostCall('commit.commit.doctype.commit_documentation_page.commit_documentation_page.publish_documentation') + + const onSubmit: SubmitHandler = (data) => { + // call({ + // project_branch: project_branch, + // endpoint: endPoint, + // viewer_type: viewerType, + // page_name: data.page_name, + // module_name: data.module_name, + // live: data.live, + // documentation: data.documentation + // }).then(() => { + // mutate() + // reset() + // toast({ + // description: "Documentation Published", + // duration: 1500 + // }) + // }).then(() => setOpen(false)) + } + + useEffect(() => { + methods.reset() + }, [open]) + + return ( + + + Publish Documentation + + {error && } + +
      +
      + {/* + + + + - +
      ) } \ No newline at end of file From 67b7766dabca1bf3d5c9e7b3d289b7a8634eca45 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 1 Nov 2024 21:16:44 +0530 Subject: [PATCH 064/110] feat:CreatableSelect Component --- .../common/Checkbox/CreatableSelect.tsx | 296 ++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 dashboard/src/components/common/Checkbox/CreatableSelect.tsx diff --git a/dashboard/src/components/common/Checkbox/CreatableSelect.tsx b/dashboard/src/components/common/Checkbox/CreatableSelect.tsx new file mode 100644 index 0000000..4c46907 --- /dev/null +++ b/dashboard/src/components/common/Checkbox/CreatableSelect.tsx @@ -0,0 +1,296 @@ +import * as React from 'react'; +import { cn } from '@/lib/utils'; +import { Button } from '@/components/ui/button'; +import { + Command, + CommandGroup, + CommandInput, + CommandItem, +} from '@/components/ui/command'; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from '@/components/ui/popover'; +import { ScrollArea } from '@/components/ui/scroll-area'; +import { MdAdd, MdCheck } from 'react-icons/md'; +import { LuChevronsUpDown } from 'react-icons/lu'; +import { Input } from '@/components/ui/input'; +import { Controller, UseControllerProps, useFormContext } from 'react-hook-form'; + +export type ComboboxOptions = { + value: string; + label: string; +}; + +type Mode = 'single' | 'multiple'; + +interface ComboboxProps { + mode?: Mode; + options: ComboboxOptions[] | []; + selected: string | string[]; + className?: string; + label?: string; + onChange?: (event: string | string[]) => void; + onCreate?: (value: string) => void; +} + +export const CreatableSelect = ({ options, selected, className, label, mode = 'single', onChange, onCreate }: ComboboxProps) => { + const [open, setOpen] = React.useState(false); + const [query, setQuery] = React.useState(''); + const [isCreating, setIsCreating] = React.useState(false); + const [newItemValue, setNewItemValue] = React.useState(''); + + const handleCreate = () => { + if (onCreate && newItemValue.trim()) { + onCreate(newItemValue); + setNewItemValue(''); + setIsCreating(false); + } + }; + + return ( +
      + + + + + + + setQuery(value)} + /> + { + e.stopPropagation(); + }}> +
      + + {options.map((option) => ( + { + if (onChange) { + if (mode === 'multiple' && Array.isArray(selected)) { + onChange( + selected.includes(option.value) + ? selected.filter( + (item) => item !== option.value + ) + : [...selected, option.value] + ); + } else { + onChange(option.value); + } + } + }} + > + + {option.label} + + ))} + +
      +
      + {isCreating ? ( +
      + setNewItemValue(e.target.value)} + placeholder="Enter new item name" + onKeyDown={(e) => { + if (e.key === 'Enter') handleCreate(); + }} + /> + +
      + ) : ( + + )} +
      +
      +
      +
      + ); +}; + +export interface FormCreatableSelectProps extends Omit { + name: string + label: string, + rules?: UseControllerProps['rules'] + controllerProps?: Partial> +} + +export const FormCreatableSelect = ({ + name, + rules, + options, + mode = 'single', + label, + onCreate, + className, +}: FormCreatableSelectProps) => { + const { control } = useFormContext(); + const [open, setOpen] = React.useState(false); + const [query, setQuery] = React.useState(''); + const [isCreating, setIsCreating] = React.useState(false); + const [newItemValue, setNewItemValue] = React.useState(''); + + const handleCreate = () => { + if (onCreate && newItemValue.trim()) { + onCreate(newItemValue); + setNewItemValue(''); + setIsCreating(false); + } + }; + + return ( + ( +
      + + + + + + + setQuery(value)} + /> + e.stopPropagation()}> +
      + + {options.map((option) => ( + { + if (mode === 'multiple' && Array.isArray(value)) { + const newValue = value.includes(option.value) + ? value.filter((item) => item !== option.value) + : [...value, option.value]; + onChange(newValue); + } else { + onChange(option.value); + } + }} + > + + {option.label} + + ))} + +
      +
      + {isCreating ? ( +
      + setNewItemValue(e.target.value)} + placeholder="Enter new item name" + onKeyDown={(e) => { + if (e.key === 'Enter') handleCreate(); + }} + /> + +
      + ) : ( + + )} +
      +
      +
      +
      + )} + /> + ); +}; \ No newline at end of file From 4ee3ff203633803e2db2ce06cda55ed7599aae84 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 1 Nov 2024 21:17:11 +0530 Subject: [PATCH 065/110] feat: Add published field to Commit Docs and update API documentation handling --- .../doctype/commit_docs/commit_docs.json | 9 +- .../commit/doctype/commit_docs/commit_docs.py | 28 +++- .../documentation/APIDocumentation.tsx | 138 ++++++++++++------ dashboard/src/types/APIData.ts | 5 + 4 files changed, 134 insertions(+), 46 deletions(-) diff --git a/commit/commit/doctype/commit_docs/commit_docs.json b/commit/commit/doctype/commit_docs/commit_docs.json index f4c7693..d232ff8 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.json +++ b/commit/commit/doctype/commit_docs/commit_docs.json @@ -8,6 +8,7 @@ "field_order": [ "header", "route", + "published", "section_break_camv", "sidebar", "logo_section", @@ -112,11 +113,17 @@ "fieldtype": "Table", "label": "Sidebar", "options": "Commit Docs Group Item" + }, + { + "default": "1", + "fieldname": "published", + "fieldtype": "Check", + "label": "Published" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-10-29 19:51:08.985705", + "modified": "2024-11-01 11:22:21.970571", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs", diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py index 0fe2063..a7f31a0 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.py +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -1,9 +1,35 @@ # Copyright (c) 2024, The Commit Company and contributors # For license information, please see license.txt -# import frappe +import frappe from frappe.model.document import Document class CommitDocs(Document): pass + + +@frappe.whitelist() +def get_docs_sidebar_parent_labels(id:str): + ''' + Get the Parent Labels List of the Sidebar from Commit Docs + ''' + + # Get the Commit Docs Document + commit_docs = frappe.get_doc('Commit Docs', id) + + parent_labels = [] + + for sidebar in commit_docs.sidebar: + parent_labels.append(sidebar.parent_label) + + parent_labels = list(set(parent_labels)) + + parent_labels_obj = [] + for label in parent_labels: + parent_labels_obj.append({ + 'label': label, + 'value': label + }) + + return parent_labels_obj \ No newline at end of file diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx index 113c79b..b2e592e 100644 --- a/dashboard/src/components/features/documentation/APIDocumentation.tsx +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -3,11 +3,11 @@ import { SpinnerLoader } from "@/components/common/FullPageLoader/SpinnerLoader" import { Button } from "@/components/ui/button"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { APIData } from "@/types/APIData"; -import { useFrappePostCall } from "frappe-react-sdk"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { FrappeConfig, FrappeContext, useFrappePostCall } from "frappe-react-sdk"; +import { useCallback, useContext, useEffect, useMemo, useState } from "react"; import { MdOutlineRocketLaunch } from "react-icons/md"; import MDEditor from '@uiw/react-md-editor'; -import { FiEdit, FiSave } from "react-icons/fi"; +import { FiEdit, FiExternalLink, FiSave } from "react-icons/fi"; import { isSystemManager } from "@/utils/roles"; import { IoMdClose } from "react-icons/io"; import { convertFrappeTimestampToTimeAgo } from "@/components/utils/dateconversion"; @@ -19,6 +19,7 @@ import { FormElement } from "@/components/common/Forms/FormControl"; import { Input } from "@/components/ui/input"; import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown"; import { Check } from "@/components/common/Checkbox/Check"; +import { FormCreatableSelect } from "@/components/common/Checkbox/CreatableSelect"; export interface DocumentationResponse { function_name: string, @@ -128,13 +129,16 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE
      - + : }
      - {data?.documentation ? 'Publish Documentation.' : 'Generate / Save the Documentation to Publish.'} + {data?.is_published ? 'Click to view the published documentation.' : data?.documentation ? 'Publish Documentation.' : 'Generate / Save the Documentation to Publish.'}
      @@ -175,10 +179,12 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE } export interface PublishDocumentationFormFields { - page_name: string, - module_name: string, - live: boolean, - documentation: string + docs_name: string, + parent_label: string, + title: string, + published: boolean, + allow_guest: boolean, + content: string } export const PublishDocumentationDialog = ({ open, setOpen, project_branch, endPoint, viewerType, mutate, documentation }: { open: boolean, setOpen: (value: boolean) => void, project_branch: string, endPoint: string, viewerType: string, mutate: () => void, documentation: string }) => { @@ -186,38 +192,63 @@ export const PublishDocumentationDialog = ({ open, setOpen, project_branch, endP const { toast } = useToast() const methods = useForm({ defaultValues: { - page_name: '', - module_name: '', - live: true, - documentation: documentation + docs_name: '', + parent_label: '', + title: '', + published: true, + allow_guest: true, + content: documentation } }) - const { call, reset, loading, error } = useFrappePostCall('commit.commit.doctype.commit_documentation_page.commit_documentation_page.publish_documentation') + const { call: postCall, reset, loading, error } = useFrappePostCall('commit.commit.doctype.commit_docs_page.commit_docs_page.publish_documentation') const onSubmit: SubmitHandler = (data) => { - // call({ - // project_branch: project_branch, - // endpoint: endPoint, - // viewer_type: viewerType, - // page_name: data.page_name, - // module_name: data.module_name, - // live: data.live, - // documentation: data.documentation - // }).then(() => { - // mutate() - // reset() - // toast({ - // description: "Documentation Published", - // duration: 1500 - // }) - // }).then(() => setOpen(false)) + postCall({ + project_branch: project_branch, + endpoint: endPoint, + viewer_type: viewerType, + ...data + }).then(() => { + mutate() + reset() + toast({ + description: "Documentation Published", + duration: 1500 + }) + }).then(() => setOpen(false)) } useEffect(() => { methods.reset() + setOpt([]) }, [open]) + const { call } = useContext(FrappeContext) as FrappeConfig + + const [opt, setOpt] = useState<{ + label: string + value: string + }[]>([]) + + const onDocsNameChange = useCallback((value: string) => { + if (value) { + call.get('commit.commit.doctype.commit_docs.commit_docs.get_docs_sidebar_parent_labels', { + id: value + }).then((res) => { + const options = [ + ...opt, + ...res.message + ] + // Remove duplicates + const uniqueOptions = options.filter((v, i, a) => a.findIndex(t => (t.value === v.value)) === i) + setOpt(uniqueOptions) + }) + } else { + setOpt([]) + } + }, [setOpt]) + return ( @@ -227,22 +258,41 @@ export const PublishDocumentationDialog = ({ open, setOpen, project_branch, endP
      - {/* - + onDocsNameChange(e.target.value) + }} /> + + + { + methods.setValue('parent_label', value) + setOpt( + [...opt, { + label: value, + value: value + }] + ) + }} /> +

      Parent Label is the group under which the title will be shown

      +
      + + +

      Title is the name which will be shown on the sidebar under the parent label

      +
      + + - - Date: Fri, 1 Nov 2024 21:17:46 +0530 Subject: [PATCH 067/110] feat:Publish Documentation API --- .../commit_docs_page/commit_docs_page.py | 89 ++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.py b/commit/commit/doctype/commit_docs_page/commit_docs_page.py index fa190b8..acc194a 100644 --- a/commit/commit/doctype/commit_docs_page/commit_docs_page.py +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.py @@ -1,9 +1,94 @@ # Copyright (c) 2024, The Commit Company and contributors # For license information, please see license.txt -# import frappe +import frappe from frappe.model.document import Document +import json class CommitDocsPage(Document): - pass + + def before_insert(self): + # Set the route for the page based on the title + self.route = self.title.lower().replace(' ', '-') + +@frappe.whitelist(methods=['POST']) +def publish_documentation(project_branch, endpoint, viewer_type, docs_name, parent_label, title, published, allow_guest, content): + ''' + Publish the Documentation + # 1. Create a new Commit Docs Page Document + # 2. Update the Commit Docs Document with the new Page by adding it to the Sidebar child table + # 3. Based on viewer_type, update the flag is_published, published_on, published_by, publish_id + ''' + + # 1. Create a new Commit Docs Page Document + commit_docs_page = frappe.get_doc({ + 'doctype': 'Commit Docs Page', + 'title': title, + 'published': published, + 'allow_guest': allow_guest, + 'content': content + }) + + commit_docs_page.insert() + + # 2. Update the Commit Docs Document with the new Page by adding it to the Sidebar child table + + commit_docs = frappe.get_doc('Commit Docs', docs_name) + + commit_docs.append('sidebar', { + 'parent_label': parent_label, + 'docs_page': commit_docs_page.name + }) + + commit_docs.save() + + # 3. Check the viewer_type + + if viewer_type == "project": + # Get the Project Branch Document + project_branch_doc = frappe.get_doc('Commit Project Branch', project_branch) + + # Get the documentation JSON + documentation = json.loads(project_branch_doc.documentation).get("apis", []) if project_branch_doc.documentation else [] + + if documentation: + # Find the API from the documentation JSON + api = next((api for api in documentation if api.get('path') == endpoint), None) + + if api: + # Update the API with the published_on, published_by, is_published, publish_id + api['published_on'] = commit_docs_page.creation + api['published_by'] = frappe.session.user + api['is_published'] = 1 + api['publish_id'] = commit_docs_page.name + api['published_route'] = f'{commit_docs.route}/{commit_docs_page.route}' + + project_branch_doc.documentation = json.dumps({"apis": documentation}) + project_branch_doc.save() + + else: + commit_branch_documentation= frappe.get_doc('Commit Branch Documentation', project_branch) + + # Get the documentation JSON + documentation = json.loads(commit_branch_documentation.documentation).get("apis", []) if commit_branch_documentation.documentation else [] + + if documentation: + # Find the API from the documentation JSON + api = next((api for api in documentation if api.get('path') == endpoint), None) + + if api: + # Update the API with the published_on, published_by, is_published, publish_id + api['published_on'] = commit_docs_page.creation + api['published_by'] = frappe.session.user + api['is_published'] = 1 + api['publish_id'] = commit_docs_page.name + api['published_route'] = f'{commit_docs.route}/{commit_docs_page.route}' + + commit_branch_documentation.documentation = json.dumps({"apis": documentation}) + commit_branch_documentation.save() + + return { + 'commit_docs_page': commit_docs_page.name, + 'commit_docs': commit_docs.name + } \ No newline at end of file From b2d3968e92aceab1be76caba301e7609f4daa9fc Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 3 Nov 2024 21:53:17 +0530 Subject: [PATCH 068/110] fix: Ensure consistent return values in get_documentation_from_branch_documentation function --- commit/commit/code_analysis/apis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commit/commit/code_analysis/apis.py b/commit/commit/code_analysis/apis.py index 3efaadc..df9b9a2 100644 --- a/commit/commit/code_analysis/apis.py +++ b/commit/commit/code_analysis/apis.py @@ -324,7 +324,7 @@ def get_documentation_from_branch_documentation(app_name:str, name: str, api_pat publish_id = api.get("publish_id", None) published_route = api.get("published_route", None) break - return documentation, last_updated, is_published, published_on, publish_by, publish_id,published_route + return documentation, last_updated, is_published, published_on, publish_by, publish_id, published_route else: - return '', '' + return '', '', '', '', '', '', '' \ No newline at end of file From f35d3ce41b75d7589d361e6f6fcac13588eaba90 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 3 Nov 2024 21:54:08 +0530 Subject: [PATCH 069/110] feat: Add new TypeScript interfaces for complete commit module --- .../src/types/Integrations/OAuthScope.ts | 15 +++++++ .../types/commit/CommitBranchDocumentation.ts | 17 ++++++++ dashboard/src/types/commit/CommitDocs.ts | 40 +++++++++++++++++++ .../src/types/commit/CommitDocsFooterItem.ts | 21 ++++++++++ .../src/types/commit/CommitDocsGroupItem.ts | 19 +++++++++ dashboard/src/types/commit/CommitDocsPage.ts | 35 ++++++++++++++++ .../src/types/commit/CommitDocsTopbarItem.ts | 25 ++++++++++++ .../src/types/commit/CommitOrganization.ts | 2 +- dashboard/src/types/commit/CommitProject.ts | 2 +- .../src/types/commit/CommitProjectBranch.ts | 7 +++- dashboard/src/types/commit/CommitSettings.ts | 2 +- dashboard/src/types/commit/GithubSettings.ts | 2 +- dashboard/src/types/commit/GithubToken.ts | 28 +++++++++++++ .../src/types/commit/LinkedCommitDocsPage.ts | 15 +++++++ dashboard/src/types/commit/OpenAISettings.ts | 19 +++++++++ 15 files changed, 243 insertions(+), 6 deletions(-) create mode 100644 dashboard/src/types/Integrations/OAuthScope.ts create mode 100644 dashboard/src/types/commit/CommitBranchDocumentation.ts create mode 100644 dashboard/src/types/commit/CommitDocs.ts create mode 100644 dashboard/src/types/commit/CommitDocsFooterItem.ts create mode 100644 dashboard/src/types/commit/CommitDocsGroupItem.ts create mode 100644 dashboard/src/types/commit/CommitDocsPage.ts create mode 100644 dashboard/src/types/commit/CommitDocsTopbarItem.ts create mode 100644 dashboard/src/types/commit/GithubToken.ts create mode 100644 dashboard/src/types/commit/LinkedCommitDocsPage.ts create mode 100644 dashboard/src/types/commit/OpenAISettings.ts diff --git a/dashboard/src/types/Integrations/OAuthScope.ts b/dashboard/src/types/Integrations/OAuthScope.ts new file mode 100644 index 0000000..1b1c48f --- /dev/null +++ b/dashboard/src/types/Integrations/OAuthScope.ts @@ -0,0 +1,15 @@ + +export interface OAuthScope{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Scope : Data */ + scope?: string +} \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitBranchDocumentation.ts b/dashboard/src/types/commit/CommitBranchDocumentation.ts new file mode 100644 index 0000000..97ec464 --- /dev/null +++ b/dashboard/src/types/commit/CommitBranchDocumentation.ts @@ -0,0 +1,17 @@ + +export interface CommitBranchDocumentation{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** App : Data */ + app: string + /** Documentation : JSON */ + documentation?: any +} \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitDocs.ts b/dashboard/src/types/commit/CommitDocs.ts new file mode 100644 index 0000000..5680676 --- /dev/null +++ b/dashboard/src/types/commit/CommitDocs.ts @@ -0,0 +1,40 @@ +import { CommitDocsGroupItem } from './CommitDocsGroupItem' +import { CommitDocsTopbarItem } from './CommitDocsTopbarItem' +import { CommitDocsFooterItem } from './CommitDocsFooterItem' + +export interface CommitDocs{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Header : Data */ + header: string + /** Route : Data */ + route: string + /** Published : Check */ + published?: 0 | 1 + /** Sidebar : Table - Commit Docs Group Item */ + sidebar?: CommitDocsGroupItem[] + /** Light Mode Logo : Attach Image */ + light_mode_logo?: string + /** Night Mode Logo : Attach Image */ + night_mode_logo?: string + /** Navbar Items : Table - Commit Docs Topbar Item */ + navbar_items?: CommitDocsTopbarItem[] + /** Twitter : Data - Add Twitter URL */ + twitter_url?: string + /** LinkedIn : Data - Add LinkedIn URL */ + linkedin?: string + /** Github : Data - Add Github URL */ + github?: string + /** Raven : Data - Add Raven URL */ + raven?: string + /** Footer : Table - Commit Docs Footer Item */ + footer?: CommitDocsFooterItem[] +} \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitDocsFooterItem.ts b/dashboard/src/types/commit/CommitDocsFooterItem.ts new file mode 100644 index 0000000..f047f56 --- /dev/null +++ b/dashboard/src/types/commit/CommitDocsFooterItem.ts @@ -0,0 +1,21 @@ + +export interface CommitDocsFooterItem{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Parent Label : Data */ + parent_label: string + /** Label : Data */ + label: string + /** URL : Data */ + url: string + /** Hide on Footer : Check */ + hide_on_footer?: 0 | 1 +} \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitDocsGroupItem.ts b/dashboard/src/types/commit/CommitDocsGroupItem.ts new file mode 100644 index 0000000..757f0a3 --- /dev/null +++ b/dashboard/src/types/commit/CommitDocsGroupItem.ts @@ -0,0 +1,19 @@ + +export interface CommitDocsGroupItem{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Parent Label : Data */ + parent_label: string + /** Docs Page : Link - Commit Docs Page */ + docs_page: string + /** Hide on Sidebar : Check */ + hide_on_sidebar?: 0 | 1 +} \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitDocsPage.ts b/dashboard/src/types/commit/CommitDocsPage.ts new file mode 100644 index 0000000..a1e486b --- /dev/null +++ b/dashboard/src/types/commit/CommitDocsPage.ts @@ -0,0 +1,35 @@ +import { LinkedCommitDocsPage } from './LinkedCommitDocsPage' + +export interface CommitDocsPage{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Title : Data */ + title: string + /** Route : Data */ + route: string + /** Published : Check */ + published?: 0 | 1 + /** Allow Guest : Check */ + allow_guest?: 0 | 1 + /** Icon : Data - "Supports only icons from the react-icons library. Enter the icon name in the format 'libraryPrefix/IconName' (e.g., 'Fa/FaFileExcel') to display it beside the title in the sidebar." + */ + icon?: string + /** Badge : Data - This is badge field, eg: GET , POST etc. */ + badge?: string + /** Badge Color : Data - Add Tailwind colours like red, green etc. */ + badge_color?: string + /** Is Group Page : Check - When enabled, this page can hold and display nested sub-pages, creating a structured hierarchy in the sidebar. */ + is_group_page?: 0 | 1 + /** Content : Markdown Editor */ + content?: string + /** Linked Pages : Table - Linked Commit Docs Page */ + linked_pages?: LinkedCommitDocsPage[] +} \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitDocsTopbarItem.ts b/dashboard/src/types/commit/CommitDocsTopbarItem.ts new file mode 100644 index 0000000..7a056d7 --- /dev/null +++ b/dashboard/src/types/commit/CommitDocsTopbarItem.ts @@ -0,0 +1,25 @@ + +export interface CommitDocsTopbarItem{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Label : Data */ + label?: string + /** URL : Data - Link to the page you want to open. Leave blank if you want to make it a group parent. */ + url?: string + /** Open URL in a New Tab : Check */ + open_in_new_tab?: 0 | 1 + /** Hide On Navbar : Check */ + hide_on_navbar?: 0 | 1 + /** Parent Label : Select - If you set this, this Item will come in a drop-down under the selected parent. */ + parent_label?: string + /** Icon : Data */ + icon?: string +} \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitOrganization.ts b/dashboard/src/types/commit/CommitOrganization.ts index f874dbe..15aee35 100644 --- a/dashboard/src/types/commit/CommitOrganization.ts +++ b/dashboard/src/types/commit/CommitOrganization.ts @@ -1,7 +1,7 @@ export interface CommitOrganization{ - creation: string name: string + creation: string modified: string owner: string modified_by: string diff --git a/dashboard/src/types/commit/CommitProject.ts b/dashboard/src/types/commit/CommitProject.ts index 10d53c1..e05dd53 100644 --- a/dashboard/src/types/commit/CommitProject.ts +++ b/dashboard/src/types/commit/CommitProject.ts @@ -1,7 +1,7 @@ export interface CommitProject{ - creation: string name: string + creation: string modified: string owner: string modified_by: string diff --git a/dashboard/src/types/commit/CommitProjectBranch.ts b/dashboard/src/types/commit/CommitProjectBranch.ts index e31880e..c03d8c0 100644 --- a/dashboard/src/types/commit/CommitProjectBranch.ts +++ b/dashboard/src/types/commit/CommitProjectBranch.ts @@ -1,7 +1,7 @@ export interface CommitProjectBranch{ - creation: string name: string + creation: string modified: string owner: string modified_by: string @@ -22,6 +22,8 @@ export interface CommitProjectBranch{ app_name?: string /** Last fetched : Datetime */ last_fetched?: string + /** Frequency : Select */ + frequency?: "" | "Daily" | "Weekly" | "Monthly" /** Modules : Long Text */ modules?: string /** Module - Doctypes Map : JSON */ @@ -30,5 +32,6 @@ export interface CommitProjectBranch{ doctype_module_map?: any /** Whitelisted APIs : JSON */ whitelisted_apis?: any - frequency?: "Daily" | "Weekly" | "Monthly" + /** Documentation : JSON */ + documentation?: any } \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitSettings.ts b/dashboard/src/types/commit/CommitSettings.ts index 7248f2a..b3662ac 100644 --- a/dashboard/src/types/commit/CommitSettings.ts +++ b/dashboard/src/types/commit/CommitSettings.ts @@ -1,7 +1,7 @@ export interface CommitSettings{ - creation: string name: string + creation: string modified: string owner: string modified_by: string diff --git a/dashboard/src/types/commit/GithubSettings.ts b/dashboard/src/types/commit/GithubSettings.ts index 8f29a34..2d29783 100644 --- a/dashboard/src/types/commit/GithubSettings.ts +++ b/dashboard/src/types/commit/GithubSettings.ts @@ -1,7 +1,7 @@ export interface GithubSettings{ - creation: string name: string + creation: string modified: string owner: string modified_by: string diff --git a/dashboard/src/types/commit/GithubToken.ts b/dashboard/src/types/commit/GithubToken.ts new file mode 100644 index 0000000..67bb70d --- /dev/null +++ b/dashboard/src/types/commit/GithubToken.ts @@ -0,0 +1,28 @@ +import { OAuthScope } from '../Integrations/OAuthScope' + +export interface GithubToken{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** User : Link - User */ + user?: string + /** Token Type : Data */ + token_type?: string + /** Access Token : Data */ + access_token?: string + /** Expires In : Int */ + expires_in?: number + /** Refresh Token : Data */ + refresh_token?: string + /** Refresh Token Expire In : Int */ + refresh_token_expire_in?: number + /** Scopes : Table - OAuth Scope */ + scopes?: OAuthScope[] +} \ No newline at end of file diff --git a/dashboard/src/types/commit/LinkedCommitDocsPage.ts b/dashboard/src/types/commit/LinkedCommitDocsPage.ts new file mode 100644 index 0000000..b4f1dea --- /dev/null +++ b/dashboard/src/types/commit/LinkedCommitDocsPage.ts @@ -0,0 +1,15 @@ + +export interface LinkedCommitDocsPage{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Commit Docs Page : Link - Commit Docs Page */ + commit_docs_page: string +} \ No newline at end of file diff --git a/dashboard/src/types/commit/OpenAISettings.ts b/dashboard/src/types/commit/OpenAISettings.ts new file mode 100644 index 0000000..9fd1a10 --- /dev/null +++ b/dashboard/src/types/commit/OpenAISettings.ts @@ -0,0 +1,19 @@ + +export interface OpenAISettings{ + name: string + creation: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Organization : Data */ + organization: string + /** API Key : Password */ + api_key: string + /** Project : Data */ + project?: string +} \ No newline at end of file From 98ddc956df8352dede0a91ca537456673a62421b Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 3 Nov 2024 21:54:49 +0530 Subject: [PATCH 070/110] feat: Add API endpoint to retrieve Commit Docs details and sidebar,footer,navbar items --- .../commit/doctype/commit_docs/commit_docs.py | 213 +++++++++++++++++- .../commit_docs_topbar_item.json | 24 +- 2 files changed, 227 insertions(+), 10 deletions(-) diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py index a7f31a0..e0ea490 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.py +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -32,4 +32,215 @@ def get_docs_sidebar_parent_labels(id:str): 'value': label }) - return parent_labels_obj \ No newline at end of file + return parent_labels_obj + +@frappe.whitelist(allow_guest=True) +def get_commit_docs_details(route:str): + ''' + Get the Commit Docs Details + # 1. Get the Commit Docs Document from the route + # 2. Check if the Commit Docs Document Published + # 3. Return the Commit Docs Document + # 4. Get The Sidebar Items for the Commit Docs + # 5. Return the Sidebar Items + ''' + + # Check if the Commit Docs Document Exists + if frappe.db.exists('Commit Docs',{'route':route}): + + # Check if the document is published + if frappe.db.get_value('Commit Docs',{'route':route},'published'): + + # Get the Commit Docs Document + commit_docs = frappe.get_doc('Commit Docs',{'route':route}).as_dict() + + # Get the Sidebar Items + sidebar_items = get_sidebar_items(commit_docs.sidebar) + + # Get the Footer Items + footer_items = get_footer_items(commit_docs.footer) + + # Get the Navbar Items + navbar_items = get_navbar_items(commit_docs.navbar_items) + + # remove the sidebar from the commit_docs as it is not needed + commit_docs.pop('sidebar') + commit_docs.pop('footer') + commit_docs.pop('navbar_items') + + return { + 'commit_docs': commit_docs, + 'sidebar_items': sidebar_items, + 'footer_items': footer_items, + 'navbar_items': navbar_items + } + + else: + return frappe.throw('Docs Not Published') + + else: + return frappe.throw('Docs Not Found') + + +def get_footer_items(footer): + ''' + Get the Footer Items + # 1. Loop Over the Footer Items Which have Parent Label URL and Label + # 2. Check if the Footer Item is Hide on Footer + # 3. Return the Footer Items + ''' + footer_obj = {} + for footer_item in footer: + if footer_item.hide_on_footer: + continue + + if footer_item.parent_label not in footer_obj: + footer_obj[footer_item.parent_label] = [ + { + 'label': footer_item.label, + 'url': footer_item.url + } + ] + else: + footer_obj[footer_item.parent_label].append({ + 'label': footer_item.label, + 'url': footer_item.url + }) + + return footer_obj + +def get_navbar_items(navbar): + ''' + Get the Navbar Items + # 1. Loop Over the Navbar Items Which have Label, Parent Label, URL + # 2. Check if the Navbar Item is Hide on Navbar + # 3. Navbar Items are Nothing But Buttons which are displayed on the Navbar + # 4. Parent Label is not Mandatory it is nothing but Like as Menu Button which has Sub Buttons + ''' + + navbar_obj = {} + for navbar_item in navbar: + if navbar_item.hide_on_navbar: + continue + + # If the Item don't have parent label then add it as Object in the Navbar Object with the type as Button + # If the Item have parent label then check if navbar_obj have the parent label if not then add it in array as item with type as Menu + if not navbar_item.parent_label: + if navbar_item.label not in navbar_obj: + navbar_obj[navbar_item.label] = { + 'type':'Menu', + 'items': [{ + 'label': navbar_item.label, + 'url': navbar_item.url, + 'type': 'Button', + 'icon': navbar_item.icon, + 'open_in_new_tab': navbar_item.open_in_new_tab + }] + } + else: + navbar_obj[navbar_item.label]['items'].append({ + 'label': navbar_item.label, + 'url': navbar_item.url, + 'type': 'Button', + 'icon': navbar_item.icon, + 'open_in_new_tab': navbar_item.open_in_new_tab + }) + else: + navbar_obj[navbar_item.label] = { + 'label': navbar_item.label, + 'url': navbar_item.url, + 'type': 'Button', + 'icon': navbar_item.icon, + 'open_in_new_tab': navbar_item.open_in_new_tab + } + + return navbar_obj + +def get_sidebar_items(sidebar): + ''' + Get the Sidebar Items + # 1. Loop Over the Sidebar Items and Get the Commit Docs Page + # 2. Check if the Commit Docs Page is Published and Permitted + # 3. Check if the Commit Docs Page is Group Page + # 4. If Group Page then treat it as a Group and Loop Over the Group Items and Get the Commit Docs Page + # 2. Return the Sidebar Items + ''' + sidebar_obj = {} + for sidebar_item in sidebar: + if sidebar_item.hide_on_sidebar: + continue + + commit_docs_page = frappe.get_doc('Commit Docs Page',sidebar_item.docs_page) + + permitted = commit_docs_page.allow_guest or frappe.session.user != 'Guest' + published = commit_docs_page.published + is_group_page = commit_docs_page.is_group_page + + if not permitted or not published: + continue + + if is_group_page: + group_items = [] + for group_item in commit_docs_page.linked_pages: + group_commit_docs_page = frappe.get_doc('Commit Docs Page',group_item.commit_docs_page) + + permitted = group_commit_docs_page.allow_guest or frappe.session.user != 'Guest' + published = group_commit_docs_page.published + + if not permitted or not published: + continue + + # Make the Array of the Group Items + group_items.append({ + 'name': group_commit_docs_page.name, + 'type': 'Docs Page', + 'title': group_commit_docs_page.title, + 'route': group_commit_docs_page.route, + 'badge': group_commit_docs_page.badge, + 'badge_color': group_commit_docs_page.badge_color, + 'icon': group_commit_docs_page.icon, + 'parent_name': commit_docs_page.name + }) + + if sidebar_item.parent_label not in sidebar_obj: + sidebar_obj[sidebar_item.parent_label] = [ + { + 'name': commit_docs_page.name, + 'type': 'Docs Page', + 'title': commit_docs_page.title, + 'route': commit_docs_page.route, + 'badge': commit_docs_page.badge, + 'badge_color': commit_docs_page.badge_color, + 'icon': commit_docs_page.icon, + 'group_name': sidebar_item.parent_label, + 'is_group_page': is_group_page, + 'group_items': group_items + } + ] + + if sidebar_item.parent_label not in sidebar_obj: + sidebar_obj[sidebar_item.parent_label] = [ + { + 'name': commit_docs_page.name, + 'type': 'Docs Page', + 'title': commit_docs_page.title, + 'route': commit_docs_page.route, + 'badge': commit_docs_page.badge, + 'badge_color': commit_docs_page.badge_color, + 'icon': commit_docs_page.icon, + 'group_name': sidebar_item.parent_label + } + ] + else: + sidebar_obj[sidebar_item.parent_label].append({ + 'name': commit_docs_page.name, + 'type': 'Docs Page', + 'title': commit_docs_page.title, + 'route': commit_docs_page.route, + 'badge': commit_docs_page.badge, + 'badge_color': commit_docs_page.badge_color, + 'icon': commit_docs_page.icon, + 'group_name': sidebar_item.parent_label + }) + + return sidebar_obj \ No newline at end of file diff --git a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json index 049d1a0..f538953 100644 --- a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json +++ b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json @@ -10,9 +10,10 @@ "label", "url", "open_in_new_tab", - "right", + "hide_on_navbar", "column_break_5", - "parent_label" + "parent_label", + "icon" ], "fields": [ { @@ -39,12 +40,6 @@ "fieldtype": "Check", "label": "Open URL in a New Tab" }, - { - "default": "1", - "fieldname": "right", - "fieldtype": "Check", - "label": "Align Right" - }, { "fieldname": "column_break_5", "fieldtype": "Column Break" @@ -55,12 +50,23 @@ "fieldtype": "Select", "in_list_view": 1, "label": "Parent Label" + }, + { + "fieldname": "icon", + "fieldtype": "Data", + "label": "Icon" + }, + { + "default": "0", + "fieldname": "hide_on_navbar", + "fieldtype": "Check", + "label": "Hide On Navbar" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-10-29 19:17:18.340314", + "modified": "2024-11-03 21:16:28.959184", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs Topbar Item", From fecaa25de1aff4054f22c8bed1e7fb03bd3dc296 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sun, 3 Nov 2024 21:58:50 +0530 Subject: [PATCH 071/110] feat: Add DynamicIcon component for lazy loading icons --- .../DynamicIconImport/IconComponent.tsx | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 dashboard/src/components/common/DynamicIconImport/IconComponent.tsx diff --git a/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx new file mode 100644 index 0000000..1dddaf0 --- /dev/null +++ b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx @@ -0,0 +1,53 @@ +import { CSSProperties, lazy, Suspense, SVGAttributes, useMemo } from "react"; +import { IconContext } from "react-icons"; + +interface IProps { + icon: string; + color?: string; + size?: string; + className?: string; + style?: CSSProperties; + attr?: SVGAttributes; + fallback?: JSX.Element | null; +} +// Helper to load the icon +const loadIcon = async (icon: string) => { + const [library, iconName] = icon.split("/"); + const lib = library.toLowerCase(); + // Statically construct the import statement using a function map + const moduleImporters: Record Promise> = { + fa: () => import("react-icons/fa"), + md: () => import("react-icons/md"), + ai: () => import("react-icons/ai"), + // Add other libraries here as needed + }; + const importer = moduleImporters[lib]; + if (!importer) throw new Error(`Icon library "${library}" is not supported.`); + const module = await importer() + const IconComponent = module[iconName] + if (!IconComponent) throw new Error(`Icon "${icon}" not found in "${library}".`) + return IconComponent +}; + +const DynamicIcon: React.FC = ({ icon, color, size, className, style, attr, fallback = null }) => { + // Memoize the icon component so it's loaded only when `icon` changes + const Icon = useMemo( + () => lazy(() => loadIcon(icon).then((component) => ({ default: component }))), + [icon] + ); + const iconContext = { + color, + size, + className, + style, + attr, + }; + return ( + + + + + + ); +}; +export default DynamicIcon; \ No newline at end of file From eb05aec00a0f13757326fb5736d0bbcc5b2b810c Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 4 Nov 2024 13:27:05 +0530 Subject: [PATCH 072/110] fix: Handle invalid JSON format in documentation entries in get_apis_for_project function --- commit/api/api_explorer.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/commit/api/api_explorer.py b/commit/api/api_explorer.py index b16ef30..9d9a830 100644 --- a/commit/api/api_explorer.py +++ b/commit/api/api_explorer.py @@ -16,6 +16,13 @@ def get_apis_for_project(project_branch: str): for api in apis: # find the documentation for the api whose function_name equals to name and path same as path for doc in documentation: + if isinstance(doc, str): + try: + doc = json.loads(doc) + except json.JSONDecodeError: + frappe.log_error(f"Invalid JSON format in documentation entry: {doc}", "Commit Docs Error") + continue + if doc.get("function_name") == api.get("name") and doc.get("path") == api.get("api_path"): api["documentation"] = doc.get("documentation") api["last_updated"] = doc.get("last_updated") From b6a5416b292099f20146382575ec520806cd60ef Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 4 Nov 2024 21:48:38 +0530 Subject: [PATCH 073/110] feat: Expand icon library support in DynamicIcon component --- .../DynamicIconImport/IconComponent.tsx | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx index 1dddaf0..7979661 100644 --- a/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx +++ b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx @@ -15,12 +15,41 @@ const loadIcon = async (icon: string) => { const [library, iconName] = icon.split("/"); const lib = library.toLowerCase(); // Statically construct the import statement using a function map + // Full list of importable libraries from react-icons const moduleImporters: Record Promise> = { - fa: () => import("react-icons/fa"), - md: () => import("react-icons/md"), - ai: () => import("react-icons/ai"), - // Add other libraries here as needed + ai: () => import("react-icons/ai"), // Ant Design Icons + bs: () => import("react-icons/bs"), // Bootstrap Icons + bi: () => import("react-icons/bi"), // BoxIcons + ci: () => import("react-icons/ci"), // Circum Icons + cg: () => import("react-icons/cg"), // css.gg + di: () => import("react-icons/di"), // Devicons + fi: () => import("react-icons/fi"), // Feather Icons + fc: () => import("react-icons/fc"), // Flat Color Icons + fa: () => import("react-icons/fa"), // Font Awesome 5 Icons + fa6: () => import("react-icons/fa6"), // Font Awesome 6 Icons + gi: () => import("react-icons/gi"), // Game Icons + go: () => import("react-icons/go"), // GitHub Octicons + gr: () => import("react-icons/gr"), // Grommet Icons + hi: () => import("react-icons/hi"), // Heroicons + hi2: () => import("react-icons/hi2"), // Heroicons v2 + im: () => import("react-icons/im"), // IcoMoon Free + lia: () => import("react-icons/lia"), // Icons8 Line Awesome + io: () => import("react-icons/io"), // Ionicons + io5: () => import("react-icons/io5"), // Ionicons v5 + lu: () => import("react-icons/lu"), // Lucide Icons + md: () => import("react-icons/md"), // Material Design Icons + pi: () => import("react-icons/pi"), // Phosphor Icons + rx: () => import("react-icons/rx"), // Radix Icons + ri: () => import("react-icons/ri"), // Remix Icons + si: () => import("react-icons/si"), // Simple Icons + sl: () => import("react-icons/sl"), // Simple Line Icons + tb: () => import("react-icons/tb"), // Tabler Icons + tfi: () => import("react-icons/tfi"), // Themify Icons + ti: () => import("react-icons/ti"), // Typicons + vsc: () => import("react-icons/vsc"), // VS Code Icons + wi: () => import("react-icons/wi"), // Weather Icons }; + const importer = moduleImporters[lib]; if (!importer) throw new Error(`Icon library "${library}" is not supported.`); const module = await importer() @@ -50,4 +79,4 @@ const DynamicIcon: React.FC = ({ icon, color, size, className, style, at ); }; -export default DynamicIcon; \ No newline at end of file +export default DynamicIcon; From d6e975de79cf74d9e625a740c47f67676ea7c4f9 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Mon, 4 Nov 2024 21:59:59 +0530 Subject: [PATCH 074/110] feat: Enhance sidebar item retrieval with support for nested Group Pages --- .../commit/doctype/commit_docs/commit_docs.py | 176 +++++++++--------- 1 file changed, 89 insertions(+), 87 deletions(-) diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py index e0ea490..bd21399 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.py +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -157,90 +157,92 @@ def get_navbar_items(navbar): return navbar_obj def get_sidebar_items(sidebar): - ''' - Get the Sidebar Items - # 1. Loop Over the Sidebar Items and Get the Commit Docs Page - # 2. Check if the Commit Docs Page is Published and Permitted - # 3. Check if the Commit Docs Page is Group Page - # 4. If Group Page then treat it as a Group and Loop Over the Group Items and Get the Commit Docs Page - # 2. Return the Sidebar Items - ''' - sidebar_obj = {} - for sidebar_item in sidebar: - if sidebar_item.hide_on_sidebar: - continue - - commit_docs_page = frappe.get_doc('Commit Docs Page',sidebar_item.docs_page) - - permitted = commit_docs_page.allow_guest or frappe.session.user != 'Guest' - published = commit_docs_page.published - is_group_page = commit_docs_page.is_group_page - - if not permitted or not published: - continue - - if is_group_page: - group_items = [] - for group_item in commit_docs_page.linked_pages: - group_commit_docs_page = frappe.get_doc('Commit Docs Page',group_item.commit_docs_page) - - permitted = group_commit_docs_page.allow_guest or frappe.session.user != 'Guest' - published = group_commit_docs_page.published - - if not permitted or not published: - continue - - # Make the Array of the Group Items - group_items.append({ - 'name': group_commit_docs_page.name, - 'type': 'Docs Page', - 'title': group_commit_docs_page.title, - 'route': group_commit_docs_page.route, - 'badge': group_commit_docs_page.badge, - 'badge_color': group_commit_docs_page.badge_color, - 'icon': group_commit_docs_page.icon, - 'parent_name': commit_docs_page.name - }) - - if sidebar_item.parent_label not in sidebar_obj: - sidebar_obj[sidebar_item.parent_label] = [ - { - 'name': commit_docs_page.name, - 'type': 'Docs Page', - 'title': commit_docs_page.title, - 'route': commit_docs_page.route, - 'badge': commit_docs_page.badge, - 'badge_color': commit_docs_page.badge_color, - 'icon': commit_docs_page.icon, - 'group_name': sidebar_item.parent_label, - 'is_group_page': is_group_page, - 'group_items': group_items - } - ] - - if sidebar_item.parent_label not in sidebar_obj: - sidebar_obj[sidebar_item.parent_label] = [ - { - 'name': commit_docs_page.name, - 'type': 'Docs Page', - 'title': commit_docs_page.title, - 'route': commit_docs_page.route, - 'badge': commit_docs_page.badge, - 'badge_color': commit_docs_page.badge_color, - 'icon': commit_docs_page.icon, - 'group_name': sidebar_item.parent_label - } - ] - else: - sidebar_obj[sidebar_item.parent_label].append({ - 'name': commit_docs_page.name, - 'type': 'Docs Page', - 'title': commit_docs_page.title, - 'route': commit_docs_page.route, - 'badge': commit_docs_page.badge, - 'badge_color': commit_docs_page.badge_color, - 'icon': commit_docs_page.icon, - 'group_name': sidebar_item.parent_label - }) - - return sidebar_obj \ No newline at end of file + ''' + Get the Sidebar Items with support for nested Group Pages. + ''' + def get_group_items(commit_docs_page): + """ + Recursive function to fetch items for a Group Page, handling nested groups. + """ + group_items = [] + for group_item in commit_docs_page.linked_pages: + # Get the document for each linked page + group_commit_docs_page = frappe.get_doc('Commit Docs Page', group_item.commit_docs_page) + + # Check permissions and publication status + permitted = group_commit_docs_page.allow_guest or frappe.session.user != 'Guest' + published = group_commit_docs_page.published + + if not permitted or not published: + continue + + # Check if the linked page is also a Group Page + is_nested_group_page = group_commit_docs_page.is_group_page + + # If it's a nested Group Page, recursively fetch its group items + if is_nested_group_page: + nested_group_items = get_group_items(group_commit_docs_page) + group_items.append({ + 'name': group_commit_docs_page.name, + 'type': 'Docs Page', + 'title': group_commit_docs_page.title, + 'route': group_commit_docs_page.route, + 'badge': group_commit_docs_page.badge, + 'badge_color': group_commit_docs_page.badge_color, + 'icon': group_commit_docs_page.icon, + 'parent_name': commit_docs_page.name, + 'is_group_page': True, + 'group_items': nested_group_items + }) + else: + # If it's a regular Docs Page, add it directly + group_items.append({ + 'name': group_commit_docs_page.name, + 'type': 'Docs Page', + 'title': group_commit_docs_page.title, + 'route': group_commit_docs_page.route, + 'badge': group_commit_docs_page.badge, + 'badge_color': group_commit_docs_page.badge_color, + 'icon': group_commit_docs_page.icon, + 'parent_name': commit_docs_page.name + }) + return group_items + + sidebar_obj = {} + for sidebar_item in sidebar: + if sidebar_item.hide_on_sidebar: + continue + + commit_docs_page = frappe.get_doc('Commit Docs Page', sidebar_item.docs_page) + + permitted = commit_docs_page.allow_guest or frappe.session.user != 'Guest' + published = commit_docs_page.published + is_group_page = commit_docs_page.is_group_page + + if not permitted or not published: + continue + + # Process group items if it's a Group Page + group_items = get_group_items(commit_docs_page) if is_group_page else [] + + # Prepare sidebar entry with group items if it exists + sidebar_entry = { + 'name': commit_docs_page.name, + 'type': 'Docs Page', + 'title': commit_docs_page.title, + 'route': commit_docs_page.route, + 'badge': commit_docs_page.badge, + 'badge_color': commit_docs_page.badge_color, + 'icon': commit_docs_page.icon, + 'group_name': sidebar_item.parent_label, + 'is_group_page': is_group_page, + 'group_items': group_items if is_group_page else None + } + + # Add sidebar entry to the parent label + if sidebar_item.parent_label not in sidebar_obj: + sidebar_obj[sidebar_item.parent_label] = [sidebar_entry] + else: + sidebar_obj[sidebar_item.parent_label].append(sidebar_entry) + + return sidebar_obj From 8418259f46d9cf78f2515079807790aada7f3f00 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:51:08 +0530 Subject: [PATCH 075/110] feat: Add new fields for company name, Slack, Telegram, and YouTube URLs in Commit Docs; implement validation for unique routes and primary button restriction in navbar items --- .../doctype/commit_docs/commit_docs.json | 43 +++++++++++++- .../commit/doctype/commit_docs/commit_docs.py | 59 ++++++++++++++----- .../commit_docs_page/commit_docs_page.json | 4 +- .../commit_docs_topbar_item.json | 11 +++- 4 files changed, 96 insertions(+), 21 deletions(-) diff --git a/commit/commit/doctype/commit_docs/commit_docs.json b/commit/commit/doctype/commit_docs/commit_docs.json index d232ff8..8a3bdd8 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.json +++ b/commit/commit/doctype/commit_docs/commit_docs.json @@ -9,6 +9,7 @@ "header", "route", "published", + "company_name", "section_break_camv", "sidebar", "logo_section", @@ -19,8 +20,13 @@ "footer_tab", "twitter_url", "linkedin", + "slack", + "youtube", + "column_break_oxzh", "github", "raven", + "telegram", + "section_break_gawv", "footer" ], "fields": [ @@ -119,11 +125,46 @@ "fieldname": "published", "fieldtype": "Check", "label": "Published" + }, + { + "description": "Add Slack URL", + "fieldname": "slack", + "fieldtype": "Data", + "label": "Slack", + "options": "URL" + }, + { + "fieldname": "column_break_oxzh", + "fieldtype": "Column Break" + }, + { + "description": "Add Telegram URL", + "fieldname": "telegram", + "fieldtype": "Data", + "label": "Telegram", + "options": "URL" + }, + { + "fieldname": "section_break_gawv", + "fieldtype": "Section Break" + }, + { + "description": "Add Youtube URL", + "fieldname": "youtube", + "fieldtype": "Data", + "label": "Youtube", + "options": "URL" + }, + { + "description": "For Copyright Purpose", + "fieldname": "company_name", + "fieldtype": "Data", + "label": "Company Name" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-11-01 11:22:21.970571", + "modified": "2024-11-09 12:53:12.416589", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs", diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py index bd21399..79d9907 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.py +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -6,7 +6,24 @@ class CommitDocs(Document): - pass + + def after_insert(self): + ''' + Validate the Document + # 1. Check if the Route is Unique + ''' + if frappe.db.exists('Commit Docs',{'route':self.route}): + frappe.throw('Route Already Exists') + + def validate(self): + # 2. Loop Over through the Navbar Items and check there should be only one is Primary Button + primary_button_count = 0 + for navbar_item in self.navbar_items: + if navbar_item.is_primary_button: + primary_button_count += 1 + if primary_button_count > 1: + frappe.throw('Only One Primary Button is Allowed') + break @frappe.whitelist() @@ -119,40 +136,50 @@ def get_navbar_items(navbar): ''' navbar_obj = {} + parent_labels = [] for navbar_item in navbar: if navbar_item.hide_on_navbar: continue - # If the Item don't have parent label then add it as Object in the Navbar Object with the type as Button - # If the Item have parent label then check if navbar_obj have the parent label if not then add it in array as item with type as Menu - if not navbar_item.parent_label: - if navbar_item.label not in navbar_obj: - navbar_obj[navbar_item.label] = { + + if navbar_item.parent_label: + parent_labels.append(navbar_item.parent_label) + if navbar_item.parent_label not in navbar_obj: + navbar_obj[navbar_item.parent_label] = { 'type':'Menu', + 'label': navbar_item.parent_label, 'items': [{ 'label': navbar_item.label, 'url': navbar_item.url, 'type': 'Button', 'icon': navbar_item.icon, 'open_in_new_tab': navbar_item.open_in_new_tab - }] + }], + 'is_primary_button': navbar_item.is_primary_button } else: - navbar_obj[navbar_item.label]['items'].append({ + navbar_obj[navbar_item.parent_label]['items'].append({ 'label': navbar_item.label, 'url': navbar_item.url, 'type': 'Button', 'icon': navbar_item.icon, - 'open_in_new_tab': navbar_item.open_in_new_tab + 'open_in_new_tab': navbar_item.open_in_new_tab, }) else: - navbar_obj[navbar_item.label] = { - 'label': navbar_item.label, - 'url': navbar_item.url, - 'type': 'Button', - 'icon': navbar_item.icon, - 'open_in_new_tab': navbar_item.open_in_new_tab - } + if navbar_item.url: + navbar_obj[navbar_item.label] = { + 'label': navbar_item.label, + 'type': 'Button', + 'icon': navbar_item.icon, + 'open_in_new_tab': navbar_item.open_in_new_tab, + 'url': navbar_item.url, + 'is_primary_button': navbar_item.is_primary_button + } + + # Remove that Object whose type is Button and Key is in Parent Labels + button_type_keys = [key for key in navbar_obj if navbar_obj[key]['type'] == 'Button' and key in parent_labels] + for key in button_type_keys: + navbar_obj.pop(key) return navbar_obj diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.json b/commit/commit/doctype/commit_docs_page/commit_docs_page.json index fd6e4e0..aa52922 100644 --- a/commit/commit/doctype/commit_docs_page/commit_docs_page.json +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.json @@ -63,7 +63,7 @@ "label": "Badge" }, { - "description": "Add Tailwind colours like red, green etc.", + "description": "Add Tailwind colours like red-500, green-500 etc.", "fieldname": "badge_color", "fieldtype": "Data", "label": "Badge Color" @@ -105,7 +105,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-11-01 21:04:37.516864", + "modified": "2024-11-09 15:34:23.907329", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs Page", diff --git a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json index f538953..d2034da 100644 --- a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json +++ b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json @@ -13,7 +13,8 @@ "hide_on_navbar", "column_break_5", "parent_label", - "icon" + "icon", + "is_primary_button" ], "fields": [ { @@ -61,12 +62,18 @@ "fieldname": "hide_on_navbar", "fieldtype": "Check", "label": "Hide On Navbar" + }, + { + "default": "0", + "fieldname": "is_primary_button", + "fieldtype": "Check", + "label": "Is Primary Button" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-11-03 21:16:28.959184", + "modified": "2024-11-09 18:41:50.962807", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs Topbar Item", From 888db0d309d9c8d1b7086c04399800072eabce2f Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:51:25 +0530 Subject: [PATCH 076/110] feat: Add framer-motion library for enhanced animations in the dashboard --- dashboard/package.json | 1 + dashboard/yarn.lock | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/dashboard/package.json b/dashboard/package.json index 7a48bb0..61d44f1 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -42,6 +42,7 @@ "clsx": "^1.2.1", "cmdk": "^0.2.0", "downshift": "^9.0.6", + "framer-motion": "^11.11.11", "frappe-react-sdk": "^1.7.0", "html-to-image": "^1.11.11", "install": "^0.13.0", diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index 95d7659..97c26b7 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -2772,6 +2772,13 @@ fraction.js@^4.3.7: resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== +framer-motion@^11.11.11: + version "11.11.11" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.11.11.tgz#3c058c97ec134afdce77caa20396f0fd82d63b7d" + integrity sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw== + dependencies: + tslib "^2.4.0" + frappe-js-sdk@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/frappe-js-sdk/-/frappe-js-sdk-1.5.0.tgz#9fb161edb872136058c51adfba9f2c2927f81d2a" From c261d2ec5b7113bf6ac005e67fc64e3669f5a7ad Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:51:40 +0530 Subject: [PATCH 077/110] feat: Add a 404 Page Not Found component with animations and navigation --- .../common/PageNotFound/PageNotFound.tsx | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 dashboard/src/components/common/PageNotFound/PageNotFound.tsx diff --git a/dashboard/src/components/common/PageNotFound/PageNotFound.tsx b/dashboard/src/components/common/PageNotFound/PageNotFound.tsx new file mode 100644 index 0000000..d126f03 --- /dev/null +++ b/dashboard/src/components/common/PageNotFound/PageNotFound.tsx @@ -0,0 +1,56 @@ +import { motion } from 'framer-motion'; +import { Button } from "@/components/ui/button"; +import { IoCloudOutline } from "react-icons/io5"; +import { useNavigate } from 'react-router-dom'; + +export const PageNotFound = () => { + + const navigate = useNavigate() + + return ( +
      + + 404 + + + + Oops! We couldn't find that page. + + + + + + + + It seems you're floating in the clouds! Let us guide you back. + + + +
      + ); +} \ No newline at end of file From b846aff4a3f839ba5cb854f695957d5524cfe6bc Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:52:01 +0530 Subject: [PATCH 078/110] feat: Introduce new types for Docs structure including sidebar, navbar, and footer items; add company and social media fields to CommitDocs --- dashboard/src/pages/features/docs/docs.ts | 36 +++++++++++++++++++ dashboard/src/types/commit/CommitDocs.ts | 8 +++++ dashboard/src/types/commit/CommitDocsPage.ts | 2 +- .../src/types/commit/CommitDocsTopbarItem.ts | 2 ++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 dashboard/src/pages/features/docs/docs.ts diff --git a/dashboard/src/pages/features/docs/docs.ts b/dashboard/src/pages/features/docs/docs.ts new file mode 100644 index 0000000..59e608b --- /dev/null +++ b/dashboard/src/pages/features/docs/docs.ts @@ -0,0 +1,36 @@ +import { CommitDocs } from "@/types/commit/CommitDocs" + +export interface DocsSidebarItem { + name: string + type: string + title: string + route: string + badge?: string + badge_color?: string + icon?: string + parent_name?: string + is_group_page?: boolean + group_items?: DocsSidebarItem[] +} + +export interface DocsNavbarItem { + label: string + url: string + type: 'Button' | 'Menu' + icon?: string + open_in_new_tab?: boolean + items?: DocsNavbarItem[], + is_primary_button?: boolean +} + +export interface DocsFooterItem { + label: string + url: string +} + +export interface Docs { + commit_docs: Omit + sidebar_items: Record + navbar_items: Record + footer_items: Record +} diff --git a/dashboard/src/types/commit/CommitDocs.ts b/dashboard/src/types/commit/CommitDocs.ts index 5680676..cbc2466 100644 --- a/dashboard/src/types/commit/CommitDocs.ts +++ b/dashboard/src/types/commit/CommitDocs.ts @@ -19,6 +19,8 @@ export interface CommitDocs{ route: string /** Published : Check */ published?: 0 | 1 + /** Company Name : Data - For Copyright Purpose */ + company_name?: string /** Sidebar : Table - Commit Docs Group Item */ sidebar?: CommitDocsGroupItem[] /** Light Mode Logo : Attach Image */ @@ -31,10 +33,16 @@ export interface CommitDocs{ twitter_url?: string /** LinkedIn : Data - Add LinkedIn URL */ linkedin?: string + /** Slack : Data - Add Slack URL */ + slack?: string + /** Youtube : Data - Add Youtube URL */ + youtube?: string /** Github : Data - Add Github URL */ github?: string /** Raven : Data - Add Raven URL */ raven?: string + /** Telegram : Data - Add Telegram URL */ + telegram?: string /** Footer : Table - Commit Docs Footer Item */ footer?: CommitDocsFooterItem[] } \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitDocsPage.ts b/dashboard/src/types/commit/CommitDocsPage.ts index a1e486b..63aab7a 100644 --- a/dashboard/src/types/commit/CommitDocsPage.ts +++ b/dashboard/src/types/commit/CommitDocsPage.ts @@ -24,7 +24,7 @@ export interface CommitDocsPage{ icon?: string /** Badge : Data - This is badge field, eg: GET , POST etc. */ badge?: string - /** Badge Color : Data - Add Tailwind colours like red, green etc. */ + /** Badge Color : Data - Add Tailwind colours like red-500, green-500 etc. */ badge_color?: string /** Is Group Page : Check - When enabled, this page can hold and display nested sub-pages, creating a structured hierarchy in the sidebar. */ is_group_page?: 0 | 1 diff --git a/dashboard/src/types/commit/CommitDocsTopbarItem.ts b/dashboard/src/types/commit/CommitDocsTopbarItem.ts index 7a056d7..e595880 100644 --- a/dashboard/src/types/commit/CommitDocsTopbarItem.ts +++ b/dashboard/src/types/commit/CommitDocsTopbarItem.ts @@ -22,4 +22,6 @@ export interface CommitDocsTopbarItem{ parent_label?: string /** Icon : Data */ icon?: string + /** Is Primary Button : Check */ + is_primary_button?: 0 | 1 } \ No newline at end of file From a53a3ad8d0bb7d5f476f8cbe4a4ebc5c5a6808a4 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:52:13 +0530 Subject: [PATCH 079/110] feat: Add ViewDocs component for displaying document details with sidebar, navbar, and footer integration --- .../src/pages/features/docs/ViewDocs.tsx | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 dashboard/src/pages/features/docs/ViewDocs.tsx diff --git a/dashboard/src/pages/features/docs/ViewDocs.tsx b/dashboard/src/pages/features/docs/ViewDocs.tsx new file mode 100644 index 0000000..208322e --- /dev/null +++ b/dashboard/src/pages/features/docs/ViewDocs.tsx @@ -0,0 +1,103 @@ +import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; +import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; +import { useFrappeGetCall } from "frappe-react-sdk"; +import { useNavigate, useParams } from "react-router-dom"; +import { Docs } from "./docs"; +import { useEffect, useState } from "react"; +import { Sidebar } from "./Sidebar"; +import { Navbar } from "./Navbar"; +import { Footer } from "./Footer"; + +const ViewDocs = () => { + const { ID } = useParams(); + + if (ID) { + return ; + } + return null; +}; + +const ViewDocsDetails = ({ ID }: { ID: string }) => { + const [selectedendpoint, setSelectedEndpoint] = useState(""); + const navigate = useNavigate(); + + const { data, error, isLoading } = useFrappeGetCall<{ + message: Docs; + }>("commit.commit.doctype.commit_docs.commit_docs.get_commit_docs_details", + { + route: ID, + }, + undefined, + { + revalidateOnFocus: false, + revalidateIfStale: false, + onSuccess: (d: { message: Docs }) => { + if (!selectedendpoint) { + setSelectedEndpoint(d.message.sidebar_items[Object.keys(d.message.sidebar_items)[0]][0].route); + } + }, + }); + + useEffect(() => { + const searchParams = new URLSearchParams(window.location.search); + const endpointFromURL = searchParams.get("page"); + + if (endpointFromURL) { + setSelectedEndpoint(endpointFromURL); + } + }, []); + + useEffect(() => { + if (selectedendpoint) { + const searchParams = new URLSearchParams(window.location.search); + searchParams.set("page", selectedendpoint); + navigate({ search: searchParams.toString() }, { replace: true }); + } + }, [selectedendpoint, navigate]); + + if (isLoading) { + return ; + } + if (error) { + return ; + } + + if (data && data?.message) { + return ( +
      +
      + {/* Sidebar */} +
      +
      + +
      +
      + + {/* Vertical Divider */} +
      + + {/* Main Content */} +
      + {/* Fixed Navbar */} +
      + +
      + + {/* Content area with top padding to accommodate fixed Navbar */} +
      {/* Adjust '60px' based on Navbar height */} + {/* Page Content */} +
      +
      +
      +
      +
      + ); + } +}; + +export default ViewDocs; \ No newline at end of file From 05608e3d1bfc9366bb834cc63c7faa68a12b8634 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:52:20 +0530 Subject: [PATCH 080/110] feat: Add Sidebar component for document navigation with expandable groups and dynamic icons --- dashboard/src/pages/features/docs/Sidebar.tsx | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 dashboard/src/pages/features/docs/Sidebar.tsx diff --git a/dashboard/src/pages/features/docs/Sidebar.tsx b/dashboard/src/pages/features/docs/Sidebar.tsx new file mode 100644 index 0000000..73a9aaa --- /dev/null +++ b/dashboard/src/pages/features/docs/Sidebar.tsx @@ -0,0 +1,84 @@ +import { CommitDocs } from "@/types/commit/CommitDocs"; +import { DocsSidebarItem } from "./docs"; +import DynamicIcon from "@/components/common/DynamicIconImport/IconComponent"; +import { Badge } from "@/components/ui/badge"; +import { useState } from "react"; +import { MdKeyboardArrowDown, MdKeyboardArrowRight } from "react-icons/md"; + +export const Sidebar = ({ commit_docs, sidebar_items, selectedEndpoint, setSelectedEndpoint }: { commit_docs: Omit, sidebar_items: Record, selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void }) => { + + return ( +
      +
      + {commit_docs.light_mode_logo && logo} + {commit_docs.header &&
      {commit_docs.header}
      } +
      +
      + {Object.keys(sidebar_items).map((key) => ( + + ))} +
      +
      + ) +} + +const SidebarGroup = ({ groupName, items, selectedEndpoint, setSelectedEndpoint }: { groupName: string, items: DocsSidebarItem[], selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void }) => { + const [isExpanded, setIsExpanded] = useState(true); + + return ( +
      +
      setIsExpanded(!isExpanded)}> + {groupName} + {isExpanded ? : } +
      + {isExpanded && items.map((item) => ( + + ))} +
      + ) +} + +const SidebarItem = ({ item, selectedEndpoint, setSelectedEndpoint, className, level = 1 }: { item: DocsSidebarItem, selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void, className?: string, level?: number }) => { + + if (item.is_group_page && item.group_items?.length) { + const [isExpanded, setIsExpanded] = useState(false); + return ( +
      + + {isExpanded && item.group_items.map((groupItem) => ( + + ))} +
      + ) + } + + return ( + + ) +} + +const SidebarTitle = ({ item, selectedEndpoint, setSelectedEndpoint, className, isExpanded, setIsExpanded }: { item: DocsSidebarItem, selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void, className?: string, isExpanded?: boolean, setIsExpanded?: (isExpanded: boolean) => void }) => { + + const isSelected = item.route === selectedEndpoint; + + return ( +
      setIsExpanded && setIsExpanded(!isExpanded) : () => setSelectedEndpoint(item.route)} + > +
      +
      + {item.icon && } + {item.badge && {item.badge}} +
      + {item.title} +
      +
      + {item.is_group_page && item.group_items?.length ? {isExpanded ? : } : null} +
      +
      + ) +} From 95521ea4a2ee6918121905874f5578354b4988ab Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:52:25 +0530 Subject: [PATCH 081/110] feat: Add Navbar component for document navigation with search functionality and dropdown menus --- dashboard/src/pages/features/docs/Navbar.tsx | 65 ++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 dashboard/src/pages/features/docs/Navbar.tsx diff --git a/dashboard/src/pages/features/docs/Navbar.tsx b/dashboard/src/pages/features/docs/Navbar.tsx new file mode 100644 index 0000000..fcf12f3 --- /dev/null +++ b/dashboard/src/pages/features/docs/Navbar.tsx @@ -0,0 +1,65 @@ +import DynamicIcon from "@/components/common/DynamicIconImport/IconComponent"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { DocsNavbarItem } from "./docs"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; +import { FaCaretDown } from "react-icons/fa"; +import { RiSearchLine } from "react-icons/ri"; + +export const Navbar = ({ navbar_items }: { navbar_items: Record }) => { + return ( +
      + {/* Left side: Search bar */} +
      + + +
      + + {/* Right side: Navbar items */} +
      + {Object.keys(navbar_items).reverse().map((key) => ( +
      + {navbar_items[key]?.type === 'Button' ? ( + + ) : ( + + )} +
      + ))} +
      +
      + ); +}; + +const MenuButton = ({ item }: { item: DocsNavbarItem }) => { + + return ( + + + + + + {item.items?.map((subItem) => ( + window.open(subItem.url, subItem.open_in_new_tab ? "_blank" : "_self")}> + {subItem.label} + + ))} + + + ); +}; \ No newline at end of file From 7dffe69c12c696884db02b5fa1625aa93b3c2bc4 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 18:52:34 +0530 Subject: [PATCH 082/110] feat: Add Footer component with dynamic sections and social media links --- dashboard/src/App.tsx | 4 + dashboard/src/pages/features/docs/Footer.tsx | 107 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 dashboard/src/pages/features/docs/Footer.tsx diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index bb9b86f..fe5e6f1 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -5,6 +5,8 @@ import { Overview } from './pages/overview/Overview' import { ERDViewer } from './pages/features/erd/ERDViewer' import { AppAPIViewerContainer } from './pages/features/api_viewer/AppAPIViewer' import { CreateERD } from './pages/features/erd/meta/CreateERDForMeta' +import ViewDocs from './pages/features/docs/ViewDocs' +import { PageNotFound } from './components/common/PageNotFound/PageNotFound' function App() { @@ -36,6 +38,8 @@ function App() { } /> } /> } /> + } /> + } /> {/* */} diff --git a/dashboard/src/pages/features/docs/Footer.tsx b/dashboard/src/pages/features/docs/Footer.tsx new file mode 100644 index 0000000..0d82d9c --- /dev/null +++ b/dashboard/src/pages/features/docs/Footer.tsx @@ -0,0 +1,107 @@ +import { CommitDocs } from "@/types/commit/CommitDocs"; +import { DocsFooterItem } from "./docs"; +import { FaLinkedin, FaSlack, FaGithub, FaYoutube, FaTelegram } from "react-icons/fa"; +import { GiRaven } from "react-icons/gi"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; +import { FaXTwitter } from "react-icons/fa6"; + + +export const Footer = ({ commit_docs, footer_items }: { commit_docs: Omit, footer_items: Record }) => { + + const social_links = { + 'raven': commit_docs.raven, + 'twitter': commit_docs.twitter_url, + 'linkedin': commit_docs.linkedin, + 'slack': commit_docs.slack, + 'github': commit_docs.github, + 'youtube': commit_docs.youtube, + 'telegram': commit_docs.telegram, + } + return ( +
      +
      +
      + {/* Logo */} +
      + {commit_docs.light_mode_logo && ( + Logo + )} + {commit_docs.header && ( +

      {commit_docs.header}

      + )} +
      + + {/* Footer sections */} +
      + {Object.keys(footer_items).map((section) => ( +
      +
      {section}
      + +
      + ))} +
      + + {/* Social media icons */} +
      + {Object.entries(social_links).map(([field, url]) => + url ? : null + )} +
      +
      +
      +
      + Copyright © {new Date().getFullYear()} {commit_docs.company_name}, Build with commit. +
      +
      + ) +} + + +interface SocialMediaIconProps { + field: string; + url: string; +} +const classsName = "text-gray-600 hover:text-gray-800 h-5 w-5"; + +const iconMap: Record = { + twitter: , + linkedin: , + slack: , + github: , + youtube: , + telegram: , + raven: , + // Add more icons here as needed +}; + +const SocialMediaIcon: React.FC = ({ field, url }) => { + const icon = iconMap[field]; + if (!icon) return null; // Return nothing if the field is not in iconMap + + return ( + + + + + {icon} + + + + {field.charAt(0).toUpperCase() + field.slice(1)} + + + + ); +}; \ No newline at end of file From a9693f94b1d403b1c29109d6844893d8eaefb983 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 19:03:44 +0530 Subject: [PATCH 083/110] feat: Enhance Navbar component with conditional styling for primary buttons --- dashboard/src/pages/features/docs/Navbar.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/dashboard/src/pages/features/docs/Navbar.tsx b/dashboard/src/pages/features/docs/Navbar.tsx index fcf12f3..5cb4bc1 100644 --- a/dashboard/src/pages/features/docs/Navbar.tsx +++ b/dashboard/src/pages/features/docs/Navbar.tsx @@ -24,6 +24,7 @@ export const Navbar = ({ navbar_items }: { navbar_items: Record window.open(navbar_items[key].url, navbar_items[key].open_in_new_tab ? "_blank" : "_self")} > {navbar_items[key].icon && } From fb42d09c2b0fe960aa64beb6ed045d27537e741d Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 19:03:48 +0530 Subject: [PATCH 084/110] refactor: Remove commented-out print statements for cleaner code --- commit/commit/code_analysis/apis.py | 5 ----- .../commit_project_branch/commit_project_branch.py | 9 +-------- commit/commit/doctype/github_settings/github_settings.py | 6 ------ 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/commit/commit/code_analysis/apis.py b/commit/commit/code_analysis/apis.py index df9b9a2..c95ca96 100644 --- a/commit/commit/code_analysis/apis.py +++ b/commit/commit/code_analysis/apis.py @@ -18,7 +18,6 @@ def find_all_occurrences_of_whitelist(path: str, app_name: str): api_count = 0 file_count = 0 api_details = [] - # print(py_files) # For each file, check if @frappe.whitelist is present for file in py_files: file_content = open(file, 'r').read() @@ -39,10 +38,6 @@ def find_all_occurrences_of_whitelist(path: str, app_name: str): api_details.extend(apis) return api_details - - # print(f'Number of APIs: {api_count}') - # print(f'Number of files: {file_count}') - # print(f'Number of Python files: {len(py_files)}') def find_indexes_of_whitelist(file_content: str, count: int): ''' diff --git a/commit/commit/doctype/commit_project_branch/commit_project_branch.py b/commit/commit/doctype/commit_project_branch/commit_project_branch.py index eccef34..657cdc2 100644 --- a/commit/commit/doctype/commit_project_branch/commit_project_branch.py +++ b/commit/commit/doctype/commit_project_branch/commit_project_branch.py @@ -62,11 +62,8 @@ def clone_repo(self): project.org, project.repo_name) folder_path = self.path_to_folder - # print("Folder path", folder_path) - # print("Repo url", repo_url) - # print("Branch name", self.branch_name) + repo = git.Repo.clone_from(repo_url, folder_path, branch=self.branch_name, single_branch=True) - # print("Cloned repo") self.last_fetched = frappe.utils.now_datetime() self.commit_hash = repo.head.object.hexsha @@ -86,7 +83,6 @@ def fetch_repo(self): pass def get_modules(self): - # print("Getting modules") modules_path = os.path.join( self.path_to_folder, self.app_name, 'modules.txt') if os.path.isfile(modules_path): @@ -104,12 +100,10 @@ def get_modules(self): self.module_doctypes_map = module_doctypes_map self.doctype_module_map = doctype_module_map - # print("Modules", self.modules) def find_all_apis(self): apis = find_all_occurrences_of_whitelist( self.path_to_folder, self.app_name) - # print(apis) # Convert list to string and save to database self.whitelisted_apis = { "apis": apis @@ -149,7 +143,6 @@ def get_doctype_json(self, doctype_name): if self.doctype_module_map: doctype_module_map = json.loads(self.doctype_module_map) module = doctype_module_map.get(doctype_name) - # print("Module", module) if module: return get_doctype_json(self.path_to_folder, self.app_name, module, doctype_name) return None diff --git a/commit/commit/doctype/github_settings/github_settings.py b/commit/commit/doctype/github_settings/github_settings.py index 6ce4e2e..331253e 100644 --- a/commit/commit/doctype/github_settings/github_settings.py +++ b/commit/commit/doctype/github_settings/github_settings.py @@ -18,14 +18,11 @@ class GithubSettings(Document): @frappe.whitelist(allow_guest=True) def authenticate_user(code, state=None): '''API to authenticate the user with GitHub''' - # print("----- Auth Code: ", code) response = get_access_token(code) if response: user_data = get_user_details(response.get('access_token')) if user_data: - # print("Inside user data: ", user_data) user = create_user(user_data) - # print("----- User: ", user.as_dict()) def get_access_token(code): @@ -46,19 +43,16 @@ def get_access_token(code): headers = {'Accept': 'application/json'} response = requests.post(token_url, data=data, headers=headers) - # print("----- Response: ", response.json()) return response.json() def get_user_details(access_token): user_response = requests.get( 'https://api.github.com/user', headers={'Authorization': 'token ' + access_token}) - # print("----- User Response: ", user_response.json()) user_data = {} if user_response.status_code == 200 and user_response.json(): email_response = requests.get( 'https://api.github.com/user/emails', headers={'Authorization': 'token ' + access_token}) - # print("----- Email Response: ", email_response.json()) user_data = {"user_details": user_response.json( ), "email_details": email_response.json()} From 406480f0d62f5a91389c346c34a18da14f4c0988 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 9 Nov 2024 19:54:25 +0530 Subject: [PATCH 085/110] fix: Update MarkdownRenderer to handle TypeScript errors with remark and rehype plugins --- .../src/components/common/MarkdownRenderer/MarkdownRenderer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx b/dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx index 29883a7..4f145f6 100644 --- a/dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx +++ b/dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx @@ -10,8 +10,8 @@ interface MarkdownRendererProps { export const MarkdownRenderer: React.FC = ({ content }) => { return {content} From e02f222acd773e43e361629240972c7905d9e35d Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 15 Nov 2024 13:02:16 +0530 Subject: [PATCH 086/110] feat: Refactor CommitDocs to use before_insert and enhance sidebar functionality with route mapping --- .../commit/doctype/commit_docs/commit_docs.py | 20 ++++++++++---- .../commit_docs_page/commit_docs_page.json | 4 +-- dashboard/src/pages/features/docs/Sidebar.tsx | 26 +++++++++++++++++-- dashboard/src/pages/features/docs/docs.ts | 1 + dashboard/src/types/commit/CommitDocsPage.ts | 2 +- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py index 79d9907..ea9bfba 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.py +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -7,7 +7,7 @@ class CommitDocs(Document): - def after_insert(self): + def before_insert(self): ''' Validate the Document # 1. Check if the Route is Unique @@ -71,8 +71,11 @@ def get_commit_docs_details(route:str): # Get the Commit Docs Document commit_docs = frappe.get_doc('Commit Docs',{'route':route}).as_dict() + # Maintain route_map from the sidebar where key is the route and value is the name of the page + route_map = {} + # Get the Sidebar Items - sidebar_items = get_sidebar_items(commit_docs.sidebar) + sidebar_items, route_map = get_sidebar_items(commit_docs.sidebar,route_map) # Get the Footer Items footer_items = get_footer_items(commit_docs.footer) @@ -89,7 +92,8 @@ def get_commit_docs_details(route:str): 'commit_docs': commit_docs, 'sidebar_items': sidebar_items, 'footer_items': footer_items, - 'navbar_items': navbar_items + 'navbar_items': navbar_items, + 'route_map': route_map } else: @@ -183,7 +187,7 @@ def get_navbar_items(navbar): return navbar_obj -def get_sidebar_items(sidebar): +def get_sidebar_items(sidebar, route_map): ''' Get the Sidebar Items with support for nested Group Pages. ''' @@ -233,6 +237,8 @@ def get_group_items(commit_docs_page): 'icon': group_commit_docs_page.icon, 'parent_name': commit_docs_page.name }) + # Add route to route_map + route_map[group_commit_docs_page.route] = group_commit_docs_page.name return group_items sidebar_obj = {} @@ -272,4 +278,8 @@ def get_group_items(commit_docs_page): else: sidebar_obj[sidebar_item.parent_label].append(sidebar_entry) - return sidebar_obj + # Add route to route_map if it's not a group page + if not is_group_page: + route_map[commit_docs_page.route] = commit_docs_page.name + + return sidebar_obj, route_map diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.json b/commit/commit/doctype/commit_docs_page/commit_docs_page.json index aa52922..13c96cf 100644 --- a/commit/commit/doctype/commit_docs_page/commit_docs_page.json +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.json @@ -63,7 +63,7 @@ "label": "Badge" }, { - "description": "Add Tailwind colours like red-500, green-500 etc.", + "description": "Add Tailwind colours like red, green, blue, yellow, purple, pink, indigo, cyan, teal, lime, orange, gray etc.", "fieldname": "badge_color", "fieldtype": "Data", "label": "Badge Color" @@ -105,7 +105,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-11-09 15:34:23.907329", + "modified": "2024-11-15 13:00:46.803980", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs Page", diff --git a/dashboard/src/pages/features/docs/Sidebar.tsx b/dashboard/src/pages/features/docs/Sidebar.tsx index 73a9aaa..404e464 100644 --- a/dashboard/src/pages/features/docs/Sidebar.tsx +++ b/dashboard/src/pages/features/docs/Sidebar.tsx @@ -4,6 +4,8 @@ import DynamicIcon from "@/components/common/DynamicIconImport/IconComponent"; import { Badge } from "@/components/ui/badge"; import { useState } from "react"; import { MdKeyboardArrowDown, MdKeyboardArrowRight } from "react-icons/md"; +import classNames from "classnames"; +import { cn } from "@/lib/utils"; export const Sidebar = ({ commit_docs, sidebar_items, selectedEndpoint, setSelectedEndpoint }: { commit_docs: Omit, sidebar_items: Record, selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void }) => { @@ -61,6 +63,26 @@ const SidebarTitle = ({ item, selectedEndpoint, setSelectedEndpoint, className, const isSelected = item.route === selectedEndpoint; + const badgeClass = classNames({ + 'text-[10px] px-1 py-0': true, + 'bg-blue-500': item.badge_color === 'blue', + 'bg-red-500': item.badge_color === 'red', + 'bg-green-500': item.badge_color === 'green', + 'bg-yellow-500': item.badge_color === 'yellow', + 'bg-purple-500': item.badge_color === 'purple', + 'bg-pink-500': item.badge_color === 'pink', + 'bg-indigo-500': item.badge_color === 'indigo', + 'bg-cyan-500': item.badge_color === 'cyan', + 'bg-teal-500': item.badge_color === 'teal', + 'bg-lime-500': item.badge_color === 'lime', + 'bg-orange-500': item.badge_color === 'orange', + 'bg-blue-gray-500': item.badge_color === 'blue-gray', + 'bg-gray-500': item.badge_color === 'gray', + 'bg-true-gray-500': item.badge_color === 'true-gray', + 'bg-warm-gray-500': item.badge_color === 'warm-gray', + 'bg-cool-gray-500': item.badge_color === 'cool-gray', + }) + return (
      {item.icon && } - {item.badge && {item.badge}} + {item.badge && {item.badge}}
      {item.title}
      diff --git a/dashboard/src/pages/features/docs/docs.ts b/dashboard/src/pages/features/docs/docs.ts index 59e608b..e2bc70c 100644 --- a/dashboard/src/pages/features/docs/docs.ts +++ b/dashboard/src/pages/features/docs/docs.ts @@ -33,4 +33,5 @@ export interface Docs { sidebar_items: Record navbar_items: Record footer_items: Record + route_map: Record } diff --git a/dashboard/src/types/commit/CommitDocsPage.ts b/dashboard/src/types/commit/CommitDocsPage.ts index 63aab7a..c3c9140 100644 --- a/dashboard/src/types/commit/CommitDocsPage.ts +++ b/dashboard/src/types/commit/CommitDocsPage.ts @@ -24,7 +24,7 @@ export interface CommitDocsPage{ icon?: string /** Badge : Data - This is badge field, eg: GET , POST etc. */ badge?: string - /** Badge Color : Data - Add Tailwind colours like red-500, green-500 etc. */ + /** Badge Color : Data - Add Tailwind colours like red, green, blue, yellow, purple, pink, indigo, cyan, teal, lime, orange, gray etc. */ badge_color?: string /** Is Group Page : Check - When enabled, this page can hold and display nested sub-pages, creating a structured hierarchy in the sidebar. */ is_group_page?: 0 | 1 From c26ff185e75add91757657af5347edbed3b34c15 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 15 Nov 2024 17:51:25 +0530 Subject: [PATCH 087/110] feat: Add ErrorBanner component to Projects for improved error handling and update commit_docs_page to ignore XSS filter --- commit/commit/doctype/commit_docs_page/commit_docs_page.json | 3 ++- dashboard/src/components/features/projects/Projects.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.json b/commit/commit/doctype/commit_docs_page/commit_docs_page.json index 13c96cf..4110d98 100644 --- a/commit/commit/doctype/commit_docs_page/commit_docs_page.json +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.json @@ -54,6 +54,7 @@ "depends_on": "eval:doc.is_group_page == 0", "fieldname": "content", "fieldtype": "Markdown Editor", + "ignore_xss_filter": 1, "label": "Content" }, { @@ -105,7 +106,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-11-15 13:00:46.803980", + "modified": "2024-11-15 15:20:42.503563", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs Page", diff --git a/dashboard/src/components/features/projects/Projects.tsx b/dashboard/src/components/features/projects/Projects.tsx index 78f8df6..0658c2d 100644 --- a/dashboard/src/components/features/projects/Projects.tsx +++ b/dashboard/src/components/features/projects/Projects.tsx @@ -7,6 +7,7 @@ import { AddMenuButton } from "./AddMenuButton"; import { APIExplorer } from "./APIExplorer"; import ProjectCard from "./Projects/ProjectCard"; import { ViewERDButton } from "./ViewERDButton"; +import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; export interface ProjectWithBranch extends CommitProject { @@ -37,7 +38,7 @@ export const Projects = () => { ); if (error) { - return
      Error
      ; + return ; } if (isLoading) { From b94907a1c177aaf8af8fef0c8e9164dd7b2fb6e8 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 6 Dec 2024 17:45:16 +0530 Subject: [PATCH 088/110] fix: Update documentation generation to use triple backticks for code examples --- commit/api/generate_documentation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commit/api/generate_documentation.py b/commit/api/generate_documentation.py index 983bde9..8687f87 100644 --- a/commit/api/generate_documentation.py +++ b/commit/api/generate_documentation.py @@ -65,7 +65,7 @@ def generate_docs_for_chunk(api_chunk): "- ## Description: Detailed description of what the function does and what it is used for \n" "- ## Parameters: List of parameters with their types, descriptions, and indicate which are mandatory or optional\n" "- ## Return Type: Type and description of the return value\n" - "- ## Examples: Code examples demonstrating how to use the function (enclosed using
       and  Tags`).\n\n"
      +                "- ## Examples\n Provide code examples demonstrating how to use the function, enclosed in triple backticks (``````).\n\n"
                       "The response should be a valid JSON list of objects formatted as follows: "
                       "{function_name: , path: , last_updated:, documentation: }.\n"
                       "Ensure the response is in valid JSON format only, enclosed in triple backticks, and does not include `---`."
      @@ -223,7 +223,7 @@ def save_documentation_for_site_app(project_branch:str,endpoint:str,documentatio
                   apis.append({
                       "function_name": endpoint.split(".")[-1],
                       "path": endpoint,
      -                "last_updated": frappe.utils.now(),
      +                "last_updated": frappe.utils.now(), 
                       "documentation": documentation
                   })
               doc.documentation = json.dumps({"apis": apis})
      
      From 4ea23ba163e0a2f2ed39eb49134e336cb7f3c4c6 Mon Sep 17 00:00:00 2001
      From: Sumit Jain 
      Date: Fri, 6 Dec 2024 17:46:08 +0530
      Subject: [PATCH 089/110] feat: get commit page API
      
      ---
       .../commit_docs_page/commit_docs_page.py      | 53 ++++++++++++++++++-
       1 file changed, 52 insertions(+), 1 deletion(-)
      
      diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.py b/commit/commit/doctype/commit_docs_page/commit_docs_page.py
      index acc194a..e3bf74f 100644
      --- a/commit/commit/doctype/commit_docs_page/commit_docs_page.py
      +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.py
      @@ -91,4 +91,55 @@ def publish_documentation(project_branch, endpoint, viewer_type, docs_name, pare
       	return {
       		'commit_docs_page': commit_docs_page.name,
       		'commit_docs': commit_docs.name
      -	}
      \ No newline at end of file
      +	}
      +
      +@frappe.whitelist()
      +def get_commit_docs_page(name):
      +	'''
      +		Get the Commit Docs Page
      +	'''
      +	doc = frappe.get_doc('Commit Docs Page', name).as_dict()
      +
      +	# Get the content as HTML
      +	html = frappe.utils.md_to_html(doc.content)
      +
      +	# Calculate the Table of Contents
      +	toc_obj = calculate_toc_object(html)
      +
      +	return {
      +		'doc': doc,
      +		'toc_obj': toc_obj
      +	}
      +
      +
      +def calculate_toc_object(html):
      +    from bs4 import BeautifulSoup
      +    import re
      +
      +    soup = BeautifulSoup(html, "html.parser")
      +    headings = soup.find_all(["h2", "h3", "h4", "h5", "h6"])
      +
      +    toc = {}
      +
      +    def add_to_toc(toc, level, heading_id, title):
      +        if level == 2:
      +            toc[heading_id] = {"name": title, "children": {}}
      +        else:
      +            parent_level = level - 1
      +            parent = toc
      +            while parent_level > 2:
      +                if not parent:
      +                    break
      +                parent = next(iter(parent.values()))["children"]
      +                parent_level -= 1
      +            if parent:
      +                parent[next(iter(parent.keys()))]["children"][heading_id] = {"name": title, "children": {}}
      +
      +    for heading in headings:
      +        title = heading.get_text().strip()
      +        heading_id = re.sub(r"[^\u00C0-\u1FFF\u2C00-\uD7FF\w\- ]", "", title).replace(" ", "-").lower()
      +        heading["id"] = heading_id
      +        level = int(heading.name[1])
      +        add_to_toc(toc, level, heading_id, title)
      +
      +    return toc
      
      From ae0945595c7b48dfc9af7547f97b1a57e17128ad Mon Sep 17 00:00:00 2001
      From: Sumit Jain 
      Date: Fri, 6 Dec 2024 17:46:24 +0530
      Subject: [PATCH 090/110] feat: Add MDX support to Vite configuration and
       update dependencies
      
      ---
       dashboard/package.json   |   10 +-
       dashboard/vite.config.ts |    3 +-
       dashboard/yarn.lock      | 3256 +++++++++++++++++++-------------------
       3 files changed, 1642 insertions(+), 1627 deletions(-)
      
      diff --git a/dashboard/package.json b/dashboard/package.json
      index 61d44f1..08fa1da 100644
      --- a/dashboard/package.json
      +++ b/dashboard/package.json
      @@ -15,6 +15,9 @@
           "@headlessui/react": "^1.7.15",
           "@heroicons/react": "^2.0.18",
           "@hookform/resolvers": "^3.1.1",
      +    "@mdx-js/mdx": "^3.1.0",
      +    "@mdx-js/react": "^3.1.0",
      +    "@mdx-js/rollup": "^3.1.0",
           "@radix-ui/react-accordion": "^1.1.2",
           "@radix-ui/react-alert-dialog": "^1.0.4",
           "@radix-ui/react-avatar": "^1.0.3",
      @@ -39,6 +42,7 @@
           "@uiw/react-md-editor": "^4.0.4",
           "cal-sans": "^1.0.1",
           "class-variance-authority": "^0.6.1",
      +    "classnames": "^2.5.1",
           "clsx": "^1.2.1",
           "cmdk": "^0.2.0",
           "downshift": "^9.0.6",
      @@ -55,11 +59,13 @@
           "react-dropzone": "^14.2.3",
           "react-hook-form": "^7.45.1",
           "react-icons": "^5.2.1",
      -    "react-markdown": "^9.0.1",
           "react-router-dom": "^6.14.1",
           "reactflow": "^11.11.4",
      +    "rehype-katex": "^7.0.1",
           "rehype-raw": "^7.0.0",
      -    "remark-gfm": "^3.0.1",
      +    "remark-breaks": "^4.0.0",
      +    "remark-gfm": "^4.0.0",
      +    "remark-math": "^6.0.0",
           "shadcn-ui": "^0.8.0",
           "socket.io-client": "^4.5.1",
           "swr": "^2.1.5",
      diff --git a/dashboard/vite.config.ts b/dashboard/vite.config.ts
      index 85c9b99..46e2a90 100644
      --- a/dashboard/vite.config.ts
      +++ b/dashboard/vite.config.ts
      @@ -2,10 +2,11 @@ import path from 'path';
       import { defineConfig } from 'vite';
       import react from '@vitejs/plugin-react'
       import proxyOptions from './proxyOptions';
      +import mdx from '@mdx-js/rollup'
       
       // https://vitejs.dev/config/
       export default defineConfig({
      -	plugins: [react()],
      +	plugins: [react(), mdx()],
       	server: {
       		port: 8080,
       		proxy: proxyOptions
      diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock
      index 97c26b7..a35b4b6 100644
      --- a/dashboard/yarn.lock
      +++ b/dashboard/yarn.lock
      @@ -20,306 +20,247 @@
         resolved "https://registry.yarnpkg.com/@antfu/ni/-/ni-0.21.12.tgz#54d33cf0e6d35cb2ec12ab3d5092e4904540b7c0"
         integrity sha512-2aDL3WUv8hMJb2L3r/PIQWsTLyq7RQr3v9xD16fiz6O8ys1xEyLhhTOv8gxtZvJiTzjTF5pHoArvRdesGL1DMQ==
       
      -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.2":
      -  version "7.24.2"
      -  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae"
      -  integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==
      +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0":
      +  version "7.26.2"
      +  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
      +  integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
         dependencies:
      -    "@babel/highlight" "^7.24.2"
      +    "@babel/helper-validator-identifier" "^7.25.9"
      +    js-tokens "^4.0.0"
           picocolors "^1.0.0"
       
      -"@babel/compat-data@^7.23.5":
      -  version "7.24.4"
      -  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a"
      -  integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==
      +"@babel/compat-data@^7.25.9":
      +  version "7.26.2"
      +  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e"
      +  integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==
       
      -"@babel/core@^7.22.1", "@babel/core@^7.23.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.5.tgz#15ab5b98e101972d171aeef92ac70d8d6718f06a"
      -  integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==
      +"@babel/core@^7.22.1", "@babel/core@^7.25.2":
      +  version "7.26.0"
      +  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40"
      +  integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==
         dependencies:
           "@ampproject/remapping" "^2.2.0"
      -    "@babel/code-frame" "^7.24.2"
      -    "@babel/generator" "^7.24.5"
      -    "@babel/helper-compilation-targets" "^7.23.6"
      -    "@babel/helper-module-transforms" "^7.24.5"
      -    "@babel/helpers" "^7.24.5"
      -    "@babel/parser" "^7.24.5"
      -    "@babel/template" "^7.24.0"
      -    "@babel/traverse" "^7.24.5"
      -    "@babel/types" "^7.24.5"
      +    "@babel/code-frame" "^7.26.0"
      +    "@babel/generator" "^7.26.0"
      +    "@babel/helper-compilation-targets" "^7.25.9"
      +    "@babel/helper-module-transforms" "^7.26.0"
      +    "@babel/helpers" "^7.26.0"
      +    "@babel/parser" "^7.26.0"
      +    "@babel/template" "^7.25.9"
      +    "@babel/traverse" "^7.25.9"
      +    "@babel/types" "^7.26.0"
           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.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.5.tgz#e5afc068f932f05616b66713e28d0f04e99daeb3"
      -  integrity sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==
      +"@babel/generator@^7.25.9", "@babel/generator@^7.26.0":
      +  version "7.26.2"
      +  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f"
      +  integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==
         dependencies:
      -    "@babel/types" "^7.24.5"
      +    "@babel/parser" "^7.26.2"
      +    "@babel/types" "^7.26.0"
           "@jridgewell/gen-mapping" "^0.3.5"
           "@jridgewell/trace-mapping" "^0.3.25"
      -    jsesc "^2.5.1"
      +    jsesc "^3.0.2"
       
      -"@babel/helper-annotate-as-pure@^7.22.5":
      -  version "7.22.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882"
      -  integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==
      +"@babel/helper-annotate-as-pure@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4"
      +  integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==
         dependencies:
      -    "@babel/types" "^7.22.5"
      +    "@babel/types" "^7.25.9"
       
      -"@babel/helper-compilation-targets@^7.23.6":
      -  version "7.23.6"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991"
      -  integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==
      +"@babel/helper-compilation-targets@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875"
      +  integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==
         dependencies:
      -    "@babel/compat-data" "^7.23.5"
      -    "@babel/helper-validator-option" "^7.23.5"
      -    browserslist "^4.22.2"
      +    "@babel/compat-data" "^7.25.9"
      +    "@babel/helper-validator-option" "^7.25.9"
      +    browserslist "^4.24.0"
           lru-cache "^5.1.1"
           semver "^6.3.1"
       
      -"@babel/helper-create-class-features-plugin@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz#7d19da92c7e0cd8d11c09af2ce1b8e7512a6e723"
      -  integrity sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==
      -  dependencies:
      -    "@babel/helper-annotate-as-pure" "^7.22.5"
      -    "@babel/helper-environment-visitor" "^7.22.20"
      -    "@babel/helper-function-name" "^7.23.0"
      -    "@babel/helper-member-expression-to-functions" "^7.24.5"
      -    "@babel/helper-optimise-call-expression" "^7.22.5"
      -    "@babel/helper-replace-supers" "^7.24.1"
      -    "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5"
      -    "@babel/helper-split-export-declaration" "^7.24.5"
      +"@babel/helper-create-class-features-plugin@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83"
      +  integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==
      +  dependencies:
      +    "@babel/helper-annotate-as-pure" "^7.25.9"
      +    "@babel/helper-member-expression-to-functions" "^7.25.9"
      +    "@babel/helper-optimise-call-expression" "^7.25.9"
      +    "@babel/helper-replace-supers" "^7.25.9"
      +    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
      +    "@babel/traverse" "^7.25.9"
           semver "^6.3.1"
       
      -"@babel/helper-environment-visitor@^7.22.20":
      -  version "7.22.20"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167"
      -  integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
      -
      -"@babel/helper-function-name@^7.23.0":
      -  version "7.23.0"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759"
      -  integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
      -  dependencies:
      -    "@babel/template" "^7.22.15"
      -    "@babel/types" "^7.23.0"
      -
      -"@babel/helper-hoist-variables@^7.22.5":
      -  version "7.22.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb"
      -  integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==
      -  dependencies:
      -    "@babel/types" "^7.22.5"
      -
      -"@babel/helper-member-expression-to-functions@^7.23.0", "@babel/helper-member-expression-to-functions@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz#5981e131d5c7003c7d1fa1ad49e86c9b097ec475"
      -  integrity sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==
      +"@babel/helper-member-expression-to-functions@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz#9dfffe46f727005a5ea29051ac835fb735e4c1a3"
      +  integrity sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==
         dependencies:
      -    "@babel/types" "^7.24.5"
      +    "@babel/traverse" "^7.25.9"
      +    "@babel/types" "^7.25.9"
       
      -"@babel/helper-module-imports@^7.24.3":
      -  version "7.24.3"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128"
      -  integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==
      +"@babel/helper-module-imports@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715"
      +  integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==
         dependencies:
      -    "@babel/types" "^7.24.0"
      +    "@babel/traverse" "^7.25.9"
      +    "@babel/types" "^7.25.9"
       
      -"@babel/helper-module-transforms@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz#ea6c5e33f7b262a0ae762fd5986355c45f54a545"
      -  integrity sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==
      +"@babel/helper-module-transforms@^7.26.0":
      +  version "7.26.0"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae"
      +  integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==
         dependencies:
      -    "@babel/helper-environment-visitor" "^7.22.20"
      -    "@babel/helper-module-imports" "^7.24.3"
      -    "@babel/helper-simple-access" "^7.24.5"
      -    "@babel/helper-split-export-declaration" "^7.24.5"
      -    "@babel/helper-validator-identifier" "^7.24.5"
      +    "@babel/helper-module-imports" "^7.25.9"
      +    "@babel/helper-validator-identifier" "^7.25.9"
      +    "@babel/traverse" "^7.25.9"
       
      -"@babel/helper-optimise-call-expression@^7.22.5":
      -  version "7.22.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e"
      -  integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==
      +"@babel/helper-optimise-call-expression@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz#3324ae50bae7e2ab3c33f60c9a877b6a0146b54e"
      +  integrity sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==
         dependencies:
      -    "@babel/types" "^7.22.5"
      +    "@babel/types" "^7.25.9"
       
      -"@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz#a924607dd254a65695e5bd209b98b902b3b2f11a"
      -  integrity sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==
      +"@babel/helper-plugin-utils@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46"
      +  integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==
       
      -"@babel/helper-replace-supers@^7.24.1":
      -  version "7.24.1"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1"
      -  integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==
      +"@babel/helper-replace-supers@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz#ba447224798c3da3f8713fc272b145e33da6a5c5"
      +  integrity sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==
         dependencies:
      -    "@babel/helper-environment-visitor" "^7.22.20"
      -    "@babel/helper-member-expression-to-functions" "^7.23.0"
      -    "@babel/helper-optimise-call-expression" "^7.22.5"
      +    "@babel/helper-member-expression-to-functions" "^7.25.9"
      +    "@babel/helper-optimise-call-expression" "^7.25.9"
      +    "@babel/traverse" "^7.25.9"
       
      -"@babel/helper-simple-access@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz#50da5b72f58c16b07fbd992810be6049478e85ba"
      -  integrity sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==
      +"@babel/helper-skip-transparent-expression-wrappers@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9"
      +  integrity sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==
         dependencies:
      -    "@babel/types" "^7.24.5"
      +    "@babel/traverse" "^7.25.9"
      +    "@babel/types" "^7.25.9"
       
      -"@babel/helper-skip-transparent-expression-wrappers@^7.22.5":
      -  version "7.22.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847"
      -  integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==
      -  dependencies:
      -    "@babel/types" "^7.22.5"
      -
      -"@babel/helper-split-export-declaration@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz#b9a67f06a46b0b339323617c8c6213b9055a78b6"
      -  integrity sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==
      -  dependencies:
      -    "@babel/types" "^7.24.5"
      +"@babel/helper-string-parser@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
      +  integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
       
      -"@babel/helper-string-parser@^7.24.1":
      -  version "7.24.1"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e"
      -  integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==
      -
      -"@babel/helper-validator-identifier@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62"
      -  integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==
      -
      -"@babel/helper-validator-option@^7.23.5":
      -  version "7.23.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307"
      -  integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==
      -
      -"@babel/helpers@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.5.tgz#fedeb87eeafa62b621160402181ad8585a22a40a"
      -  integrity sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==
      -  dependencies:
      -    "@babel/template" "^7.24.0"
      -    "@babel/traverse" "^7.24.5"
      -    "@babel/types" "^7.24.5"
      -
      -"@babel/highlight@^7.24.2":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e"
      -  integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==
      -  dependencies:
      -    "@babel/helper-validator-identifier" "^7.24.5"
      -    chalk "^2.4.2"
      -    js-tokens "^4.0.0"
      -    picocolors "^1.0.0"
      +"@babel/helper-validator-identifier@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
      +  integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
       
      -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.6", "@babel/parser@^7.24.0", "@babel/parser@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790"
      -  integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==
      +"@babel/helper-validator-option@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72"
      +  integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==
       
      -"@babel/plugin-syntax-typescript@^7.24.1":
      -  version "7.24.1"
      -  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz#b3bcc51f396d15f3591683f90239de143c076844"
      -  integrity sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==
      +"@babel/helpers@^7.26.0":
      +  version "7.26.0"
      +  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4"
      +  integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==
         dependencies:
      -    "@babel/helper-plugin-utils" "^7.24.0"
      +    "@babel/template" "^7.25.9"
      +    "@babel/types" "^7.26.0"
       
      -"@babel/plugin-transform-react-jsx-self@^7.23.3":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.5.tgz#22cc7572947895c8e4cd034462e65d8ecf857756"
      -  integrity sha512-RtCJoUO2oYrYwFPtR1/jkoBEcFuI1ae9a9IMxeyAVa3a1Ap4AnxmyIKG2b2FaJKqkidw/0cxRbWN+HOs6ZWd1w==
      +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.6", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2":
      +  version "7.26.2"
      +  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11"
      +  integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==
         dependencies:
      -    "@babel/helper-plugin-utils" "^7.24.5"
      +    "@babel/types" "^7.26.0"
       
      -"@babel/plugin-transform-react-jsx-source@^7.23.3":
      -  version "7.24.1"
      -  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.1.tgz#a2dedb12b09532846721b5df99e52ef8dc3351d0"
      -  integrity sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==
      +"@babel/plugin-syntax-typescript@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz#67dda2b74da43727cf21d46cf9afef23f4365399"
      +  integrity sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==
         dependencies:
      -    "@babel/helper-plugin-utils" "^7.24.0"
      +    "@babel/helper-plugin-utils" "^7.25.9"
       
      -"@babel/plugin-transform-typescript@^7.22.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz#bcba979e462120dc06a75bd34c473a04781931b8"
      -  integrity sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==
      +"@babel/plugin-transform-react-jsx-self@^7.24.7":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858"
      +  integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==
         dependencies:
      -    "@babel/helper-annotate-as-pure" "^7.22.5"
      -    "@babel/helper-create-class-features-plugin" "^7.24.5"
      -    "@babel/helper-plugin-utils" "^7.24.5"
      -    "@babel/plugin-syntax-typescript" "^7.24.1"
      +    "@babel/helper-plugin-utils" "^7.25.9"
       
      -"@babel/runtime@^7.13.10":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.5.tgz#230946857c053a36ccc66e1dd03b17dd0c4ed02c"
      -  integrity sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==
      +"@babel/plugin-transform-react-jsx-source@^7.24.7":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503"
      +  integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==
         dependencies:
      -    regenerator-runtime "^0.14.0"
      +    "@babel/helper-plugin-utils" "^7.25.9"
       
      -"@babel/runtime@^7.14.6", "@babel/runtime@^7.17.2":
      -  version "7.25.6"
      -  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2"
      -  integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==
      +"@babel/plugin-transform-typescript@^7.22.5":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz#69267905c2b33c2ac6d8fe765e9dc2ddc9df3849"
      +  integrity sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==
         dependencies:
      -    regenerator-runtime "^0.14.0"
      +    "@babel/helper-annotate-as-pure" "^7.25.9"
      +    "@babel/helper-create-class-features-plugin" "^7.25.9"
      +    "@babel/helper-plugin-utils" "^7.25.9"
      +    "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
      +    "@babel/plugin-syntax-typescript" "^7.25.9"
       
      -"@babel/runtime@^7.24.5":
      -  version "7.24.7"
      -  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12"
      -  integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==
      +"@babel/runtime@^7.13.10", "@babel/runtime@^7.14.6", "@babel/runtime@^7.17.2", "@babel/runtime@^7.24.5":
      +  version "7.26.0"
      +  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
      +  integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
         dependencies:
           regenerator-runtime "^0.14.0"
       
      -"@babel/template@^7.22.15", "@babel/template@^7.24.0":
      -  version "7.24.0"
      -  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50"
      -  integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==
      -  dependencies:
      -    "@babel/code-frame" "^7.23.5"
      -    "@babel/parser" "^7.24.0"
      -    "@babel/types" "^7.24.0"
      -
      -"@babel/traverse@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.5.tgz#972aa0bc45f16983bf64aa1f877b2dd0eea7e6f8"
      -  integrity sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==
      -  dependencies:
      -    "@babel/code-frame" "^7.24.2"
      -    "@babel/generator" "^7.24.5"
      -    "@babel/helper-environment-visitor" "^7.22.20"
      -    "@babel/helper-function-name" "^7.23.0"
      -    "@babel/helper-hoist-variables" "^7.22.5"
      -    "@babel/helper-split-export-declaration" "^7.24.5"
      -    "@babel/parser" "^7.24.5"
      -    "@babel/types" "^7.24.5"
      +"@babel/template@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016"
      +  integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==
      +  dependencies:
      +    "@babel/code-frame" "^7.25.9"
      +    "@babel/parser" "^7.25.9"
      +    "@babel/types" "^7.25.9"
      +
      +"@babel/traverse@^7.25.9":
      +  version "7.25.9"
      +  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84"
      +  integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
      +  dependencies:
      +    "@babel/code-frame" "^7.25.9"
      +    "@babel/generator" "^7.25.9"
      +    "@babel/parser" "^7.25.9"
      +    "@babel/template" "^7.25.9"
      +    "@babel/types" "^7.25.9"
           debug "^4.3.1"
           globals "^11.1.0"
       
      -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.24.0", "@babel/types@^7.24.5":
      -  version "7.24.5"
      -  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.5.tgz#7661930afc638a5383eb0c4aee59b74f38db84d7"
      -  integrity sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==
      +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.9", "@babel/types@^7.26.0":
      +  version "7.26.0"
      +  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff"
      +  integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==
         dependencies:
      -    "@babel/helper-string-parser" "^7.24.1"
      -    "@babel/helper-validator-identifier" "^7.24.5"
      -    to-fast-properties "^2.0.0"
      +    "@babel/helper-string-parser" "^7.25.9"
      +    "@babel/helper-validator-identifier" "^7.25.9"
       
       "@dagrejs/dagre@^1.0.2":
      -  version "1.1.2"
      -  resolved "https://registry.yarnpkg.com/@dagrejs/dagre/-/dagre-1.1.2.tgz#5ec339979447091f48d2144deed8c70dfadae374"
      -  integrity sha512-F09dphqvHsbe/6C2t2unbmpr5q41BNPEfJCdn8Z7aEBpVSy/zFQ/b4SWsweQjWNsYMDvE2ffNUN8X0CeFsEGNw==
      +  version "1.1.4"
      +  resolved "https://registry.yarnpkg.com/@dagrejs/dagre/-/dagre-1.1.4.tgz#66f9c0e2b558308f2c268f60e2c28f22ee17e339"
      +  integrity sha512-QUTc54Cg/wvmlEUxB+uvoPVKFazM1H18kVHBQNmK2NbrDR5ihOCR6CXLnDSZzMcSQKJtabPUWridBOlJM3WkDg==
         dependencies:
      -    "@dagrejs/graphlib" "2.2.2"
      +    "@dagrejs/graphlib" "2.2.4"
       
      -"@dagrejs/graphlib@2.2.2":
      -  version "2.2.2"
      -  resolved "https://registry.yarnpkg.com/@dagrejs/graphlib/-/graphlib-2.2.2.tgz#74154d5cb880a23b4fae71034a09b4b5aef06feb"
      -  integrity sha512-CbyGpCDKsiTg/wuk79S7Muoj8mghDGAESWGxcSyhHX5jD35vYMBZochYVFzlHxynpE9unpu6O+4ZuhrLxASsOg==
      +"@dagrejs/graphlib@2.2.4":
      +  version "2.2.4"
      +  resolved "https://registry.yarnpkg.com/@dagrejs/graphlib/-/graphlib-2.2.4.tgz#d77bfa9ff49e2307c0c6e6b8b26b5dd3c05816c4"
      +  integrity sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==
       
       "@esbuild/android-arm64@0.18.20":
         version "0.18.20"
      @@ -432,16 +373,16 @@
         integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
       
       "@eslint-community/eslint-utils@^4.2.0":
      -  version "4.4.0"
      -  resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
      -  integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
      +  version "4.4.1"
      +  resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56"
      +  integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==
         dependencies:
      -    eslint-visitor-keys "^3.3.0"
      +    eslint-visitor-keys "^3.4.3"
       
       "@eslint-community/regexpp@^4.6.1":
      -  version "4.10.0"
      -  resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63"
      -  integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==
      +  version "4.12.1"
      +  resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
      +  integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
       
       "@eslint/eslintrc@^2.1.4":
         version "2.1.4"
      @@ -458,37 +399,37 @@
           minimatch "^3.1.2"
           strip-json-comments "^3.1.1"
       
      -"@eslint/js@8.57.0":
      -  version "8.57.0"
      -  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f"
      -  integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==
      +"@eslint/js@8.57.1":
      +  version "8.57.1"
      +  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2"
      +  integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==
       
      -"@floating-ui/core@^1.0.0":
      -  version "1.6.2"
      -  resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.2.tgz#d37f3e0ac1f1c756c7de45db13303a266226851a"
      -  integrity sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==
      +"@floating-ui/core@^1.6.0":
      +  version "1.6.8"
      +  resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.8.tgz#aa43561be075815879305965020f492cdb43da12"
      +  integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==
         dependencies:
      -    "@floating-ui/utils" "^0.2.0"
      +    "@floating-ui/utils" "^0.2.8"
       
       "@floating-ui/dom@^1.0.0":
      -  version "1.6.5"
      -  resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.5.tgz#323f065c003f1d3ecf0ff16d2c2c4d38979f4cb9"
      -  integrity sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==
      +  version "1.6.12"
      +  resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.12.tgz#6333dcb5a8ead3b2bf82f33d6bc410e95f54e556"
      +  integrity sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==
         dependencies:
      -    "@floating-ui/core" "^1.0.0"
      -    "@floating-ui/utils" "^0.2.0"
      +    "@floating-ui/core" "^1.6.0"
      +    "@floating-ui/utils" "^0.2.8"
       
       "@floating-ui/react-dom@^2.0.0":
      -  version "2.0.9"
      -  resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.9.tgz#264ba8b061000baa132b5910f0427a6acf7ad7ce"
      -  integrity sha512-q0umO0+LQK4+p6aGyvzASqKbKOJcAHJ7ycE9CuUvfx3s9zTHWmGJTPOIlM/hmSBfUfg/XfY5YhLBLR/LHwShQQ==
      +  version "2.1.2"
      +  resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.2.tgz#a1349bbf6a0e5cb5ded55d023766f20a4d439a31"
      +  integrity sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==
         dependencies:
           "@floating-ui/dom" "^1.0.0"
       
      -"@floating-ui/utils@^0.2.0":
      -  version "0.2.2"
      -  resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.2.tgz#d8bae93ac8b815b2bd7a98078cf91e2724ef11e5"
      -  integrity sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==
      +"@floating-ui/utils@^0.2.8":
      +  version "0.2.8"
      +  resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62"
      +  integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==
       
       "@headlessui/react@^1.7.15":
         version "1.7.19"
      @@ -499,21 +440,21 @@
           client-only "^0.0.1"
       
       "@heroicons/react@^2.0.18":
      -  version "2.1.3"
      -  resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.1.3.tgz#78a2a7f504a7370283d07eabcddc7fec04f503db"
      -  integrity sha512-fEcPfo4oN345SoqdlCDdSa4ivjaKbk0jTd+oubcgNxnNgAfzysfwWfQUr+51wigiWHQQRiZNd1Ao0M5Y3M2EGg==
      +  version "2.1.5"
      +  resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.1.5.tgz#1e13f34976cc542deae92353c01c8b3d7942e9ba"
      +  integrity sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==
       
       "@hookform/resolvers@^3.1.1":
      -  version "3.4.0"
      -  resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.4.0.tgz#4ca2c08a26118fc8b6a572da94fdd57750a79b62"
      -  integrity sha512-+oAqK3okmoEDnvUkJ3N/mvNMeeMv5Apgy1jkoRmlaaAF4vBgcJs9tHvtXU7VE4DvPosvAUUkPOaNFunzt1dbgA==
      +  version "3.9.1"
      +  resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.9.1.tgz#a23883c40bfd449cb6c6ab5a0fa0729184c950ff"
      +  integrity sha512-ud2HqmGBM0P0IABqoskKWI6PEf6ZDDBZkFqe2Vnl+mTHCEHzr3ISjjZyCwTjC/qpL25JC9aIDkloQejvMeq0ug==
       
      -"@humanwhocodes/config-array@^0.11.14":
      -  version "0.11.14"
      -  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"
      -  integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==
      +"@humanwhocodes/config-array@^0.13.0":
      +  version "0.13.0"
      +  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748"
      +  integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==
         dependencies:
      -    "@humanwhocodes/object-schema" "^2.0.2"
      +    "@humanwhocodes/object-schema" "^2.0.3"
           debug "^4.3.1"
           minimatch "^3.0.5"
       
      @@ -522,7 +463,7 @@
         resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
         integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
       
      -"@humanwhocodes/object-schema@^2.0.2":
      +"@humanwhocodes/object-schema@^2.0.3":
         version "2.0.3"
         resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3"
         integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
      @@ -559,9 +500,9 @@
         integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
       
       "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
      -  version "1.4.15"
      -  resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
      -  integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
      +  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"
      @@ -571,6 +512,53 @@
           "@jridgewell/resolve-uri" "^3.1.0"
           "@jridgewell/sourcemap-codec" "^1.4.14"
       
      +"@mdx-js/mdx@^3.0.0", "@mdx-js/mdx@^3.1.0":
      +  version "3.1.0"
      +  resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-3.1.0.tgz#10235cab8ad7d356c262e8c21c68df5850a97dc3"
      +  integrity sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    "@types/estree-jsx" "^1.0.0"
      +    "@types/hast" "^3.0.0"
      +    "@types/mdx" "^2.0.0"
      +    collapse-white-space "^2.0.0"
      +    devlop "^1.0.0"
      +    estree-util-is-identifier-name "^3.0.0"
      +    estree-util-scope "^1.0.0"
      +    estree-walker "^3.0.0"
      +    hast-util-to-jsx-runtime "^2.0.0"
      +    markdown-extensions "^2.0.0"
      +    recma-build-jsx "^1.0.0"
      +    recma-jsx "^1.0.0"
      +    recma-stringify "^1.0.0"
      +    rehype-recma "^1.0.0"
      +    remark-mdx "^3.0.0"
      +    remark-parse "^11.0.0"
      +    remark-rehype "^11.0.0"
      +    source-map "^0.7.0"
      +    unified "^11.0.0"
      +    unist-util-position-from-estree "^2.0.0"
      +    unist-util-stringify-position "^4.0.0"
      +    unist-util-visit "^5.0.0"
      +    vfile "^6.0.0"
      +
      +"@mdx-js/react@^3.1.0":
      +  version "3.1.0"
      +  resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.0.tgz#c4522e335b3897b9a845db1dbdd2f966ae8fb0ed"
      +  integrity sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==
      +  dependencies:
      +    "@types/mdx" "^2.0.0"
      +
      +"@mdx-js/rollup@^3.1.0":
      +  version "3.1.0"
      +  resolved "https://registry.yarnpkg.com/@mdx-js/rollup/-/rollup-3.1.0.tgz#55df5cf4db52ac95be26d0cfa039ebf4e945e6e4"
      +  integrity sha512-q4xOtUXpCzeouE8GaJ8StT4rDxm/U5j6lkMHL2srb2Q3Y7cobE0aXyPzXVVlbeIMBi+5R5MpbiaVE5/vJUdnHg==
      +  dependencies:
      +    "@mdx-js/mdx" "^3.0.0"
      +    "@rollup/pluginutils" "^5.0.0"
      +    source-map "^0.7.0"
      +    vfile "^6.0.0"
      +
       "@nodelib/fs.scandir@2.1.5":
         version "2.1.5"
         resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
      @@ -604,6 +592,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/number@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.1.0.tgz#1e95610461a09cdf8bb05c152e76ca1278d5da46"
      +  integrity sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==
      +
       "@radix-ui/primitive@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253"
      @@ -618,34 +611,37 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/primitive@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2"
      +  integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==
      +
       "@radix-ui/react-accordion@^1.1.2":
      -  version "1.1.2"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-accordion/-/react-accordion-1.1.2.tgz#738441f7343e5142273cdef94d12054c3287966f"
      -  integrity sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-collapsible" "1.0.3"
      -    "@radix-ui/react-collection" "1.0.3"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-direction" "1.0.1"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      +  version "1.2.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-accordion/-/react-accordion-1.2.1.tgz#5c942c42c24267376b26204ec6847b17d15659b3"
      +  integrity sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-collapsible" "1.1.1"
      +    "@radix-ui/react-collection" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-direction" "1.1.0"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
       
       "@radix-ui/react-alert-dialog@^1.0.4":
      -  version "1.0.5"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.0.5.tgz#70dd529cbf1e4bff386814d3776901fcaa131b8c"
      -  integrity sha512-OrVIOcZL0tl6xibeuGt5/+UxoT2N27KCFOPjFyfXMnchxSHZ/OW7cCX2nGlIYJrbHK/fczPcFzAwvNBB6XBNMA==
      +  version "1.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.2.tgz#ac3bb7f71f5cbb595d3d0949bb12b598c2a99981"
      +  integrity sha512-eGSlLzPhKO+TErxkiGcCZGuvbVMnLA1MTnyBksGOeGRGkxHiiJUujsjmNTdWTm4iHVSRaUao9/4Ur671auMghQ==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-dialog" "1.0.5"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-slot" "1.0.2"
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-dialog" "1.1.2"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-slot" "1.1.0"
       
       "@radix-ui/react-arrow@1.0.3":
         version "1.0.3"
      @@ -655,46 +651,50 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-primitive" "1.0.3"
       
      -"@radix-ui/react-avatar@^1.0.3":
      -  version "1.0.4"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.0.4.tgz#de9a5349d9e3de7bbe990334c4d2011acbbb9623"
      -  integrity sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==
      +"@radix-ui/react-arrow@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz#744f388182d360b86285217e43b6c63633f39e7a"
      +  integrity sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      -    "@radix-ui/react-use-layout-effect" "1.0.1"
      +    "@radix-ui/react-primitive" "2.0.0"
       
      -"@radix-ui/react-checkbox@^1.0.4":
      -  version "1.0.4"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz#98f22c38d5010dd6df4c5744cac74087e3275f4b"
      -  integrity sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==
      +"@radix-ui/react-avatar@^1.0.3":
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.1.1.tgz#5848d2ed5f34d18b36fc7e2d227c41fca8600ea1"
      +  integrity sha512-eoOtThOmxeoizxpX6RiEsQZ2wj5r4+zoeqAwO0cBaFQGjJwIH3dIX0OCxNrCyrrdxG+vBweMETh3VziQG7c1kw==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      -    "@radix-ui/react-use-previous" "1.0.1"
      -    "@radix-ui/react-use-size" "1.0.1"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
       
      -"@radix-ui/react-collapsible@1.0.3":
      -  version "1.0.3"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz#df0e22e7a025439f13f62d4e4a9e92c4a0df5b81"
      -  integrity sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      -    "@radix-ui/react-use-layout-effect" "1.0.1"
      +"@radix-ui/react-checkbox@^1.0.4":
      +  version "1.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.1.2.tgz#6465b800420923ecc39cbeaa8f357b5f09dbfd52"
      +  integrity sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
      +    "@radix-ui/react-use-previous" "1.1.0"
      +    "@radix-ui/react-use-size" "1.1.0"
      +
      +"@radix-ui/react-collapsible@1.1.1":
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz#1382cc9ec48f8b473c14f3779d317f0cdf6da5e9"
      +  integrity sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
       
       "@radix-ui/react-collection@1.0.3":
         version "1.0.3"
      @@ -707,6 +707,16 @@
           "@radix-ui/react-primitive" "1.0.3"
           "@radix-ui/react-slot" "1.0.2"
       
      +"@radix-ui/react-collection@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz#f18af78e46454a2360d103c2251773028b7724ed"
      +  integrity sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==
      +  dependencies:
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.0"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-slot" "1.1.0"
      +
       "@radix-ui/react-compose-refs@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz#37595b1f16ec7f228d698590e78eeed18ff218ae"
      @@ -721,6 +731,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/react-compose-refs@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74"
      +  integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==
      +
       "@radix-ui/react-context@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.0.tgz#f38e30c5859a9fb5e9aa9a9da452ee3ed9e0aee0"
      @@ -735,6 +750,16 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/react-context@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.0.tgz#6df8d983546cfd1999c8512f3a8ad85a6e7fcee8"
      +  integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==
      +
      +"@radix-ui/react-context@1.1.1":
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a"
      +  integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==
      +
       "@radix-ui/react-dialog@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz#997e97cb183bc90bd888b26b8e23a355ac9fe5f0"
      @@ -756,26 +781,25 @@
           aria-hidden "^1.1.1"
           react-remove-scroll "2.5.4"
       
      -"@radix-ui/react-dialog@1.0.5", "@radix-ui/react-dialog@^1.0.4":
      -  version "1.0.5"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300"
      -  integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-dismissable-layer" "1.0.5"
      -    "@radix-ui/react-focus-guards" "1.0.1"
      -    "@radix-ui/react-focus-scope" "1.0.4"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-portal" "1.0.4"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-slot" "1.0.2"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      +"@radix-ui/react-dialog@1.1.2", "@radix-ui/react-dialog@^1.0.4":
      +  version "1.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz#d9345575211d6f2d13e209e84aec9a8584b54d6c"
      +  integrity sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-dismissable-layer" "1.1.1"
      +    "@radix-ui/react-focus-guards" "1.1.1"
      +    "@radix-ui/react-focus-scope" "1.1.0"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-portal" "1.1.2"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-slot" "1.1.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
           aria-hidden "^1.1.1"
      -    react-remove-scroll "2.5.5"
      +    react-remove-scroll "2.6.0"
       
       "@radix-ui/react-direction@1.0.1":
         version "1.0.1"
      @@ -784,6 +808,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/react-direction@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc"
      +  integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==
      +
       "@radix-ui/react-dismissable-layer@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz#35b7826fa262fd84370faef310e627161dffa76b"
      @@ -808,31 +837,29 @@
           "@radix-ui/react-use-callback-ref" "1.0.1"
           "@radix-ui/react-use-escape-keydown" "1.0.3"
       
      -"@radix-ui/react-dismissable-layer@1.0.5":
      -  version "1.0.5"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4"
      -  integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==
      +"@radix-ui/react-dismissable-layer@1.1.1":
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz#cbdcb739c5403382bdde5f9243042ba643883396"
      +  integrity sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      -    "@radix-ui/react-use-escape-keydown" "1.0.3"
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +    "@radix-ui/react-use-escape-keydown" "1.1.0"
       
       "@radix-ui/react-dropdown-menu@^2.0.5":
      -  version "2.0.6"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz#cdf13c956c5e263afe4e5f3587b3071a25755b63"
      -  integrity sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==
      +  version "2.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.2.tgz#acc49577130e3c875ef0133bd1e271ea3392d924"
      +  integrity sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-menu" "2.0.6"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-menu" "2.1.2"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
       
       "@radix-ui/react-focus-guards@1.0.0":
         version "1.0.0"
      @@ -848,6 +875,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/react-focus-guards@1.1.1":
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz#8635edd346304f8b42cae86b05912b61aef27afe"
      +  integrity sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==
      +
       "@radix-ui/react-focus-scope@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz#95a0c1188276dc8933b1eac5f1cdb6471e01ade5"
      @@ -868,36 +900,34 @@
           "@radix-ui/react-primitive" "1.0.3"
           "@radix-ui/react-use-callback-ref" "1.0.1"
       
      -"@radix-ui/react-focus-scope@1.0.4":
      -  version "1.0.4"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525"
      -  integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==
      +"@radix-ui/react-focus-scope@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2"
      +  integrity sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
       
       "@radix-ui/react-hover-card@^1.0.6":
      -  version "1.0.7"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-hover-card/-/react-hover-card-1.0.7.tgz#684bca2504432566357e7157e087051aa3577948"
      -  integrity sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-dismissable-layer" "1.0.5"
      -    "@radix-ui/react-popper" "1.1.3"
      -    "@radix-ui/react-portal" "1.0.4"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      +  version "1.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-hover-card/-/react-hover-card-1.1.2.tgz#912e158cd9ee71cba86f08ba063d1f5953cfb0e6"
      +  integrity sha512-Y5w0qGhysvmqsIy6nQxaPa6mXNKznfoGjOfBgzOjocLxr2XlSjqBMYQQL+FfyogsMuX+m8cZyQGYhJxvxUzO4w==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-dismissable-layer" "1.1.1"
      +    "@radix-ui/react-popper" "1.2.0"
      +    "@radix-ui/react-portal" "1.1.2"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
       
       "@radix-ui/react-icons@^1.3.0":
      -  version "1.3.0"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.0.tgz#c61af8f323d87682c5ca76b856d60c2312dbcb69"
      -  integrity sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==
      +  version "1.3.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.2.tgz#09be63d178262181aeca5fb7f7bc944b10a7f441"
      +  integrity sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==
       
       "@radix-ui/react-id@1.0.0":
         version "1.0.0"
      @@ -915,60 +945,64 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-use-layout-effect" "1.0.1"
       
      -"@radix-ui/react-label@^2.0.1":
      -  version "2.0.2"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-2.0.2.tgz#9c72f1d334aac996fdc27b48a8bdddd82108fb6d"
      -  integrity sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==
      +"@radix-ui/react-id@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed"
      +  integrity sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/react-primitive" "1.0.3"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
       
      -"@radix-ui/react-menu@2.0.6":
      -  version "2.0.6"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.0.6.tgz#2c9e093c1a5d5daa87304b2a2f884e32288ae79e"
      -  integrity sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==
      +"@radix-ui/react-label@^2.0.1":
      +  version "2.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-2.1.0.tgz#3aa2418d70bb242be37c51ff5e51a2adcbc372e3"
      +  integrity sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-collection" "1.0.3"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-direction" "1.0.1"
      -    "@radix-ui/react-dismissable-layer" "1.0.5"
      -    "@radix-ui/react-focus-guards" "1.0.1"
      -    "@radix-ui/react-focus-scope" "1.0.4"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-popper" "1.1.3"
      -    "@radix-ui/react-portal" "1.0.4"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-roving-focus" "1.0.4"
      -    "@radix-ui/react-slot" "1.0.2"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +
      +"@radix-ui/react-menu@2.1.2":
      +  version "2.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.1.2.tgz#91f6815845a4298dde775563ed2d80b7ad667899"
      +  integrity sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-collection" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-direction" "1.1.0"
      +    "@radix-ui/react-dismissable-layer" "1.1.1"
      +    "@radix-ui/react-focus-guards" "1.1.1"
      +    "@radix-ui/react-focus-scope" "1.1.0"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-popper" "1.2.0"
      +    "@radix-ui/react-portal" "1.1.2"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-roving-focus" "1.1.0"
      +    "@radix-ui/react-slot" "1.1.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
           aria-hidden "^1.1.1"
      -    react-remove-scroll "2.5.5"
      +    react-remove-scroll "2.6.0"
       
       "@radix-ui/react-popover@^1.0.6":
      -  version "1.0.7"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.0.7.tgz#23eb7e3327330cb75ec7b4092d685398c1654e3c"
      -  integrity sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-dismissable-layer" "1.0.5"
      -    "@radix-ui/react-focus-guards" "1.0.1"
      -    "@radix-ui/react-focus-scope" "1.0.4"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-popper" "1.1.3"
      -    "@radix-ui/react-portal" "1.0.4"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-slot" "1.0.2"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      +  version "1.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.2.tgz#a0cab25f69aa49ad0077d91e9e9dcd323758020c"
      +  integrity sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-dismissable-layer" "1.1.1"
      +    "@radix-ui/react-focus-guards" "1.1.1"
      +    "@radix-ui/react-focus-scope" "1.1.0"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-popper" "1.2.0"
      +    "@radix-ui/react-portal" "1.1.2"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-slot" "1.1.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
           aria-hidden "^1.1.1"
      -    react-remove-scroll "2.5.5"
      +    react-remove-scroll "2.6.0"
       
       "@radix-ui/react-popper@1.1.2":
         version "1.1.2"
      @@ -987,22 +1021,21 @@
           "@radix-ui/react-use-size" "1.0.1"
           "@radix-ui/rect" "1.0.1"
       
      -"@radix-ui/react-popper@1.1.3":
      -  version "1.1.3"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42"
      -  integrity sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==
      +"@radix-ui/react-popper@1.2.0":
      +  version "1.2.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz#a3e500193d144fe2d8f5d5e60e393d64111f2a7a"
      +  integrity sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
           "@floating-ui/react-dom" "^2.0.0"
      -    "@radix-ui/react-arrow" "1.0.3"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      -    "@radix-ui/react-use-layout-effect" "1.0.1"
      -    "@radix-ui/react-use-rect" "1.0.1"
      -    "@radix-ui/react-use-size" "1.0.1"
      -    "@radix-ui/rect" "1.0.1"
      +    "@radix-ui/react-arrow" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.0"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
      +    "@radix-ui/react-use-rect" "1.1.0"
      +    "@radix-ui/react-use-size" "1.1.0"
      +    "@radix-ui/rect" "1.1.0"
       
       "@radix-ui/react-portal@1.0.0":
         version "1.0.0"
      @@ -1020,13 +1053,13 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-primitive" "1.0.3"
       
      -"@radix-ui/react-portal@1.0.4":
      -  version "1.0.4"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15"
      -  integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==
      +"@radix-ui/react-portal@1.1.2":
      +  version "1.1.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz#51eb46dae7505074b306ebcb985bf65cc547d74e"
      +  integrity sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/react-primitive" "1.0.3"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
       
       "@radix-ui/react-presence@1.0.0":
         version "1.0.0"
      @@ -1037,14 +1070,13 @@
           "@radix-ui/react-compose-refs" "1.0.0"
           "@radix-ui/react-use-layout-effect" "1.0.0"
       
      -"@radix-ui/react-presence@1.0.1":
      -  version "1.0.1"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba"
      -  integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==
      +"@radix-ui/react-presence@1.1.1":
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz#98aba423dba5e0c687a782c0669dcd99de17f9b1"
      +  integrity sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-use-layout-effect" "1.0.1"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
       
       "@radix-ui/react-primitive@1.0.0":
         version "1.0.0"
      @@ -1062,63 +1094,66 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-slot" "1.0.2"
       
      -"@radix-ui/react-progress@^1.0.3":
      -  version "1.0.3"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-progress/-/react-progress-1.0.3.tgz#8380272fdc64f15cbf263a294dea70a7d5d9b4fa"
      -  integrity sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==
      +"@radix-ui/react-primitive@2.0.0":
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz#fe05715faa9203a223ccc0be15dc44b9f9822884"
      +  integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      +    "@radix-ui/react-slot" "1.1.0"
       
      -"@radix-ui/react-radio-group@^1.1.3":
      -  version "1.1.3"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz#3197f5dcce143bcbf961471bf89320735c0212d3"
      -  integrity sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==
      +"@radix-ui/react-progress@^1.0.3":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-progress/-/react-progress-1.1.0.tgz#28c267885ec154fc557ec7a66cb462787312f7e2"
      +  integrity sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-direction" "1.0.1"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-roving-focus" "1.0.4"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      -    "@radix-ui/react-use-previous" "1.0.1"
      -    "@radix-ui/react-use-size" "1.0.1"
      +    "@radix-ui/react-context" "1.1.0"
      +    "@radix-ui/react-primitive" "2.0.0"
       
      -"@radix-ui/react-roving-focus@1.0.4":
      -  version "1.0.4"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz#e90c4a6a5f6ac09d3b8c1f5b5e81aab2f0db1974"
      -  integrity sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-collection" "1.0.3"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-direction" "1.0.1"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      +"@radix-ui/react-radio-group@^1.1.3":
      +  version "1.2.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-1.2.1.tgz#42b914c85f3a77be3ab766b6e49a9598680f76d1"
      +  integrity sha512-kdbv54g4vfRjja9DNWPMxKvXblzqbpEC8kspEkZ6dVP7kQksGCn+iZHkcCz2nb00+lPdRvxrqy4WrvvV1cNqrQ==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-direction" "1.1.0"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-roving-focus" "1.1.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
      +    "@radix-ui/react-use-previous" "1.1.0"
      +    "@radix-ui/react-use-size" "1.1.0"
      +
      +"@radix-ui/react-roving-focus@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz#b30c59daf7e714c748805bfe11c76f96caaac35e"
      +  integrity sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-collection" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.0"
      +    "@radix-ui/react-direction" "1.1.0"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
       
       "@radix-ui/react-scroll-area@^1.0.4":
      -  version "1.0.5"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.5.tgz#01160c6893f24a2ddb5aa399ae5b3ba84ad4d3cc"
      -  integrity sha512-b6PAgH4GQf9QEn8zbT2XUHpW5z8BzqEc7Kl11TwDrvuTrxlkcjTD5qa/bxgKr+nmuXKu4L/W5UZ4mlP/VG/5Gw==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/number" "1.0.1"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-direction" "1.0.1"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      -    "@radix-ui/react-use-layout-effect" "1.0.1"
      +  version "1.2.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.1.tgz#610c53e07d017e24b62bd73a0a6eb23fa7331b3b"
      +  integrity sha512-FnM1fHfCtEZ1JkyfH/1oMiTcFBQvHKl4vD9WnpwkLgtF+UmnXMCad6ECPTaAjcDjam+ndOEJWgHyKDGNteWSHw==
      +  dependencies:
      +    "@radix-ui/number" "1.1.0"
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-direction" "1.1.0"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
       
       "@radix-ui/react-select@^1.2.2":
         version "1.2.2"
      @@ -1149,12 +1184,11 @@
           react-remove-scroll "2.5.5"
       
       "@radix-ui/react-separator@^1.0.3":
      -  version "1.0.3"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.0.3.tgz#be5a931a543d5726336b112f465f58585c04c8aa"
      -  integrity sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.1.0.tgz#ee0f4d86003b0e3ea7bc6ccab01ea0adee32663e"
      +  integrity sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/react-primitive" "1.0.3"
      +    "@radix-ui/react-primitive" "2.0.0"
       
       "@radix-ui/react-slot@1.0.0":
         version "1.0.0"
      @@ -1164,7 +1198,7 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-compose-refs" "1.0.0"
       
      -"@radix-ui/react-slot@1.0.2", "@radix-ui/react-slot@^1.0.2":
      +"@radix-ui/react-slot@1.0.2":
         version "1.0.2"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab"
         integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==
      @@ -1172,72 +1206,75 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-compose-refs" "1.0.1"
       
      -"@radix-ui/react-switch@^1.0.2":
      -  version "1.0.3"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.0.3.tgz#6119f16656a9eafb4424c600fdb36efa5ec5837e"
      -  integrity sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==
      +"@radix-ui/react-slot@1.1.0", "@radix-ui/react-slot@^1.0.2":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz#7c5e48c36ef5496d97b08f1357bb26ed7c714b84"
      +  integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==
         dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      -    "@radix-ui/react-use-previous" "1.0.1"
      -    "@radix-ui/react-use-size" "1.0.1"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +
      +"@radix-ui/react-switch@^1.0.2":
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.1.1.tgz#1401658c24d66a18610f18793afbaa7fedf5429a"
      +  integrity sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
      +    "@radix-ui/react-use-previous" "1.1.0"
      +    "@radix-ui/react-use-size" "1.1.0"
       
       "@radix-ui/react-tabs@^1.0.4":
      -  version "1.0.4"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz#993608eec55a5d1deddd446fa9978d2bc1053da2"
      -  integrity sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-direction" "1.0.1"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-roving-focus" "1.0.4"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.1.1.tgz#698bd97923f6bcd629738198a73beebcc4c88b30"
      +  integrity sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-direction" "1.1.0"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-roving-focus" "1.1.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
       
       "@radix-ui/react-toast@^1.1.4":
      -  version "1.1.5"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-toast/-/react-toast-1.1.5.tgz#f5788761c0142a5ae9eb97f0051fd3c48106d9e6"
      -  integrity sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-collection" "1.0.3"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-dismissable-layer" "1.0.5"
      -    "@radix-ui/react-portal" "1.0.4"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-use-callback-ref" "1.0.1"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      -    "@radix-ui/react-use-layout-effect" "1.0.1"
      -    "@radix-ui/react-visually-hidden" "1.0.3"
      +  version "1.2.2"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-toast/-/react-toast-1.2.2.tgz#fdd8ed0b80f47d6631dfd90278fee6debc06bf33"
      +  integrity sha512-Z6pqSzmAP/bFJoqMAston4eSNa+ud44NSZTiZUmUen+IOZ5nBY8kzuU5WDBVyFXPtcW6yUalOHsxM/BP6Sv8ww==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-collection" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-dismissable-layer" "1.1.1"
      +    "@radix-ui/react-portal" "1.1.2"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
      +    "@radix-ui/react-visually-hidden" "1.1.0"
       
       "@radix-ui/react-tooltip@^1.0.6":
      -  version "1.0.7"
      -  resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz#8f55070f852e7e7450cc1d9210b793d2e5a7686e"
      -  integrity sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==
      -  dependencies:
      -    "@babel/runtime" "^7.13.10"
      -    "@radix-ui/primitive" "1.0.1"
      -    "@radix-ui/react-compose-refs" "1.0.1"
      -    "@radix-ui/react-context" "1.0.1"
      -    "@radix-ui/react-dismissable-layer" "1.0.5"
      -    "@radix-ui/react-id" "1.0.1"
      -    "@radix-ui/react-popper" "1.1.3"
      -    "@radix-ui/react-portal" "1.0.4"
      -    "@radix-ui/react-presence" "1.0.1"
      -    "@radix-ui/react-primitive" "1.0.3"
      -    "@radix-ui/react-slot" "1.0.2"
      -    "@radix-ui/react-use-controllable-state" "1.0.1"
      -    "@radix-ui/react-visually-hidden" "1.0.3"
      +  version "1.1.4"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.1.4.tgz#152d8485859b80d395d6b3229f676fef3cec56b3"
      +  integrity sha512-QpObUH/ZlpaO4YgHSaYzrLO2VuO+ZBFFgGzjMUPwtiYnAzzNNDPJeEGRrT7qNOrWm/Jr08M1vlp+vTHtnSQ0Uw==
      +  dependencies:
      +    "@radix-ui/primitive" "1.1.0"
      +    "@radix-ui/react-compose-refs" "1.1.0"
      +    "@radix-ui/react-context" "1.1.1"
      +    "@radix-ui/react-dismissable-layer" "1.1.1"
      +    "@radix-ui/react-id" "1.1.0"
      +    "@radix-ui/react-popper" "1.2.0"
      +    "@radix-ui/react-portal" "1.1.2"
      +    "@radix-ui/react-presence" "1.1.1"
      +    "@radix-ui/react-primitive" "2.0.0"
      +    "@radix-ui/react-slot" "1.1.0"
      +    "@radix-ui/react-use-controllable-state" "1.1.0"
      +    "@radix-ui/react-visually-hidden" "1.1.0"
       
       "@radix-ui/react-use-callback-ref@1.0.0":
         version "1.0.0"
      @@ -1253,6 +1290,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/react-use-callback-ref@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1"
      +  integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==
      +
       "@radix-ui/react-use-controllable-state@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz#a64deaafbbc52d5d407afaa22d493d687c538b7f"
      @@ -1269,6 +1311,13 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-use-callback-ref" "1.0.1"
       
      +"@radix-ui/react-use-controllable-state@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0"
      +  integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==
      +  dependencies:
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +
       "@radix-ui/react-use-escape-keydown@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz#aef375db4736b9de38a5a679f6f49b45a060e5d1"
      @@ -1285,6 +1334,13 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-use-callback-ref" "1.0.1"
       
      +"@radix-ui/react-use-escape-keydown@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754"
      +  integrity sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==
      +  dependencies:
      +    "@radix-ui/react-use-callback-ref" "1.1.0"
      +
       "@radix-ui/react-use-layout-effect@1.0.0":
         version "1.0.0"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz#2fc19e97223a81de64cd3ba1dc42ceffd82374dc"
      @@ -1299,6 +1355,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/react-use-layout-effect@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27"
      +  integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==
      +
       "@radix-ui/react-use-previous@1.0.1":
         version "1.0.1"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz#b595c087b07317a4f143696c6a01de43b0d0ec66"
      @@ -1306,6 +1367,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/react-use-previous@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz#d4dd37b05520f1d996a384eb469320c2ada8377c"
      +  integrity sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==
      +
       "@radix-ui/react-use-rect@1.0.1":
         version "1.0.1"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2"
      @@ -1314,6 +1380,13 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/rect" "1.0.1"
       
      +"@radix-ui/react-use-rect@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz#13b25b913bd3e3987cc9b073a1a164bb1cf47b88"
      +  integrity sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==
      +  dependencies:
      +    "@radix-ui/rect" "1.1.0"
      +
       "@radix-ui/react-use-size@1.0.1":
         version "1.0.1"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2"
      @@ -1322,6 +1395,13 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-use-layout-effect" "1.0.1"
       
      +"@radix-ui/react-use-size@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz#b4dba7fbd3882ee09e8d2a44a3eed3a7e555246b"
      +  integrity sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==
      +  dependencies:
      +    "@radix-ui/react-use-layout-effect" "1.1.0"
      +
       "@radix-ui/react-visually-hidden@1.0.3":
         version "1.0.3"
         resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac"
      @@ -1330,6 +1410,13 @@
           "@babel/runtime" "^7.13.10"
           "@radix-ui/react-primitive" "1.0.3"
       
      +"@radix-ui/react-visually-hidden@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz#ad47a8572580f7034b3807c8e6740cd41038a5a2"
      +  integrity sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==
      +  dependencies:
      +    "@radix-ui/react-primitive" "2.0.0"
      +
       "@radix-ui/rect@1.0.1":
         version "1.0.1"
         resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.1.tgz#bf8e7d947671996da2e30f4904ece343bc4a883f"
      @@ -1337,6 +1424,11 @@
         dependencies:
           "@babel/runtime" "^7.13.10"
       
      +"@radix-ui/rect@1.1.0":
      +  version "1.1.0"
      +  resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.0.tgz#f817d1d3265ac5415dadc67edab30ae196696438"
      +  integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==
      +
       "@reactflow/background@11.3.14":
         version "11.3.14"
         resolved "https://registry.yarnpkg.com/@reactflow/background/-/background-11.3.14.tgz#778ca30174f3de77fc321459ab3789e66e71a699"
      @@ -1403,10 +1495,19 @@
           classcat "^5.0.3"
           zustand "^4.4.1"
       
      -"@remix-run/router@1.16.1":
      -  version "1.16.1"
      -  resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.16.1.tgz#73db3c48b975eeb06d0006481bde4f5f2d17d1cd"
      -  integrity sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==
      +"@remix-run/router@1.21.0":
      +  version "1.21.0"
      +  resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5"
      +  integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==
      +
      +"@rollup/pluginutils@^5.0.0":
      +  version "5.1.3"
      +  resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz#3001bf1a03f3ad24457591f2c259c8e514e0dbdf"
      +  integrity sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    estree-walker "^2.0.2"
      +    picomatch "^4.0.2"
       
       "@socket.io/component-emitter@~3.1.0":
         version "3.1.2"
      @@ -1414,28 +1515,28 @@
         integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==
       
       "@tanstack/react-table@^8.9.3":
      -  version "8.17.3"
      -  resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.17.3.tgz#4e10b4cf5355a40d6d72a83d3f4b3ecd32f56bf4"
      -  integrity sha512-5gwg5SvPD3lNAXPuJJz1fOCEZYk9/GeBFH3w/hCgnfyszOIzwkwgp5I7Q4MJtn0WECp84b5STQUDdmvGi8m3nA==
      +  version "8.20.5"
      +  resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.20.5.tgz#19987d101e1ea25ef5406dce4352cab3932449d8"
      +  integrity sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==
         dependencies:
      -    "@tanstack/table-core" "8.17.3"
      +    "@tanstack/table-core" "8.20.5"
       
       "@tanstack/react-virtual@^3.0.0-beta.60":
      -  version "3.5.0"
      -  resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz#873b5b77cf78af563a4a11e6251ed51ee8868132"
      -  integrity sha512-rtvo7KwuIvqK9zb0VZ5IL7fiJAEnG+0EiFZz8FUOs+2mhGqdGmjKIaT1XU7Zq0eFqL0jonLlhbayJI/J2SA/Bw==
      +  version "3.10.9"
      +  resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.10.9.tgz#40606b6dd8aba8e977f576d8f7df07f69ca63eea"
      +  integrity sha512-OXO2uBjFqA4Ibr2O3y0YMnkrRWGVNqcvHQXmGvMu6IK8chZl3PrDxFXdGZ2iZkSrKh3/qUYoFqYe+Rx23RoU0g==
         dependencies:
      -    "@tanstack/virtual-core" "3.5.0"
      +    "@tanstack/virtual-core" "3.10.9"
       
      -"@tanstack/table-core@8.17.3":
      -  version "8.17.3"
      -  resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.17.3.tgz#d7a9830abb29cd369b52b2a7159dc0360af646fd"
      -  integrity sha512-mPBodDGVL+fl6d90wUREepHa/7lhsghg2A3vFpakEhrhtbIlgNAZiMr7ccTgak5qbHqF14Fwy+W1yFWQt+WmYQ==
      +"@tanstack/table-core@8.20.5":
      +  version "8.20.5"
      +  resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.20.5.tgz#3974f0b090bed11243d4107283824167a395cf1d"
      +  integrity sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==
       
      -"@tanstack/virtual-core@3.5.0":
      -  version "3.5.0"
      -  resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.5.0.tgz#108208d0f1d75271300bc5560cf9a85a1fa01e89"
      -  integrity sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==
      +"@tanstack/virtual-core@3.10.9":
      +  version "3.10.9"
      +  resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.9.tgz#55710c92b311fdaa8d8c66682a0dbdd684bc77c4"
      +  integrity sha512-kBknKOKzmeR7lN+vSadaKWXaLS0SZZG+oqpQ/k80Q6g9REn6zRHS/ZYdrIzHnpHgy/eWs00SujveUN/GJT2qTw==
       
       "@ts-morph/common@~0.19.0":
         version "0.19.0"
      @@ -1447,6 +1548,13 @@
           mkdirp "^2.1.6"
           path-browserify "^1.0.1"
       
      +"@types/acorn@^4.0.0":
      +  version "4.0.6"
      +  resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22"
      +  integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==
      +  dependencies:
      +    "@types/estree" "*"
      +
       "@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"
      @@ -1474,9 +1582,9 @@
           "@babel/types" "^7.0.0"
       
       "@types/babel__traverse@*":
      -  version "7.20.5"
      -  resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd"
      -  integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==
      +  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"
       
      @@ -1552,9 +1660,9 @@
           "@types/d3-dsv" "*"
       
       "@types/d3-force@*":
      -  version "3.0.9"
      -  resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.9.tgz#dd96ccefba4386fe4ff36b8e4ee4e120c21fcf29"
      -  integrity sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA==
      +  version "3.0.10"
      +  resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.10.tgz#6dc8fc6e1f35704f3b057090beeeb7ac674bff1a"
      +  integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==
       
       "@types/d3-format@*":
         version "3.0.4"
      @@ -1613,9 +1721,9 @@
           "@types/d3-time" "*"
       
       "@types/d3-selection@*", "@types/d3-selection@^3.0.3":
      -  version "3.0.10"
      -  resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.10.tgz#98cdcf986d0986de6912b5892e7c015a95ca27fe"
      -  integrity sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==
      +  version "3.0.11"
      +  resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.11.tgz#bd7a45fc0a8c3167a631675e61bc2ca2b058d4a3"
      +  integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==
       
       "@types/d3-shape@*":
         version "3.1.6"
      @@ -1640,9 +1748,9 @@
         integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==
       
       "@types/d3-transition@*":
      -  version "3.0.8"
      -  resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.8.tgz#677707f5eed5b24c66a1918cde05963021351a8f"
      -  integrity sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==
      +  version "3.0.9"
      +  resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.9.tgz#1136bc57e9ddb3c390dccc9b5ff3b7d2b8d94706"
      +  integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==
         dependencies:
           "@types/d3-selection" "*"
       
      @@ -1705,9 +1813,9 @@
           "@types/estree" "*"
       
       "@types/estree@*", "@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==
      +  version "1.0.6"
      +  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
      +  integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
       
       "@types/geojson@*":
         version "7946.0.14"
      @@ -1728,12 +1836,10 @@
         dependencies:
           "@types/unist" "*"
       
      -"@types/mdast@^3.0.0":
      -  version "3.0.15"
      -  resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5"
      -  integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==
      -  dependencies:
      -    "@types/unist" "^2"
      +"@types/katex@^0.16.0":
      +  version "0.16.7"
      +  resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.16.7.tgz#03ab680ab4fa4fbc6cb46ecf987ecad5d8019868"
      +  integrity sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==
       
       "@types/mdast@^4.0.0":
         version "4.0.4"
      @@ -1742,52 +1848,57 @@
         dependencies:
           "@types/unist" "*"
       
      +"@types/mdx@^2.0.0":
      +  version "2.0.13"
      +  resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd"
      +  integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==
      +
       "@types/ms@*":
         version "0.7.34"
         resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
         integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
       
       "@types/node@^20.4.2":
      -  version "20.12.12"
      -  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050"
      -  integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==
      +  version "20.17.6"
      +  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.6.tgz#6e4073230c180d3579e8c60141f99efdf5df0081"
      +  integrity sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==
         dependencies:
      -    undici-types "~5.26.4"
      +    undici-types "~6.19.2"
       
       "@types/prismjs@^1.0.0":
      -  version "1.26.4"
      -  resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.4.tgz#1a9e1074619ce1d7322669e5b46fbe823925103a"
      -  integrity sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==
      +  version "1.26.5"
      +  resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.5.tgz#72499abbb4c4ec9982446509d2f14fb8483869d6"
      +  integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==
       
       "@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==
      +  version "15.7.13"
      +  resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451"
      +  integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==
       
       "@types/react-dom@^18.2.6":
      -  version "18.3.0"
      -  resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0"
      -  integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==
      +  version "18.3.1"
      +  resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.1.tgz#1e4654c08a9cdcfb6594c780ac59b55aad42fe07"
      +  integrity sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==
         dependencies:
           "@types/react" "*"
       
       "@types/react@*", "@types/react@^18.2.14":
      -  version "18.3.2"
      -  resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.2.tgz#462ae4904973bc212fa910424d901e3d137dbfcd"
      -  integrity sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==
      +  version "18.3.12"
      +  resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60"
      +  integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==
         dependencies:
           "@types/prop-types" "*"
           csstype "^3.0.2"
       
       "@types/unist@*", "@types/unist@^3.0.0":
      -  version "3.0.2"
      -  resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20"
      -  integrity sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==
      +  version "3.0.3"
      +  resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c"
      +  integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==
       
       "@types/unist@^2", "@types/unist@^2.0.0":
      -  version "2.0.10"
      -  resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc"
      -  integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==
      +  version "2.0.11"
      +  resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4"
      +  integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
       
       "@uiw/copy-to-clipboard@~1.0.12":
         version "1.0.17"
      @@ -1829,25 +1940,25 @@
         integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
       
       "@vitejs/plugin-react@^4.0.1":
      -  version "4.2.1"
      -  resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz#744d8e4fcb120fc3dbaa471dadd3483f5a304bb9"
      -  integrity sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==
      +  version "4.3.3"
      +  resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz#28301ac6d7aaf20b73a418ee5c65b05519b4836c"
      +  integrity sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==
         dependencies:
      -    "@babel/core" "^7.23.5"
      -    "@babel/plugin-transform-react-jsx-self" "^7.23.3"
      -    "@babel/plugin-transform-react-jsx-source" "^7.23.3"
      +    "@babel/core" "^7.25.2"
      +    "@babel/plugin-transform-react-jsx-self" "^7.24.7"
      +    "@babel/plugin-transform-react-jsx-source" "^7.24.7"
           "@types/babel__core" "^7.20.5"
      -    react-refresh "^0.14.0"
      +    react-refresh "^0.14.2"
       
      -acorn-jsx@^5.3.2:
      +acorn-jsx@^5.0.0, acorn-jsx@^5.3.2:
         version "5.3.2"
         resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
         integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
       
      -acorn@^8.9.0:
      -  version "8.11.3"
      -  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
      -  integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
      +acorn@^8.0.0, acorn@^8.9.0:
      +  version "8.14.0"
      +  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
      +  integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
       
       agent-base@^7.0.2:
         version "7.1.1"
      @@ -1872,16 +1983,9 @@ ansi-regex@^5.0.1:
         integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
       
       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"
      +  version "6.1.0"
      +  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654"
      +  integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==
       
       ansi-styles@^4.0.0, ansi-styles@^4.1.0:
         version "4.3.0"
      @@ -1932,32 +2036,37 @@ ast-types@^0.16.1:
         dependencies:
           tslib "^2.0.1"
       
      +astring@^1.8.0:
      +  version "1.9.0"
      +  resolved "https://registry.yarnpkg.com/astring/-/astring-1.9.0.tgz#cc73e6062a7eb03e7d19c22d8b0b3451fd9bfeef"
      +  integrity sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==
      +
       asynckit@^0.4.0:
         version "0.4.0"
         resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
         integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
       
      -attr-accept@^2.2.2:
      -  version "2.2.2"
      -  resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
      -  integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
      +attr-accept@^2.2.4:
      +  version "2.2.5"
      +  resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e"
      +  integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==
       
       autoprefixer@^10.4.14:
      -  version "10.4.19"
      -  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f"
      -  integrity sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==
      +  version "10.4.20"
      +  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b"
      +  integrity sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==
         dependencies:
      -    browserslist "^4.23.0"
      -    caniuse-lite "^1.0.30001599"
      +    browserslist "^4.23.3"
      +    caniuse-lite "^1.0.30001646"
           fraction.js "^4.3.7"
           normalize-range "^0.1.2"
      -    picocolors "^1.0.0"
      +    picocolors "^1.0.1"
           postcss-value-parser "^4.2.0"
       
      -axios@^1.6.7:
      -  version "1.6.8"
      -  resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66"
      -  integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==
      +axios@^1.7.4:
      +  version "1.7.7"
      +  resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f"
      +  integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==
         dependencies:
           follow-redirects "^1.15.6"
           form-data "^4.0.0"
      @@ -2017,22 +2126,22 @@ brace-expansion@^2.0.1:
         dependencies:
           balanced-match "^1.0.0"
       
      -braces@^3.0.2, braces@~3.0.2:
      -  version "3.0.2"
      -  resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
      -  integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
      +braces@^3.0.3, braces@~3.0.2:
      +  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.0.1"
      +    fill-range "^7.1.1"
       
      -browserslist@^4.22.2, browserslist@^4.23.0:
      -  version "4.23.0"
      -  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab"
      -  integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==
      +browserslist@^4.23.3, browserslist@^4.24.0:
      +  version "4.24.2"
      +  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580"
      +  integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==
         dependencies:
      -    caniuse-lite "^1.0.30001587"
      -    electron-to-chromium "^1.4.668"
      -    node-releases "^2.0.14"
      -    update-browserslist-db "^1.0.13"
      +    caniuse-lite "^1.0.30001669"
      +    electron-to-chromium "^1.5.41"
      +    node-releases "^2.0.18"
      +    update-browserslist-db "^1.1.1"
       
       buffer@^6.0.3:
         version "6.0.3"
      @@ -2057,10 +2166,10 @@ camelcase-css@^2.0.1:
         resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
         integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
       
      -caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599:
      -  version "1.0.30001620"
      -  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001620.tgz#78bb6f35b8fe315b96b8590597094145d0b146b4"
      -  integrity sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew==
      +caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001669:
      +  version "1.0.30001680"
      +  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz#5380ede637a33b9f9f1fc6045ea99bd142f3da5e"
      +  integrity sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==
       
       ccount@^2.0.0:
         version "2.0.1"
      @@ -2072,15 +2181,6 @@ chalk@5.2.0:
         resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3"
         integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==
       
      -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@^4.0.0:
         version "4.1.2"
         resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
      @@ -2114,7 +2214,7 @@ character-reference-invalid@^2.0.0:
         resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9"
         integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==
       
      -chokidar@^3.5.3:
      +chokidar@^3.6.0:
         version "3.6.0"
         resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
         integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
      @@ -2141,6 +2241,11 @@ classcat@^5.0.3, classcat@^5.0.4:
         resolved "https://registry.yarnpkg.com/classcat/-/classcat-5.0.5.tgz#8c209f359a93ac302404a10161b501eba9c09c77"
         integrity sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==
       
      +classnames@^2.5.1:
      +  version "2.5.1"
      +  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
      +  integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
      +
       cli-cursor@^4.0.0:
         version "4.0.0"
         resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea"
      @@ -2180,12 +2285,10 @@ code-block-writer@^12.0.0:
         resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770"
         integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==
       
      -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"
      +collapse-white-space@^2.0.0:
      +  version "2.1.0"
      +  resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-2.1.0.tgz#640257174f9f42c740b40f3b55ee752924feefca"
      +  integrity sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==
       
       color-convert@^2.0.1:
         version "2.0.1"
      @@ -2194,11 +2297,6 @@ color-convert@^2.0.1:
         dependencies:
           color-name "~1.1.4"
       
      -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==
      -
       color-name@~1.1.4:
         version "1.1.4"
         resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
      @@ -2226,6 +2324,11 @@ commander@^4.0.0:
         resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
         integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
       
      +commander@^8.3.0:
      +  version "8.3.0"
      +  resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
      +  integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
      +
       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"
      @@ -2252,9 +2355,9 @@ cosmiconfig@^8.1.3:
           path-type "^4.0.0"
       
       cross-spawn@^7.0.0, cross-spawn@^7.0.2, 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==
      +  version "7.0.5"
      +  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.5.tgz#910aac880ff5243da96b728bc6521a5f6c2f2f82"
      +  integrity sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==
         dependencies:
           path-key "^3.1.0"
           shebang-command "^2.0.0"
      @@ -2343,11 +2446,11 @@ data-uri-to-buffer@^4.0.0:
         integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==
       
       debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
      -  version "4.3.4"
      -  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
      -  integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
      +  version "4.3.7"
      +  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
      +  integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
         dependencies:
      -    ms "2.1.2"
      +    ms "^2.1.3"
       
       decode-named-character-reference@^1.0.0:
         version "1.0.2"
      @@ -2395,7 +2498,7 @@ didyoumean@^1.2.2:
         resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
         integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
       
      -diff@^5.0.0, diff@^5.1.0:
      +diff@^5.1.0:
         version "5.2.0"
         resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531"
         integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==
      @@ -2418,9 +2521,9 @@ doctrine@^3.0.0:
           esutils "^2.0.2"
       
       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==
      +  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"
      @@ -2433,10 +2536,10 @@ eastasianwidth@^0.2.0:
         resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
         integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
       
      -electron-to-chromium@^1.4.668:
      -  version "1.4.774"
      -  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.774.tgz#1017d1758aaeeefe5423aa9d67b4b1e5d1d0a856"
      -  integrity sha512-132O1XCd7zcTkzS3FgkAzKmnBuNJjK8WjcTtNuoylj7MYbqw5eXehjQ5OK91g0zm7OTKIPeaAG4CPoRfD9M1Mg==
      +electron-to-chromium@^1.5.41:
      +  version "1.5.60"
      +  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.60.tgz#29944afe568c58c40729e67af0f59f52d4d0ed32"
      +  integrity sha512-HcraRUkTKJ+8yA3b10i9qvhUlPBRDlKjn1XGek1zDGVfAKcvi8TsUnImGqLiEm9j6ZulxXIWWIo9BmbkbCTGgA==
       
       emoji-regex@^8.0.0:
         version "8.0.0"
      @@ -2448,23 +2551,34 @@ emoji-regex@^9.2.2:
         resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
         integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
       
      -engine.io-client@~6.5.1, engine.io-client@~6.5.2:
      -  version "6.5.3"
      -  resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.5.3.tgz#4cf6fa24845029b238f83c628916d9149c399bc5"
      -  integrity sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==
      +engine.io-client@~6.5.1:
      +  version "6.5.4"
      +  resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.5.4.tgz#b8bc71ed3f25d0d51d587729262486b4b33bd0d0"
      +  integrity sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==
         dependencies:
           "@socket.io/component-emitter" "~3.1.0"
           debug "~4.3.1"
           engine.io-parser "~5.2.1"
      -    ws "~8.11.0"
      +    ws "~8.17.1"
           xmlhttprequest-ssl "~2.0.0"
       
      +engine.io-client@~6.6.1:
      +  version "6.6.2"
      +  resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.6.2.tgz#e0a09e1c90effe5d6264da1c56d7281998f1e50b"
      +  integrity sha512-TAr+NKeoVTjEVW8P3iHguO1LO6RlUz9O5Y8o7EY0fU+gY1NYqas7NN3slpFtbXEsLMHk0h90fJMfKjRkQ0qUIw==
      +  dependencies:
      +    "@socket.io/component-emitter" "~3.1.0"
      +    debug "~4.3.1"
      +    engine.io-parser "~5.2.1"
      +    ws "~8.17.1"
      +    xmlhttprequest-ssl "~2.1.1"
      +
       engine.io-parser@~5.2.1:
      -  version "5.2.2"
      -  resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.2.tgz#37b48e2d23116919a3453738c5720455e64e1c49"
      -  integrity sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==
      +  version "5.2.3"
      +  resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f"
      +  integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==
       
      -entities@^4.4.0:
      +entities@^4.5.0:
         version "4.5.0"
         resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
         integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
      @@ -2476,6 +2590,26 @@ error-ex@^1.3.1:
         dependencies:
           is-arrayish "^0.2.1"
       
      +esast-util-from-estree@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz#8d1cfb51ad534d2f159dc250e604f3478a79f1ad"
      +  integrity sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==
      +  dependencies:
      +    "@types/estree-jsx" "^1.0.0"
      +    devlop "^1.0.0"
      +    estree-util-visit "^2.0.0"
      +    unist-util-position-from-estree "^2.0.0"
      +
      +esast-util-from-js@^2.0.0:
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz#5147bec34cc9da44accf52f87f239a40ac3e8225"
      +  integrity sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==
      +  dependencies:
      +    "@types/estree-jsx" "^1.0.0"
      +    acorn "^8.0.0"
      +    esast-util-from-estree "^2.0.0"
      +    vfile-message "^4.0.0"
      +
       esbuild@^0.18.10:
         version "0.18.20"
         resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
      @@ -2504,15 +2638,10 @@ esbuild@^0.18.10:
           "@esbuild/win32-ia32" "0.18.20"
           "@esbuild/win32-x64" "0.18.20"
       
      -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-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==
      +escalade@^3.2.0:
      +  version "3.2.0"
      +  resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
      +  integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
       
       escape-string-regexp@^4.0.0:
         version "4.0.0"
      @@ -2530,9 +2659,9 @@ eslint-plugin-react-hooks@^4.6.0:
         integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==
       
       eslint-plugin-react-refresh@^0.4.1:
      -  version "0.4.7"
      -  resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.7.tgz#1f597f9093b254f10ee0961c139a749acb19af7d"
      -  integrity sha512-yrj+KInFmwuQS2UQcg1SF83ha1tuHC1jMQbRNyuWtlEzzKRDgAl7L4Yp4NlDUZTZNlWvHEzOtJhMi40R7JxcSw==
      +  version "0.4.14"
      +  resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.14.tgz#e3c611ead69bbf7436d01295c853d4abb8c59f68"
      +  integrity sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA==
       
       eslint-scope@^7.2.2:
         version "7.2.2"
      @@ -2542,21 +2671,21 @@ eslint-scope@^7.2.2:
           esrecurse "^4.3.0"
           estraverse "^5.2.0"
       
      -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
      +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
         version "3.4.3"
         resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
         integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
       
       eslint@^8.44.0:
      -  version "8.57.0"
      -  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668"
      -  integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==
      +  version "8.57.1"
      +  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9"
      +  integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==
         dependencies:
           "@eslint-community/eslint-utils" "^4.2.0"
           "@eslint-community/regexpp" "^4.6.1"
           "@eslint/eslintrc" "^2.1.4"
      -    "@eslint/js" "8.57.0"
      -    "@humanwhocodes/config-array" "^0.11.14"
      +    "@eslint/js" "8.57.1"
      +    "@humanwhocodes/config-array" "^0.13.0"
           "@humanwhocodes/module-importer" "^1.0.1"
           "@nodelib/fs.walk" "^1.2.8"
           "@ungap/structured-clone" "^1.2.0"
      @@ -2606,9 +2735,9 @@ esprima@~4.0.0:
         integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
       
       esquery@^1.4.2:
      -  version "1.5.0"
      -  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b"
      -  integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==
      +  version "1.6.0"
      +  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7"
      +  integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==
         dependencies:
           estraverse "^5.1.0"
       
      @@ -2624,11 +2753,65 @@ estraverse@^5.1.0, estraverse@^5.2.0:
         resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
         integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
       
      +estree-util-attach-comments@^3.0.0:
      +  version "3.0.0"
      +  resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz#344bde6a64c8a31d15231e5ee9e297566a691c2d"
      +  integrity sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +
      +estree-util-build-jsx@^3.0.0:
      +  version "3.0.1"
      +  resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz#b6d0bced1dcc4f06f25cf0ceda2b2dcaf98168f1"
      +  integrity sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==
      +  dependencies:
      +    "@types/estree-jsx" "^1.0.0"
      +    devlop "^1.0.0"
      +    estree-util-is-identifier-name "^3.0.0"
      +    estree-walker "^3.0.0"
      +
       estree-util-is-identifier-name@^3.0.0:
         version "3.0.0"
         resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz#0b5ef4c4ff13508b34dcd01ecfa945f61fce5dbd"
         integrity sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==
       
      +estree-util-scope@^1.0.0:
      +  version "1.0.0"
      +  resolved "https://registry.yarnpkg.com/estree-util-scope/-/estree-util-scope-1.0.0.tgz#9cbdfc77f5cb51e3d9ed4ad9c4adbff22d43e585"
      +  integrity sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    devlop "^1.0.0"
      +
      +estree-util-to-js@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz#10a6fb924814e6abb62becf0d2bc4dea51d04f17"
      +  integrity sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==
      +  dependencies:
      +    "@types/estree-jsx" "^1.0.0"
      +    astring "^1.8.0"
      +    source-map "^0.7.0"
      +
      +estree-util-visit@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-2.0.0.tgz#13a9a9f40ff50ed0c022f831ddf4b58d05446feb"
      +  integrity sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==
      +  dependencies:
      +    "@types/estree-jsx" "^1.0.0"
      +    "@types/unist" "^3.0.0"
      +
      +estree-walker@^2.0.2:
      +  version "2.0.2"
      +  resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
      +  integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
      +
      +estree-walker@^3.0.0:
      +  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"
      +
       esutils@^2.0.2:
         version "2.0.3"
         resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
      @@ -2659,7 +2842,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^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==
       
      -fast-glob@^3.2.12, fast-glob@^3.3.0, fast-glob@^3.3.2:
      +fast-glob@^3.2.12, fast-glob@^3.3.2:
         version "3.3.2"
         resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
         integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
      @@ -2702,17 +2885,17 @@ file-entry-cache@^6.0.1:
         dependencies:
           flat-cache "^3.0.4"
       
      -file-selector@^0.6.0:
      -  version "0.6.0"
      -  resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.6.0.tgz#fa0a8d9007b829504db4d07dd4de0310b65287dc"
      -  integrity sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==
      +file-selector@^2.1.0:
      +  version "2.1.0"
      +  resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-2.1.0.tgz#beb164ca5ce48af8a48d3e632c94750bc573581a"
      +  integrity sha512-ZuXAqGePcSPz4JuerOY06Dzzq0hrmQ6VGoXVzGyFI1npeOfBgqGIKKpznfYWRkSLJlXutkqVC5WvGZtkFVhu9Q==
         dependencies:
      -    tslib "^2.4.0"
      +    tslib "^2.7.0"
       
      -fill-range@^7.0.1:
      -  version "7.0.1"
      -  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
      -  integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
      +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"
       
      @@ -2739,22 +2922,22 @@ flatted@^3.2.9:
         integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
       
       follow-redirects@^1.15.6:
      -  version "1.15.6"
      -  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
      -  integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
      +  version "1.15.9"
      +  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
      +  integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
       
       foreground-child@^3.1.0:
      -  version "3.1.1"
      -  resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d"
      -  integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==
      +  version "3.3.0"
      +  resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77"
      +  integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==
         dependencies:
           cross-spawn "^7.0.0"
           signal-exit "^4.0.1"
       
       form-data@^4.0.0:
      -  version "4.0.0"
      -  resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
      -  integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
      +  version "4.0.1"
      +  resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48"
      +  integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==
         dependencies:
           asynckit "^0.4.0"
           combined-stream "^1.0.8"
      @@ -2773,25 +2956,25 @@ fraction.js@^4.3.7:
         integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
       
       framer-motion@^11.11.11:
      -  version "11.11.11"
      -  resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.11.11.tgz#3c058c97ec134afdce77caa20396f0fd82d63b7d"
      -  integrity sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw==
      +  version "11.11.17"
      +  resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.11.17.tgz#fff0fd26b9b5c16dc0cc7e450f9af7db13fb35d0"
      +  integrity sha512-O8QzvoKiuzI5HSAHbcYuL6xU+ZLXbrH7C8Akaato4JzQbX2ULNeniqC2Vo5eiCtFktX9XsJ+7nUhxcl2E2IjpA==
         dependencies:
           tslib "^2.4.0"
       
      -frappe-js-sdk@^1.5.0:
      -  version "1.5.0"
      -  resolved "https://registry.yarnpkg.com/frappe-js-sdk/-/frappe-js-sdk-1.5.0.tgz#9fb161edb872136058c51adfba9f2c2927f81d2a"
      -  integrity sha512-KzBTvncqhBImIyIRWzZ0JcvYwEBPvGfCvvZ9JTtHE5Zn/YJtbN4GfXDG3x3AGNTVtwdU66zC8ADu20j/tBTXmQ==
      +frappe-js-sdk@^1.7.0:
      +  version "1.7.0"
      +  resolved "https://registry.yarnpkg.com/frappe-js-sdk/-/frappe-js-sdk-1.7.0.tgz#ed289a11e7cd03df71840d93687c230a1dcbebb9"
      +  integrity sha512-M8kPf0dTzdYRpQvg/adbyioY2byLOEfNQsfK+b3ebIgXCNjX1H38GvhhU3OX9o/2x2QB65npgI7ODlUmpT6grA==
         dependencies:
      -    axios "^1.6.7"
      +    axios "^1.7.4"
       
       frappe-react-sdk@^1.7.0:
      -  version "1.7.0"
      -  resolved "https://registry.yarnpkg.com/frappe-react-sdk/-/frappe-react-sdk-1.7.0.tgz#6d7430f2e606dbe733ffbe1fda7566fc815b6a45"
      -  integrity sha512-UBch8j7nWCkYWQjGG7tOds5tFif/hFdAbg8T+FlOiJAyFmtpbVdBOsWx2ime9aBkNa2U8zqjOkQLLIvL2/qOrg==
      +  version "1.9.0"
      +  resolved "https://registry.yarnpkg.com/frappe-react-sdk/-/frappe-react-sdk-1.9.0.tgz#d0502ca5ee5e43fe0551d4d3e1657f017a2685dd"
      +  integrity sha512-ZeUCv8iyo9uSAY/VN/kcUVsRVW3ut2D1/ws6gEfi6V9Me7LdpKL9ICL9yBiEM2tTxh6BoiURaQ8xMeVZqt/oMQ==
         dependencies:
      -    frappe-js-sdk "^1.5.0"
      +    frappe-js-sdk "^1.7.0"
           socket.io-client "4.7.1"
           swr "^2.2.5"
       
      @@ -2854,15 +3037,16 @@ glob-parent@^6.0.2:
           is-glob "^4.0.3"
       
       glob@^10.3.10:
      -  version "10.3.15"
      -  resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.15.tgz#e72bc61bc3038c90605f5dd48543dc67aaf3b50d"
      -  integrity sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==
      +  version "10.4.5"
      +  resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
      +  integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
         dependencies:
           foreground-child "^3.1.0"
      -    jackspeak "^2.3.6"
      -    minimatch "^9.0.1"
      -    minipass "^7.0.4"
      -    path-scurry "^1.11.0"
      +    jackspeak "^3.1.2"
      +    minimatch "^9.0.4"
      +    minipass "^7.1.2"
      +    package-json-from-dist "^1.0.0"
      +    path-scurry "^1.11.1"
       
       glob@^7.1.3:
         version "7.2.3"
      @@ -2898,23 +3082,37 @@ graphemer@^1.4.0:
         resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
         integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
       
      -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-flag@^4.0.0:
         version "4.0.0"
         resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
         integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
       
      -hasown@^2.0.0:
      +hasown@^2.0.2:
         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"
       
      +hast-util-from-dom@^5.0.0:
      +  version "5.0.0"
      +  resolved "https://registry.yarnpkg.com/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz#d32edd25bf28f4b178b5ae318f8d05762e67bd16"
      +  integrity sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==
      +  dependencies:
      +    "@types/hast" "^3.0.0"
      +    hastscript "^8.0.0"
      +    web-namespaces "^2.0.0"
      +
      +hast-util-from-html-isomorphic@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz#b31baee386a899a2472326a3c5692f29f86d1d3c"
      +  integrity sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==
      +  dependencies:
      +    "@types/hast" "^3.0.0"
      +    hast-util-from-dom "^5.0.0"
      +    hast-util-from-html "^2.0.0"
      +    unist-util-remove-position "^5.0.0"
      +
       hast-util-from-html@^2.0.0:
         version "2.0.3"
         resolved "https://registry.yarnpkg.com/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz#485c74785358beb80c4ba6346299311ac4c49c82"
      @@ -2977,9 +3175,9 @@ hast-util-parse-selector@^4.0.0:
           "@types/hast" "^3.0.0"
       
       hast-util-raw@^9.0.0:
      -  version "9.0.3"
      -  resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.0.3.tgz#87ad66bdd7b1ceb166452bdab7dfb3e9ba640419"
      -  integrity sha512-ICWvVOF2fq4+7CMmtCPD5CM4QKjPbHpPotE6+8tDooV0ZuyJVUzHsrNX+O5NaRbieTf0F7FfeBOMAwi6Td0+yQ==
      +  version "9.1.0"
      +  resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.1.0.tgz#79b66b26f6f68fb50dfb4716b2cdca90d92adf2e"
      +  integrity sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==
         dependencies:
           "@types/hast" "^3.0.0"
           "@types/unist" "^3.0.0"
      @@ -2996,9 +3194,9 @@ hast-util-raw@^9.0.0:
           zwitch "^2.0.0"
       
       hast-util-select@^6.0.0:
      -  version "6.0.2"
      -  resolved "https://registry.yarnpkg.com/hast-util-select/-/hast-util-select-6.0.2.tgz#f1e6c583ab6227cb510383471328734342bd1d1c"
      -  integrity sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==
      +  version "6.0.3"
      +  resolved "https://registry.yarnpkg.com/hast-util-select/-/hast-util-select-6.0.3.tgz#d30471b26efc88ae8a126ec36cd8ee6420fe3839"
      +  integrity sha512-OVRQlQ1XuuLP8aFVLYmC2atrfWHS5UD3shonxpnyrjcCkwtvmt/+N6kYJdcY4mkMJhxp4kj2EFIxQ9kvkkt/eQ==
         dependencies:
           "@types/hast" "^3.0.0"
           "@types/unist" "^3.0.0"
      @@ -3010,13 +3208,34 @@ hast-util-select@^6.0.0:
           hast-util-has-property "^3.0.0"
           hast-util-to-string "^3.0.0"
           hast-util-whitespace "^3.0.0"
      -    not "^0.1.0"
           nth-check "^2.0.0"
           property-information "^6.0.0"
           space-separated-tokens "^2.0.0"
           unist-util-visit "^5.0.0"
           zwitch "^2.0.0"
       
      +hast-util-to-estree@^3.0.0:
      +  version "3.1.0"
      +  resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz#f2afe5e869ddf0cf690c75f9fc699f3180b51b19"
      +  integrity sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    "@types/estree-jsx" "^1.0.0"
      +    "@types/hast" "^3.0.0"
      +    comma-separated-tokens "^2.0.0"
      +    devlop "^1.0.0"
      +    estree-util-attach-comments "^3.0.0"
      +    estree-util-is-identifier-name "^3.0.0"
      +    hast-util-whitespace "^3.0.0"
      +    mdast-util-mdx-expression "^2.0.0"
      +    mdast-util-mdx-jsx "^3.0.0"
      +    mdast-util-mdxjs-esm "^2.0.0"
      +    property-information "^6.0.0"
      +    space-separated-tokens "^2.0.0"
      +    style-to-object "^0.4.0"
      +    unist-util-position "^5.0.0"
      +    zwitch "^2.0.0"
      +
       hast-util-to-html@^9.0.0:
         version "9.0.3"
         resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz#a9999a0ba6b4919576a9105129fead85d37f302b"
      @@ -3035,9 +3254,9 @@ hast-util-to-html@^9.0.0:
           zwitch "^2.0.4"
       
       hast-util-to-jsx-runtime@^2.0.0:
      -  version "2.3.0"
      -  resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz#3ed27caf8dc175080117706bf7269404a0aa4f7c"
      -  integrity sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==
      +  version "2.3.2"
      +  resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz#6d11b027473e69adeaa00ca4cfb5bb68e3d282fa"
      +  integrity sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==
         dependencies:
           "@types/estree" "^1.0.0"
           "@types/hast" "^3.0.0"
      @@ -3069,11 +3288,21 @@ hast-util-to-parse5@^8.0.0:
           zwitch "^2.0.0"
       
       hast-util-to-string@^3.0.0:
      -  version "3.0.0"
      -  resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz#2a131948b4b1b26461a2c8ac876e2c88d02946bd"
      -  integrity sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==
      +  version "3.0.1"
      +  resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz#a4f15e682849326dd211c97129c94b0c3e76527c"
      +  integrity sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==
      +  dependencies:
      +    "@types/hast" "^3.0.0"
      +
      +hast-util-to-text@^4.0.0:
      +  version "4.0.2"
      +  resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz#57b676931e71bf9cb852453678495b3080bfae3e"
      +  integrity sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==
         dependencies:
           "@types/hast" "^3.0.0"
      +    "@types/unist" "^3.0.0"
      +    hast-util-is-element "^3.0.0"
      +    unist-util-find-after "^5.0.0"
       
       hast-util-whitespace@^3.0.0:
         version "3.0.0"
      @@ -3110,9 +3339,9 @@ html-to-image@^1.11.11:
         integrity sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==
       
       html-url-attributes@^3.0.0:
      -  version "3.0.0"
      -  resolved "https://registry.yarnpkg.com/html-url-attributes/-/html-url-attributes-3.0.0.tgz#fc4abf0c3fb437e2329c678b80abb3c62cff6f08"
      -  integrity sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==
      +  version "3.0.1"
      +  resolved "https://registry.yarnpkg.com/html-url-attributes/-/html-url-attributes-3.0.1.tgz#83b052cd5e437071b756cd74ae70f708870c2d87"
      +  integrity sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==
       
       html-void-elements@^3.0.0:
         version "3.0.0"
      @@ -3138,9 +3367,9 @@ ieee754@^1.2.1:
         integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
       
       ignore@^5.2.0:
      -  version "5.3.1"
      -  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef"
      -  integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==
      +  version "5.3.2"
      +  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
      +  integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
       
       import-fresh@^3.2.1, import-fresh@^3.3.0:
         version "3.3.0"
      @@ -3168,10 +3397,15 @@ inherits@2, inherits@^2.0.3, inherits@^2.0.4:
         resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
         integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
       
      -inline-style-parser@0.2.3:
      -  version "0.2.3"
      -  resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.3.tgz#e35c5fb45f3a83ed7849fe487336eb7efa25971c"
      -  integrity sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==
      +inline-style-parser@0.1.1:
      +  version "0.1.1"
      +  resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1"
      +  integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==
      +
      +inline-style-parser@0.2.4:
      +  version "0.2.4"
      +  resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.4.tgz#f4af5fe72e612839fcd453d989a586566d695f22"
      +  integrity sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==
       
       install@^0.13.0:
         version "0.13.0"
      @@ -3210,17 +3444,12 @@ is-binary-path@~2.1.0:
         dependencies:
           binary-extensions "^2.0.0"
       
      -is-buffer@^2.0.0:
      -  version "2.0.5"
      -  resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
      -  integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
      -
       is-core-module@^2.13.0:
      -  version "2.13.1"
      -  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
      -  integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
      +  version "2.15.1"
      +  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37"
      +  integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==
         dependencies:
      -    hasown "^2.0.0"
      +    hasown "^2.0.2"
       
       is-decimal@^2.0.0:
         version "2.0.1"
      @@ -3284,24 +3513,24 @@ isexe@^2.0.0:
         resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
         integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
       
      -jackspeak@^2.3.6:
      -  version "2.3.6"
      -  resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8"
      -  integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==
      +jackspeak@^3.1.2:
      +  version "3.4.3"
      +  resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a"
      +  integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==
         dependencies:
           "@isaacs/cliui" "^8.0.2"
         optionalDependencies:
           "@pkgjs/parseargs" "^0.11.0"
       
      -jiti@^1.21.0:
      -  version "1.21.0"
      -  resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
      -  integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
      +jiti@^1.21.6:
      +  version "1.21.6"
      +  resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268"
      +  integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
       
       jotai@^2.8.3:
      -  version "2.8.3"
      -  resolved "https://registry.yarnpkg.com/jotai/-/jotai-2.8.3.tgz#21b50c89c9ee2d24e694158b925bade1f38641d7"
      -  integrity sha512-pR4plVvdbzB6zyt7VLLHPMAkcRSKhRIvZKd+qkifQLa3CEziEo1uwZjePj4acTmQrboiISBlYSdCz3gWcr1Nkg==
      +  version "2.10.2"
      +  resolved "https://registry.yarnpkg.com/jotai/-/jotai-2.10.2.tgz#c5fe5419e0526c262d401d6033f7a2c0049ce1b4"
      +  integrity sha512-DqsBTlRglIBviuJLfK6JxZzpd6vKfbuJ4IqRCz70RFEDeZf46Fcteb/FXxNr1UnoxR5oUy3oq7IE8BrEq0G5DQ==
       
       "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
         version "4.0.0"
      @@ -3315,10 +3544,10 @@ js-yaml@^4.1.0:
         dependencies:
           argparse "^2.0.1"
       
      -jsesc@^2.5.1:
      -  version "2.5.2"
      -  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
      -  integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
      +jsesc@^3.0.2:
      +  version "3.0.2"
      +  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
      +  integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
       
       json-buffer@3.0.1:
         version "3.0.1"
      @@ -3354,6 +3583,13 @@ jsonfile@^6.0.1:
         optionalDependencies:
           graceful-fs "^4.1.6"
       
      +katex@^0.16.0:
      +  version "0.16.11"
      +  resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.11.tgz#4bc84d5584f996abece5f01c6ad11304276a33f5"
      +  integrity sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==
      +  dependencies:
      +    commander "^8.3.0"
      +
       keyv@^4.5.3:
         version "4.5.4"
         resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
      @@ -3366,11 +3602,6 @@ kleur@^3.0.3:
         resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
         integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
       
      -kleur@^4.0.3:
      -  version "4.1.5"
      -  resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
      -  integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
      -
       levn@^0.4.1:
         version "0.4.1"
         resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
      @@ -3385,9 +3616,9 @@ lilconfig@^2.1.0:
         integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
       
       lilconfig@^3.0.0:
      -  version "3.1.1"
      -  resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.1.tgz#9d8a246fa753106cfc205fd2d77042faca56e5e3"
      -  integrity sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==
      +  version "3.1.2"
      +  resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb"
      +  integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==
       
       lines-and-columns@^1.1.6:
         version "1.2.4"
      @@ -3457,9 +3688,9 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
           js-tokens "^3.0.0 || ^4.0.0"
       
       lru-cache@^10.2.0:
      -  version "10.2.2"
      -  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878"
      -  integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==
      +  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"
      @@ -3468,20 +3699,15 @@ lru-cache@^5.1.1:
         dependencies:
           yallist "^3.0.2"
       
      -markdown-table@^3.0.0:
      -  version "3.0.3"
      -  resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.3.tgz#e6331d30e493127e031dd385488b5bd326e4a6bd"
      -  integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==
      +markdown-extensions@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-2.0.0.tgz#34bebc83e9938cae16e0e017e4a9814a8330d3c4"
      +  integrity sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==
       
      -mdast-util-find-and-replace@^2.0.0:
      -  version "2.2.2"
      -  resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz#cc2b774f7f3630da4bd592f61966fecade8b99b1"
      -  integrity sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    escape-string-regexp "^5.0.0"
      -    unist-util-is "^5.0.0"
      -    unist-util-visit-parents "^5.0.0"
      +markdown-table@^3.0.0:
      +  version "3.0.4"
      +  resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a"
      +  integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==
       
       mdast-util-find-and-replace@^3.0.0:
         version "3.0.1"
      @@ -3493,28 +3719,10 @@ mdast-util-find-and-replace@^3.0.0:
           unist-util-is "^6.0.0"
           unist-util-visit-parents "^6.0.0"
       
      -mdast-util-from-markdown@^1.0.0:
      -  version "1.3.1"
      -  resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz#9421a5a247f10d31d2faed2a30df5ec89ceafcf0"
      -  integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    "@types/unist" "^2.0.0"
      -    decode-named-character-reference "^1.0.0"
      -    mdast-util-to-string "^3.1.0"
      -    micromark "^3.0.0"
      -    micromark-util-decode-numeric-character-reference "^1.0.0"
      -    micromark-util-decode-string "^1.0.0"
      -    micromark-util-normalize-identifier "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -    unist-util-stringify-position "^3.0.0"
      -    uvu "^0.5.0"
      -
       mdast-util-from-markdown@^2.0.0:
      -  version "2.0.1"
      -  resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz#32a6e8f512b416e1f51eb817fc64bd867ebcd9cc"
      -  integrity sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==
      +  version "2.0.2"
      +  resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz#4850390ca7cf17413a9b9a0fbefcd1bc0eb4160a"
      +  integrity sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==
         dependencies:
           "@types/mdast" "^4.0.0"
           "@types/unist" "^3.0.0"
      @@ -3529,16 +3737,6 @@ mdast-util-from-markdown@^2.0.0:
           micromark-util-types "^2.0.0"
           unist-util-stringify-position "^4.0.0"
       
      -mdast-util-gfm-autolink-literal@^1.0.0:
      -  version "1.0.3"
      -  resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz#67a13abe813d7eba350453a5333ae1bc0ec05c06"
      -  integrity sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    ccount "^2.0.0"
      -    mdast-util-find-and-replace "^2.0.0"
      -    micromark-util-character "^1.0.0"
      -
       mdast-util-gfm-autolink-literal@^2.0.0:
         version "2.0.1"
         resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz#abd557630337bd30a6d5a4bd8252e1c2dc0875d5"
      @@ -3550,15 +3748,6 @@ mdast-util-gfm-autolink-literal@^2.0.0:
           mdast-util-find-and-replace "^3.0.0"
           micromark-util-character "^2.0.0"
       
      -mdast-util-gfm-footnote@^1.0.0:
      -  version "1.0.2"
      -  resolved "https://registry.yarnpkg.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz#ce5e49b639c44de68d5bf5399877a14d5020424e"
      -  integrity sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    mdast-util-to-markdown "^1.3.0"
      -    micromark-util-normalize-identifier "^1.0.0"
      -
       mdast-util-gfm-footnote@^2.0.0:
         version "2.0.0"
         resolved "https://registry.yarnpkg.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz#25a1753c7d16db8bfd53cd84fe50562bd1e6d6a9"
      @@ -3570,14 +3759,6 @@ mdast-util-gfm-footnote@^2.0.0:
           mdast-util-to-markdown "^2.0.0"
           micromark-util-normalize-identifier "^2.0.0"
       
      -mdast-util-gfm-strikethrough@^1.0.0:
      -  version "1.0.3"
      -  resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz#5470eb105b483f7746b8805b9b989342085795b7"
      -  integrity sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    mdast-util-to-markdown "^1.3.0"
      -
       mdast-util-gfm-strikethrough@^2.0.0:
         version "2.0.0"
         resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz#d44ef9e8ed283ac8c1165ab0d0dfd058c2764c16"
      @@ -3587,16 +3768,6 @@ mdast-util-gfm-strikethrough@^2.0.0:
           mdast-util-from-markdown "^2.0.0"
           mdast-util-to-markdown "^2.0.0"
       
      -mdast-util-gfm-table@^1.0.0:
      -  version "1.0.7"
      -  resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz#3552153a146379f0f9c4c1101b071d70bbed1a46"
      -  integrity sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    markdown-table "^3.0.0"
      -    mdast-util-from-markdown "^1.0.0"
      -    mdast-util-to-markdown "^1.3.0"
      -
       mdast-util-gfm-table@^2.0.0:
         version "2.0.0"
         resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz#7a435fb6223a72b0862b33afbd712b6dae878d38"
      @@ -3608,14 +3779,6 @@ mdast-util-gfm-table@^2.0.0:
           mdast-util-from-markdown "^2.0.0"
           mdast-util-to-markdown "^2.0.0"
       
      -mdast-util-gfm-task-list-item@^1.0.0:
      -  version "1.0.2"
      -  resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz#b280fcf3b7be6fd0cc012bbe67a59831eb34097b"
      -  integrity sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    mdast-util-to-markdown "^1.3.0"
      -
       mdast-util-gfm-task-list-item@^2.0.0:
         version "2.0.0"
         resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz#e68095d2f8a4303ef24094ab642e1047b991a936"
      @@ -3626,19 +3789,6 @@ mdast-util-gfm-task-list-item@^2.0.0:
           mdast-util-from-markdown "^2.0.0"
           mdast-util-to-markdown "^2.0.0"
       
      -mdast-util-gfm@^2.0.0:
      -  version "2.0.2"
      -  resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz#e92f4d8717d74bdba6de57ed21cc8b9552e2d0b6"
      -  integrity sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==
      -  dependencies:
      -    mdast-util-from-markdown "^1.0.0"
      -    mdast-util-gfm-autolink-literal "^1.0.0"
      -    mdast-util-gfm-footnote "^1.0.0"
      -    mdast-util-gfm-strikethrough "^1.0.0"
      -    mdast-util-gfm-table "^1.0.0"
      -    mdast-util-gfm-task-list-item "^1.0.0"
      -    mdast-util-to-markdown "^1.0.0"
      -
       mdast-util-gfm@^3.0.0:
         version "3.0.0"
         resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz#3f2aecc879785c3cb6a81ff3a243dc11eca61095"
      @@ -3652,10 +3802,23 @@ mdast-util-gfm@^3.0.0:
           mdast-util-gfm-task-list-item "^2.0.0"
           mdast-util-to-markdown "^2.0.0"
       
      +mdast-util-math@^3.0.0:
      +  version "3.0.0"
      +  resolved "https://registry.yarnpkg.com/mdast-util-math/-/mdast-util-math-3.0.0.tgz#8d79dd3baf8ab8ac781f62b8853768190b9a00b0"
      +  integrity sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==
      +  dependencies:
      +    "@types/hast" "^3.0.0"
      +    "@types/mdast" "^4.0.0"
      +    devlop "^1.0.0"
      +    longest-streak "^3.0.0"
      +    mdast-util-from-markdown "^2.0.0"
      +    mdast-util-to-markdown "^2.1.0"
      +    unist-util-remove-position "^5.0.0"
      +
       mdast-util-mdx-expression@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz#4968b73724d320a379110d853e943a501bfd9d87"
      -  integrity sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz#43f0abac9adc756e2086f63822a38c8d3c3a5096"
      +  integrity sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==
         dependencies:
           "@types/estree-jsx" "^1.0.0"
           "@types/hast" "^3.0.0"
      @@ -3665,9 +3828,9 @@ mdast-util-mdx-expression@^2.0.0:
           mdast-util-to-markdown "^2.0.0"
       
       mdast-util-mdx-jsx@^3.0.0:
      -  version "3.1.2"
      -  resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz#daae777c72f9c4a106592e3025aa50fb26068e1b"
      -  integrity sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==
      +  version "3.1.3"
      +  resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz#76b957b3da18ebcfd0de3a9b4451dcd6fdec2320"
      +  integrity sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==
         dependencies:
           "@types/estree-jsx" "^1.0.0"
           "@types/hast" "^3.0.0"
      @@ -3679,10 +3842,20 @@ mdast-util-mdx-jsx@^3.0.0:
           mdast-util-to-markdown "^2.0.0"
           parse-entities "^4.0.0"
           stringify-entities "^4.0.0"
      -    unist-util-remove-position "^5.0.0"
           unist-util-stringify-position "^4.0.0"
           vfile-message "^4.0.0"
       
      +mdast-util-mdx@^3.0.0:
      +  version "3.0.0"
      +  resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz#792f9cf0361b46bee1fdf1ef36beac424a099c41"
      +  integrity sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==
      +  dependencies:
      +    mdast-util-from-markdown "^2.0.0"
      +    mdast-util-mdx-expression "^2.0.0"
      +    mdast-util-mdx-jsx "^3.0.0"
      +    mdast-util-mdxjs-esm "^2.0.0"
      +    mdast-util-to-markdown "^2.0.0"
      +
       mdast-util-mdxjs-esm@^2.0.0:
         version "2.0.1"
         resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz#019cfbe757ad62dd557db35a695e7314bcc9fa97"
      @@ -3695,13 +3868,13 @@ mdast-util-mdxjs-esm@^2.0.0:
           mdast-util-from-markdown "^2.0.0"
           mdast-util-to-markdown "^2.0.0"
       
      -mdast-util-phrasing@^3.0.0:
      -  version "3.0.1"
      -  resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz#c7c21d0d435d7fb90956038f02e8702781f95463"
      -  integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==
      +mdast-util-newline-to-break@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/mdast-util-newline-to-break/-/mdast-util-newline-to-break-2.0.0.tgz#4e73ef621b6b1a590240336cfe6c29915e198df0"
      +  integrity sha512-MbgeFca0hLYIEx/2zGsszCSEJJ1JSCdiY5xQxRcLDDGa8EPvlLPupJ4DSajbMPAnC0je8jfb9TiUATnxxrHUog==
         dependencies:
      -    "@types/mdast" "^3.0.0"
      -    unist-util-is "^5.0.0"
      +    "@types/mdast" "^4.0.0"
      +    mdast-util-find-and-replace "^3.0.0"
       
       mdast-util-phrasing@^4.0.0:
         version "4.1.0"
      @@ -3712,9 +3885,9 @@ mdast-util-phrasing@^4.0.0:
           unist-util-is "^6.0.0"
       
       mdast-util-to-hast@^13.0.0:
      -  version "13.1.0"
      -  resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz#1ae54d903150a10fe04d59f03b2b95fd210b2124"
      -  integrity sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==
      +  version "13.2.0"
      +  resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4"
      +  integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==
         dependencies:
           "@types/hast" "^3.0.0"
           "@types/mdast" "^4.0.0"
      @@ -3726,41 +3899,21 @@ mdast-util-to-hast@^13.0.0:
           unist-util-visit "^5.0.0"
           vfile "^6.0.0"
       
      -mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0:
      -  version "1.5.0"
      -  resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz#c13343cb3fc98621911d33b5cd42e7d0731171c6"
      -  integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -    "@types/unist" "^2.0.0"
      -    longest-streak "^3.0.0"
      -    mdast-util-phrasing "^3.0.0"
      -    mdast-util-to-string "^3.0.0"
      -    micromark-util-decode-string "^1.0.0"
      -    unist-util-visit "^4.0.0"
      -    zwitch "^2.0.0"
      -
      -mdast-util-to-markdown@^2.0.0:
      -  version "2.1.0"
      -  resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz#9813f1d6e0cdaac7c244ec8c6dabfdb2102ea2b4"
      -  integrity sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==
      +mdast-util-to-markdown@^2.0.0, mdast-util-to-markdown@^2.1.0:
      +  version "2.1.2"
      +  resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz#f910ffe60897f04bb4b7e7ee434486f76288361b"
      +  integrity sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==
         dependencies:
           "@types/mdast" "^4.0.0"
           "@types/unist" "^3.0.0"
           longest-streak "^3.0.0"
           mdast-util-phrasing "^4.0.0"
           mdast-util-to-string "^4.0.0"
      +    micromark-util-classify-character "^2.0.0"
           micromark-util-decode-string "^2.0.0"
           unist-util-visit "^5.0.0"
           zwitch "^2.0.0"
       
      -mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0:
      -  version "3.2.0"
      -  resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz#66f7bb6324756741c5f47a53557f0cbf16b6f789"
      -  integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==
      -  dependencies:
      -    "@types/mdast" "^3.0.0"
      -
       mdast-util-to-string@^4.0.0:
         version "4.0.0"
         resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz#7a5121475556a04e7eddeb67b264aae79d312814"
      @@ -3778,32 +3931,10 @@ merge2@^1.3.0:
         resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
         integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
       
      -micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz#1386628df59946b2d39fb2edfd10f3e8e0a75bb8"
      -  integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==
      -  dependencies:
      -    decode-named-character-reference "^1.0.0"
      -    micromark-factory-destination "^1.0.0"
      -    micromark-factory-label "^1.0.0"
      -    micromark-factory-space "^1.0.0"
      -    micromark-factory-title "^1.0.0"
      -    micromark-factory-whitespace "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-chunked "^1.0.0"
      -    micromark-util-classify-character "^1.0.0"
      -    micromark-util-html-tag-name "^1.0.0"
      -    micromark-util-normalize-identifier "^1.0.0"
      -    micromark-util-resolve-all "^1.0.0"
      -    micromark-util-subtokenize "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.1"
      -    uvu "^0.5.0"
      -
       micromark-core-commonmark@^2.0.0:
      -  version "2.0.1"
      -  resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz#9a45510557d068605c6e9a80f282b2bb8581e43d"
      -  integrity sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==
      +  version "2.0.2"
      +  resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz#6a45bbb139e126b3f8b361a10711ccc7c6e15e93"
      +  integrity sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==
         dependencies:
           decode-named-character-reference "^1.0.0"
           devlop "^1.0.0"
      @@ -3822,16 +3953,6 @@ micromark-core-commonmark@^2.0.0:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-extension-gfm-autolink-literal@^1.0.0:
      -  version "1.0.5"
      -  resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz#5853f0e579bbd8ef9e39a7c0f0f27c5a063a66e7"
      -  integrity sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==
      -  dependencies:
      -    micromark-util-character "^1.0.0"
      -    micromark-util-sanitize-uri "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -
       micromark-extension-gfm-autolink-literal@^2.0.0:
         version "2.1.0"
         resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz#6286aee9686c4462c1e3552a9d505feddceeb935"
      @@ -3842,20 +3963,6 @@ micromark-extension-gfm-autolink-literal@^2.0.0:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-extension-gfm-footnote@^1.0.0:
      -  version "1.1.2"
      -  resolved "https://registry.yarnpkg.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz#05e13034d68f95ca53c99679040bc88a6f92fe2e"
      -  integrity sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==
      -  dependencies:
      -    micromark-core-commonmark "^1.0.0"
      -    micromark-factory-space "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-normalize-identifier "^1.0.0"
      -    micromark-util-sanitize-uri "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -    uvu "^0.5.0"
      -
       micromark-extension-gfm-footnote@^2.0.0:
         version "2.1.0"
         resolved "https://registry.yarnpkg.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz#4dab56d4e398b9853f6fe4efac4fc9361f3e0750"
      @@ -3870,18 +3977,6 @@ micromark-extension-gfm-footnote@^2.0.0:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-extension-gfm-strikethrough@^1.0.0:
      -  version "1.0.7"
      -  resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz#c8212c9a616fa3bf47cb5c711da77f4fdc2f80af"
      -  integrity sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==
      -  dependencies:
      -    micromark-util-chunked "^1.0.0"
      -    micromark-util-classify-character "^1.0.0"
      -    micromark-util-resolve-all "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -    uvu "^0.5.0"
      -
       micromark-extension-gfm-strikethrough@^2.0.0:
         version "2.1.0"
         resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz#86106df8b3a692b5f6a92280d3879be6be46d923"
      @@ -3894,17 +3989,6 @@ micromark-extension-gfm-strikethrough@^2.0.0:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-extension-gfm-table@^1.0.0:
      -  version "1.0.7"
      -  resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz#dcb46074b0c6254c3fc9cc1f6f5002c162968008"
      -  integrity sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==
      -  dependencies:
      -    micromark-factory-space "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -    uvu "^0.5.0"
      -
       micromark-extension-gfm-table@^2.0.0:
         version "2.1.0"
         resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz#5cadedfbb29fca7abf752447967003dc3b6583c9"
      @@ -3916,13 +4000,6 @@ micromark-extension-gfm-table@^2.0.0:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-extension-gfm-tagfilter@^1.0.0:
      -  version "1.0.2"
      -  resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz#aa7c4dd92dabbcb80f313ebaaa8eb3dac05f13a7"
      -  integrity sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==
      -  dependencies:
      -    micromark-util-types "^1.0.0"
      -
       micromark-extension-gfm-tagfilter@^2.0.0:
         version "2.0.0"
         resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz#f26d8a7807b5985fba13cf61465b58ca5ff7dc57"
      @@ -3930,17 +4007,6 @@ micromark-extension-gfm-tagfilter@^2.0.0:
         dependencies:
           micromark-util-types "^2.0.0"
       
      -micromark-extension-gfm-task-list-item@^1.0.0:
      -  version "1.0.5"
      -  resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz#b52ce498dc4c69b6a9975abafc18f275b9dde9f4"
      -  integrity sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==
      -  dependencies:
      -    micromark-factory-space "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -    uvu "^0.5.0"
      -
       micromark-extension-gfm-task-list-item@^2.0.0:
         version "2.1.0"
         resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz#bcc34d805639829990ec175c3eea12bb5b781f2c"
      @@ -3952,20 +4018,6 @@ micromark-extension-gfm-task-list-item@^2.0.0:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-extension-gfm@^2.0.0:
      -  version "2.0.3"
      -  resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz#e517e8579949a5024a493e49204e884aa74f5acf"
      -  integrity sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==
      -  dependencies:
      -    micromark-extension-gfm-autolink-literal "^1.0.0"
      -    micromark-extension-gfm-footnote "^1.0.0"
      -    micromark-extension-gfm-strikethrough "^1.0.0"
      -    micromark-extension-gfm-table "^1.0.0"
      -    micromark-extension-gfm-tagfilter "^1.0.0"
      -    micromark-extension-gfm-task-list-item "^1.0.0"
      -    micromark-util-combine-extensions "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -
       micromark-extension-gfm@^3.0.0:
         version "3.0.0"
         resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz#3e13376ab95dd7a5cfd0e29560dfe999657b3c5b"
      @@ -3980,331 +4032,268 @@ micromark-extension-gfm@^3.0.0:
           micromark-util-combine-extensions "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-factory-destination@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz#eb815957d83e6d44479b3df640f010edad667b9f"
      -  integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==
      -  dependencies:
      -    micromark-util-character "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      +micromark-extension-math@^3.0.0:
      +  version "3.1.0"
      +  resolved "https://registry.yarnpkg.com/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz#c42ee3b1dd5a9a03584e83dd8f08e3de510212c1"
      +  integrity sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==
      +  dependencies:
      +    "@types/katex" "^0.16.0"
      +    devlop "^1.0.0"
      +    katex "^0.16.0"
      +    micromark-factory-space "^2.0.0"
      +    micromark-util-character "^2.0.0"
      +    micromark-util-symbol "^2.0.0"
      +    micromark-util-types "^2.0.0"
      +
      +micromark-extension-mdx-expression@^3.0.0:
      +  version "3.0.0"
      +  resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz#1407b9ce69916cf5e03a196ad9586889df25302a"
      +  integrity sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    devlop "^1.0.0"
      +    micromark-factory-mdx-expression "^2.0.0"
      +    micromark-factory-space "^2.0.0"
      +    micromark-util-character "^2.0.0"
      +    micromark-util-events-to-acorn "^2.0.0"
      +    micromark-util-symbol "^2.0.0"
      +    micromark-util-types "^2.0.0"
      +
      +micromark-extension-mdx-jsx@^3.0.0:
      +  version "3.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz#5abb83da5ddc8e473a374453e6ea56fbd66b59ad"
      +  integrity sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==
      +  dependencies:
      +    "@types/acorn" "^4.0.0"
      +    "@types/estree" "^1.0.0"
      +    devlop "^1.0.0"
      +    estree-util-is-identifier-name "^3.0.0"
      +    micromark-factory-mdx-expression "^2.0.0"
      +    micromark-factory-space "^2.0.0"
      +    micromark-util-character "^2.0.0"
      +    micromark-util-events-to-acorn "^2.0.0"
      +    micromark-util-symbol "^2.0.0"
      +    micromark-util-types "^2.0.0"
      +    vfile-message "^4.0.0"
      +
      +micromark-extension-mdx-md@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz#1d252881ea35d74698423ab44917e1f5b197b92d"
      +  integrity sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==
      +  dependencies:
      +    micromark-util-types "^2.0.0"
      +
      +micromark-extension-mdxjs-esm@^3.0.0:
      +  version "3.0.0"
      +  resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz#de21b2b045fd2059bd00d36746081de38390d54a"
      +  integrity sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    devlop "^1.0.0"
      +    micromark-core-commonmark "^2.0.0"
      +    micromark-util-character "^2.0.0"
      +    micromark-util-events-to-acorn "^2.0.0"
      +    micromark-util-symbol "^2.0.0"
      +    micromark-util-types "^2.0.0"
      +    unist-util-position-from-estree "^2.0.0"
      +    vfile-message "^4.0.0"
      +
      +micromark-extension-mdxjs@^3.0.0:
      +  version "3.0.0"
      +  resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz#b5a2e0ed449288f3f6f6c544358159557549de18"
      +  integrity sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==
      +  dependencies:
      +    acorn "^8.0.0"
      +    acorn-jsx "^5.0.0"
      +    micromark-extension-mdx-expression "^3.0.0"
      +    micromark-extension-mdx-jsx "^3.0.0"
      +    micromark-extension-mdx-md "^2.0.0"
      +    micromark-extension-mdxjs-esm "^3.0.0"
      +    micromark-util-combine-extensions "^2.0.0"
      +    micromark-util-types "^2.0.0"
       
       micromark-factory-destination@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz#857c94debd2c873cba34e0445ab26b74f6a6ec07"
      -  integrity sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz#8fef8e0f7081f0474fbdd92deb50c990a0264639"
      +  integrity sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==
         dependencies:
           micromark-util-character "^2.0.0"
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-factory-label@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz#cc95d5478269085cfa2a7282b3de26eb2e2dec68"
      -  integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==
      -  dependencies:
      -    micromark-util-character "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -    uvu "^0.5.0"
      -
       micromark-factory-label@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz#17c5c2e66ce39ad6f4fc4cbf40d972f9096f726a"
      -  integrity sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz#5267efa97f1e5254efc7f20b459a38cb21058ba1"
      +  integrity sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==
         dependencies:
           devlop "^1.0.0"
           micromark-util-character "^2.0.0"
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-factory-space@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf"
      -  integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==
      +micromark-factory-mdx-expression@^2.0.0:
      +  version "2.0.2"
      +  resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz#2afaa8ba6d5f63e0cead3e4dee643cad184ca260"
      +  integrity sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==
         dependencies:
      -    micromark-util-character "^1.0.0"
      -    micromark-util-types "^1.0.0"
      +    "@types/estree" "^1.0.0"
      +    devlop "^1.0.0"
      +    micromark-factory-space "^2.0.0"
      +    micromark-util-character "^2.0.0"
      +    micromark-util-events-to-acorn "^2.0.0"
      +    micromark-util-symbol "^2.0.0"
      +    micromark-util-types "^2.0.0"
      +    unist-util-position-from-estree "^2.0.0"
      +    vfile-message "^4.0.0"
       
       micromark-factory-space@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz#5e7afd5929c23b96566d0e1ae018ae4fcf81d030"
      -  integrity sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz#36d0212e962b2b3121f8525fc7a3c7c029f334fc"
      +  integrity sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==
         dependencies:
           micromark-util-character "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-factory-title@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz#dd0fe951d7a0ac71bdc5ee13e5d1465ad7f50ea1"
      -  integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==
      -  dependencies:
      -    micromark-factory-space "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -
       micromark-factory-title@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz#726140fc77892af524705d689e1cf06c8a83ea95"
      -  integrity sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz#237e4aa5d58a95863f01032d9ee9b090f1de6e94"
      +  integrity sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==
         dependencies:
           micromark-factory-space "^2.0.0"
           micromark-util-character "^2.0.0"
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-factory-whitespace@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz#798fb7489f4c8abafa7ca77eed6b5745853c9705"
      -  integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==
      -  dependencies:
      -    micromark-factory-space "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -
       micromark-factory-whitespace@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz#9e92eb0f5468083381f923d9653632b3cfb5f763"
      -  integrity sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz#06b26b2983c4d27bfcc657b33e25134d4868b0b1"
      +  integrity sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==
         dependencies:
           micromark-factory-space "^2.0.0"
           micromark-util-character "^2.0.0"
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-util-character@^1.0.0:
      -  version "1.2.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc"
      -  integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==
      -  dependencies:
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -
       micromark-util-character@^2.0.0:
      -  version "2.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz#31320ace16b4644316f6bf057531689c71e2aee1"
      -  integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==
      +  version "2.1.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz#2f987831a40d4c510ac261e89852c4e9703ccda6"
      +  integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==
         dependencies:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-util-chunked@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz#37a24d33333c8c69a74ba12a14651fd9ea8a368b"
      -  integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==
      -  dependencies:
      -    micromark-util-symbol "^1.0.0"
      -
       micromark-util-chunked@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz#e51f4db85fb203a79dbfef23fd41b2f03dc2ef89"
      -  integrity sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz#47fbcd93471a3fccab86cff03847fc3552db1051"
      +  integrity sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==
         dependencies:
           micromark-util-symbol "^2.0.0"
       
      -micromark-util-classify-character@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz#6a7f8c8838e8a120c8e3c4f2ae97a2bff9190e9d"
      -  integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==
      -  dependencies:
      -    micromark-util-character "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -
       micromark-util-classify-character@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz#8c7537c20d0750b12df31f86e976d1d951165f34"
      -  integrity sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz#d399faf9c45ca14c8b4be98b1ea481bced87b629"
      +  integrity sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==
         dependencies:
           micromark-util-character "^2.0.0"
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-util-combine-extensions@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz#192e2b3d6567660a85f735e54d8ea6e3952dbe84"
      -  integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==
      -  dependencies:
      -    micromark-util-chunked "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -
       micromark-util-combine-extensions@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz#75d6ab65c58b7403616db8d6b31315013bfb7ee5"
      -  integrity sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz#2a0f490ab08bff5cc2fd5eec6dd0ca04f89b30a9"
      +  integrity sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==
         dependencies:
           micromark-util-chunked "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-util-decode-numeric-character-reference@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz#b1e6e17009b1f20bc652a521309c5f22c85eb1c6"
      -  integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==
      -  dependencies:
      -    micromark-util-symbol "^1.0.0"
      -
       micromark-util-decode-numeric-character-reference@^2.0.0:
      -  version "2.0.1"
      -  resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz#2698bbb38f2a9ba6310e359f99fcb2b35a0d2bd5"
      -  integrity sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==
      +  version "2.0.2"
      +  resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz#fcf15b660979388e6f118cdb6bf7d79d73d26fe5"
      +  integrity sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==
         dependencies:
           micromark-util-symbol "^2.0.0"
       
      -micromark-util-decode-string@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz#dc12b078cba7a3ff690d0203f95b5d5537f2809c"
      -  integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==
      -  dependencies:
      -    decode-named-character-reference "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-decode-numeric-character-reference "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -
       micromark-util-decode-string@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz#7dfa3a63c45aecaa17824e656bcdb01f9737154a"
      -  integrity sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz#6cb99582e5d271e84efca8e61a807994d7161eb2"
      +  integrity sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==
         dependencies:
           decode-named-character-reference "^1.0.0"
           micromark-util-character "^2.0.0"
           micromark-util-decode-numeric-character-reference "^2.0.0"
           micromark-util-symbol "^2.0.0"
       
      -micromark-util-encode@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz#92e4f565fd4ccb19e0dcae1afab9a173bbeb19a5"
      -  integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==
      -
       micromark-util-encode@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz#0921ac7953dc3f1fd281e3d1932decfdb9382ab1"
      -  integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz#0d51d1c095551cfaac368326963cf55f15f540b8"
      +  integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==
       
      -micromark-util-html-tag-name@^1.0.0:
      -  version "1.2.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz#48fd7a25826f29d2f71479d3b4e83e94829b3588"
      -  integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==
      +micromark-util-events-to-acorn@^2.0.0:
      +  version "2.0.2"
      +  resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz#4275834f5453c088bd29cd72dfbf80e3327cec07"
      +  integrity sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==
      +  dependencies:
      +    "@types/acorn" "^4.0.0"
      +    "@types/estree" "^1.0.0"
      +    "@types/unist" "^3.0.0"
      +    devlop "^1.0.0"
      +    estree-util-visit "^2.0.0"
      +    micromark-util-symbol "^2.0.0"
      +    micromark-util-types "^2.0.0"
      +    vfile-message "^4.0.0"
       
       micromark-util-html-tag-name@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz#ae34b01cbe063363847670284c6255bb12138ec4"
      -  integrity sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==
      -
      -micromark-util-normalize-identifier@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz#7a73f824eb9f10d442b4d7f120fecb9b38ebf8b7"
      -  integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==
      -  dependencies:
      -    micromark-util-symbol "^1.0.0"
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz#e40403096481986b41c106627f98f72d4d10b825"
      +  integrity sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==
       
       micromark-util-normalize-identifier@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz#91f9a4e65fe66cc80c53b35b0254ad67aa431d8b"
      -  integrity sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz#c30d77b2e832acf6526f8bf1aa47bc9c9438c16d"
      +  integrity sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==
         dependencies:
           micromark-util-symbol "^2.0.0"
       
      -micromark-util-resolve-all@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz#4652a591ee8c8fa06714c9b54cd6c8e693671188"
      -  integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==
      -  dependencies:
      -    micromark-util-types "^1.0.0"
      -
       micromark-util-resolve-all@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz#189656e7e1a53d0c86a38a652b284a252389f364"
      -  integrity sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz#e1a2d62cdd237230a2ae11839027b19381e31e8b"
      +  integrity sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==
         dependencies:
           micromark-util-types "^2.0.0"
       
      -micromark-util-sanitize-uri@^1.0.0:
      -  version "1.2.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz#613f738e4400c6eedbc53590c67b197e30d7f90d"
      -  integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==
      -  dependencies:
      -    micromark-util-character "^1.0.0"
      -    micromark-util-encode "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -
       micromark-util-sanitize-uri@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz#ec8fbf0258e9e6d8f13d9e4770f9be64342673de"
      -  integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz#ab89789b818a58752b73d6b55238621b7faa8fd7"
      +  integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==
         dependencies:
           micromark-util-character "^2.0.0"
           micromark-util-encode "^2.0.0"
           micromark-util-symbol "^2.0.0"
       
      -micromark-util-subtokenize@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz#941c74f93a93eaf687b9054aeb94642b0e92edb1"
      -  integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==
      -  dependencies:
      -    micromark-util-chunked "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.0"
      -    uvu "^0.5.0"
      -
       micromark-util-subtokenize@^2.0.0:
      -  version "2.0.1"
      -  resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz#76129c49ac65da6e479c09d0ec4b5f29ec6eace5"
      -  integrity sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==
      +  version "2.0.2"
      +  resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.2.tgz#ea5e3984b96b13cda7b1329763e15f3b4a4e063b"
      +  integrity sha512-xKxhkB62vwHUuuxHe9Xqty3UaAsizV2YKq5OV344u3hFBbf8zIYrhYOWhAQb94MtMPkjTOzzjJ/hid9/dR5vFA==
         dependencies:
           devlop "^1.0.0"
           micromark-util-chunked "^2.0.0"
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromark-util-symbol@^1.0.0:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142"
      -  integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==
      -
       micromark-util-symbol@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz#12225c8f95edf8b17254e47080ce0862d5db8044"
      -  integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==
      -
      -micromark-util-types@^1.0.0, micromark-util-types@^1.0.1:
      -  version "1.1.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283"
      -  integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz#e5da494e8eb2b071a0d08fb34f6cefec6c0a19b8"
      +  integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==
       
       micromark-util-types@^2.0.0:
      -  version "2.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz#63b4b7ffeb35d3ecf50d1ca20e68fc7caa36d95e"
      -  integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==
      -
      -micromark@^3.0.0:
      -  version "3.2.0"
      -  resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.2.0.tgz#1af9fef3f995ea1ea4ac9c7e2f19c48fd5c006e9"
      -  integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==
      -  dependencies:
      -    "@types/debug" "^4.0.0"
      -    debug "^4.0.0"
      -    decode-named-character-reference "^1.0.0"
      -    micromark-core-commonmark "^1.0.1"
      -    micromark-factory-space "^1.0.0"
      -    micromark-util-character "^1.0.0"
      -    micromark-util-chunked "^1.0.0"
      -    micromark-util-combine-extensions "^1.0.0"
      -    micromark-util-decode-numeric-character-reference "^1.0.0"
      -    micromark-util-encode "^1.0.0"
      -    micromark-util-normalize-identifier "^1.0.0"
      -    micromark-util-resolve-all "^1.0.0"
      -    micromark-util-sanitize-uri "^1.0.0"
      -    micromark-util-subtokenize "^1.0.0"
      -    micromark-util-symbol "^1.0.0"
      -    micromark-util-types "^1.0.1"
      -    uvu "^0.5.0"
      +  version "2.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.1.tgz#a3edfda3022c6c6b55bfb049ef5b75d70af50709"
      +  integrity sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==
       
       micromark@^4.0.0:
      -  version "4.0.0"
      -  resolved "https://registry.yarnpkg.com/micromark/-/micromark-4.0.0.tgz#84746a249ebd904d9658cfabc1e8e5f32cbc6249"
      -  integrity sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==
      +  version "4.0.1"
      +  resolved "https://registry.yarnpkg.com/micromark/-/micromark-4.0.1.tgz#294c2f12364759e5f9e925a767ae3dfde72223ff"
      +  integrity sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==
         dependencies:
           "@types/debug" "^4.0.0"
           debug "^4.0.0"
      @@ -4324,12 +4313,12 @@ micromark@^4.0.0:
           micromark-util-symbol "^2.0.0"
           micromark-util-types "^2.0.0"
       
      -micromatch@^4.0.4, micromatch@^4.0.5:
      -  version "4.0.5"
      -  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
      -  integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
      +micromatch@^4.0.4, micromatch@^4.0.8:
      +  version "4.0.8"
      +  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
      +  integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
         dependencies:
      -    braces "^3.0.2"
      +    braces "^3.0.3"
           picomatch "^2.3.1"
       
       mime-db@1.52.0:
      @@ -4368,10 +4357,10 @@ minimatch@^7.4.3:
         dependencies:
           brace-expansion "^2.0.1"
       
      -minimatch@^9.0.1:
      -  version "9.0.4"
      -  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51"
      -  integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==
      +minimatch@^9.0.4:
      +  version "9.0.5"
      +  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
      +  integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
         dependencies:
           brace-expansion "^2.0.1"
       
      @@ -4380,10 +4369,10 @@ minimist@^1.2.6:
         resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
         integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
       
      -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4:
      -  version "7.1.1"
      -  resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.1.tgz#f7f85aff59aa22f110b20e27692465cf3bf89481"
      -  integrity sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==
      +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
      +  version "7.1.2"
      +  resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
      +  integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
       
       mkdirp@^2.1.6:
         version "2.1.6"
      @@ -4391,9 +4380,9 @@ mkdirp@^2.1.6:
         integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==
       
       moment-timezone@^0.5.43:
      -  version "0.5.45"
      -  resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.45.tgz#cb685acd56bac10e69d93c536366eb65aa6bcf5c"
      -  integrity sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==
      +  version "0.5.46"
      +  resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.46.tgz#a21aa6392b3c6b3ed916cd5e95858a28d893704a"
      +  integrity sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw==
         dependencies:
           moment "^2.29.4"
       
      @@ -4402,15 +4391,10 @@ moment@^2.29.4:
         resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
         integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
       
      -mri@^1.1.0:
      -  version "1.2.0"
      -  resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
      -  integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
      -
      -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:
      +  version "2.1.3"
      +  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
      +  integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
       
       mz@^2.7.0:
         version "2.7.0"
      @@ -4445,10 +4429,10 @@ node-fetch@^3.3.0:
           fetch-blob "^3.1.4"
           formdata-polyfill "^4.0.10"
       
      -node-releases@^2.0.14:
      -  version "2.0.14"
      -  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
      -  integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==
      +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-path@^3.0.0, normalize-path@~3.0.0:
         version "3.0.0"
      @@ -4460,11 +4444,6 @@ normalize-range@^0.1.2:
         resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
         integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
       
      -not@^0.1.0:
      -  version "0.1.0"
      -  resolved "https://registry.yarnpkg.com/not/-/not-0.1.0.tgz#c9691c1746c55dcfbe54cbd8bd4ff041bc2b519d"
      -  integrity sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==
      -
       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"
      @@ -4551,6 +4530,11 @@ p-locate@^5.0.0:
         dependencies:
           p-limit "^3.0.2"
       
      +package-json-from-dist@^1.0.0:
      +  version "1.0.1"
      +  resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505"
      +  integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
      +
       parent-module@^1.0.0:
         version "1.0.1"
         resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
      @@ -4588,11 +4572,11 @@ parse-numeric-range@^1.3.0:
         integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==
       
       parse5@^7.0.0:
      -  version "7.1.2"
      -  resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"
      -  integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==
      +  version "7.2.1"
      +  resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.2.1.tgz#8928f55915e6125f430cc44309765bf17556a33a"
      +  integrity sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==
         dependencies:
      -    entities "^4.4.0"
      +    entities "^4.5.0"
       
       path-browserify@^1.0.1:
         version "1.0.1"
      @@ -4624,7 +4608,7 @@ path-parse@^1.0.7:
         resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
         integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
       
      -path-scurry@^1.11.0:
      +path-scurry@^1.11.1:
         version "1.11.1"
         resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2"
         integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
      @@ -4637,16 +4621,21 @@ path-type@^4.0.0:
         resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
         integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
       
      -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==
      +picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0, picocolors@^1.1.1:
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
      +  integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
       
       picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
         version "2.3.1"
         resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
         integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
       
      +picomatch@^4.0.2:
      +  version "4.0.2"
      +  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
      +  integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
      +
       pify@^2.3.0:
         version "2.3.0"
         resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
      @@ -4673,7 +4662,7 @@ postcss-js@^4.0.1:
         dependencies:
           camelcase-css "^2.0.1"
       
      -postcss-load-config@^4.0.1:
      +postcss-load-config@^4.0.2:
         version "4.0.2"
         resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3"
         integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==
      @@ -4681,17 +4670,17 @@ postcss-load-config@^4.0.1:
           lilconfig "^3.0.0"
           yaml "^2.3.4"
       
      -postcss-nested@^6.0.1:
      -  version "6.0.1"
      -  resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c"
      -  integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==
      +postcss-nested@^6.2.0:
      +  version "6.2.0"
      +  resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131"
      +  integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==
         dependencies:
      -    postcss-selector-parser "^6.0.11"
      +    postcss-selector-parser "^6.1.1"
       
      -postcss-selector-parser@^6.0.11:
      -  version "6.0.16"
      -  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz#3b88b9f5c5abd989ef4e2fc9ec8eedd34b20fb04"
      -  integrity sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==
      +postcss-selector-parser@^6.1.1, postcss-selector-parser@^6.1.2:
      +  version "6.1.2"
      +  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de"
      +  integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==
         dependencies:
           cssesc "^3.0.0"
           util-deprecate "^1.0.2"
      @@ -4701,14 +4690,14 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^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.23, postcss@^8.4.26, postcss@^8.4.27:
      -  version "8.4.38"
      -  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e"
      -  integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
      +postcss@^8.4.26, postcss@^8.4.27, postcss@^8.4.47:
      +  version "8.4.49"
      +  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19"
      +  integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==
         dependencies:
           nanoid "^3.3.7"
      -    picocolors "^1.0.0"
      -    source-map-js "^1.2.0"
      +    picocolors "^1.1.1"
      +    source-map-js "^1.2.1"
       
       prelude-ls@^1.2.1:
         version "1.2.1"
      @@ -4761,23 +4750,23 @@ react-dom@^18.2.0:
           scheduler "^0.23.2"
       
       react-dropzone@^14.2.3:
      -  version "14.2.3"
      -  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.2.3.tgz#0acab68308fda2d54d1273a1e626264e13d4e84b"
      -  integrity sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==
      +  version "14.3.5"
      +  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.3.5.tgz#1a8bd312c8a353ec78ef402842ccb3589c225add"
      +  integrity sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==
         dependencies:
      -    attr-accept "^2.2.2"
      -    file-selector "^0.6.0"
      +    attr-accept "^2.2.4"
      +    file-selector "^2.1.0"
           prop-types "^15.8.1"
       
       react-hook-form@^7.45.1:
      -  version "7.51.4"
      -  resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.51.4.tgz#c3a47aeb22b699c45de9fc12b58763606cb52f0c"
      -  integrity sha512-V14i8SEkh+V1gs6YtD0hdHYnoL4tp/HX/A45wWQN15CYr9bFRmmRdYStSO5L65lCCZRF+kYiSKhm9alqbcdiVA==
      +  version "7.53.2"
      +  resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.53.2.tgz#6fa37ae27330af81089baadd7f322cc987b8e2ac"
      +  integrity sha512-YVel6fW5sOeedd1524pltpHX+jgU2u3DSDtXEaBORNdqiNrsX/nUI/iGXONegttg0mJVnfrIkiV0cmTU6Oo2xw==
       
       react-icons@^5.2.1:
      -  version "5.2.1"
      -  resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.2.1.tgz#28c2040917b2a2eda639b0f797bff1888e018e4a"
      -  integrity sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==
      +  version "5.3.0"
      +  resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c"
      +  integrity sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==
       
       react-is@18.2.0:
         version "18.2.0"
      @@ -4789,7 +4778,7 @@ react-is@^16.13.1:
         resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
         integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
       
      -react-markdown@^9.0.1, react-markdown@~9.0.1:
      +react-markdown@~9.0.1:
         version "9.0.1"
         resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-9.0.1.tgz#c05ddbff67fd3b3f839f8c648e6fb35d022397d1"
         integrity sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==
      @@ -4805,12 +4794,12 @@ react-markdown@^9.0.1, react-markdown@~9.0.1:
           unist-util-visit "^5.0.0"
           vfile "^6.0.0"
       
      -react-refresh@^0.14.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-remove-scroll-bar@^2.3.3:
      +react-remove-scroll-bar@^2.3.3, react-remove-scroll-bar@^2.3.6:
         version "2.3.6"
         resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c"
         integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==
      @@ -4840,20 +4829,31 @@ react-remove-scroll@2.5.5:
           use-callback-ref "^1.3.0"
           use-sidecar "^1.1.2"
       
      +react-remove-scroll@2.6.0:
      +  version "2.6.0"
      +  resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz#fb03a0845d7768a4f1519a99fdb84983b793dc07"
      +  integrity sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==
      +  dependencies:
      +    react-remove-scroll-bar "^2.3.6"
      +    react-style-singleton "^2.2.1"
      +    tslib "^2.1.0"
      +    use-callback-ref "^1.3.0"
      +    use-sidecar "^1.1.2"
      +
       react-router-dom@^6.14.1:
      -  version "6.23.1"
      -  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.23.1.tgz#30cbf266669693e9492aa4fc0dde2541ab02322f"
      -  integrity sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==
      +  version "6.28.0"
      +  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6"
      +  integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==
         dependencies:
      -    "@remix-run/router" "1.16.1"
      -    react-router "6.23.1"
      +    "@remix-run/router" "1.21.0"
      +    react-router "6.28.0"
       
      -react-router@6.23.1:
      -  version "6.23.1"
      -  resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.23.1.tgz#d08cbdbd9d6aedc13eea6e94bc6d9b29cb1c4be9"
      -  integrity sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==
      +react-router@6.28.0:
      +  version "6.28.0"
      +  resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d"
      +  integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==
         dependencies:
      -    "@remix-run/router" "1.16.1"
      +    "@remix-run/router" "1.21.0"
       
       react-style-singleton@^2.2.1:
         version "2.2.1"
      @@ -4907,9 +4907,9 @@ readdirp@~3.6.0:
           picomatch "^2.2.1"
       
       recast@^0.23.2:
      -  version "0.23.7"
      -  resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.7.tgz#1e08f164e10402b075c904a2b01022b3da039c72"
      -  integrity sha512-MpQlLZVpqbbxYcqEjwpRWo88sGvjOYoXptySz710RuddNMHx+wPkoNX6YyLZJlXAh5VZr1qmPrTwcTuFMh0Lag==
      +  version "0.23.9"
      +  resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.9.tgz#587c5d3a77c2cfcb0c18ccce6da4361528c2587b"
      +  integrity sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==
         dependencies:
           ast-types "^0.16.1"
           esprima "~4.0.0"
      @@ -4917,6 +4917,46 @@ recast@^0.23.2:
           tiny-invariant "^1.3.3"
           tslib "^2.0.1"
       
      +recma-build-jsx@^1.0.0:
      +  version "1.0.0"
      +  resolved "https://registry.yarnpkg.com/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz#c02f29e047e103d2fab2054954e1761b8ea253c4"
      +  integrity sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    estree-util-build-jsx "^3.0.0"
      +    vfile "^6.0.0"
      +
      +recma-jsx@^1.0.0:
      +  version "1.0.0"
      +  resolved "https://registry.yarnpkg.com/recma-jsx/-/recma-jsx-1.0.0.tgz#f7bef02e571a49d6ba3efdfda8e2efab48dbe3aa"
      +  integrity sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==
      +  dependencies:
      +    acorn-jsx "^5.0.0"
      +    estree-util-to-js "^2.0.0"
      +    recma-parse "^1.0.0"
      +    recma-stringify "^1.0.0"
      +    unified "^11.0.0"
      +
      +recma-parse@^1.0.0:
      +  version "1.0.0"
      +  resolved "https://registry.yarnpkg.com/recma-parse/-/recma-parse-1.0.0.tgz#c351e161bb0ab47d86b92a98a9d891f9b6814b52"
      +  integrity sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    esast-util-from-js "^2.0.0"
      +    unified "^11.0.0"
      +    vfile "^6.0.0"
      +
      +recma-stringify@^1.0.0:
      +  version "1.0.0"
      +  resolved "https://registry.yarnpkg.com/recma-stringify/-/recma-stringify-1.0.0.tgz#54632030631e0c7546136ff9ef8fde8e7b44f130"
      +  integrity sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    estree-util-to-js "^2.0.0"
      +    unified "^11.0.0"
      +    vfile "^6.0.0"
      +
       refractor@^4.8.0:
         version "4.8.1"
         resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42"
      @@ -4961,10 +5001,23 @@ rehype-ignore@^2.0.0:
           unified "^11.0.0"
           unist-util-visit "^5.0.0"
       
      +rehype-katex@^7.0.1:
      +  version "7.0.1"
      +  resolved "https://registry.yarnpkg.com/rehype-katex/-/rehype-katex-7.0.1.tgz#832e6d7af2744a228981d1b0fe89483a9e7c93a1"
      +  integrity sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==
      +  dependencies:
      +    "@types/hast" "^3.0.0"
      +    "@types/katex" "^0.16.0"
      +    hast-util-from-html-isomorphic "^2.0.0"
      +    hast-util-to-text "^4.0.0"
      +    katex "^0.16.0"
      +    unist-util-visit-parents "^6.0.0"
      +    vfile "^6.0.0"
      +
       rehype-parse@^9.0.0:
      -  version "9.0.0"
      -  resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-9.0.0.tgz#3949faeec6f466ec57774215661e0d75469195d9"
      -  integrity sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==
      +  version "9.0.1"
      +  resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-9.0.1.tgz#9993bda129acc64c417a9d3654a7be38b2a94c20"
      +  integrity sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==
         dependencies:
           "@types/hast" "^3.0.0"
           hast-util-from-html "^2.0.0"
      @@ -4991,6 +5044,15 @@ rehype-raw@^7.0.0:
           hast-util-raw "^9.0.0"
           vfile "^6.0.0"
       
      +rehype-recma@^1.0.0:
      +  version "1.0.0"
      +  resolved "https://registry.yarnpkg.com/rehype-recma/-/rehype-recma-1.0.0.tgz#d68ef6344d05916bd96e25400c6261775411aa76"
      +  integrity sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==
      +  dependencies:
      +    "@types/estree" "^1.0.0"
      +    "@types/hast" "^3.0.0"
      +    hast-util-to-estree "^3.0.0"
      +
       rehype-rewrite@~4.0.0:
         version "4.0.2"
         resolved "https://registry.yarnpkg.com/rehype-rewrite/-/rehype-rewrite-4.0.2.tgz#7b094bb586dfda83333994cb3dbb01cb1e8c361d"
      @@ -5012,35 +5074,34 @@ rehype-slug@~6.0.0:
           unist-util-visit "^5.0.0"
       
       rehype-stringify@^10.0.0:
      -  version "10.0.0"
      -  resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-10.0.0.tgz#2031cf6fdd0355393706f0474ec794c75e5492f2"
      -  integrity sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==
      +  version "10.0.1"
      +  resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-10.0.1.tgz#2ec1ebc56c6aba07905d3b4470bdf0f684f30b75"
      +  integrity sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==
         dependencies:
           "@types/hast" "^3.0.0"
           hast-util-to-html "^9.0.0"
           unified "^11.0.0"
       
       rehype@~13.0.0:
      -  version "13.0.1"
      -  resolved "https://registry.yarnpkg.com/rehype/-/rehype-13.0.1.tgz#56384ba83955e2f3aa7eca1975b406c67d9dbd5e"
      -  integrity sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg==
      +  version "13.0.2"
      +  resolved "https://registry.yarnpkg.com/rehype/-/rehype-13.0.2.tgz#ab0b3ac26573d7b265a0099feffad450e4cf1952"
      +  integrity sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==
         dependencies:
           "@types/hast" "^3.0.0"
           rehype-parse "^9.0.0"
           rehype-stringify "^10.0.0"
           unified "^11.0.0"
       
      -remark-gfm@^3.0.1:
      -  version "3.0.1"
      -  resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-3.0.1.tgz#0b180f095e3036545e9dddac0e8df3fa5cfee54f"
      -  integrity sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==
      +remark-breaks@^4.0.0:
      +  version "4.0.0"
      +  resolved "https://registry.yarnpkg.com/remark-breaks/-/remark-breaks-4.0.0.tgz#dcc19a2891733906f3b97eaa8acb8621e8da8852"
      +  integrity sha512-IjEjJOkH4FuJvHZVIW0QCDWxcG96kCq7An/KVH2NfJe6rKZU2AsHeB3OEjPNRxi4QC34Xdx7I2KGYn6IpT7gxQ==
         dependencies:
      -    "@types/mdast" "^3.0.0"
      -    mdast-util-gfm "^2.0.0"
      -    micromark-extension-gfm "^2.0.0"
      -    unified "^10.0.0"
      +    "@types/mdast" "^4.0.0"
      +    mdast-util-newline-to-break "^2.0.0"
      +    unified "^11.0.0"
       
      -remark-gfm@~4.0.0:
      +remark-gfm@^4.0.0, remark-gfm@~4.0.0:
         version "4.0.0"
         resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-4.0.0.tgz#aea777f0744701aa288b67d28c43565c7e8c35de"
         integrity sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==
      @@ -5053,12 +5114,30 @@ remark-gfm@~4.0.0:
           unified "^11.0.0"
       
       remark-github-blockquote-alert@^1.0.0:
      -  version "1.2.1"
      -  resolved "https://registry.yarnpkg.com/remark-github-blockquote-alert/-/remark-github-blockquote-alert-1.2.1.tgz#adb58d7fb57e96bc5a53674167f130029d1cb3c0"
      -  integrity sha512-qNf2mSAoZgh3Cl23/9Y1L7S4Kbf9NsdHvYK398ab/52yEsDPDU5I4cuTcgDRrdIX7Ltc6RK+KCLRtWkbFnL6Dg==
      +  version "1.3.0"
      +  resolved "https://registry.yarnpkg.com/remark-github-blockquote-alert/-/remark-github-blockquote-alert-1.3.0.tgz#12748e0ab7dc8720ad6763adfc33a3c936c4090b"
      +  integrity sha512-cwkBA4x+VH4J2VAMzhbmSeAmK5tBd5iwesgSUUQuRtuQ48XQm6sXXNLY9PR7ohZmZiqMeoDMUGCTur5zwR4lTQ==
         dependencies:
           unist-util-visit "^5.0.0"
       
      +remark-math@^6.0.0:
      +  version "6.0.0"
      +  resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-6.0.0.tgz#0acdf74675f1c195fea6efffa78582f7ed7fc0d7"
      +  integrity sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==
      +  dependencies:
      +    "@types/mdast" "^4.0.0"
      +    mdast-util-math "^3.0.0"
      +    micromark-extension-math "^3.0.0"
      +    unified "^11.0.0"
      +
      +remark-mdx@^3.0.0:
      +  version "3.1.0"
      +  resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-3.1.0.tgz#f979be729ecb35318fa48e2135c1169607a78343"
      +  integrity sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==
      +  dependencies:
      +    mdast-util-mdx "^3.0.0"
      +    micromark-extension-mdxjs "^3.0.0"
      +
       remark-parse@^11.0.0:
         version "11.0.0"
         resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-11.0.0.tgz#aa60743fcb37ebf6b069204eb4da304e40db45a1"
      @@ -5070,9 +5149,9 @@ remark-parse@^11.0.0:
           unified "^11.0.0"
       
       remark-rehype@^11.0.0:
      -  version "11.1.0"
      -  resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-11.1.0.tgz#d5f264f42bcbd4d300f030975609d01a1697ccdc"
      -  integrity sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==
      +  version "11.1.1"
      +  resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-11.1.1.tgz#f864dd2947889a11997c0a2667cd6b38f685bca7"
      +  integrity sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==
         dependencies:
           "@types/hast" "^3.0.0"
           "@types/mdast" "^4.0.0"
      @@ -5094,7 +5173,7 @@ resolve-from@^4.0.0:
         resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
         integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
       
      -resolve@^1.1.7, resolve@^1.22.2:
      +resolve@^1.1.7, resolve@^1.22.8:
         version "1.22.8"
         resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
         integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
      @@ -5124,9 +5203,9 @@ rimraf@^3.0.2:
           glob "^7.1.3"
       
       rollup@^3.27.1:
      -  version "3.29.4"
      -  resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981"
      -  integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==
      +  version "3.29.5"
      +  resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.5.tgz#8a2e477a758b520fb78daf04bca4c522c1da8a54"
      +  integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==
         optionalDependencies:
           fsevents "~2.3.2"
       
      @@ -5137,13 +5216,6 @@ run-parallel@^1.1.9:
         dependencies:
           queue-microtask "^1.2.2"
       
      -sade@^1.7.3:
      -  version "1.8.1"
      -  resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
      -  integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
      -  dependencies:
      -    mri "^1.1.0"
      -
       safe-buffer@~5.2.0:
         version "5.2.1"
         resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
      @@ -5225,13 +5297,13 @@ socket.io-client@4.7.1:
           socket.io-parser "~4.2.4"
       
       socket.io-client@^4.5.1:
      -  version "4.7.5"
      -  resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.7.5.tgz#919be76916989758bdc20eec63f7ee0ae45c05b7"
      -  integrity sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==
      +  version "4.8.1"
      +  resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.8.1.tgz#1941eca135a5490b94281d0323fe2a35f6f291cb"
      +  integrity sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==
         dependencies:
           "@socket.io/component-emitter" "~3.1.0"
           debug "~4.3.2"
      -    engine.io-client "~6.5.2"
      +    engine.io-client "~6.6.1"
           socket.io-parser "~4.2.4"
       
       socket.io-parser@~4.2.4:
      @@ -5242,10 +5314,15 @@ socket.io-parser@~4.2.4:
           "@socket.io/component-emitter" "~3.1.0"
           debug "~4.3.1"
       
      -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==
      +source-map-js@^1.2.1:
      +  version "1.2.1"
      +  resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
      +  integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
      +
      +source-map@^0.7.0:
      +  version "0.7.4"
      +  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
      +  integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
       
       source-map@~0.6.1:
         version "0.6.1"
      @@ -5265,7 +5342,6 @@ stdin-discarder@^0.1.0:
           bl "^5.0.0"
       
       "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
      -  name string-width-cjs
         version "4.2.3"
         resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
         integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
      @@ -5327,14 +5403,21 @@ strip-json-comments@^3.1.1:
         resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
         integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
       
      +style-to-object@^0.4.0:
      +  version "0.4.4"
      +  resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec"
      +  integrity sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==
      +  dependencies:
      +    inline-style-parser "0.1.1"
      +
       style-to-object@^1.0.0:
      -  version "1.0.6"
      -  resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.6.tgz#0c28aed8be1813d166c60d962719b2907c26547b"
      -  integrity sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==
      +  version "1.0.8"
      +  resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.8.tgz#67a29bca47eaa587db18118d68f9d95955e81292"
      +  integrity sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==
         dependencies:
      -    inline-style-parser "0.2.3"
      +    inline-style-parser "0.2.4"
       
      -sucrase@^3.32.0:
      +sucrase@^3.35.0:
         version "3.35.0"
         resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263"
         integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==
      @@ -5347,13 +5430,6 @@ sucrase@^3.32.0:
           pirates "^4.0.1"
           ts-interface-checker "^0.1.9"
       
      -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"
      -
       supports-color@^7.1.0:
         version "7.2.0"
         resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
      @@ -5385,32 +5461,32 @@ tailwindcss-animate@^1.0.6:
         integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==
       
       tailwindcss@^3.3.3:
      -  version "3.4.3"
      -  resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.3.tgz#be48f5283df77dfced705451319a5dffb8621519"
      -  integrity sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==
      +  version "3.4.15"
      +  resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.15.tgz#04808bf4bf1424b105047d19e7d4bfab368044a9"
      +  integrity sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==
         dependencies:
           "@alloc/quick-lru" "^5.2.0"
           arg "^5.0.2"
      -    chokidar "^3.5.3"
      +    chokidar "^3.6.0"
           didyoumean "^1.2.2"
           dlv "^1.1.3"
      -    fast-glob "^3.3.0"
      +    fast-glob "^3.3.2"
           glob-parent "^6.0.2"
           is-glob "^4.0.3"
      -    jiti "^1.21.0"
      +    jiti "^1.21.6"
           lilconfig "^2.1.0"
      -    micromatch "^4.0.5"
      +    micromatch "^4.0.8"
           normalize-path "^3.0.0"
           object-hash "^3.0.0"
      -    picocolors "^1.0.0"
      -    postcss "^8.4.23"
      +    picocolors "^1.1.1"
      +    postcss "^8.4.47"
           postcss-import "^15.1.0"
           postcss-js "^4.0.1"
      -    postcss-load-config "^4.0.1"
      -    postcss-nested "^6.0.1"
      -    postcss-selector-parser "^6.0.11"
      -    resolve "^1.22.2"
      -    sucrase "^3.32.0"
      +    postcss-load-config "^4.0.2"
      +    postcss-nested "^6.2.0"
      +    postcss-selector-parser "^6.1.2"
      +    resolve "^1.22.8"
      +    sucrase "^3.35.0"
       
       text-table@^0.2.0:
         version "0.2.0"
      @@ -5448,11 +5524,6 @@ tiny-invariant@^1.3.3:
         resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
         integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
       
      -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"
      @@ -5492,15 +5563,10 @@ tsconfig-paths@^4.2.0:
           minimist "^1.2.6"
           strip-bom "^3.0.0"
       
      -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0:
      -  version "2.6.2"
      -  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
      -  integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
      -
      -tslib@^2.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==
      +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.7.0:
      +  version "2.8.1"
      +  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
      +  integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
       
       type-check@^0.4.0, type-check@~0.4.0:
         version "0.4.0"
      @@ -5515,27 +5581,14 @@ type-fest@^0.20.2:
         integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
       
       typescript@^5.0.2:
      -  version "5.4.5"
      -  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
      -  integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==
      -
      -undici-types@~5.26.4:
      -  version "5.26.5"
      -  resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
      -  integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
      +  version "5.6.3"
      +  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b"
      +  integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==
       
      -unified@^10.0.0:
      -  version "10.1.2"
      -  resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df"
      -  integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==
      -  dependencies:
      -    "@types/unist" "^2.0.0"
      -    bail "^2.0.0"
      -    extend "^3.0.0"
      -    is-buffer "^2.0.0"
      -    is-plain-obj "^4.0.0"
      -    trough "^2.0.0"
      -    vfile "^5.0.0"
      +undici-types@~6.19.2:
      +  version "6.19.8"
      +  resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
      +  integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
       
       unified@^11.0.0, unified@^11.0.3, unified@~11.0.0:
         version "11.0.5"
      @@ -5559,12 +5612,13 @@ unist-util-filter@^5.0.0:
           unist-util-is "^6.0.0"
           unist-util-visit-parents "^6.0.0"
       
      -unist-util-is@^5.0.0:
      -  version "5.2.1"
      -  resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9"
      -  integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==
      +unist-util-find-after@^5.0.0:
      +  version "5.0.0"
      +  resolved "https://registry.yarnpkg.com/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz#3fccc1b086b56f34c8b798e1ff90b5c54468e896"
      +  integrity sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==
         dependencies:
      -    "@types/unist" "^2.0.0"
      +    "@types/unist" "^3.0.0"
      +    unist-util-is "^6.0.0"
       
       unist-util-is@^6.0.0:
         version "6.0.0"
      @@ -5573,6 +5627,13 @@ unist-util-is@^6.0.0:
         dependencies:
           "@types/unist" "^3.0.0"
       
      +unist-util-position-from-estree@^2.0.0:
      +  version "2.0.0"
      +  resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz#d94da4df596529d1faa3de506202f0c9a23f2200"
      +  integrity sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==
      +  dependencies:
      +    "@types/unist" "^3.0.0"
      +
       unist-util-position@^5.0.0:
         version "5.0.0"
         resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4"
      @@ -5588,13 +5649,6 @@ unist-util-remove-position@^5.0.0:
           "@types/unist" "^3.0.0"
           unist-util-visit "^5.0.0"
       
      -unist-util-stringify-position@^3.0.0:
      -  version "3.0.3"
      -  resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d"
      -  integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==
      -  dependencies:
      -    "@types/unist" "^2.0.0"
      -
       unist-util-stringify-position@^4.0.0:
         version "4.0.0"
         resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2"
      @@ -5602,14 +5656,6 @@ unist-util-stringify-position@^4.0.0:
         dependencies:
           "@types/unist" "^3.0.0"
       
      -unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1:
      -  version "5.1.3"
      -  resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz#b4520811b0ca34285633785045df7a8d6776cfeb"
      -  integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==
      -  dependencies:
      -    "@types/unist" "^2.0.0"
      -    unist-util-is "^5.0.0"
      -
       unist-util-visit-parents@^6.0.0:
         version "6.0.1"
         resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815"
      @@ -5618,15 +5664,6 @@ unist-util-visit-parents@^6.0.0:
           "@types/unist" "^3.0.0"
           unist-util-is "^6.0.0"
       
      -unist-util-visit@^4.0.0:
      -  version "4.1.2"
      -  resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz#125a42d1eb876283715a3cb5cceaa531828c72e2"
      -  integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==
      -  dependencies:
      -    "@types/unist" "^2.0.0"
      -    unist-util-is "^5.0.0"
      -    unist-util-visit-parents "^5.1.1"
      -
       unist-util-visit@^5.0.0, unist-util-visit@~5.0.0:
         version "5.0.0"
         resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6"
      @@ -5641,13 +5678,13 @@ universalify@^2.0.0:
         resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
         integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==
       
      -update-browserslist-db@^1.0.13:
      -  version "1.0.16"
      -  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz#f6d489ed90fb2f07d67784eb3f53d7891f736356"
      -  integrity sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==
      +update-browserslist-db@^1.1.1:
      +  version "1.1.1"
      +  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5"
      +  integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==
         dependencies:
      -    escalade "^3.1.2"
      -    picocolors "^1.0.1"
      +    escalade "^3.2.0"
      +    picocolors "^1.1.0"
       
       uri-js@^4.2.2:
         version "4.4.1"
      @@ -5671,12 +5708,7 @@ use-sidecar@^1.1.2:
           detect-node-es "^1.1.0"
           tslib "^2.0.0"
       
      -use-sync-external-store@1.2.0:
      -  version "1.2.0"
      -  resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
      -  integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
      -
      -use-sync-external-store@^1.2.0:
      +use-sync-external-store@1.2.2, use-sync-external-store@^1.2.0:
         version "1.2.2"
         resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz#c3b6390f3a30eba13200d2302dcdf1e7b57b2ef9"
         integrity sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==
      @@ -5686,32 +5718,14 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2:
         resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
         integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
       
      -uvu@^0.5.0:
      -  version "0.5.6"
      -  resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"
      -  integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==
      -  dependencies:
      -    dequal "^2.0.0"
      -    diff "^5.0.0"
      -    kleur "^4.0.3"
      -    sade "^1.7.3"
      -
       vfile-location@^5.0.0:
      -  version "5.0.2"
      -  resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.2.tgz#220d9ca1ab6f8b2504a4db398f7ebc149f9cb464"
      -  integrity sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==
      +  version "5.0.3"
      +  resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3"
      +  integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==
         dependencies:
           "@types/unist" "^3.0.0"
           vfile "^6.0.0"
       
      -vfile-message@^3.0.0:
      -  version "3.1.4"
      -  resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea"
      -  integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==
      -  dependencies:
      -    "@types/unist" "^2.0.0"
      -    unist-util-stringify-position "^3.0.0"
      -
       vfile-message@^4.0.0:
         version "4.0.2"
         resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181"
      @@ -5720,29 +5734,18 @@ vfile-message@^4.0.0:
           "@types/unist" "^3.0.0"
           unist-util-stringify-position "^4.0.0"
       
      -vfile@^5.0.0:
      -  version "5.3.7"
      -  resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.7.tgz#de0677e6683e3380fafc46544cfe603118826ab7"
      -  integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==
      -  dependencies:
      -    "@types/unist" "^2.0.0"
      -    is-buffer "^2.0.0"
      -    unist-util-stringify-position "^3.0.0"
      -    vfile-message "^3.0.0"
      -
       vfile@^6.0.0:
      -  version "6.0.1"
      -  resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.1.tgz#1e8327f41eac91947d4fe9d237a2dd9209762536"
      -  integrity sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==
      +  version "6.0.3"
      +  resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab"
      +  integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==
         dependencies:
           "@types/unist" "^3.0.0"
      -    unist-util-stringify-position "^4.0.0"
           vfile-message "^4.0.0"
       
       vite@^4.4.0:
      -  version "4.5.3"
      -  resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.3.tgz#d88a4529ea58bae97294c7e2e6f0eab39a50fb1a"
      -  integrity sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==
      +  version "4.5.5"
      +  resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.5.tgz#639b9feca5c0a3bfe3c60cb630ef28bf219d742e"
      +  integrity sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==
         dependencies:
           esbuild "^0.18.10"
           postcss "^8.4.27"
      @@ -5802,25 +5805,30 @@ wrappy@1:
         resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
         integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
       
      -ws@~8.11.0:
      -  version "8.11.0"
      -  resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
      -  integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
      +ws@~8.17.1:
      +  version "8.17.1"
      +  resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
      +  integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
       
       xmlhttprequest-ssl@~2.0.0:
         version "2.0.0"
         resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67"
         integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==
       
      +xmlhttprequest-ssl@~2.1.1:
      +  version "2.1.2"
      +  resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz#e9e8023b3f29ef34b97a859f584c5e6c61418e23"
      +  integrity sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==
      +
       yallist@^3.0.2:
         version "3.1.1"
         resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
         integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
       
       yaml@^2.3.4:
      -  version "2.4.2"
      -  resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.2.tgz#7a2b30f2243a5fc299e1f14ca58d475ed4bc5362"
      -  integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==
      +  version "2.6.0"
      +  resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.0.tgz#14059ad9d0b1680d0f04d3a60fe00f3a857303c3"
      +  integrity sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==
       
       yocto-queue@^0.1.0:
         version "0.1.0"
      @@ -5833,11 +5841,11 @@ zod@^3.20.2, zod@^3.21.4:
         integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
       
       zustand@^4.4.1:
      -  version "4.5.2"
      -  resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.2.tgz#fddbe7cac1e71d45413b3682cdb47b48034c3848"
      -  integrity sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==
      +  version "4.5.5"
      +  resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.5.tgz#f8c713041543715ec81a2adda0610e1dc82d4ad1"
      +  integrity sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==
         dependencies:
      -    use-sync-external-store "1.2.0"
      +    use-sync-external-store "1.2.2"
       
       zwitch@^2.0.0, zwitch@^2.0.4:
         version "2.0.4"
      
      From 71f13f91b819ba9573294298e60ce6f99d54f776 Mon Sep 17 00:00:00 2001
      From: Sumit Jain 
      Date: Fri, 6 Dec 2024 17:47:06 +0530
      Subject: [PATCH 091/110] feat: MDXRenderer Component for rendering MDX
      
      ---
       .../common/AsyncDropdown/AsyncDropdown.tsx    |    4 +-
       .../common/ErrorBanner/ErrorBanner.tsx        |    5 +-
       .../common/MarkdownRenderer/MDX.tsx           |   89 ++
       .../MarkdownRenderer/MarkdownRenderer.tsx     |   19 -
       .../common/MarkdownRenderer/markdown.css      | 1237 ++++++++++++++++-
       5 files changed, 1329 insertions(+), 25 deletions(-)
       create mode 100644 dashboard/src/components/common/MarkdownRenderer/MDX.tsx
       delete mode 100644 dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx
      
      diff --git a/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx b/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx
      index af1c6fb..6e807bc 100644
      --- a/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx
      +++ b/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx
      @@ -12,7 +12,7 @@ import { useDebounce } from '@/hooks/useDebounce';
       import { getLinkTitleAtom, setLinkTitleAtom } from './LinkTitles';
       import { AsyncSpinnerLoader } from '../FullPageLoader/SpinnerLoader';
       import { getErrorMessages } from '../ErrorBanner/ErrorBanner';
      -import { MarkdownRenderer } from '../MarkdownRenderer/MarkdownRenderer';
      +import MDXRenderer from '../MarkdownRenderer/MDX';
       
       
       interface ResultItem {
      @@ -472,7 +472,7 @@ const ErrorContainer = ({ error }: { error?: FrappeError }) => {
                   

      - {getErrorMessages(error).map(e => )} + {getErrorMessages(error).map(e => )}

      ); diff --git a/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx b/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx index 597b251..640316c 100644 --- a/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx +++ b/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx @@ -1,6 +1,6 @@ import { FrappeError } from 'frappe-react-sdk' import { useMemo } from 'react' -import { MarkdownRenderer } from '../MarkdownRenderer/MarkdownRenderer' +import MDXRenderer from '../MarkdownRenderer/MDX' interface ErrorBannerProps extends React.HTMLAttributes { @@ -123,7 +123,8 @@ export const ErrorBanner = ({ error, overrideHeading, ...props }: ErrorBannerPro

      - {messages.map((m, i) => )} + {messages.map((m, i) => + )}

      diff --git a/dashboard/src/components/common/MarkdownRenderer/MDX.tsx b/dashboard/src/components/common/MarkdownRenderer/MDX.tsx new file mode 100644 index 0000000..01953e7 --- /dev/null +++ b/dashboard/src/components/common/MarkdownRenderer/MDX.tsx @@ -0,0 +1,89 @@ +import React, { useState, useEffect } from 'react'; +import { compile, run } from '@mdx-js/mdx'; +import * as runtime from 'react/jsx-runtime'; +import './markdown.css'; // Import your custom styles for markdown +import 'katex/dist/katex.min.css'; + +// Plugins +import remarkMdx from 'remark-mdx'; +import remarkMath from 'remark-math'; +import remarkGfm from 'remark-gfm'; +import remarkBreaks from 'remark-breaks'; +import rehypeKatex from 'rehype-katex'; +import rehypeSlug from 'rehype-slug'; +import CustomHeading from '@/components/features/custommdxcomponent/CustomHeading'; +import CustomCodeBlock from '@/components/features/custommdxcomponent/CustomCodeBlock'; + +// Custom components +const CustomParagraph = ({ children }: { children?: React.ReactNode }) => { + const hasParagraph = React.Children.toArray(children).some( + (child) => React.isValidElement(child) && child.type === 'p' + ); + + if (hasParagraph) { + return <>{children}; // Return children as is if they already contain

      + } + + return

      {children}

      ; // Otherwise, wrap with

      +}; + +// Custom component mapping +const components = { + p: CustomParagraph, + pre: CustomCodeBlock, + h2: (props: any) => , + h3: (props: any) => , + h4: (props: any) => , + h5: (props: any) => , + h6: (props: any) => , +}; + +const compileMDX = async (mdxContent: string) => { + const compiled = await compile(mdxContent, { + outputFormat: 'function-body', + remarkPlugins: [remarkMdx, remarkMath, remarkBreaks, remarkGfm], + rehypePlugins: [rehypeSlug, rehypeKatex], + }); + return String(compiled); +}; + +const renderMDX = async (compiledMdx: string, customComponents: any) => { + try { + const { default: MDXContent } = await run(compiledMdx, { ...runtime }); + + // Wrap MDXContent with MDXProvider to use custom components + const MDXWithProvider = (props: any) => + + + return MDXWithProvider; + } catch (error) { + console.error('Error rendering MDX:', error); + return null; + } +}; + +const MDXRenderer = ({ mdxContent }: { mdxContent: string }) => { + const [MDXComponent, setMDXComponent] = useState(null); + + useEffect(() => { + const renderContent = async () => { + const compiledMdx = await compileMDX(mdxContent); + const MDXContent = await renderMDX(compiledMdx, components); + setMDXComponent(() => MDXContent); + }; + + renderContent(); + }, [mdxContent]); + + if (!MDXComponent) { + return

      Loading content...

      ; + } + + return ( +
      + +
      + ); +}; + +export default MDXRenderer; diff --git a/dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx b/dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx deleted file mode 100644 index 4f145f6..0000000 --- a/dashboard/src/components/common/MarkdownRenderer/MarkdownRenderer.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react' -import rehypeRaw from 'rehype-raw' -import ReactMarkdown from 'react-markdown' -import remarkGfm from 'remark-gfm' -import './markdown.css' - -interface MarkdownRendererProps { - content: string -} - -export const MarkdownRenderer: React.FC = ({ content }) => { - return - {content} - -} \ No newline at end of file diff --git a/dashboard/src/components/common/MarkdownRenderer/markdown.css b/dashboard/src/components/common/MarkdownRenderer/markdown.css index 637ac96..0b74867 100644 --- a/dashboard/src/components/common/MarkdownRenderer/markdown.css +++ b/dashboard/src/components/common/MarkdownRenderer/markdown.css @@ -1,3 +1,1236 @@ -.markdown { - font-size: var(--chakra-fontSizes-sm) +.markdown-body { + --base-size-4: 0.25rem; + --base-size-8: 0.5rem; + --base-size-16: 1rem; + --base-size-24: 1.5rem; + --base-size-40: 2.5rem; + --base-text-weight-normal: 400; + --base-text-weight-medium: 500; + --base-text-weight-semibold: 600; + --fontStack-monospace: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; + --fgColor-accent: Highlight; + } + /* @media (prefers-color-scheme: dark) { + .markdown-body, [data-theme="dark"] { + color-scheme: dark; + --focus-outlineColor: #1f6feb; + --fgColor-default: #f0f6fc; + --fgColor-muted: #9198a1; + --fgColor-accent: #4493f8; + --fgColor-success: #3fb950; + --fgColor-attention: #d29922; + --fgColor-danger: #f85149; + --fgColor-done: #ab7df8; + --bgColor-default: #0d1117; + --bgColor-muted: #151b23; + --bgColor-neutral-muted: #656c7633; + --bgColor-attention-muted: #bb800926; + --borderColor-default: #3d444d; + --borderColor-muted: #3d444db3; + --borderColor-neutral-muted: #3d444db3; + --borderColor-accent-emphasis: #1f6feb; + --borderColor-success-emphasis: #238636; + --borderColor-attention-emphasis: #9e6a03; + --borderColor-danger-emphasis: #da3633; + --borderColor-done-emphasis: #8957e5; + --color-prettylights-syntax-comment: #9198a1; + --color-prettylights-syntax-constant: #79c0ff; + --color-prettylights-syntax-constant-other-reference-link: #a5d6ff; + --color-prettylights-syntax-entity: #d2a8ff; + --color-prettylights-syntax-storage-modifier-import: #f0f6fc; + --color-prettylights-syntax-entity-tag: #7ee787; + --color-prettylights-syntax-keyword: #ff7b72; + --color-prettylights-syntax-string: #a5d6ff; + --color-prettylights-syntax-variable: #ffa657; + --color-prettylights-syntax-brackethighlighter-unmatched: #f85149; + --color-prettylights-syntax-brackethighlighter-angle: #9198a1; + --color-prettylights-syntax-invalid-illegal-text: #f0f6fc; + --color-prettylights-syntax-invalid-illegal-bg: #8e1519; + --color-prettylights-syntax-carriage-return-text: #f0f6fc; + --color-prettylights-syntax-carriage-return-bg: #b62324; + --color-prettylights-syntax-string-regexp: #7ee787; + --color-prettylights-syntax-markup-list: #f2cc60; + --color-prettylights-syntax-markup-heading: #1f6feb; + --color-prettylights-syntax-markup-italic: #f0f6fc; + --color-prettylights-syntax-markup-bold: #f0f6fc; + --color-prettylights-syntax-markup-deleted-text: #ffdcd7; + --color-prettylights-syntax-markup-deleted-bg: #67060c; + --color-prettylights-syntax-markup-inserted-text: #aff5b4; + --color-prettylights-syntax-markup-inserted-bg: #033a16; + --color-prettylights-syntax-markup-changed-text: #ffdfb6; + --color-prettylights-syntax-markup-changed-bg: #5a1e02; + --color-prettylights-syntax-markup-ignored-text: #f0f6fc; + --color-prettylights-syntax-markup-ignored-bg: #1158c7; + --color-prettylights-syntax-meta-diff-range: #d2a8ff; + --color-prettylights-syntax-sublimelinter-gutter-mark: #3d444d; + } + } */ + @media (prefers-color-scheme: light) { + .markdown-body, [data-theme="light"] { + /* light */ + color-scheme: light; + --focus-outlineColor: #0969da; + --fgColor-default: #1f2328; + --fgColor-muted: #59636e; + --fgColor-accent: #0969da; + --fgColor-success: #1a7f37; + --fgColor-attention: #9a6700; + --fgColor-danger: #d1242f; + --fgColor-done: #8250df; + --bgColor-default: #ffffff; + --bgColor-muted: #f6f8fa; + --bgColor-neutral-muted: #818b981f; + --bgColor-attention-muted: #fff8c5; + --borderColor-default: #d1d9e0; + --borderColor-muted: #d1d9e0b3; + --borderColor-neutral-muted: #d1d9e0b3; + --borderColor-accent-emphasis: #0969da; + --borderColor-success-emphasis: #1a7f37; + --borderColor-attention-emphasis: #9a6700; + --borderColor-danger-emphasis: #cf222e; + --borderColor-done-emphasis: #8250df; + --color-prettylights-syntax-comment: #59636e; + --color-prettylights-syntax-constant: #0550ae; + --color-prettylights-syntax-constant-other-reference-link: #0a3069; + --color-prettylights-syntax-entity: #6639ba; + --color-prettylights-syntax-storage-modifier-import: #1f2328; + --color-prettylights-syntax-entity-tag: #0550ae; + --color-prettylights-syntax-keyword: #cf222e; + --color-prettylights-syntax-string: #0a3069; + --color-prettylights-syntax-variable: #953800; + --color-prettylights-syntax-brackethighlighter-unmatched: #82071e; + --color-prettylights-syntax-brackethighlighter-angle: #59636e; + --color-prettylights-syntax-invalid-illegal-text: #f6f8fa; + --color-prettylights-syntax-invalid-illegal-bg: #82071e; + --color-prettylights-syntax-carriage-return-text: #f6f8fa; + --color-prettylights-syntax-carriage-return-bg: #cf222e; + --color-prettylights-syntax-string-regexp: #116329; + --color-prettylights-syntax-markup-list: #3b2300; + --color-prettylights-syntax-markup-heading: #0550ae; + --color-prettylights-syntax-markup-italic: #1f2328; + --color-prettylights-syntax-markup-bold: #1f2328; + --color-prettylights-syntax-markup-deleted-text: #82071e; + --color-prettylights-syntax-markup-deleted-bg: #ffebe9; + --color-prettylights-syntax-markup-inserted-text: #116329; + --color-prettylights-syntax-markup-inserted-bg: #dafbe1; + --color-prettylights-syntax-markup-changed-text: #953800; + --color-prettylights-syntax-markup-changed-bg: #ffd8b5; + --color-prettylights-syntax-markup-ignored-text: #d1d9e0; + --color-prettylights-syntax-markup-ignored-bg: #0550ae; + --color-prettylights-syntax-meta-diff-range: #8250df; + --color-prettylights-syntax-sublimelinter-gutter-mark: #818b98; + } + } + + .markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + margin: 0; + color: var(--fgColor-default); + background-color: var(--bgColor-default); + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; + font-size: 16px; + line-height: 1.5; + word-wrap: break-word; + scroll-behavior: auto !important; + } + + .markdown-body .octicon { + display: inline-block; + fill: currentColor; + vertical-align: text-bottom; + } + + .markdown-body h1:hover .anchor .octicon-link:before, + .markdown-body h2:hover .anchor .octicon-link:before, + .markdown-body h3:hover .anchor .octicon-link:before, + .markdown-body h4:hover .anchor .octicon-link:before, + .markdown-body h5:hover .anchor .octicon-link:before, + .markdown-body h6:hover .anchor .octicon-link:before { + width: 16px; + height: 16px; + content: ' '; + display: inline-block; + background-color: currentColor; + -webkit-mask-image: url("data:image/svg+xml,"); + mask-image: url("data:image/svg+xml,"); + } + + .markdown-body details, + .markdown-body figcaption, + .markdown-body figure { + display: block; + } + + .markdown-body summary { + display: list-item; + } + + .markdown-body [hidden] { + display: none !important; + } + + .markdown-body a { + background-color: transparent; + color: var(--fgColor-accent); + text-decoration: none; + } + + .markdown-body abbr[title] { + border-bottom: none; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + } + + .markdown-body b, + .markdown-body strong { + font-weight: var(--base-text-weight-semibold, 600); + } + + .markdown-body dfn { + font-style: italic; + } + + .markdown-body h1 { + margin: .67em 0; + font-weight: var(--base-text-weight-semibold, 600); + padding-bottom: .3em; + font-size: 2em; + } + + .markdown-body mark { + background-color: var(--bgColor-attention-muted); + color: var(--fgColor-default); + } + + .markdown-body small { + font-size: 90%; + } + + .markdown-body sub, + .markdown-body sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; + } + + .markdown-body sub { + bottom: -0.25em; + } + + .markdown-body sup { + top: -0.5em; + } + + .markdown-body img { + border-style: none; + max-width: 100%; + box-sizing: content-box; + } + + .markdown-body code, + .markdown-body kbd, + .markdown-body pre, + .markdown-body samp { + font-family: monospace; + font-size: 1em; + } + + .markdown-body figure { + margin: 1em var(--base-size-40); + } + + .markdown-body hr { + box-sizing: content-box; + overflow: hidden; + background: transparent; + height: .25em; + padding: 0; + margin: var(--base-size-24) 0; + background-color: var(--borderColor-default); + border: 0; + } + + .markdown-body input { + font: inherit; + margin: 0; + overflow: visible; + font-family: inherit; + font-size: inherit; + line-height: inherit; + } + + .markdown-body [type=button], + .markdown-body [type=reset], + .markdown-body [type=submit] { + -webkit-appearance: button; + appearance: button; + } + + .markdown-body [type=checkbox], + .markdown-body [type=radio] { + box-sizing: border-box; + padding: 0; + } + + .markdown-body [type=number]::-webkit-inner-spin-button, + .markdown-body [type=number]::-webkit-outer-spin-button { + height: auto; + } + + .markdown-body [type=search]::-webkit-search-cancel-button, + .markdown-body [type=search]::-webkit-search-decoration { + -webkit-appearance: none; + appearance: none; + } + + .markdown-body ::-webkit-input-placeholder { + color: inherit; + opacity: .54; + } + + .markdown-body ::-webkit-file-upload-button { + -webkit-appearance: button; + appearance: button; + font: inherit; + } + + .markdown-body a:hover { + text-decoration: underline; + } + + .markdown-body ::placeholder { + color: var(--fgColor-muted); + opacity: 1; + } + + .markdown-body hr::before { + display: table; + content: ""; + } + + .markdown-body hr::after { + display: table; + clear: both; + content: ""; + } + + .markdown-body table { + border-spacing: 0; + border-collapse: collapse; + display: block; + width: max-content; + max-width: 100%; + overflow: auto; + } + + .markdown-body td, + .markdown-body th { + padding: 0; + } + + .markdown-body details summary { + cursor: pointer; + } + + .markdown-body a:focus, + .markdown-body [role=button]:focus, + .markdown-body input[type=radio]:focus, + .markdown-body input[type=checkbox]:focus { + outline: 2px solid var(--focus-outlineColor); + outline-offset: -2px; + box-shadow: none; + } + + .markdown-body a:focus:not(:focus-visible), + .markdown-body [role=button]:focus:not(:focus-visible), + .markdown-body input[type=radio]:focus:not(:focus-visible), + .markdown-body input[type=checkbox]:focus:not(:focus-visible) { + outline: solid 1px transparent; + } + + .markdown-body a:focus-visible, + .markdown-body [role=button]:focus-visible, + .markdown-body input[type=radio]:focus-visible, + .markdown-body input[type=checkbox]:focus-visible { + outline: 2px solid var(--focus-outlineColor); + outline-offset: -2px; + box-shadow: none; + } + + .markdown-body a:not([class]):focus, + .markdown-body a:not([class]):focus-visible, + .markdown-body input[type=radio]:focus, + .markdown-body input[type=radio]:focus-visible, + .markdown-body input[type=checkbox]:focus, + .markdown-body input[type=checkbox]:focus-visible { + outline-offset: 0; + } + + .markdown-body kbd { + display: inline-block; + padding: var(--base-size-4); + font: 11px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); + line-height: 10px; + color: var(--fgColor-default); + vertical-align: middle; + background-color: var(--bgColor-muted); + border: solid 1px var(--borderColor-neutral-muted); + border-bottom-color: var(--borderColor-neutral-muted); + border-radius: 6px; + box-shadow: inset 0 -1px 0 var(--borderColor-neutral-muted); + } + + .markdown-body h1, + .markdown-body h2, + .markdown-body h3, + .markdown-body h4, + .markdown-body h5, + .markdown-body h6 { + margin-top: var(--base-size-8); + margin-bottom: var(--base-size-8); + font-weight: var(--base-text-weight-semibold, 600); + line-height: 1.25; + } + + .markdown-body h2 { + font-weight: var(--base-text-weight-semibold, 600); + padding-bottom: .3em; + font-size: 1.5em; + + } + + .markdown-body h3 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: 1.25em; + } + + .markdown-body h4 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: 1em; + } + + .markdown-body h5 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: .875em; + } + + .markdown-body h6 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: .85em; + color: var(--fgColor-muted); + } + + .markdown-body p { + margin-top: 0; + margin-bottom: 10px; + } + + .markdown-body blockquote { + margin: 0; + padding: 0 1em; + color: var(--fgColor-muted); + border-left: .25em solid var(--borderColor-default); + } + + .markdown-body ul, + .markdown-body ol { + margin-top: 0; + margin-bottom: 0; + padding-left: 2em; + } + + .markdown-body ol ol, + .markdown-body ul ol { + list-style-type: lower-roman; + } + + .markdown-body ul ul ol, + .markdown-body ul ol ol, + .markdown-body ol ul ol, + .markdown-body ol ol ol { + list-style-type: lower-alpha; + } + + .markdown-body dd { + margin-left: 0; + } + + .markdown-body tt, + .markdown-body code, + .markdown-body samp { + font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); + font-size: 12px; + } + + .markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); + font-size: 12px; + word-wrap: normal; + } + + .markdown-body .octicon { + display: inline-block; + overflow: visible !important; + vertical-align: text-bottom; + fill: currentColor; + } + + .markdown-body input::-webkit-outer-spin-button, + .markdown-body input::-webkit-inner-spin-button { + margin: 0; + -webkit-appearance: none; + appearance: none; + } + + .markdown-body .mr-2 { + margin-right: var(--base-size-8, 8px) !important; + } + + .markdown-body::before { + display: table; + content: ""; + } + + .markdown-body::after { + display: table; + clear: both; + content: ""; + } + + .markdown-body>*:first-child { + margin-top: 0 !important; + } + + .markdown-body>*:last-child { + margin-bottom: 0 !important; + } + + .markdown-body a:not([href]) { + color: inherit; + text-decoration: none; + } + + .markdown-body .absent { + color: var(--fgColor-danger); + } + + .markdown-body .anchor { + float: left; + padding-right: var(--base-size-4); + margin-left: -20px; + line-height: 1; + } + + .markdown-body .anchor:focus { + outline: none; + } + + .markdown-body p, + .markdown-body blockquote, + .markdown-body ul, + .markdown-body ol, + .markdown-body dl, + .markdown-body table, + .markdown-body pre, + .markdown-body details { + margin-top: 0; + margin-bottom: var(--base-size-16); + } + + .markdown-body blockquote>:first-child { + margin-top: 0; + } + + .markdown-body blockquote>:last-child { + margin-bottom: 0; + } + + .markdown-body h1 .octicon-link, + .markdown-body h2 .octicon-link, + .markdown-body h3 .octicon-link, + .markdown-body h4 .octicon-link, + .markdown-body h5 .octicon-link, + .markdown-body h6 .octicon-link { + color: var(--fgColor-default); + vertical-align: middle; + visibility: hidden; + } + + .markdown-body h1:hover .anchor, + .markdown-body h2:hover .anchor, + .markdown-body h3:hover .anchor, + .markdown-body h4:hover .anchor, + .markdown-body h5:hover .anchor, + .markdown-body h6:hover .anchor { + text-decoration: none; + } + + .markdown-body h1:hover .anchor .octicon-link, + .markdown-body h2:hover .anchor .octicon-link, + .markdown-body h3:hover .anchor .octicon-link, + .markdown-body h4:hover .anchor .octicon-link, + .markdown-body h5:hover .anchor .octicon-link, + .markdown-body h6:hover .anchor .octicon-link { + visibility: visible; + } + + .markdown-body h1 tt, + .markdown-body h1 code, + .markdown-body h2 tt, + .markdown-body h2 code, + .markdown-body h3 tt, + .markdown-body h3 code, + .markdown-body h4 tt, + .markdown-body h4 code, + .markdown-body h5 tt, + .markdown-body h5 code, + .markdown-body h6 tt, + .markdown-body h6 code { + padding: 0 .2em; + font-size: inherit; + } + + .markdown-body summary h1, + .markdown-body summary h2, + .markdown-body summary h3, + .markdown-body summary h4, + .markdown-body summary h5, + .markdown-body summary h6 { + display: inline-block; + } + + .markdown-body summary h1 .anchor, + .markdown-body summary h2 .anchor, + .markdown-body summary h3 .anchor, + .markdown-body summary h4 .anchor, + .markdown-body summary h5 .anchor, + .markdown-body summary h6 .anchor { + margin-left: -40px; + } + + .markdown-body summary h1, + .markdown-body summary h2 { + padding-bottom: 0; + border-bottom: 0; + } + + .markdown-body ul.no-list, + .markdown-body ol.no-list { + padding: 0; + list-style-type: none; + } + + .markdown-body ol[type="a s"] { + list-style-type: lower-alpha; + } + + .markdown-body ol[type="A s"] { + list-style-type: upper-alpha; + } + + .markdown-body ol[type="i s"] { + list-style-type: lower-roman; + } + + .markdown-body ol[type="I s"] { + list-style-type: upper-roman; + } + + .markdown-body ol[type="1"] { + list-style-type: decimal; + } + + .markdown-body div>ol:not([type]) { + list-style-type: decimal; + } + + .markdown-body ul ul, + .markdown-body ul ol, + .markdown-body ol ol, + .markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; + } + + .markdown-body li>p { + margin-top: var(--base-size-16); + } + + .markdown-body li+li { + margin-top: .25em; + } + + .markdown-body dl { + padding: 0; + } + + .markdown-body dl dt { + padding: 0; + margin-top: var(--base-size-16); + font-size: 1em; + font-style: italic; + font-weight: var(--base-text-weight-semibold, 600); + } + + .markdown-body dl dd { + padding: 0 var(--base-size-16); + margin-bottom: var(--base-size-16); + } + + .markdown-body table th { + font-weight: var(--base-text-weight-semibold, 600); + } + + .markdown-body table th, + .markdown-body table td { + padding: 6px 13px; + border: 1px solid var(--borderColor-default); + } + + .markdown-body table td>:last-child { + margin-bottom: 0; + } + + .markdown-body table tr { + background-color: var(--bgColor-default); + border-top: 1px solid var(--borderColor-muted); + } + + .markdown-body table tr:nth-child(2n) { + background-color: var(--bgColor-muted); + } + + .markdown-body table img { + background-color: transparent; + } + + .markdown-body img[align=right] { + padding-left: 20px; + } + + .markdown-body img[align=left] { + padding-right: 20px; + } + + .markdown-body .emoji { + max-width: none; + vertical-align: text-top; + background-color: transparent; + } + + .markdown-body span.frame { + display: block; + overflow: hidden; + } + + .markdown-body span.frame>span { + display: block; + float: left; + width: auto; + padding: 7px; + margin: 13px 0 0; + overflow: hidden; + border: 1px solid var(--borderColor-default); + } + + .markdown-body span.frame span img { + display: block; + float: left; + } + + .markdown-body span.frame span span { + display: block; + padding: 5px 0 0; + clear: both; + color: var(--fgColor-default); + } + + .markdown-body span.align-center { + display: block; + overflow: hidden; + clear: both; + } + + .markdown-body span.align-center>span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: center; + } + + .markdown-body span.align-center span img { + margin: 0 auto; + text-align: center; + } + + .markdown-body span.align-right { + display: block; + overflow: hidden; + clear: both; + } + + .markdown-body span.align-right>span { + display: block; + margin: 13px 0 0; + overflow: hidden; + text-align: right; + } + + .markdown-body span.align-right span img { + margin: 0; + text-align: right; + } + + .markdown-body span.float-left { + display: block; + float: left; + margin-right: 13px; + overflow: hidden; + } + + .markdown-body span.float-left span { + margin: 13px 0 0; + } + + .markdown-body span.float-right { + display: block; + float: right; + margin-left: 13px; + overflow: hidden; + } + + .markdown-body span.float-right>span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: right; + } + + .markdown-body code, + .markdown-body tt { + padding: .2em .4em; + margin: 0; + font-size: 85%; + white-space: break-spaces; + background-color: var(--bgColor-neutral-muted); + border-radius: 6px; + } + + .markdown-body code br, + .markdown-body tt br { + display: none; + } + + .markdown-body del code { + text-decoration: inherit; + } + + .markdown-body samp { + font-size: 85%; + } + + .markdown-body pre code { + font-size: 100%; + } + + .markdown-body pre>code { + padding: 0; + margin: 0; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; + } + + .markdown-body .highlight { + margin-bottom: var(--base-size-16); + } + + .markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; + } + + .markdown-body .highlight pre, + .markdown-body pre { + padding: var(--base-size-16); + overflow: auto; + font-size: 85%; + line-height: 1.45; + color: var(--fgColor-default); + background-color: var(--bgColor-muted); + border-radius: 6px; + } + + .markdown-body pre code, + .markdown-body pre tt { + display: inline; + max-width: auto; + padding: 0; + margin: 0; + overflow: visible; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; + } + + .markdown-body .csv-data td, + .markdown-body .csv-data th { + padding: 5px; + overflow: hidden; + font-size: 12px; + line-height: 1; + text-align: left; + white-space: nowrap; + } + + .markdown-body .csv-data .blob-num { + padding: 10px var(--base-size-8) 9px; + text-align: right; + background: var(--bgColor-default); + border: 0; + } + + .markdown-body .csv-data tr { + border-top: 0; + } + + .markdown-body .csv-data th { + font-weight: var(--base-text-weight-semibold, 600); + background: var(--bgColor-muted); + border-top: 0; + } + + .markdown-body [data-footnote-ref]::before { + content: "["; + } + + .markdown-body [data-footnote-ref]::after { + content: "]"; + } + + .markdown-body .footnotes { + font-size: 12px; + color: var(--fgColor-muted); + border-top: 1px solid var(--borderColor-default); + } + + .markdown-body .footnotes ol { + padding-left: var(--base-size-16); + } + + .markdown-body .footnotes ol ul { + display: inline-block; + padding-left: var(--base-size-16); + margin-top: var(--base-size-16); + } + + .markdown-body .footnotes li { + position: relative; + } + + .markdown-body .footnotes li:target::before { + position: absolute; + top: calc(var(--base-size-8)*-1); + right: calc(var(--base-size-8)*-1); + bottom: calc(var(--base-size-8)*-1); + left: calc(var(--base-size-24)*-1); + pointer-events: none; + content: ""; + border: 2px solid var(--borderColor-accent-emphasis); + border-radius: 6px; + } + + .markdown-body .footnotes li:target { + color: var(--fgColor-default); + } + + .markdown-body .footnotes .data-footnote-backref g-emoji { + font-family: monospace; + } + + .markdown-body .pl-c { + color: var(--color-prettylights-syntax-comment); + } + + .markdown-body .pl-c1, + .markdown-body .pl-s .pl-v { + color: var(--color-prettylights-syntax-constant); + } + + .markdown-body .pl-e, + .markdown-body .pl-en { + color: var(--color-prettylights-syntax-entity); + } + + .markdown-body .pl-smi, + .markdown-body .pl-s .pl-s1 { + color: var(--color-prettylights-syntax-storage-modifier-import); + } + + .markdown-body .pl-ent { + color: var(--color-prettylights-syntax-entity-tag); + } + + .markdown-body .pl-k { + color: var(--color-prettylights-syntax-keyword); + } + + .markdown-body .pl-s, + .markdown-body .pl-pds, + .markdown-body .pl-s .pl-pse .pl-s1, + .markdown-body .pl-sr, + .markdown-body .pl-sr .pl-cce, + .markdown-body .pl-sr .pl-sre, + .markdown-body .pl-sr .pl-sra { + color: var(--color-prettylights-syntax-string); + } + + .markdown-body .pl-v, + .markdown-body .pl-smw { + color: var(--color-prettylights-syntax-variable); + } + + .markdown-body .pl-bu { + color: var(--color-prettylights-syntax-brackethighlighter-unmatched); + } + + .markdown-body .pl-ii { + color: var(--color-prettylights-syntax-invalid-illegal-text); + background-color: var(--color-prettylights-syntax-invalid-illegal-bg); + } + + .markdown-body .pl-c2 { + color: var(--color-prettylights-syntax-carriage-return-text); + background-color: var(--color-prettylights-syntax-carriage-return-bg); + } + + .markdown-body .pl-sr .pl-cce { + font-weight: bold; + color: var(--color-prettylights-syntax-string-regexp); + } + + .markdown-body .pl-ml { + color: var(--color-prettylights-syntax-markup-list); + } + + .markdown-body .pl-mh, + .markdown-body .pl-mh .pl-en, + .markdown-body .pl-ms { + font-weight: bold; + color: var(--color-prettylights-syntax-markup-heading); + } + + .markdown-body .pl-mi { + font-style: italic; + color: var(--color-prettylights-syntax-markup-italic); + } + + .markdown-body .pl-mb { + font-weight: bold; + color: var(--color-prettylights-syntax-markup-bold); + } + + .markdown-body .pl-md { + color: var(--color-prettylights-syntax-markup-deleted-text); + background-color: var(--color-prettylights-syntax-markup-deleted-bg); + } + + .markdown-body .pl-mi1 { + color: var(--color-prettylights-syntax-markup-inserted-text); + background-color: var(--color-prettylights-syntax-markup-inserted-bg); + } + + .markdown-body .pl-mc { + color: var(--color-prettylights-syntax-markup-changed-text); + background-color: var(--color-prettylights-syntax-markup-changed-bg); + } + + .markdown-body .pl-mi2 { + color: var(--color-prettylights-syntax-markup-ignored-text); + background-color: var(--color-prettylights-syntax-markup-ignored-bg); + } + + .markdown-body .pl-mdr { + font-weight: bold; + color: var(--color-prettylights-syntax-meta-diff-range); + } + + .markdown-body .pl-ba { + color: var(--color-prettylights-syntax-brackethighlighter-angle); + } + + .markdown-body .pl-sg { + color: var(--color-prettylights-syntax-sublimelinter-gutter-mark); + } + + .markdown-body .pl-corl { + text-decoration: underline; + color: var(--color-prettylights-syntax-constant-other-reference-link); + } + + .markdown-body [role=button]:focus:not(:focus-visible), + .markdown-body [role=tabpanel][tabindex="0"]:focus:not(:focus-visible), + .markdown-body button:focus:not(:focus-visible), + .markdown-body summary:focus:not(:focus-visible), + .markdown-body a:focus:not(:focus-visible) { + outline: none; + box-shadow: none; + } + + .markdown-body [tabindex="0"]:focus:not(:focus-visible), + .markdown-body details-dialog:focus:not(:focus-visible) { + outline: none; + } + + .markdown-body g-emoji { + display: inline-block; + min-width: 1ch; + font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; + font-size: 1em; + font-style: normal !important; + font-weight: var(--base-text-weight-normal, 400); + line-height: 1; + vertical-align: -0.075em; + } + + .markdown-body g-emoji img { + width: 1em; + height: 1em; + } + + .markdown-body .task-list-item { + list-style-type: none; + } + + .markdown-body .task-list-item label { + font-weight: var(--base-text-weight-normal, 400); + } + + .markdown-body .task-list-item.enabled label { + cursor: pointer; + } + + .markdown-body .task-list-item+.task-list-item { + margin-top: var(--base-size-4); + } + + .markdown-body .task-list-item .handle { + display: none; + } + + .markdown-body .task-list-item-checkbox { + margin: 0 .2em .25em -1.4em; + vertical-align: middle; + } + + .markdown-body ul:dir(rtl) .task-list-item-checkbox { + margin: 0 -1.6em .25em .2em; + } + + .markdown-body ol:dir(rtl) .task-list-item-checkbox { + margin: 0 -1.6em .25em .2em; + } + + .markdown-body .contains-task-list:hover .task-list-item-convert-container, + .markdown-body .contains-task-list:focus-within .task-list-item-convert-container { + display: block; + width: auto; + height: 24px; + overflow: visible; + clip: auto; + } + + .markdown-body ::-webkit-calendar-picker-indicator { + filter: invert(50%); + } + + .markdown-body .markdown-alert { + padding: var(--base-size-8) var(--base-size-16); + margin-bottom: var(--base-size-16); + color: inherit; + border-left: .25em solid var(--borderColor-default); + } + + .markdown-body .markdown-alert>:first-child { + margin-top: 0; + } + + .markdown-body .markdown-alert>:last-child { + margin-bottom: 0; + } + + .markdown-body .markdown-alert .markdown-alert-title { + display: flex; + font-weight: var(--base-text-weight-medium, 500); + align-items: center; + line-height: 1; + } + + .markdown-body .markdown-alert.markdown-alert-note { + border-left-color: var(--borderColor-accent-emphasis); + } + + .markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title { + color: var(--fgColor-accent); + } + + .markdown-body .markdown-alert.markdown-alert-important { + border-left-color: var(--borderColor-done-emphasis); + } + + .markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title { + color: var(--fgColor-done); + } + + .markdown-body .markdown-alert.markdown-alert-warning { + border-left-color: var(--borderColor-attention-emphasis); + } + + .markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title { + color: var(--fgColor-attention); + } + + .markdown-body .markdown-alert.markdown-alert-tip { + border-left-color: var(--borderColor-success-emphasis); + } + + .markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title { + color: var(--fgColor-success); + } + + .markdown-body .markdown-alert.markdown-alert-caution { + border-left-color: var(--borderColor-danger-emphasis); + } + + .markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title { + color: var(--fgColor-danger); + } + + .markdown-body>*:first-child>.heading-element:first-child { + margin-top: 0 !important; + } + +.markdown-body ol, +.markdown-body ul { + list-style: initial; /* Ensure list markers are displayed */ + padding-left: 1.5em; /* Add padding to the left for indentation */ + margin-bottom: 1em; /* Add margin to the bottom for spacing */ +} + +.markdown-body ol { + list-style-type: decimal; /* Use numbers for ordered lists */ +} + +.markdown-body ul { + list-style-type: disc; /* Use dots for unordered lists */ +} + +.markdown-body li { + margin-bottom: 0.5em; /* Add margin to the bottom of list items */ } \ No newline at end of file From 01d7c0e0e7ccef3cb7029933f169cc2f68f4a1dd Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 6 Dec 2024 17:47:18 +0530 Subject: [PATCH 092/110] feat: Add CustomCodeBlock and CustomHeading components for enhanced MDX support --- .../custommdxcomponent/CustomCodeBlock.tsx | 56 +++++++++++++++++++ .../custommdxcomponent/CustomHeading.tsx | 25 +++++++++ 2 files changed, 81 insertions(+) create mode 100644 dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx create mode 100644 dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx diff --git a/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx new file mode 100644 index 0000000..da882f9 --- /dev/null +++ b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx @@ -0,0 +1,56 @@ +import { Button } from "@/components/ui/button"; +import { useToast } from "@/components/ui/use-toast"; +import { CheckIcon, CopyIcon } from "@radix-ui/react-icons"; +import { useState } from "react"; + +// Custom Code Block Component +const CustomCodeBlock = ({ children }: { children: React.ReactNode }) => { + const [isCopied, setIsCopied] = useState(false); + + const { toast } = useToast() + + const copyToClipboardWithMeta = async () => { + try { + // @ts-expect-error + await navigator.clipboard.writeText(children?.props?.children) + .then(() => toast({ description: "Copied to clipboard", duration: 1500 })).then(() => { + setTimeout(() => { + setIsCopied(false) + }, 2000) + }) + } + catch (err) { console.error("Failed to copy: ", err) } + } + + + return ( +
      +
      +                {children}
      +            
      + +
      + ); +}; + +export default CustomCodeBlock; + diff --git a/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx new file mode 100644 index 0000000..735e01a --- /dev/null +++ b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx @@ -0,0 +1,25 @@ +import { Button } from "@/components/ui/button"; +import React from "react"; +import { MdLink } from "react-icons/md"; + +const CustomHeading = ({ id, children, as }: { id: string, children: React.ReactNode, as: string }) => { + return ( +
      + {React.createElement(as, { id }, children)} + + + +
      + ); +}; + +export default CustomHeading; \ No newline at end of file From 7e5b6c0f168a65330e37a58ca3f3d9807947f430 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 6 Dec 2024 17:48:00 +0530 Subject: [PATCH 093/110] feat: Docs Page with sidebar, navbar, footer, Pagecontent --- dashboard/src/pages/features/docs/Footer.tsx | 81 +++++++++-------- dashboard/src/pages/features/docs/Navbar.tsx | 60 +++++++------ .../src/pages/features/docs/PageContent.tsx | 59 +++++++++++++ dashboard/src/pages/features/docs/Sidebar.tsx | 87 +++++++++++++------ .../src/pages/features/docs/ViewDocs.tsx | 45 +++++----- 5 files changed, 212 insertions(+), 120 deletions(-) create mode 100644 dashboard/src/pages/features/docs/PageContent.tsx diff --git a/dashboard/src/pages/features/docs/Footer.tsx b/dashboard/src/pages/features/docs/Footer.tsx index 0d82d9c..fbf480a 100644 --- a/dashboard/src/pages/features/docs/Footer.tsx +++ b/dashboard/src/pages/features/docs/Footer.tsx @@ -18,51 +18,50 @@ export const Footer = ({ commit_docs, footer_items }: { commit_docs: Omit -
      -
      - {/* Logo */} -
      - {commit_docs.light_mode_logo && ( - Logo - )} - {commit_docs.header && ( -

      {commit_docs.header}

      - )} -
      +
      +
      +
      +
      +
      + {commit_docs.light_mode_logo && ( + Logo + )} + {commit_docs.header && ( +

      {commit_docs.header}

      + )} +
      - {/* Footer sections */} -
      - {Object.keys(footer_items).map((section) => ( -
      -
      {section}
      - -
      - ))} -
      +
      + {Object.keys(footer_items).map((section) => ( +
      +
      {section}
      + +
      + ))} +
      - {/* Social media icons */} -
      - {Object.entries(social_links).map(([field, url]) => - url ? : null - )} +
      + {Object.entries(social_links).map(([field, url]) => + url ? : null + )} +
      -
      -
      - Copyright © {new Date().getFullYear()} {commit_docs.company_name}, Build with commit. +
      + Copyright © {new Date().getFullYear()} {commit_docs.company_name}, Build with commit. +
      ) diff --git a/dashboard/src/pages/features/docs/Navbar.tsx b/dashboard/src/pages/features/docs/Navbar.tsx index 5cb4bc1..2ef3f35 100644 --- a/dashboard/src/pages/features/docs/Navbar.tsx +++ b/dashboard/src/pages/features/docs/Navbar.tsx @@ -8,33 +8,41 @@ import { RiSearchLine } from "react-icons/ri"; export const Navbar = ({ navbar_items }: { navbar_items: Record }) => { return ( -
      - {/* Left side: Search bar */} -
      - - -
      - - {/* Right side: Navbar items */} -
      - {Object.keys(navbar_items).reverse().map((key) => ( -
      - {navbar_items[key]?.type === 'Button' ? ( - - ) : ( - - )} +
      +
      +
      +
      +
      +
      + {/* Left side: Search bar */} +
      + + +
      + {/* Right side: Navbar items */} +
      + {Object.keys(navbar_items).reverse().map((key) => ( +
      + {navbar_items[key]?.type === 'Button' ? ( + + ) : ( + + )} +
      + ))} +
      +
      - ))} +
      ); diff --git a/dashboard/src/pages/features/docs/PageContent.tsx b/dashboard/src/pages/features/docs/PageContent.tsx new file mode 100644 index 0000000..0a7c476 --- /dev/null +++ b/dashboard/src/pages/features/docs/PageContent.tsx @@ -0,0 +1,59 @@ +import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; +import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; +import MDXRenderer from "@/components/common/MarkdownRenderer/MDX"; +import { OnThisPage } from "@/components/features/documentation/OnThisPage"; +import { CommitDocsPage } from "@/types/commit/CommitDocsPage"; +import { useFrappeGetCall } from "frappe-react-sdk"; + + +export interface PageData { + doc: CommitDocsPage + toc_obj: TocObj +} + +export type TocChildren = { + [key: string]: TocItem; +}; + +export type TocItem = { + name: string; + children: TocChildren; +}; + +export interface TocObj { + [key: string]: TocItem; +}; + +export const PageContent = ({ selectedEndpoint, route_map }: { selectedEndpoint: string, route_map: Record }) => { + + const selectedEndpointRoute = route_map[selectedEndpoint]; + + const { data, error, isLoading } = useFrappeGetCall<{ message: PageData; }>("commit.commit.doctype.commit_docs_page.commit_docs_page.get_commit_docs_page", { + name: selectedEndpointRoute + }); + + if (isLoading) { + return ; + } + + if (error) { + return
      + +
      + } + + if (data && data?.message) { + return ( +
      +
      +
      {data?.message?.doc?.title}
      + +
      +
      + +
      +
      + ) + } + +} \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/Sidebar.tsx b/dashboard/src/pages/features/docs/Sidebar.tsx index 404e464..73fedb8 100644 --- a/dashboard/src/pages/features/docs/Sidebar.tsx +++ b/dashboard/src/pages/features/docs/Sidebar.tsx @@ -7,35 +7,58 @@ import { MdKeyboardArrowDown, MdKeyboardArrowRight } from "react-icons/md"; import classNames from "classnames"; import { cn } from "@/lib/utils"; -export const Sidebar = ({ commit_docs, sidebar_items, selectedEndpoint, setSelectedEndpoint }: { commit_docs: Omit, sidebar_items: Record, selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void }) => { - +export const Sidebar = ({ + commit_docs, + sidebar_items, + selectedEndpoint, + setSelectedEndpoint, +}: { + commit_docs: Omit; + sidebar_items: Record; + selectedEndpoint: string; + setSelectedEndpoint: (selectedEndpoint: string) => void; +}) => { return ( -
      -
      - {commit_docs.light_mode_logo && logo} - {commit_docs.header &&
      {commit_docs.header}
      } -
      -
      +
      +
      + {/* Header */} +
      + {commit_docs.light_mode_logo && ( + logo + )} + {commit_docs.header &&
      {commit_docs.header}
      } +
      + {/* Sidebar Items */} {Object.keys(sidebar_items).map((key) => ( - + ))}
      - ) -} + ); +}; const SidebarGroup = ({ groupName, items, selectedEndpoint, setSelectedEndpoint }: { groupName: string, items: DocsSidebarItem[], selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void }) => { const [isExpanded, setIsExpanded] = useState(true); return ( -
      -
      setIsExpanded(!isExpanded)}> - {groupName} +
      +
      setIsExpanded(!isExpanded)}> +
      {groupName}
      {isExpanded ? : }
      - {isExpanded && items.map((item) => ( - - ))} + {isExpanded && items.length > 0 && ( +
        + {items.map((item) => ( + + ))} +
      + )}
      ) } @@ -45,17 +68,23 @@ const SidebarItem = ({ item, selectedEndpoint, setSelectedEndpoint, className, l if (item.is_group_page && item.group_items?.length) { const [isExpanded, setIsExpanded] = useState(false); return ( -
      +
    • - {isExpanded && item.group_items.map((groupItem) => ( - - ))} -
    • + {isExpanded && item.group_items.length && +
        + {item.group_items.map((groupItem) => ( + + ))} +
      + } + ) } return ( - +
    • + +
    • ) } @@ -85,14 +114,16 @@ const SidebarTitle = ({ item, selectedEndpoint, setSelectedEndpoint, className, return (
      setIsExpanded && setIsExpanded(!isExpanded) : () => setSelectedEndpoint(item.route)} > -
      +
      - {item.icon && } + {item.icon && } {item.badge && {item.badge}}
      diff --git a/dashboard/src/pages/features/docs/ViewDocs.tsx b/dashboard/src/pages/features/docs/ViewDocs.tsx index 208322e..5a377d4 100644 --- a/dashboard/src/pages/features/docs/ViewDocs.tsx +++ b/dashboard/src/pages/features/docs/ViewDocs.tsx @@ -7,6 +7,7 @@ import { useEffect, useState } from "react"; import { Sidebar } from "./Sidebar"; import { Navbar } from "./Navbar"; import { Footer } from "./Footer"; +import { PageContent } from "./PageContent"; const ViewDocs = () => { const { ID } = useParams(); @@ -64,37 +65,31 @@ const ViewDocsDetails = ({ ID }: { ID: string }) => { if (data && data?.message) { return ( -
      -
      +
      +
      + +
      +
      {/* Sidebar */} -
      -
      - -
      -
      - - {/* Vertical Divider */} -
      + {/* Main Content */} -
      - {/* Fixed Navbar */} -
      - +
      +
      +
      - - {/* Content area with top padding to accommodate fixed Navbar */} -
      {/* Adjust '60px' based on Navbar height */} - {/* Page Content */} -
      -
      +
      +
      +
      ); } From 379a41b093233f5cf803af48b981e933b9465a45 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 6 Dec 2024 17:48:05 +0530 Subject: [PATCH 094/110] feat: Add OnThisPage component for table of contents navigation --- .../features/documentation/OnThisPage.tsx | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 dashboard/src/components/features/documentation/OnThisPage.tsx diff --git a/dashboard/src/components/features/documentation/OnThisPage.tsx b/dashboard/src/components/features/documentation/OnThisPage.tsx new file mode 100644 index 0000000..014218d --- /dev/null +++ b/dashboard/src/components/features/documentation/OnThisPage.tsx @@ -0,0 +1,64 @@ +import { cn } from "@/lib/utils"; +import { TocItem, TocObj } from "@/pages/features/docs/PageContent"; +import { useEffect } from "react"; +import { HiOutlineMenuAlt1 } from "react-icons/hi"; + +export const OnThisPage = ({ toc_obj }: { toc_obj: TocObj }) => { + + useEffect(() => { + const hash = window.location.hash; + if (!hash) { + const firstKey = Object.keys(toc_obj)[0]?.replace(/[^\w\s-]/g, '').replace(/\s+/g, '-').toLowerCase(); + window.location.hash = `#${firstKey}`; + } + }, [toc_obj]); + + if (Object.keys(toc_obj).length > 0) { + + const hash = window.location.hash; + return ( +
      +
      + + On This Page +
      +
        + {Object.keys(toc_obj).map((key) => ( + + ))} +
      +
      + ); + } + return null; +}; + +const TocItemComponent = ({ item, hash }: { item: TocItem, hash: string }) => { + // fetch the hash from url and compare with the item name + // if it matches, add a class to the anchor tag + + const sanitizeName = (name: string) => { + return name.replace(/[^\w\s-]/g, '').replace(/\s+/g, '-').toLowerCase(); + }; + + const isActive = hash === `#${sanitizeName(item.name)}`; + + return ( +
    • + + {item.name.replace(/[^\w\s-]/g, '')} + + {Object.keys(item.children).length > 0 && ( +
        + {Object.keys(item.children).map((key) => ( + + ))} +
      + )} +
    • + ); +}; From 6254e6887336689f7ba753910477fd5520c73d34 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 10 Dec 2024 13:43:37 +0530 Subject: [PATCH 095/110] feat: Implement DocsPage component and route navigation for commit documentation --- .../commit/doctype/commit_docs/commit_docs.py | 21 ++++++++ dashboard/src/App.tsx | 4 +- .../src/pages/features/docs/DocsPage.tsx | 48 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 dashboard/src/pages/features/docs/DocsPage.tsx diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py index ea9bfba..5f493ae 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.py +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -283,3 +283,24 @@ def get_group_items(commit_docs_page): route_map[commit_docs_page.route] = commit_docs_page.name return sidebar_obj, route_map + + +@frappe.whitelist(allow_guest=True) +def get_first_page_route(route:str): + ''' + Get the First Page Route from the Commit Docs + ''' + if frappe.db.exists('Commit Docs',{'route':route}): + commit_docs = frappe.get_doc('Commit Docs',{'route':route}) + found = False + for sidebar in commit_docs.sidebar: + commit_docs_page = frappe.get_doc('Commit Docs Page',sidebar.docs_page) + if commit_docs_page.published: + found = True + return commit_docs_page.route + + if not found: + return frappe.throw('Create and Publish the First Page') + + else: + return frappe.throw('Commit Docs Not Found') diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index fe5e6f1..d36d6e1 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -7,6 +7,7 @@ import { AppAPIViewerContainer } from './pages/features/api_viewer/AppAPIViewer' import { CreateERD } from './pages/features/erd/meta/CreateERDForMeta' import ViewDocs from './pages/features/docs/ViewDocs' import { PageNotFound } from './components/common/PageNotFound/PageNotFound' +import DocsPage from './pages/features/docs/DocsPage' function App() { @@ -38,7 +39,8 @@ function App() { } /> } /> } /> - } /> + } /> + } /> } /> {/* */} diff --git a/dashboard/src/pages/features/docs/DocsPage.tsx b/dashboard/src/pages/features/docs/DocsPage.tsx new file mode 100644 index 0000000..bb08eb1 --- /dev/null +++ b/dashboard/src/pages/features/docs/DocsPage.tsx @@ -0,0 +1,48 @@ +import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; +import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; +import { useFrappeGetCall } from "frappe-react-sdk"; +import { useNavigate, useParams } from "react-router-dom"; + + +const DocsPage = () => { + + const { ID } = useParams(); + + if (ID) { + return ; + } + return null; +} + +export const NavigateToFirstPage = ({ ID }: { ID: string }) => { + + const navigate = useNavigate(); + + const { error, isLoading } = useFrappeGetCall<{ + message: string + }>("commit.commit.doctype.commit_docs.commit_docs.get_first_page_route", + { + route: ID, + }, + undefined, + { + revalidateOnFocus: false, + revalidateIfStale: false, + onSuccess: (data) => { + if (data?.message) { + navigate(data.message); + } + } + }); + + if (isLoading) { + + } + if (error) { + return + } + + return null +} + +export default DocsPage \ No newline at end of file From b7c963ca3832791d2d6f9a376c586d7078269bd7 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 10 Dec 2024 13:44:00 +0530 Subject: [PATCH 096/110] feat: Enhance ViewDocs component to support pageID and simplify state management --- .../custommdxcomponent/CustomCodeBlock.tsx | 2 +- .../src/pages/features/docs/ViewDocs.tsx | 40 +++++-------------- 2 files changed, 11 insertions(+), 31 deletions(-) diff --git a/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx index da882f9..20cfee9 100644 --- a/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx +++ b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx @@ -24,7 +24,7 @@ const CustomCodeBlock = ({ children }: { children: React.ReactNode }) => { return ( -
      +
                       {children}
                   
      diff --git a/dashboard/src/pages/features/docs/ViewDocs.tsx b/dashboard/src/pages/features/docs/ViewDocs.tsx index 5a377d4..9c06ffb 100644 --- a/dashboard/src/pages/features/docs/ViewDocs.tsx +++ b/dashboard/src/pages/features/docs/ViewDocs.tsx @@ -3,23 +3,21 @@ import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoade import { useFrappeGetCall } from "frappe-react-sdk"; import { useNavigate, useParams } from "react-router-dom"; import { Docs } from "./docs"; -import { useEffect, useState } from "react"; import { Sidebar } from "./Sidebar"; import { Navbar } from "./Navbar"; import { Footer } from "./Footer"; import { PageContent } from "./PageContent"; const ViewDocs = () => { - const { ID } = useParams(); + const { ID, pageID } = useParams(); - if (ID) { - return ; + if (ID && pageID) { + return ; } return null; }; -const ViewDocsDetails = ({ ID }: { ID: string }) => { - const [selectedendpoint, setSelectedEndpoint] = useState(""); +const ViewDocsDetails = ({ ID, pageID }: { ID: string, pageID: string }) => { const navigate = useNavigate(); const { data, error, isLoading } = useFrappeGetCall<{ @@ -32,29 +30,11 @@ const ViewDocsDetails = ({ ID }: { ID: string }) => { { revalidateOnFocus: false, revalidateIfStale: false, - onSuccess: (d: { message: Docs }) => { - if (!selectedendpoint) { - setSelectedEndpoint(d.message.sidebar_items[Object.keys(d.message.sidebar_items)[0]][0].route); - } - }, }); - useEffect(() => { - const searchParams = new URLSearchParams(window.location.search); - const endpointFromURL = searchParams.get("page"); - - if (endpointFromURL) { - setSelectedEndpoint(endpointFromURL); - } - }, []); - - useEffect(() => { - if (selectedendpoint) { - const searchParams = new URLSearchParams(window.location.search); - searchParams.set("page", selectedendpoint); - navigate({ search: searchParams.toString() }, { replace: true }); - } - }, [selectedendpoint, navigate]); + const onPageChange = (pageID: string) => { + navigate(`/docs/${ID}/${pageID}`); + } if (isLoading) { return ; @@ -75,15 +55,15 @@ const ViewDocsDetails = ({ ID }: { ID: string }) => { {/* Main Content */}
      - +
      From 95b84a1d21b7cedc372c23282a38d1821cf1af84 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 10 Dec 2024 13:44:20 +0530 Subject: [PATCH 097/110] feat: enhance CustomHeading component with scroll behavior --- .../common/MarkdownRenderer/markdown.css | 4 +- .../custommdxcomponent/CustomHeading.tsx | 41 ++++++++++++++++++- .../features/documentation/OnThisPage.tsx | 19 +++------ 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/dashboard/src/components/common/MarkdownRenderer/markdown.css b/dashboard/src/components/common/MarkdownRenderer/markdown.css index 0b74867..d452b8d 100644 --- a/dashboard/src/components/common/MarkdownRenderer/markdown.css +++ b/dashboard/src/components/common/MarkdownRenderer/markdown.css @@ -388,8 +388,8 @@ .markdown-body h4, .markdown-body h5, .markdown-body h6 { - margin-top: var(--base-size-8); - margin-bottom: var(--base-size-8); + margin-top: var(--base-size-16); + margin-bottom: var(--base-size-16); font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; } diff --git a/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx index 735e01a..15a5490 100644 --- a/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx +++ b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx @@ -1,10 +1,47 @@ import { Button } from "@/components/ui/button"; -import React from "react"; +import React, { useEffect, useRef } from "react"; import { MdLink } from "react-icons/md"; const CustomHeading = ({ id, children, as }: { id: string, children: React.ReactNode, as: string }) => { + const headingRef = useRef(null); + + useEffect(() => { + const handleHashChange = () => { + if (window.location.hash === `#${id}` && headingRef.current) { + const offset = 74; // Adjust this value as needed + const bodyRect = document.body.getBoundingClientRect().top; + const elementRect = headingRef.current.getBoundingClientRect().top; + const elementPosition = elementRect - bodyRect; + const offsetPosition = elementPosition - offset; + + window.scrollTo({ + top: offsetPosition, + }); + } + }; + + window.addEventListener("hashchange", handleHashChange, false); + + // Check if the current hash matches the id on initial load + if (window.location.hash === `#${id}` && headingRef.current) { + const offset = 74; // Adjust this value as needed + const bodyRect = document.body.getBoundingClientRect().top; + const elementRect = headingRef.current.getBoundingClientRect().top; + const elementPosition = elementRect - bodyRect; + const offsetPosition = elementPosition - offset; + + window.scrollTo({ + top: offsetPosition, + }); + } + + return () => { + window.removeEventListener("hashchange", handleHashChange, false); + }; + }, [id]); + return ( - @@ -33,7 +24,7 @@ export const OnThisPage = ({ toc_obj }: { toc_obj: TocObj }) => { return null; }; -const TocItemComponent = ({ item, hash }: { item: TocItem, hash: string }) => { +const TocItemComponent = ({ item, hash, index }: { item: TocItem, hash: string, index: number }) => { // fetch the hash from url and compare with the item name // if it matches, add a class to the anchor tag @@ -41,7 +32,7 @@ const TocItemComponent = ({ item, hash }: { item: TocItem, hash: string }) => { return name.replace(/[^\w\s-]/g, '').replace(/\s+/g, '-').toLowerCase(); }; - const isActive = hash === `#${sanitizeName(item.name)}`; + const isActive = hash === `#${sanitizeName(item.name)}` || (index === 0 && hash === ""); return (
    • @@ -55,7 +46,7 @@ const TocItemComponent = ({ item, hash }: { item: TocItem, hash: string }) => { {Object.keys(item.children).length > 0 && (
        {Object.keys(item.children).map((key) => ( - + ))}
      )} From c246ccc3d1d82089a33a73485d09e87ca5040801 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Dec 2024 12:51:29 +0530 Subject: [PATCH 098/110] feat: update Commit Docs Page and related components for improved guest access and icon support --- .../commit_docs_page/commit_docs_page.json | 262 +++++++++--------- .../commit_docs_page/commit_docs_page.py | 2 +- .../commit_docs_topbar_item.json | 3 +- commit/www/commit.py | 6 +- 4 files changed, 136 insertions(+), 137 deletions(-) diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.json b/commit/commit/doctype/commit_docs_page/commit_docs_page.json index 4110d98..989f952 100644 --- a/commit/commit/doctype/commit_docs_page/commit_docs_page.json +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.json @@ -1,133 +1,133 @@ { - "actions": [], - "allow_rename": 1, - "autoname": "format:{title}-{route}", - "creation": "2024-10-29 19:39:29.842455", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "title", - "route", - "published", - "allow_guest", - "icon", - "column_break_sedp", - "badge", - "badge_color", - "is_group_page", - "documentation_section", - "content", - "section_break_twyn", - "linked_pages" - ], - "fields": [ - { - "fieldname": "title", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Title", - "reqd": 1 - }, - { - "fieldname": "route", - "fieldtype": "Data", - "in_list_view": 1, - "in_preview": 1, - "in_standard_filter": 1, - "label": "Route", - "reqd": 1, - "unique": 1 - }, - { - "default": "1", - "fieldname": "published", - "fieldtype": "Check", - "label": "Published" - }, - { - "default": "1", - "fieldname": "allow_guest", - "fieldtype": "Check", - "label": "Allow Guest" - }, - { - "depends_on": "eval:doc.is_group_page == 0", - "fieldname": "content", - "fieldtype": "Markdown Editor", - "ignore_xss_filter": 1, - "label": "Content" - }, - { - "description": "This is badge field, eg: GET , POST etc.", - "fieldname": "badge", - "fieldtype": "Data", - "label": "Badge" - }, - { - "description": "Add Tailwind colours like red, green, blue, yellow, purple, pink, indigo, cyan, teal, lime, orange, gray etc.", - "fieldname": "badge_color", - "fieldtype": "Data", - "label": "Badge Color" - }, - { - "fieldname": "column_break_sedp", - "fieldtype": "Column Break" - }, - { - "default": "0", - "description": "When enabled, this page can hold and display nested sub-pages, creating a structured hierarchy in the sidebar.", - "fieldname": "is_group_page", - "fieldtype": "Check", - "label": "Is Group Page" - }, - { - "fieldname": "documentation_section", - "fieldtype": "Section Break", - "label": "Documentation" - }, - { - "description": "\"Supports only icons from the react-icons library. Enter the icon name in the format 'libraryPrefix/IconName' (e.g., 'Fa/FaFileExcel') to display it beside the title in the sidebar.\"\n", - "documentation_url": "https://react-icons.github.io/react-icons/search/", - "fieldname": "icon", - "fieldtype": "Data", - "label": "Icon" - }, - { - "fieldname": "section_break_twyn", - "fieldtype": "Section Break" - }, - { - "depends_on": "eval:doc.is_group_page == 1", - "fieldname": "linked_pages", - "fieldtype": "Table", - "label": "Linked Pages", - "options": "Linked Commit Docs Page" - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified": "2024-11-15 15:20:42.503563", - "modified_by": "Administrator", - "module": "commit", - "name": "Commit Docs Page", - "naming_rule": "Expression", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], - "sort_field": "creation", - "sort_order": "DESC", - "states": [], - "title_field": "title" + "actions": [], + "allow_rename": 1, + "autoname": "format:{title}-{route}", + "creation": "2024-10-29 19:39:29.842455", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "title", + "route", + "published", + "allow_guest", + "icon", + "column_break_sedp", + "badge", + "badge_color", + "is_group_page", + "documentation_section", + "content", + "section_break_twyn", + "linked_pages" + ], + "fields": [ + { + "fieldname": "title", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Title", + "reqd": 1 + }, + { + "fieldname": "route", + "fieldtype": "Data", + "in_list_view": 1, + "in_preview": 1, + "in_standard_filter": 1, + "label": "Route", + "reqd": 1, + "unique": 1 + }, + { + "default": "1", + "fieldname": "published", + "fieldtype": "Check", + "label": "Published" + }, + { + "default": "1", + "fieldname": "allow_guest", + "fieldtype": "Check", + "label": "Allow Guest" + }, + { + "depends_on": "eval:doc.is_group_page == 0", + "fieldname": "content", + "fieldtype": "Markdown Editor", + "ignore_xss_filter": 1, + "label": "Content" + }, + { + "description": "This is badge field, eg: GET , POST etc.", + "fieldname": "badge", + "fieldtype": "Data", + "label": "Badge" + }, + { + "description": "Add Tailwind colours like red, green, blue, yellow, purple, pink, indigo, cyan, teal, lime, orange, gray etc.", + "fieldname": "badge_color", + "fieldtype": "Data", + "label": "Badge Color" + }, + { + "fieldname": "column_break_sedp", + "fieldtype": "Column Break" + }, + { + "default": "0", + "description": "When enabled, this page can hold and display nested sub-pages, creating a structured hierarchy in the sidebar.", + "fieldname": "is_group_page", + "fieldtype": "Check", + "label": "Is Group Page" + }, + { + "fieldname": "documentation_section", + "fieldtype": "Section Break", + "label": "Documentation" + }, + { + "description": "\"Supports only icons from the lucid-react library. Enter the icon name in the format 'libraryPrefix/IconName' (e.g., 'Fa/FaFileExcel') to display it beside the title in the sidebar.\"\n", + "documentation_url": "https://lucide.dev/icons", + "fieldname": "icon", + "fieldtype": "Data", + "label": "Icon" + }, + { + "fieldname": "section_break_twyn", + "fieldtype": "Section Break" + }, + { + "depends_on": "eval:doc.is_group_page == 1", + "fieldname": "linked_pages", + "fieldtype": "Table", + "label": "Linked Pages", + "options": "Linked Commit Docs Page" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-12-13 14:07:48.524842", + "modified_by": "Administrator", + "module": "commit", + "name": "Commit Docs Page", + "naming_rule": "Expression", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "creation", + "sort_order": "DESC", + "states": [], + "title_field": "title" } \ No newline at end of file diff --git a/commit/commit/doctype/commit_docs_page/commit_docs_page.py b/commit/commit/doctype/commit_docs_page/commit_docs_page.py index e3bf74f..3726f55 100644 --- a/commit/commit/doctype/commit_docs_page/commit_docs_page.py +++ b/commit/commit/doctype/commit_docs_page/commit_docs_page.py @@ -93,7 +93,7 @@ def publish_documentation(project_branch, endpoint, viewer_type, docs_name, pare 'commit_docs': commit_docs.name } -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def get_commit_docs_page(name): ''' Get the Commit Docs Page diff --git a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json index d2034da..fa2edf2 100644 --- a/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json +++ b/commit/commit/doctype/commit_docs_topbar_item/commit_docs_topbar_item.json @@ -53,6 +53,7 @@ "label": "Parent Label" }, { + "description": "\"Supports only icons from the lucid-react library. Enter the icon name, eg:\"Bell\" to display it beside the title in the sidebar.\"\n", "fieldname": "icon", "fieldtype": "Data", "label": "Icon" @@ -73,7 +74,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-11-09 18:41:50.962807", + "modified": "2024-12-13 14:08:16.402492", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs Topbar Item", diff --git a/commit/www/commit.py b/commit/www/commit.py index d92d51f..4bbf913 100644 --- a/commit/www/commit.py +++ b/commit/www/commit.py @@ -2,19 +2,16 @@ import json import frappe.sessions import re - +from commit.api.meta_data import get_installed_apps no_cache = 1 SCRIPT_TAG_PATTERN = re.compile(r"\") CLOSING_SCRIPT_TAG_PATTERN = re.compile(r"") def get_context(context): - csrf_token = frappe.sessions.get_csrf_token() - frappe.db.commit() context = frappe._dict() context.boot = get_boot() - context.csrf_token = csrf_token context.build_version = frappe.utils.get_build_version() return context @@ -36,6 +33,7 @@ def get_boot(): show_system_apps = commit_settings.show_system_apps boot["show_system_apps"] = show_system_apps + boot["get_installed_apps"] = get_installed_apps() boot_json = frappe.as_json(boot, indent=None, separators=(",", ":")) boot_json = SCRIPT_TAG_PATTERN.sub("", boot_json) From 14a86e98df880bbac6305981ec63f46cb81b9da9 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Dec 2024 12:54:26 +0530 Subject: [PATCH 099/110] feat: replace react-icons with lucide-react icons for consistency and improved styling --- .../common/Checkbox/CreatableSelect.tsx | 15 ++- .../DynamicIconImport/IconComponent.tsx | 103 ++++++++---------- .../common/ImageUploader2/FileDrop.tsx | 13 +-- .../common/ImageUploader2/ImageUploader.tsx | 4 +- .../common/PageNotFound/PageNotFound.tsx | 10 +- .../features/APIClient/APIClientContent.tsx | 15 +-- .../features/api_viewer/APIDetails.tsx | 32 +++--- .../features/api_viewer/APIList.tsx | 16 +-- .../custommdxcomponent/CustomHeading.tsx | 6 +- .../features/documentation/OnThisPage.tsx | 4 +- .../features/projects/APIExplorer.tsx | 21 ++-- .../features/projects/AddMenuButton.tsx | 12 +- .../projects/Branch/ManageBranchItem.tsx | 14 +-- .../projects/Projects/ProjectCard.tsx | 12 +- .../features/projects/ViewERDButton.tsx | 10 +- dashboard/src/pages/features/docs/Footer.tsx | 18 ++- dashboard/src/pages/features/docs/Navbar.tsx | 8 +- dashboard/src/pages/features/docs/Sidebar.tsx | 10 +- dashboard/src/pages/features/erd/Graph.tsx | 7 +- .../src/pages/features/erd/TableHoverCard.tsx | 4 +- .../src/pages/features/erd/TableNode.tsx | 4 +- .../src/pages/features/erd/meta/MetaGraph.tsx | 7 +- 22 files changed, 158 insertions(+), 187 deletions(-) diff --git a/dashboard/src/components/common/Checkbox/CreatableSelect.tsx b/dashboard/src/components/common/Checkbox/CreatableSelect.tsx index 4c46907..6c1b7a7 100644 --- a/dashboard/src/components/common/Checkbox/CreatableSelect.tsx +++ b/dashboard/src/components/common/Checkbox/CreatableSelect.tsx @@ -13,10 +13,9 @@ import { PopoverTrigger, } from '@/components/ui/popover'; import { ScrollArea } from '@/components/ui/scroll-area'; -import { MdAdd, MdCheck } from 'react-icons/md'; -import { LuChevronsUpDown } from 'react-icons/lu'; import { Input } from '@/components/ui/input'; import { Controller, UseControllerProps, useFormContext } from 'react-hook-form'; +import { Check, ChevronsUpDown, Plus } from 'lucide-react'; export type ComboboxOptions = { value: string; @@ -76,7 +75,7 @@ export const CreatableSelect = ({ options, selected, className, label, mode = 's ) : ( `Select ${label ?? 'Item'}` )} - + @@ -111,7 +110,7 @@ export const CreatableSelect = ({ options, selected, className, label, mode = 's } }} > - + )} @@ -218,7 +217,7 @@ export const FormCreatableSelect = ({ ) : ( `Select ${label ?? 'Item'}` )} - + @@ -246,7 +245,7 @@ export const FormCreatableSelect = ({ } }} > - setIsCreating(true)} > {`Add ${label ?? 'Item'}`} - + )} diff --git a/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx index 7979661..f11595c 100644 --- a/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx +++ b/dashboard/src/components/common/DynamicIconImport/IconComponent.tsx @@ -1,82 +1,65 @@ -import { CSSProperties, lazy, Suspense, SVGAttributes, useMemo } from "react"; -import { IconContext } from "react-icons"; +import React, { CSSProperties, lazy, Suspense, SVGAttributes, useMemo } from 'react'; -interface IProps { +interface LucideDynamicIconProps { icon: string; color?: string; - size?: string; + size?: number | string; className?: string; style?: CSSProperties; + strokeWidth?: number; + absoluteStrokeWidth?: boolean; attr?: SVGAttributes; fallback?: JSX.Element | null; } + // Helper to load the icon -const loadIcon = async (icon: string) => { - const [library, iconName] = icon.split("/"); - const lib = library.toLowerCase(); - // Statically construct the import statement using a function map - // Full list of importable libraries from react-icons - const moduleImporters: Record Promise> = { - ai: () => import("react-icons/ai"), // Ant Design Icons - bs: () => import("react-icons/bs"), // Bootstrap Icons - bi: () => import("react-icons/bi"), // BoxIcons - ci: () => import("react-icons/ci"), // Circum Icons - cg: () => import("react-icons/cg"), // css.gg - di: () => import("react-icons/di"), // Devicons - fi: () => import("react-icons/fi"), // Feather Icons - fc: () => import("react-icons/fc"), // Flat Color Icons - fa: () => import("react-icons/fa"), // Font Awesome 5 Icons - fa6: () => import("react-icons/fa6"), // Font Awesome 6 Icons - gi: () => import("react-icons/gi"), // Game Icons - go: () => import("react-icons/go"), // GitHub Octicons - gr: () => import("react-icons/gr"), // Grommet Icons - hi: () => import("react-icons/hi"), // Heroicons - hi2: () => import("react-icons/hi2"), // Heroicons v2 - im: () => import("react-icons/im"), // IcoMoon Free - lia: () => import("react-icons/lia"), // Icons8 Line Awesome - io: () => import("react-icons/io"), // Ionicons - io5: () => import("react-icons/io5"), // Ionicons v5 - lu: () => import("react-icons/lu"), // Lucide Icons - md: () => import("react-icons/md"), // Material Design Icons - pi: () => import("react-icons/pi"), // Phosphor Icons - rx: () => import("react-icons/rx"), // Radix Icons - ri: () => import("react-icons/ri"), // Remix Icons - si: () => import("react-icons/si"), // Simple Icons - sl: () => import("react-icons/sl"), // Simple Line Icons - tb: () => import("react-icons/tb"), // Tabler Icons - tfi: () => import("react-icons/tfi"), // Themify Icons - ti: () => import("react-icons/ti"), // Typicons - vsc: () => import("react-icons/vsc"), // VS Code Icons - wi: () => import("react-icons/wi"), // Weather Icons - }; +const loadLucideIcon = async (iconName: string) => { + try { + const module: any = await import('lucide-react'); + const IconComponent = module[iconName]; + + if (!IconComponent) { + throw new Error(`Icon "${iconName}" not found in Lucide React library`); + } - const importer = moduleImporters[lib]; - if (!importer) throw new Error(`Icon library "${library}" is not supported.`); - const module = await importer() - const IconComponent = module[iconName] - if (!IconComponent) throw new Error(`Icon "${icon}" not found in "${library}".`) - return IconComponent + return IconComponent; + } catch (error) { + console.error('Failed to load Lucide icon:', error); + throw error; + } }; -const DynamicIcon: React.FC = ({ icon, color, size, className, style, attr, fallback = null }) => { +const DynamicIcon: React.FC = ({ + icon, + color, + size = 24, + className, + style, + strokeWidth, + absoluteStrokeWidth, + attr, + fallback = null +}) => { // Memoize the icon component so it's loaded only when `icon` changes const Icon = useMemo( - () => lazy(() => loadIcon(icon).then((component) => ({ default: component }))), + () => lazy(() => loadLucideIcon(icon).then((component) => ({ default: component }))), [icon] ); - const iconContext = { - color, - size, - className, - style, - attr, - }; + return ( - - - + ); }; + export default DynamicIcon; diff --git a/dashboard/src/components/common/ImageUploader2/FileDrop.tsx b/dashboard/src/components/common/ImageUploader2/FileDrop.tsx index 4683ac7..018942a 100644 --- a/dashboard/src/components/common/ImageUploader2/FileDrop.tsx +++ b/dashboard/src/components/common/ImageUploader2/FileDrop.tsx @@ -1,12 +1,9 @@ import { Accept, useDropzone } from "react-dropzone" -import { MdOutlineDevices } from "react-icons/md" import { useEffect, useState } from "react" import { CustomFile } from "./ImageUploader" import { useToast } from "@/components/ui/use-toast" import { Button } from "@/components/ui/button" -import { TbTrash } from "react-icons/tb" -import { FiFile, FiLink } from 'react-icons/fi' -import { IoMdCheckmark } from "react-icons/io" +import { Check, MonitorSmartphone, Trash2, File as LucidFile, Link } from "lucide-react" export interface FileDropProps extends React.HTMLAttributes { @@ -87,7 +84,7 @@ export const FileDrop = ({ files, onFileChange, maxFiles = 1, uploading, accept,

      Drag 'n' drop your files here.

      @@ -128,7 +125,7 @@ export const FileListItem = ({ file, removeFile, isUploading, ...props }: FileLi {previewURL ? ( File preview ) : ( - file.fileType === 'file' ? : + file.fileType === 'file' ? : )}
      @@ -140,10 +137,10 @@ export const FileListItem = ({ file, removeFile, isUploading, ...props }: FileLi
      {isUploading ? ( - + ) : ( )}
      diff --git a/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx b/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx index e49d7d3..0fbed14 100644 --- a/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx +++ b/dashboard/src/components/common/ImageUploader2/ImageUploader.tsx @@ -1,6 +1,5 @@ import { useFrappeUpdateDoc } from "frappe-react-sdk" import { Accept } from "react-dropzone" -import { MdOutlineFileUpload } from 'react-icons/md' import { useState } from "react" import { useToast } from "@/components/ui/use-toast" import { File } from "@/types/Core/File" @@ -11,6 +10,7 @@ import { SpinnerLoader } from "../FullPageLoader/SpinnerLoader" import { DocumentUploadModal } from "./DocumentUploadModal" import { cn } from "@/lib/utils" import { useGetFilePreviewUrl } from "./FileDrop" +import { Upload } from "lucide-react" /** * Custom File Type for FILE UPLOADER component; with 'fileID' for unique ID & 'preview' for blob URL. @@ -136,7 +136,7 @@ export const ImageUploader = ({ file, doctype, docname, onUpdate, fieldname = 'i
    • : updatingDoc ?
      :
      - {icon ? icon : } + {icon ? icon : }
      } {deleteImage && } diff --git a/dashboard/src/components/common/PageNotFound/PageNotFound.tsx b/dashboard/src/components/common/PageNotFound/PageNotFound.tsx index d126f03..2e097d5 100644 --- a/dashboard/src/components/common/PageNotFound/PageNotFound.tsx +++ b/dashboard/src/components/common/PageNotFound/PageNotFound.tsx @@ -1,9 +1,9 @@ import { motion } from 'framer-motion'; import { Button } from "@/components/ui/button"; -import { IoCloudOutline } from "react-icons/io5"; import { useNavigate } from 'react-router-dom'; +import { Cloud } from 'lucide-react'; -export const PageNotFound = () => { +const PageNotFound = () => { const navigate = useNavigate() @@ -33,7 +33,7 @@ export const PageNotFound = () => { transition={{ duration: 1.2, ease: 'easeInOut' }} className="mb-10" > - + {
      ); -} \ No newline at end of file +} + +export default PageNotFound; \ No newline at end of file diff --git a/dashboard/src/components/features/APIClient/APIClientContent.tsx b/dashboard/src/components/features/APIClient/APIClientContent.tsx index 08c95cd..8472e78 100644 --- a/dashboard/src/components/features/APIClient/APIClientContent.tsx +++ b/dashboard/src/components/features/APIClient/APIClientContent.tsx @@ -6,10 +6,9 @@ import { Input } from "@/components/ui/input" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Argument } from "@/types/APIData" import { FrappeConfig, FrappeContext } from "frappe-react-sdk" +import { ChevronDown, Plus } from "lucide-react" import { useCallback, useContext, useEffect, useState } from "react" import { FormProvider, useForm } from "react-hook-form" -import { FaCaretDown } from "react-icons/fa" -import { IoAdd } from "react-icons/io5"; export interface APIClientContentProps { @@ -18,7 +17,7 @@ export interface APIClientContentProps { open: boolean } -export const APIClientContent = ({ endpoint, open, parameters }: APIClientContentProps) => { +const APIClientContent = ({ endpoint, open, parameters }: APIClientContentProps) => { const [requestType, setRequestType] = useState<"GET" | "POST">('GET') @@ -164,7 +163,7 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten className="rounded-r-none w-[12ch]" > {requestType} - + @@ -196,7 +195,7 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten className="w-[14ch]" > {paramsType === 'params' ? 'Params' : 'Form Data'} - + @@ -256,7 +255,7 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten + }} variant="outline">Add Param
      }
      @@ -281,4 +280,6 @@ export const APIClientContent = ({ endpoint, open, parameters }: APIClientConten ) -} \ No newline at end of file +} + +export default APIClientContent \ No newline at end of file diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 3245c83..49825b1 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -6,17 +6,17 @@ import { Button } from "@/components/ui/button" import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { web_url } from "@/config/socket" import { APIData, Argument } from "@/types/APIData" -import { XMarkIcon } from "@heroicons/react/24/outline" import { useFrappeGetCall } from "frappe-react-sdk" -import { useMemo, useState } from "react" -import { MdOutlineFileDownload } from "react-icons/md" -import { APIDocumentationOfSiteApp } from "../documentation/APIDocumentation" +import { lazy, Suspense, useMemo, useState } from "react" import { Dialog } from "@/components/ui/dialog" -import { APIClientContent } from "../APIClient/APIClientContent" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" -import { AiOutlineThunderbolt } from "react-icons/ai" +import { Download, X, Zap } from "lucide-react" -export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType, mutate }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string, mutate: () => void }) => { + +const APIDocumentationOfSiteApp = lazy(() => import('../documentation/APIDocumentation')) +const APIClientContent = lazy(() => import('../APIClient/APIClientContent')) + +const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelectedEndpoint, viewerType, mutate }: { project_branch: string, endpointData: APIData[], selectedEndpoint: string, setSelectedEndpoint: React.Dispatch>, viewerType: string, mutate: () => void }) => { const data = useMemo(() => { return endpointData.find((endpoint: APIData) => endpoint.name === selectedEndpoint) }, [endpointData, selectedEndpoint]) @@ -73,7 +73,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set > Close panel -
      @@ -94,7 +94,7 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set size="sm" onClick={() => setApiOpen(true)} > - Call API + Call API @@ -139,11 +139,15 @@ export const APIDetails = ({ project_branch, endpointData, selectedEndpoint, set - + }> + + - + }> + +
      ) @@ -236,7 +240,7 @@ export const Bruno = ({ doc }: { doc: APIData }) => {
      @@ -258,4 +262,6 @@ export const Bruno = ({ doc }: { doc: APIData }) => {
      ) -} \ No newline at end of file +} + +export default APIDetails \ No newline at end of file diff --git a/dashboard/src/components/features/api_viewer/APIList.tsx b/dashboard/src/components/features/api_viewer/APIList.tsx index 2edab0f..17d38af 100644 --- a/dashboard/src/components/features/api_viewer/APIList.tsx +++ b/dashboard/src/components/features/api_viewer/APIList.tsx @@ -4,10 +4,8 @@ import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { APIData } from "@/types/APIData" import { useEffect, useMemo, useRef, useState } from "react" -import { AiOutlineBranches } from "react-icons/ai" -import { GoPackage } from "react-icons/go" import { CommandContent } from "../commands/CommandsContent" -import { HiOutlineCommandLine } from "react-icons/hi2"; +import { Box, GitBranch, SquareTerminal } from "lucide-react" export interface APIListProps { apiList: APIData[] @@ -19,7 +17,7 @@ export interface APIListProps { listRef?: React.RefObject } -export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, selectedEndpoint, path_to_folder, listRef }: APIListProps) => { +const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, selectedEndpoint, path_to_folder, listRef }: APIListProps) => { const [searchQuery, setSearchQuery] = useState('') const [requestTypeFilter, setRequestTypeFilter] = useState('All') @@ -53,19 +51,19 @@ export const APIList = ({ apiList, app_name, branch_name, setSelectedEndpoint, s
      - +

      {app_name}

      - +

      {branch_name}

      @@ -161,4 +159,6 @@ export const ListView = ({ list, setSelectedEndpoint, selectedEndpoint, searchQu
      }
      ) -} \ No newline at end of file +} + +export default APIList \ No newline at end of file diff --git a/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx index 15a5490..82e3f66 100644 --- a/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx +++ b/dashboard/src/components/features/custommdxcomponent/CustomHeading.tsx @@ -1,6 +1,6 @@ import { Button } from "@/components/ui/button"; +import { Link2 } from "lucide-react"; import React, { useEffect, useRef } from "react"; -import { MdLink } from "react-icons/md"; const CustomHeading = ({ id, children, as }: { id: string, children: React.ReactNode, as: string }) => { const headingRef = useRef(null); @@ -50,9 +50,9 @@ const CustomHeading = ({ id, children, as }: { id: string, children: React.React
      diff --git a/dashboard/src/components/features/documentation/OnThisPage.tsx b/dashboard/src/components/features/documentation/OnThisPage.tsx index 6b216c4..84bb521 100644 --- a/dashboard/src/components/features/documentation/OnThisPage.tsx +++ b/dashboard/src/components/features/documentation/OnThisPage.tsx @@ -1,6 +1,6 @@ import { cn } from "@/lib/utils"; import { TocItem, TocObj } from "@/pages/features/docs/PageContent"; -import { HiOutlineMenuAlt1 } from "react-icons/hi"; +import { Menu } from "lucide-react"; export const OnThisPage = ({ toc_obj }: { toc_obj: TocObj }) => { @@ -10,7 +10,7 @@ export const OnThisPage = ({ toc_obj }: { toc_obj: TocObj }) => { return (
      - + On This Page
        diff --git a/dashboard/src/components/features/projects/APIExplorer.tsx b/dashboard/src/components/features/projects/APIExplorer.tsx index c3c027f..2d1ea69 100644 --- a/dashboard/src/components/features/projects/APIExplorer.tsx +++ b/dashboard/src/components/features/projects/APIExplorer.tsx @@ -10,14 +10,15 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { CommitProjectBranch } from "@/types/commit/CommitProjectBranch" import { Label } from "@/components/ui/label" import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card" -import { MdKeyboardArrowRight } from "react-icons/md" import api from '../../../assets/api.svg' +import { ChevronRight } from "lucide-react" export const APIExplorer = () => { const { data, error, isLoading } = useFrappeGetCall<{ message: ProjectData[] }>('commit.api.commit_project.commit_project.get_project_list_with_branches', {}, 'get_project_list_with_branches', { keepPreviousData: true, - revalidateOnFocus: true, revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, }) if (error) { @@ -42,17 +43,15 @@ export const APIExplorer = () => { - - + + - - - + + + + +
      diff --git a/dashboard/src/components/features/projects/AddMenuButton.tsx b/dashboard/src/components/features/projects/AddMenuButton.tsx index 6e14c03..24fbe34 100644 --- a/dashboard/src/components/features/projects/AddMenuButton.tsx +++ b/dashboard/src/components/features/projects/AddMenuButton.tsx @@ -7,14 +7,12 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { useState } from "react" -import { IoIosGitBranch } from "react-icons/io" -import { MdAdd } from "react-icons/md" -import { VscGithubProject, VscOrganization } from "react-icons/vsc" import CreateOrgModal from "./Org/CreateOrgModal" import { KeyedMutator } from "swr" import { ProjectData } from "./Projects" import CreateProjectModal from "./Projects/CreateProjectModal" import CreateBranchModal from "./Branch/CreateBranchModal" +import { Building, GitBranch, PanelsTopLeft, Plus } from "lucide-react" export const AddMenuButton = ({ mutate }: { mutate: KeyedMutator<{ @@ -41,20 +39,20 @@ export const AddMenuButton = ({ mutate }: { setCreateOrg(true)} > - + Add Org setCreateProject(true)}> - + Add Project setOpen(true)} > - + Add Branch diff --git a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx index 0c6a19c..5b7b180 100644 --- a/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx +++ b/dashboard/src/components/features/projects/Branch/ManageBranchItem.tsx @@ -3,8 +3,6 @@ import { toast } from '@/components/ui/use-toast'; import { convertFrappeTimestampToTimeAgo } from '@/components/utils/dateconversion'; import { CommitProjectBranch } from '@/types/commit/CommitProjectBranch'; import { useFrappeDeleteDoc, useFrappePostCall, useFrappeUpdateDoc } from 'frappe-react-sdk'; -import { AiOutlineDelete } from 'react-icons/ai'; -import { IoMdSync } from 'react-icons/io'; import { ProjectData } from '../Projects'; import { KeyedMutator } from 'swr'; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; @@ -12,8 +10,8 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { Controller, FormProvider, useForm } from 'react-hook-form'; import { Label } from '@/components/ui/label'; import { useEffect, useState } from 'react'; -import { HiOutlineDotsVertical } from "react-icons/hi"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; +import { EllipsisVertical, RefreshCcw, Trash } from 'lucide-react'; const ManageBranchItem = ({ branch, mutate }: { branch: CommitProjectBranch, mutate: KeyedMutator<{ message: ProjectData[]; }> }) => { const { call, loading: syncLoading, reset: callReset } = useFrappePostCall<{ message: any }>('commit.commit.doctype.commit_project_branch.commit_project_branch.fetch_repo'); @@ -134,7 +132,7 @@ const SyncButton = ({ loading, onSync }: { loading: boolean, onSync: () => void disabled={loading} aria-label="Sync branch" > - + Fetch latest code ); @@ -201,7 +199,7 @@ const DeleteButton = ({ loading, onDelete }: { loading: boolean, onDelete: () => disabled={loading} aria-label="Delete branch" > - + ); @@ -224,16 +222,16 @@ const ActionDropdown = ({ size="sm" aria-label="Actions" > - + - + Fetch latest code - + Delete branch diff --git a/dashboard/src/components/features/projects/Projects/ProjectCard.tsx b/dashboard/src/components/features/projects/Projects/ProjectCard.tsx index 1e5ca9f..9da6279 100644 --- a/dashboard/src/components/features/projects/Projects/ProjectCard.tsx +++ b/dashboard/src/components/features/projects/Projects/ProjectCard.tsx @@ -1,17 +1,15 @@ import { Button } from "@/components/ui/button"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; -import { AiOutlineDelete } from "react-icons/ai"; import { AlertDialog } from "@/components/ui/alert-dialog"; import { KeyedMutator } from "swr"; import { useMemo, useState } from "react"; import { isSystemManager } from "@/utils/roles"; -import { RxDragHandleDots1 } from "react-icons/rx"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; -import { BsThreeDotsVertical } from "react-icons/bs"; import { Dialog } from "@radix-ui/react-dialog"; import ManageBranchModal from "../Branch/ManageBranchModal"; import { ProjectWithBranch, ProjectData } from "../Projects"; import DeleteProjectModal from "./DeleteProjectModal"; +import { EllipsisVertical, Grip, Trash } from "lucide-react"; export interface ProjectCardProps { project: ProjectWithBranch @@ -59,21 +57,21 @@ const ProjectCard = ({ project, mutate, orgName, githubOrg }: ProjectCardProps) {isCreateAccess && ( - {project.branches.length > 0 && ( { setOpenManageModal(true) }}> <> - + Manage Branches )} setOpenDeleteDialogModal(true)}> - + Delete Project diff --git a/dashboard/src/components/features/projects/ViewERDButton.tsx b/dashboard/src/components/features/projects/ViewERDButton.tsx index 482b710..53a58f3 100644 --- a/dashboard/src/components/features/projects/ViewERDButton.tsx +++ b/dashboard/src/components/features/projects/ViewERDButton.tsx @@ -3,9 +3,9 @@ import { Dialog, DialogTrigger } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { ViewERDDialogContent } from "./ViewERDAppDialog"; import { ProjectData } from "./Projects"; -import { MdKeyboardArrowRight } from "react-icons/md"; import { useNavigate } from "react-router-dom"; import erd from '../../../assets/erd.svg' +import { ChevronRight } from "lucide-react"; export const ViewERDButton = ({ data }: { data: ProjectData[] }) => { return ( @@ -26,9 +26,7 @@ export const ViewERDButton = ({ data }: { data: ProjectData[] }) => { className="rounded-full px-4 pr-2 py-2 shadow-md" > Get Started - + @@ -67,9 +65,7 @@ export const ViewERDButtonForSiteApps = () => { }} > Get Started - +
      diff --git a/dashboard/src/pages/features/docs/Footer.tsx b/dashboard/src/pages/features/docs/Footer.tsx index fbf480a..628ecc2 100644 --- a/dashboard/src/pages/features/docs/Footer.tsx +++ b/dashboard/src/pages/features/docs/Footer.tsx @@ -1,9 +1,7 @@ import { CommitDocs } from "@/types/commit/CommitDocs"; import { DocsFooterItem } from "./docs"; -import { FaLinkedin, FaSlack, FaGithub, FaYoutube, FaTelegram } from "react-icons/fa"; -import { GiRaven } from "react-icons/gi"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; -import { FaXTwitter } from "react-icons/fa6"; +import { Bird, Github, Linkedin, Send, Slack, Twitter, Youtube } from "lucide-react"; export const Footer = ({ commit_docs, footer_items }: { commit_docs: Omit, footer_items: Record }) => { @@ -75,13 +73,13 @@ interface SocialMediaIconProps { const classsName = "text-gray-600 hover:text-gray-800 h-5 w-5"; const iconMap: Record = { - twitter: , - linkedin: , - slack: , - github: , - youtube: , - telegram: , - raven: , + twitter: , + linkedin: , + slack: , + github: , + youtube: , + telegram: , + raven: , // Add more icons here as needed }; diff --git a/dashboard/src/pages/features/docs/Navbar.tsx b/dashboard/src/pages/features/docs/Navbar.tsx index 2ef3f35..ce88d29 100644 --- a/dashboard/src/pages/features/docs/Navbar.tsx +++ b/dashboard/src/pages/features/docs/Navbar.tsx @@ -3,8 +3,8 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { DocsNavbarItem } from "./docs"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; -import { FaCaretDown } from "react-icons/fa"; -import { RiSearchLine } from "react-icons/ri"; +import { ChevronDown, Search } from "lucide-react"; + export const Navbar = ({ navbar_items }: { navbar_items: Record }) => { return ( @@ -17,7 +17,7 @@ export const Navbar = ({ navbar_items }: { navbar_items: Record - +
      {/* Right side: Navbar items */}
      @@ -59,7 +59,7 @@ const MenuButton = ({ item }: { item: DocsNavbarItem }) => { size={'sm'} > {item.label} - + diff --git a/dashboard/src/pages/features/docs/Sidebar.tsx b/dashboard/src/pages/features/docs/Sidebar.tsx index 73fedb8..00d19fb 100644 --- a/dashboard/src/pages/features/docs/Sidebar.tsx +++ b/dashboard/src/pages/features/docs/Sidebar.tsx @@ -3,9 +3,9 @@ import { DocsSidebarItem } from "./docs"; import DynamicIcon from "@/components/common/DynamicIconImport/IconComponent"; import { Badge } from "@/components/ui/badge"; import { useState } from "react"; -import { MdKeyboardArrowDown, MdKeyboardArrowRight } from "react-icons/md"; import classNames from "classnames"; import { cn } from "@/lib/utils"; +import { ChevronDown, ChevronRight } from "lucide-react"; export const Sidebar = ({ commit_docs, @@ -50,7 +50,7 @@ const SidebarGroup = ({ groupName, items, selectedEndpoint, setSelectedEndpoint
      setIsExpanded(!isExpanded)}>
      {groupName}
      - {isExpanded ? : } + {isExpanded ? : }
      {isExpanded && items.length > 0 && (
        @@ -122,15 +122,15 @@ const SidebarTitle = ({ item, selectedEndpoint, setSelectedEndpoint, className, onClick={item.is_group_page ? () => setIsExpanded && setIsExpanded(!isExpanded) : () => setSelectedEndpoint(item.route)} >
        -
        - {item.icon && } +
        + {item.icon && } {item.badge && {item.badge}}
        {item.title}
        - {item.is_group_page && item.group_items?.length ? {isExpanded ? : } : null} + {item.is_group_page && item.group_items?.length ? {isExpanded ? : } : null}
        ) diff --git a/dashboard/src/pages/features/erd/Graph.tsx b/dashboard/src/pages/features/erd/Graph.tsx index d6cfc92..fc06144 100644 --- a/dashboard/src/pages/features/erd/Graph.tsx +++ b/dashboard/src/pages/features/erd/Graph.tsx @@ -18,10 +18,9 @@ import ReactFlow, { } from 'reactflow' import 'reactflow/dist/style.css' import { PostgresTable, PostgresRelationship, TableNodeData } from '@/types/Table' -import { CgMaximizeAlt } from 'react-icons/cg' -import { TbArrowsMinimize } from 'react-icons/tb' import { TableNode } from './TableNode' import { TableDrawer } from '../TableDrawer/TableDrawer' +import { Maximize2, Minimize2 } from 'lucide-react' // ReactFlow is scaling everything by the factor of 2 export const NODE_WIDTH = 320 @@ -351,8 +350,8 @@ const TablesGraph: FC<{ > - {!fullscreenOn && } - {fullscreenOn && } + {!fullscreenOn && } + {fullscreenOn && }
        diff --git a/dashboard/src/pages/features/erd/TableHoverCard.tsx b/dashboard/src/pages/features/erd/TableHoverCard.tsx index 0f93d85..e00d68d 100644 --- a/dashboard/src/pages/features/erd/TableHoverCard.tsx +++ b/dashboard/src/pages/features/erd/TableHoverCard.tsx @@ -1,8 +1,6 @@ import { ICON_KEY, ICON_KEY_MAP } from "@/components/common/Icons"; import { PostgresColumn } from "@/types/Table"; import { Arrow, HoverCardContent } from "@radix-ui/react-hover-card"; -// import { AiOutlineLink } from "react-icons/ai"; - export const TableHoverCard = ({ column }: { column: PostgresColumn }) => { @@ -14,7 +12,7 @@ export const TableHoverCard = ({ column }: { column: PostgresColumn }) => { {/*
        */} {/* */}
        - +
        diff --git a/dashboard/src/pages/features/erd/TableNode.tsx b/dashboard/src/pages/features/erd/TableNode.tsx index 2e369fb..761cf69 100644 --- a/dashboard/src/pages/features/erd/TableNode.tsx +++ b/dashboard/src/pages/features/erd/TableNode.tsx @@ -2,8 +2,8 @@ import { PostgresTable } from "@/types/Table"; import { NodeProps, Handle, useReactFlow } from "reactflow"; import { NODE_WIDTH } from "./Graph"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; -import { XMarkIcon } from '@heroicons/react/24/outline' import { cn } from "@/lib/utils"; +import { X } from "lucide-react"; export const TableNode = ({ data, targetPosition, sourcePosition }: NodeProps) => { @@ -66,7 +66,7 @@ export const TableNode = ({ data, targetPosition, sourcePosition }: NodeProps - diff --git a/dashboard/src/pages/features/erd/meta/MetaGraph.tsx b/dashboard/src/pages/features/erd/meta/MetaGraph.tsx index 5d0a8e4..d6a081f 100644 --- a/dashboard/src/pages/features/erd/meta/MetaGraph.tsx +++ b/dashboard/src/pages/features/erd/meta/MetaGraph.tsx @@ -18,8 +18,7 @@ import ReactFlow, { } from 'reactflow' import 'reactflow/dist/style.css' import { PostgresTable, PostgresRelationship, TableNodeData } from '@/types/Table' -import { CgMaximizeAlt } from 'react-icons/cg' -import { TbArrowsMinimize } from 'react-icons/tb' +import { Maximize2, Minimize2 } from 'lucide-react' import { TableNode } from '../TableNode' import { MetaTableDrawer } from '../../TableDrawer/MetaTableDrawer' import { Button } from '@/components/ui/button' @@ -338,8 +337,8 @@ const TablesGraph: FC<{ > - {!fullscreenOn && } - {fullscreenOn && } + {!fullscreenOn && } + {fullscreenOn && }
        From a37c610a67dbef5aa3ed1a390b9d41228fa0ad16 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Dec 2024 13:01:00 +0530 Subject: [PATCH 100/110] feat:lazy load the components --- dashboard/package.json | 2 +- dashboard/src/App.tsx | 55 ++++++----- .../common/AsyncDropdown/AsyncDropdown.tsx | 10 +- .../common/ErrorBanner/ErrorBanner.tsx | 7 +- dashboard/src/components/common/Icons.ts | 99 ++++++++----------- .../documentation/APIDocumentation.tsx | 50 +++++----- .../features/projects/Org/OrgComponent.tsx | 13 ++- .../components/features/projects/Projects.tsx | 7 +- .../pages/features/api_viewer/APIViewer.tsx | 51 +++++----- .../features/api_viewer/AppAPIViewer.tsx | 37 ++++--- .../src/pages/features/docs/PageContent.tsx | 8 +- .../src/pages/features/erd/ERDViewer.tsx | 11 ++- .../features/erd/meta/CreateERDForMeta.tsx | 13 +-- .../erd/meta/ERDDoctypeAndAppModal.tsx | 3 +- dashboard/src/pages/overview/Overview.tsx | 24 +++-- dashboard/src/types/commit/CommitDocsPage.ts | 2 +- .../src/types/commit/CommitDocsTopbarItem.ts | 3 +- dashboard/yarn.lock | 11 ++- 18 files changed, 221 insertions(+), 185 deletions(-) diff --git a/dashboard/package.json b/dashboard/package.json index 08fa1da..93a2f28 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -53,12 +53,12 @@ "jotai": "^2.8.3", "lodash": "^4.17.21", "lodash.isplainobject": "^4.0.6", + "lucide-react": "^0.468.0", "moment-timezone": "^0.5.43", "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-hook-form": "^7.45.1", - "react-icons": "^5.2.1", "react-router-dom": "^6.14.1", "reactflow": "^11.11.4", "rehype-katex": "^7.0.1", diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index d36d6e1..56702d0 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -1,13 +1,16 @@ import { FrappeProvider } from 'frappe-react-sdk' import { BrowserRouter, Route, Routes } from 'react-router-dom' -import { APIViewerContainer } from './pages/features/api_viewer/APIViewer' -import { Overview } from './pages/overview/Overview' -import { ERDViewer } from './pages/features/erd/ERDViewer' -import { AppAPIViewerContainer } from './pages/features/api_viewer/AppAPIViewer' -import { CreateERD } from './pages/features/erd/meta/CreateERDForMeta' -import ViewDocs from './pages/features/docs/ViewDocs' -import { PageNotFound } from './components/common/PageNotFound/PageNotFound' -import DocsPage from './pages/features/docs/DocsPage' +import { lazy, Suspense } from 'react' +import { FullPageLoader } from './components/common/FullPageLoader/FullPageLoader' + +const ERDViewer = lazy(async () => import('./pages/features/erd/ERDViewer')) +const Overview = lazy(async () => import('./pages/overview/Overview')) +const APIViewerContainer = lazy(async () => import('./pages/features/api_viewer/APIViewer')) +const AppAPIViewerContainer = lazy(async () => import('./pages/features/api_viewer/AppAPIViewer')) +const CreateERD = lazy(async () => import('./pages/features/erd/meta/CreateERDForMeta')) +const ViewDocs = lazy(async () => import('./pages/features/docs/ViewDocs')) +const PageNotFound = lazy(async () => import('./components/common/PageNotFound/PageNotFound')) +const DocsPage = lazy(async () => import('./pages/features/docs/DocsPage')) function App() { @@ -24,25 +27,27 @@ function App() { return ( + }> {/* */} - - {/** Public Routes */} - {/* } /> */} + + {/** Public Routes */} + {/* } /> */} - {/** Private Routes */} - {/* } /> */} - {/* default route on '/' */} - } /> - {/*TODO: Need to Change below route */} - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + {/** Private Routes */} + {/* } /> */} + {/* default route on '/' */} + } /> + {/*TODO: Need to Change below route */} + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + {/* */} diff --git a/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx b/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx index 6e807bc..4eb76a8 100644 --- a/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx +++ b/dashboard/src/components/common/AsyncDropdown/AsyncDropdown.tsx @@ -1,5 +1,5 @@ import { FrappeError, useFrappePostCall } from 'frappe-react-sdk' -import { PropsWithChildren, useEffect, useRef } from 'react' +import { lazy, PropsWithChildren, Suspense, useEffect, useRef } from 'react' import { Filter, useFrappeGetCall } from "frappe-react-sdk"; import { useCallback, useMemo, useState } from "react"; import { RegisterOptions, useController, useFormContext } from "react-hook-form"; @@ -12,9 +12,11 @@ import { useDebounce } from '@/hooks/useDebounce'; import { getLinkTitleAtom, setLinkTitleAtom } from './LinkTitles'; import { AsyncSpinnerLoader } from '../FullPageLoader/SpinnerLoader'; import { getErrorMessages } from '../ErrorBanner/ErrorBanner'; -import MDXRenderer from '../MarkdownRenderer/MDX'; +import { FullPageLoader } from '../FullPageLoader/FullPageLoader'; +const MDXRenderer = lazy(() => import('../MarkdownRenderer/MDX')) + interface ResultItem { value: string, description: string, @@ -472,7 +474,9 @@ const ErrorContainer = ({ error }: { error?: FrappeError }) => {

        - {getErrorMessages(error).map(e => )} + }> + {getErrorMessages(error).map(e => )} +

        ); diff --git a/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx b/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx index 640316c..f7cee0e 100644 --- a/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx +++ b/dashboard/src/components/common/ErrorBanner/ErrorBanner.tsx @@ -1,7 +1,8 @@ import { FrappeError } from 'frappe-react-sdk' -import { useMemo } from 'react' -import MDXRenderer from '../MarkdownRenderer/MDX' +import { lazy, Suspense, useMemo } from 'react' +import { FullPageLoader } from '../FullPageLoader/FullPageLoader' +const MDXRenderer = lazy(() => import('../MarkdownRenderer/MDX')) interface ErrorBannerProps extends React.HTMLAttributes { error?: FrappeError | null, @@ -123,8 +124,10 @@ export const ErrorBanner = ({ error, overrideHeading, ...props }: ErrorBannerPro

        + }> {messages.map((m, i) => )} +

        diff --git a/dashboard/src/components/common/Icons.ts b/dashboard/src/components/common/Icons.ts index 8de3f8a..45e3cbf 100644 --- a/dashboard/src/components/common/Icons.ts +++ b/dashboard/src/components/common/Icons.ts @@ -1,63 +1,48 @@ -import { IconType } from 'react-icons' -import { GrCurrency, GrFormAttachment, GrTextAlignFull } from 'react-icons/gr' -import { AiFillCode, AiFillFileImage, AiFillHtml5, AiOutlineHtml5, AiOutlineLink, AiOutlinePhone, AiOutlineStar, AiOutlineTable } from 'react-icons/ai' -import { BiBarcode, BiCheckboxChecked, BiColorFill, BiCurrentLocation, BiEdit, BiHeading, BiStopwatch, BiTime } from 'react-icons/bi' -import { BsBodyText, BsCalendarDate, BsFileEarmarkImage, BsFiletypeMdx, BsLink45Deg, BsMenuButton, BsPercent } from 'react-icons/bs' -import { TbTxt } from 'react-icons/tb' -import { HiOutlineLightBulb } from 'react-icons/hi' -import { TiSortNumerically } from 'react-icons/ti' -import { MdOutlineFunctions, MdOutlineNumbers } from 'react-icons/md' -import { FaIcons } from 'react-icons/fa' -import { VscJson } from 'react-icons/vsc' -import { RiLockPasswordLine } from 'react-icons/ri' -import { CiRead } from 'react-icons/ci' -import { IoIosArrowDropdown } from 'react-icons/io' -import { PiSignatureLight } from 'react-icons/pi' -import { LuText } from 'react-icons/lu' +import { ArrowUp01, Barcode, Calendar, CalendarClock, Check, Clock3, Code, FileCode, FileDigit, FileJson, Grid3x3, Heading, Heading1, Image, IndianRupee, LetterText, Lightbulb, Link, Link2, MapPinned, Menu, MousePointer2, PaintBucket, Paperclip, Parentheses, Pencil, PenOff, Percent, Phone, RectangleEllipsis, ScrollText, Signature, SquareStack, Star, Table, Timer, TypeOutline } from 'lucide-react' export type ICON_KEY = 'Autocomplete' | 'Attach' | 'Attach Image' | 'Barcode' | 'Button' | 'Check' | 'Code' | 'Color' | 'Currency' | 'Data' | 'Date' | 'Datetime' | 'Duration' | 'Dynamic Link' | 'Float' | 'Fold' | 'Geolocation' | 'Heading' | 'HTML' | 'HTML Editor' | 'Icon' | 'Image' | 'Int' | 'JSON' | 'Link' | 'Long Text' | 'Markdown Editor' | 'Password' | 'Percent' | 'Phone' | 'Read Only' | 'Rating' | 'Select' | 'Signature' | 'Small Text' | 'Table' | 'Table MultiSelect' | 'Text' | 'Text Editor' | 'Time' -export const ICON_KEY_MAP: Record = { - 'Autocomplete': HiOutlineLightBulb as IconType, - 'Attach': GrFormAttachment as IconType, - 'Attach Image': AiFillFileImage as IconType, - 'Barcode': BiBarcode as IconType, - 'Button': BsMenuButton as IconType, - 'Check': BiCheckboxChecked as IconType, - 'Code': AiFillCode as IconType, - 'Color': BiColorFill as IconType, - 'Currency': GrCurrency as IconType, - 'Data': TbTxt as IconType, - 'Date': BsCalendarDate as IconType, - 'Datetime': BsCalendarDate as IconType, - 'Duration': BiStopwatch as IconType, - 'Dynamic Link': BsLink45Deg as IconType, - 'Float': TiSortNumerically as IconType, - 'Fold': MdOutlineFunctions as IconType, - 'Geolocation': BiCurrentLocation as IconType, - 'Heading': BiHeading as IconType, - 'HTML': AiOutlineHtml5 as IconType, - 'HTML Editor': AiFillHtml5 as IconType, - 'Icon': FaIcons as IconType, - 'Image': BsFileEarmarkImage as IconType, - 'Int': MdOutlineNumbers as IconType, - 'JSON': VscJson as IconType, - 'Link': AiOutlineLink as IconType, - 'Long Text': BsBodyText as IconType, - 'Markdown Editor': BsFiletypeMdx as IconType, - 'Password': RiLockPasswordLine as IconType, - 'Percent': BsPercent as IconType, - 'Phone': AiOutlinePhone as IconType, - 'Read Only': CiRead as IconType, - 'Rating': AiOutlineStar as IconType, - 'Select': IoIosArrowDropdown as IconType, - 'Signature': PiSignatureLight as IconType, - 'Small Text': LuText as IconType, - 'Table': AiOutlineTable as IconType, - 'Table MultiSelect': AiOutlineTable as IconType, - 'Text': GrTextAlignFull as IconType, - 'Text Editor': BiEdit as IconType, - 'Time': BiTime as IconType, +export const ICON_KEY_MAP: Record = { + 'Autocomplete': Lightbulb as any, + 'Attach': Paperclip as any, + 'Attach Image': Image as any, + 'Barcode': Barcode as any, + 'Button': Menu as any, + 'Check': Check as any, + 'Code': Code as any, + 'Color': PaintBucket as any, + 'Currency': IndianRupee as any, + 'Data': TypeOutline as any, + 'Date': Calendar as any, + 'Datetime': CalendarClock as any, + 'Duration': Timer as any, + 'Dynamic Link': Link as any, + 'Float': ArrowUp01 as any, + 'Fold': Parentheses as any, + 'Geolocation': MapPinned as any, + 'Heading': Heading1 as any, + 'HTML': Heading as any, + 'HTML Editor': FileCode as any, + 'Icon': SquareStack as any, + 'Image': Image as any, + 'Int': FileDigit as any, + 'JSON': FileJson as any, + 'Link': Link2 as any, + 'Long Text': ScrollText as any, + 'Markdown Editor': Heading1 as any, + 'Password': RectangleEllipsis as any, + 'Percent': Percent as any, + 'Phone': Phone as any, + 'Read Only': PenOff as any, + 'Rating': Star as any, + 'Select': MousePointer2 as any, + 'Signature': Signature as any, + 'Small Text': LetterText as any, + 'Table': Table as any, + 'Table MultiSelect': Grid3x3 as any, + 'Text': LetterText as any, + 'Text Editor': Pencil as any, + 'Time': Clock3 as any, } diff --git a/dashboard/src/components/features/documentation/APIDocumentation.tsx b/dashboard/src/components/features/documentation/APIDocumentation.tsx index b2e592e..a5bdf76 100644 --- a/dashboard/src/components/features/documentation/APIDocumentation.tsx +++ b/dashboard/src/components/features/documentation/APIDocumentation.tsx @@ -4,14 +4,9 @@ import { Button } from "@/components/ui/button"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { APIData } from "@/types/APIData"; import { FrappeConfig, FrappeContext, useFrappePostCall } from "frappe-react-sdk"; -import { useCallback, useContext, useEffect, useMemo, useState } from "react"; -import { MdOutlineRocketLaunch } from "react-icons/md"; -import MDEditor from '@uiw/react-md-editor'; -import { FiEdit, FiExternalLink, FiSave } from "react-icons/fi"; +import { lazy, Suspense, useCallback, useContext, useEffect, useMemo, useState } from "react"; import { isSystemManager } from "@/utils/roles"; -import { IoMdClose } from "react-icons/io"; import { convertFrappeTimestampToTimeAgo } from "@/components/utils/dateconversion"; -import { AiOutlineGlobal } from "react-icons/ai"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { useToast } from "@/components/ui/use-toast"; import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; @@ -20,13 +15,16 @@ import { Input } from "@/components/ui/input"; import { AsyncDropdown } from "@/components/common/AsyncDropdown/AsyncDropdown"; import { Check } from "@/components/common/Checkbox/Check"; import { FormCreatableSelect } from "@/components/common/Checkbox/CreatableSelect"; +import { ExternalLink, Globe, Rocket, Save, SquarePen, X } from "lucide-react"; + +const MDEditor = lazy(() => import('@uiw/react-md-editor')); export interface DocumentationResponse { function_name: string, path: string, documentation: string } -export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint, viewerType, mutate }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string, viewerType: string, mutate: () => void }) => { +const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path, endPoint, viewerType, mutate }: { apiData: APIData, project_branch: string, file_path: string, endPoint: string, viewerType: string, mutate: () => void }) => { const renderContent = () => { // return string by type checking @@ -101,17 +99,19 @@ export const APIDocumentationOfSiteApp = ({ apiData, project_branch, file_path,
        {isCreateAccess && }
        : (isCreateAccess && )} - onDocumentationChange(value ?? '')} - style={{ - minHeight: (apiData?.last_updated || isCreateAccess) ? 'calc(100vh - 22rem)' : 'calc(100vh - 19rem)', - overflowY: 'auto', margin: 8, padding: 4 - }} - /> + }> + onDocumentationChange(value ?? '')} + style={{ + minHeight: (apiData?.last_updated || isCreateAccess) ? 'calc(100vh - 22rem)' : 'calc(100vh - 19rem)', + overflowY: 'auto', margin: 8, padding: 4 + }} + /> +
      @@ -130,10 +130,10 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE
      {data?.is_published ? : }
      @@ -147,7 +147,7 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE @@ -159,13 +159,13 @@ export const AllButton = ({ generateDocumentation, loading, edit, setEdit, SaveE setEdit(false) setDocumentation(renderContent()) }}> - + } @@ -304,4 +304,6 @@ export const PublishDocumentationDialog = ({ open, setOpen, project_branch, endP ) -} \ No newline at end of file +} + +export default APIDocumentationOfSiteApp; \ No newline at end of file diff --git a/dashboard/src/components/features/projects/Org/OrgComponent.tsx b/dashboard/src/components/features/projects/Org/OrgComponent.tsx index 212959d..8e8788f 100644 --- a/dashboard/src/components/features/projects/Org/OrgComponent.tsx +++ b/dashboard/src/components/features/projects/Org/OrgComponent.tsx @@ -1,11 +1,11 @@ import { Button } from "@/components/ui/button"; import { isSystemManager } from "@/utils/roles"; -import { AiOutlineDelete } from "react-icons/ai"; import { KeyedMutator } from "swr"; import { ProjectData } from "../Projects"; import DeleteOrgModal from "./DeleteOrgModal"; import { AlertDialog, AlertDialogTrigger } from "@/components/ui/alert-dialog"; -import { ProjectCard } from "../Projects/ProjectCard"; +import ProjectCard from "../Projects/ProjectCard"; +import { Trash } from "lucide-react"; interface OrgComponentProps { @@ -23,7 +23,7 @@ export const OrgComponent = ({ org, mutate }: OrgComponentProps) => { {isCreateAccess && @@ -32,7 +32,12 @@ export const OrgComponent = ({ org, mutate }: OrgComponentProps) => {
      {org.projects.map((project) => { return ( - + ) } )} diff --git a/dashboard/src/components/features/projects/Projects.tsx b/dashboard/src/components/features/projects/Projects.tsx index 0658c2d..5345589 100644 --- a/dashboard/src/components/features/projects/Projects.tsx +++ b/dashboard/src/components/features/projects/Projects.tsx @@ -21,7 +21,7 @@ export interface ProjectData extends CommitProjectBranch { name: string; about: string; } -export const Projects = () => { +const Projects = () => { const isCreateAccess = isSystemManager(); const { data, error, isLoading, mutate } = useFrappeGetCall<{ @@ -32,8 +32,9 @@ export const Projects = () => { "get_project_list_with_branches", { keepPreviousData: true, - revalidateOnFocus: true, revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, } ); @@ -78,3 +79,5 @@ export const Projects = () => { ); } }; + +export default Projects; \ No newline at end of file diff --git a/dashboard/src/pages/features/api_viewer/APIViewer.tsx b/dashboard/src/pages/features/api_viewer/APIViewer.tsx index 288c462..c3cb37b 100644 --- a/dashboard/src/pages/features/api_viewer/APIViewer.tsx +++ b/dashboard/src/pages/features/api_viewer/APIViewer.tsx @@ -1,6 +1,4 @@ -import { APIDetails } from "@/components/features/api_viewer/APIDetails" -import { APIList } from "@/components/features/api_viewer/APIList" -import { useEffect, useRef, useState } from "react" +import { lazy, Suspense, useEffect, useRef, useState } from "react" import { useFrappeGetCall } from "frappe-react-sdk" import { APIData } from "@/types/APIData" import { useNavigate, useParams } from "react-router-dom" @@ -8,6 +6,8 @@ import { Header } from "@/components/common/Header" import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner" +const APIList = lazy(() => import('@/components/features/api_viewer/APIList')) +const APIDetails = lazy(() => import('@/components/features/api_viewer/APIDetails')) interface GetAPIResponse { apis: APIData[] @@ -21,7 +21,8 @@ interface GetAPIResponse { project_branch: string, path_to_folder: string } -export const APIViewerContainer = () => { + +const APIViewerContainer = () => { const { ID } = useParams() if (ID) { @@ -84,15 +85,17 @@ export const APIViewer = ({ projectBranch }: { projectBranch: string }) => { {error && } {data &&
      - + }> + +
      {selectedendpoint && ( @@ -100,17 +103,21 @@ export const APIViewer = ({ projectBranch }: { projectBranch: string }) => { className={`fixed z-10 right-0 w-[80vw] h-full bg-white shadow-lg transition-transform transform ${selectedendpoint ? 'translate-x-0' : 'translate-x-full' } md:relative md:translate-x-0 sm:w-[55%]`} > - + }> + +
      )}
      }
      ) -} \ No newline at end of file +} + +export default APIViewerContainer \ No newline at end of file diff --git a/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx b/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx index e11bd33..88e3ac4 100644 --- a/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx +++ b/dashboard/src/pages/features/api_viewer/AppAPIViewer.tsx @@ -1,19 +1,20 @@ import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner" import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { Header } from "@/components/common/Header" -import { APIDetails } from "@/components/features/api_viewer/APIDetails" -import { APIList } from "@/components/features/api_viewer/APIList" import { APIData } from "@/types/APIData" import { useFrappeGetCall } from "frappe-react-sdk" -import { useEffect, useRef, useState } from "react" +import { lazy, Suspense, useEffect, useRef, useState } from "react" import { useNavigate, useParams } from "react-router-dom" +const APIList = lazy(() => import('@/components/features/api_viewer/APIList')) +const APIDetails = lazy(() => import('@/components/features/api_viewer/APIDetails')) + interface GetAPIResponse { apis: APIData[] app_name: string branch_name: string } -export const AppAPIViewerContainer = () => { +const AppAPIViewerContainer = () => { const { ID } = useParams() if (ID) { @@ -72,15 +73,17 @@ export const AppAPIViewer = ({ appName }: { appName: string }) => { {error && } {data &&
      - + }> + +
      @@ -89,11 +92,15 @@ export const AppAPIViewer = ({ appName }: { appName: string }) => { className={`fixed z-10 right-0 w-[80vw] h-full bg-white shadow-lg transition-transform transform ${selectedendpoint ? 'translate-x-0' : 'translate-x-full' } md:relative md:translate-x-0 sm:w-[55%]`} > - + }> + +
      )}
      }
      ) -} \ No newline at end of file +} + +export default AppAPIViewerContainer \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/PageContent.tsx b/dashboard/src/pages/features/docs/PageContent.tsx index 0a7c476..071165a 100644 --- a/dashboard/src/pages/features/docs/PageContent.tsx +++ b/dashboard/src/pages/features/docs/PageContent.tsx @@ -1,11 +1,11 @@ import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; -import MDXRenderer from "@/components/common/MarkdownRenderer/MDX"; import { OnThisPage } from "@/components/features/documentation/OnThisPage"; import { CommitDocsPage } from "@/types/commit/CommitDocsPage"; import { useFrappeGetCall } from "frappe-react-sdk"; +import { lazy, Suspense } from "react"; - +const MDXRenderer = lazy(() => import('@/components/common/MarkdownRenderer/MDX')); export interface PageData { doc: CommitDocsPage toc_obj: TocObj @@ -47,7 +47,9 @@ export const PageContent = ({ selectedEndpoint, route_map }: { selectedEndpoint:
      {data?.message?.doc?.title}
      - + }> + +
      diff --git a/dashboard/src/pages/features/erd/ERDViewer.tsx b/dashboard/src/pages/features/erd/ERDViewer.tsx index 9f4c542..ab6c0c2 100644 --- a/dashboard/src/pages/features/erd/ERDViewer.tsx +++ b/dashboard/src/pages/features/erd/ERDViewer.tsx @@ -3,7 +3,6 @@ import { Button } from "@/components/ui/button" import { Checkbox } from "@/components/ui/checkbox" import { AppModuleData } from "@/types/CommitProjectBranch" import { Dialog, Transition } from "@headlessui/react" -import { XMarkIcon } from "@heroicons/react/20/solid" import { useFrappeGetCall } from "frappe-react-sdk" import { Fragment, useEffect, useMemo, useRef, useState } from "react" import { useLocation } from "react-router-dom" @@ -14,10 +13,10 @@ import { ERDForDoctypes } from "./ERDForDoctypes" import { Dialog as Dialog2 } from "@/components/ui/dialog" import { Popover, PopoverTrigger } from "@/components/ui/popover" import { DoctypeListPopover, ViewERDAppList } from "./meta/ERDDoctypeAndAppModal" -import { BsDownload } from "react-icons/bs" import { toPng } from 'html-to-image' +import { Download, X } from "lucide-react" -export const ERDViewer = () => { +const ERDViewer = () => { const [open, setOpen] = useState(true) @@ -70,7 +69,7 @@ export const ERDViewer = () => { }); }}>
      - Download + Download
      @@ -168,7 +167,7 @@ export const ModuleDoctypeListDrawer = ({ open, setOpen, apps, setSelectedApps, > Close panel -
      @@ -289,3 +288,5 @@ export const ModuleList = ({ apps, doctype, setDocType }: { apps: string[], doct return null } + +export default ERDViewer \ No newline at end of file diff --git a/dashboard/src/pages/features/erd/meta/CreateERDForMeta.tsx b/dashboard/src/pages/features/erd/meta/CreateERDForMeta.tsx index ebf00ed..1b25f9c 100644 --- a/dashboard/src/pages/features/erd/meta/CreateERDForMeta.tsx +++ b/dashboard/src/pages/features/erd/meta/CreateERDForMeta.tsx @@ -2,7 +2,6 @@ import { Header } from "@/components/common/Header" import { Button } from "@/components/ui/button" import { Dialog, Transition } from "@headlessui/react" import { Fragment, useEffect, useRef, useState } from "react" -import { XMarkIcon } from "@heroicons/react/20/solid" import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner" import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { Input } from "@/components/ui/input" @@ -13,10 +12,10 @@ import { useDebounce } from "@/hooks/useDebounce" import { ERDForMetaDoctypes } from "./ERDForMetaDoctype" import { Popover, PopoverTrigger } from "@/components/ui/popover" import { DoctypeListPopoverForMeta } from "./ERDDoctypeAndAppModal" -import { BsDownload } from "react-icons/bs" import { toPng } from 'html-to-image' +import { Download, X } from "lucide-react" -export const CreateERD = () => { +const CreateERD = () => { const [open, setOpen] = useState(true) const [erdDoctypes, setERDDocTypes] = useState([]) @@ -55,7 +54,7 @@ export const CreateERD = () => { }); }}>
      - Download + Download
      @@ -134,7 +133,7 @@ export const ModuleDoctypeListDrawer = ({ open, setOpen, erdDoctypes, setERDDocT > Close panel -
      @@ -221,4 +220,6 @@ export const ModuleList = ({ doctype, setDocType }: { doctype: string[], setDocT } return null -} \ No newline at end of file +} + +export default CreateERD \ No newline at end of file diff --git a/dashboard/src/pages/features/erd/meta/ERDDoctypeAndAppModal.tsx b/dashboard/src/pages/features/erd/meta/ERDDoctypeAndAppModal.tsx index 8c3165a..1c0240c 100644 --- a/dashboard/src/pages/features/erd/meta/ERDDoctypeAndAppModal.tsx +++ b/dashboard/src/pages/features/erd/meta/ERDDoctypeAndAppModal.tsx @@ -67,8 +67,9 @@ export const ViewERDAppList = ({ apps, setApps, onClose }: { apps: string[], set const { data, error, isLoading } = useFrappeGetCall<{ message: ProjectData[] }>('commit.api.commit_project.commit_project.get_project_list_with_branches', {}, 'get_project_list_with_branches', { keepPreviousData: true, - revalidateOnFocus: true, revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, }) const onViewERD = () => { diff --git a/dashboard/src/pages/overview/Overview.tsx b/dashboard/src/pages/overview/Overview.tsx index 64090d7..7be224a 100644 --- a/dashboard/src/pages/overview/Overview.tsx +++ b/dashboard/src/pages/overview/Overview.tsx @@ -1,11 +1,12 @@ +import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { Header } from "@/components/common/Header" -import { YourApps } from "@/components/features/meta_apps/YourApps" -import { Projects } from "@/components/features/projects/Projects" import { TabsContent, TabsList, TabsTrigger, Tabs } from "@/components/ui/tabs" import { isSystemAppAvailable } from "@/utils/roles" +import { lazy, Suspense } from "react" - -export const Overview = () => { +const Projects = lazy(() => import('@/components/features/projects/Projects')) +const YourApps = lazy(() => import('@/components/features/meta_apps/YourApps')) +const Overview = () => { const areAppsAvailable = isSystemAppAvailable() return ( @@ -17,12 +18,19 @@ export const Overview = () => { Site Apps - + }> + + - + }> + + - : } + : }> + + }
      ) -} \ No newline at end of file +} +export default Overview \ No newline at end of file diff --git a/dashboard/src/types/commit/CommitDocsPage.ts b/dashboard/src/types/commit/CommitDocsPage.ts index c3c9140..b086364 100644 --- a/dashboard/src/types/commit/CommitDocsPage.ts +++ b/dashboard/src/types/commit/CommitDocsPage.ts @@ -19,7 +19,7 @@ export interface CommitDocsPage{ published?: 0 | 1 /** Allow Guest : Check */ allow_guest?: 0 | 1 - /** Icon : Data - "Supports only icons from the react-icons library. Enter the icon name in the format 'libraryPrefix/IconName' (e.g., 'Fa/FaFileExcel') to display it beside the title in the sidebar." + /** Icon : Data - "Supports only icons from the lucid-react library. Enter the icon name in the format 'libraryPrefix/IconName' (e.g., 'Fa/FaFileExcel') to display it beside the title in the sidebar." */ icon?: string /** Badge : Data - This is badge field, eg: GET , POST etc. */ diff --git a/dashboard/src/types/commit/CommitDocsTopbarItem.ts b/dashboard/src/types/commit/CommitDocsTopbarItem.ts index e595880..edc26bf 100644 --- a/dashboard/src/types/commit/CommitDocsTopbarItem.ts +++ b/dashboard/src/types/commit/CommitDocsTopbarItem.ts @@ -20,7 +20,8 @@ export interface CommitDocsTopbarItem{ hide_on_navbar?: 0 | 1 /** Parent Label : Select - If you set this, this Item will come in a drop-down under the selected parent. */ parent_label?: string - /** Icon : Data */ + /** Icon : Data - "Supports only icons from the lucid-react library. Enter the icon name, eg:"Bell" to display it beside the title in the sidebar." + */ icon?: string /** Is Primary Button : Check */ is_primary_button?: 0 | 1 diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index a35b4b6..0c2381a 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -3699,6 +3699,11 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lucide-react@^0.468.0: + version "0.468.0" + resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.468.0.tgz#830c1bfd905575ddd23b832baa420c87db166910" + integrity sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA== + markdown-extensions@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-2.0.0.tgz#34bebc83e9938cae16e0e017e4a9814a8330d3c4" @@ -4763,11 +4768,6 @@ react-hook-form@^7.45.1: resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.53.2.tgz#6fa37ae27330af81089baadd7f322cc987b8e2ac" integrity sha512-YVel6fW5sOeedd1524pltpHX+jgU2u3DSDtXEaBORNdqiNrsX/nUI/iGXONegttg0mJVnfrIkiV0cmTU6Oo2xw== -react-icons@^5.2.1: - version "5.3.0" - resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c" - integrity sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg== - react-is@18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" @@ -5342,6 +5342,7 @@ stdin-discarder@^0.1.0: bl "^5.0.0" "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: + name string-width-cjs version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== From 95077ff0bf80ef3cfe0370ee34a55fdf33009bf8 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Dec 2024 13:01:22 +0530 Subject: [PATCH 101/110] feat: refactor YourAppAPIExplorer and YourApps components to use custom hook for installed apps comes from boot --- .../features/meta_apps/YourAppAPIExplorer.tsx | 15 +++---- .../features/meta_apps/YourApps.tsx | 14 +++--- .../features/meta_apps/useGetInstalledApp.ts | 43 +++++++++++++++++++ 3 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 dashboard/src/components/features/meta_apps/useGetInstalledApp.ts diff --git a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx index 05aa70c..032b357 100644 --- a/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx +++ b/dashboard/src/components/features/meta_apps/YourAppAPIExplorer.tsx @@ -1,5 +1,4 @@ import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" -import { useFrappeGetCall } from "frappe-react-sdk" import { useNavigate } from "react-router-dom" import { AppsData } from "./YourApps" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" @@ -9,16 +8,14 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card" -import { MdKeyboardArrowRight } from "react-icons/md" import api from '../../../assets/api.svg' +import { ChevronRight } from "lucide-react" +import { useInstalledApps } from "./useGetInstalledApp" export const YourAppAPIExplorer = () => { - const { data, error, isLoading } = useFrappeGetCall<{ message: AppsData[] }>('commit.api.meta_data.get_installed_apps', {}, 'get_installed_apps', { - keepPreviousData: true, - revalidateOnFocus: true, - revalidateIfStale: false, - }) + const { data, error, isLoading } = useInstalledApps() + if (error) { return
      Error
      @@ -46,9 +43,7 @@ export const YourAppAPIExplorer = () => { diff --git a/dashboard/src/components/features/meta_apps/YourApps.tsx b/dashboard/src/components/features/meta_apps/YourApps.tsx index 9d26140..d98a94c 100644 --- a/dashboard/src/components/features/meta_apps/YourApps.tsx +++ b/dashboard/src/components/features/meta_apps/YourApps.tsx @@ -1,10 +1,10 @@ import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader" import { Avatar, AvatarFallback } from "@/components/ui/avatar" import { AvatarImage } from "@radix-ui/react-avatar" -import { useFrappeGetCall } from "frappe-react-sdk" import { useMemo } from "react" import { YourAppAPIExplorer } from "./YourAppAPIExplorer" import { ViewERDButtonForSiteApps } from "../projects/ViewERDButton" +import { useInstalledApps } from "./useGetInstalledApp" export interface AppsData { app_name: string @@ -15,13 +15,9 @@ export interface AppsData { git_branch?: string } -export const YourApps = () => { +const YourApps = () => { - const { data, error, isLoading } = useFrappeGetCall<{ message: AppsData[] }>('commit.api.meta_data.get_installed_apps', {}, 'get_installed_apps', { - keepPreviousData: true, - revalidateOnFocus: true, - revalidateIfStale: false, - }) + const { data, error, isLoading } = useInstalledApps() if (error) { return
      Error
      @@ -80,4 +76,6 @@ const AppsCard = ({ app }: { app: AppsData }) => {
      ); -}; \ No newline at end of file +}; + +export default YourApps \ No newline at end of file diff --git a/dashboard/src/components/features/meta_apps/useGetInstalledApp.ts b/dashboard/src/components/features/meta_apps/useGetInstalledApp.ts new file mode 100644 index 0000000..b3a7fc6 --- /dev/null +++ b/dashboard/src/components/features/meta_apps/useGetInstalledApp.ts @@ -0,0 +1,43 @@ +import { useMemo } from 'react'; +import { useFrappeGetCall } from 'frappe-react-sdk'; + +interface AppsData { + // Define the structure of your apps data here + name: string; + // Add other properties as needed +} + +export const useInstalledApps = () => { + // First, check if the apps are already available in window.frappe.boot + const bootInstalledApps = useMemo(() => { + // @ts-expect-error + return window?.frappe?.boot?.get_installed_apps || null; + }, []); + + // Use the API call hook with conditional fetching + const { + data: apiInstalledApps, + error, + isLoading + } = useFrappeGetCall<{ message: AppsData[] }>( + 'commit.api.meta_data.get_installed_apps', + {}, + bootInstalledApps === null ? 'get_installed_apps' : null, + { + // Only fetch if boot data is not available + keepPreviousData: true, + revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + } + ); + + // Determine the final apps data + const installedApps = bootInstalledApps ? { message: bootInstalledApps } : apiInstalledApps; + + return { + data: installedApps, + error, + isLoading: isLoading && !bootInstalledApps + }; +}; \ No newline at end of file From 63fb399cc8ef98c21ad854a210cdc7530c4b32bc Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Dec 2024 13:01:50 +0530 Subject: [PATCH 102/110] feat: add preload link for fetching project list with branches in dashboard --- dashboard/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dashboard/index.html b/dashboard/index.html index 2eaa979..bf666cf 100644 --- a/dashboard/index.html +++ b/dashboard/index.html @@ -9,6 +9,8 @@ + Commit - Developer tooling for the Frappeverse From ae6cead83b3df01ce3253eaa008b99851f02e4cd Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Dec 2024 14:06:55 +0530 Subject: [PATCH 103/110] feat: add API for fetching all published commit docs details and refactor related components --- .../commit/doctype/commit_docs/commit_docs.py | 79 +++++++++++++------ commit/www/commit.py | 2 + dashboard/index.html | 2 +- .../meta_apps/useGetCommitDocsDetails.ts | 35 ++++++++ .../src/pages/features/docs/ViewDocs.tsx | 27 ++----- 5 files changed, 100 insertions(+), 45 deletions(-) create mode 100644 dashboard/src/components/features/meta_apps/useGetCommitDocsDetails.ts diff --git a/commit/commit/doctype/commit_docs/commit_docs.py b/commit/commit/doctype/commit_docs/commit_docs.py index 5f493ae..152e3bd 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.py +++ b/commit/commit/doctype/commit_docs/commit_docs.py @@ -51,6 +51,33 @@ def get_docs_sidebar_parent_labels(id:str): return parent_labels_obj +@frappe.whitelist() +def get_all_commit_docs_detail(): + ''' + Get the All Commit Docs Details which are Published + # 1. Get the Commit Docs Document from the route + # 2. Check if the Commit Docs Document Published + # 3. Return the Commit Docs Document + # 4. Get The Sidebar Items for the Commit Docs + # 5. Return the Sidebar Items + ''' + + # Get All the Commit Docs which are Published + all_commit_docs = frappe.get_all('Commit Docs',{'published':1},'name') + + # Maintain the Commit Docs Object + commit_docs_obj = {} + + for commit_docs in all_commit_docs: + commit_docs = frappe.get_doc('Commit Docs',commit_docs.name).as_dict() + + parse_doc = parse_commit_docs(commit_docs) + + commit_docs_obj[commit_docs['route']] = parse_doc + + return commit_docs_obj + + @frappe.whitelist(allow_guest=True) def get_commit_docs_details(route:str): ''' @@ -67,35 +94,11 @@ def get_commit_docs_details(route:str): # Check if the document is published if frappe.db.get_value('Commit Docs',{'route':route},'published'): - # Get the Commit Docs Document commit_docs = frappe.get_doc('Commit Docs',{'route':route}).as_dict() - # Maintain route_map from the sidebar where key is the route and value is the name of the page - route_map = {} - - # Get the Sidebar Items - sidebar_items, route_map = get_sidebar_items(commit_docs.sidebar,route_map) - - # Get the Footer Items - footer_items = get_footer_items(commit_docs.footer) - - # Get the Navbar Items - navbar_items = get_navbar_items(commit_docs.navbar_items) + return parse_commit_docs(commit_docs) - # remove the sidebar from the commit_docs as it is not needed - commit_docs.pop('sidebar') - commit_docs.pop('footer') - commit_docs.pop('navbar_items') - - return { - 'commit_docs': commit_docs, - 'sidebar_items': sidebar_items, - 'footer_items': footer_items, - 'navbar_items': navbar_items, - 'route_map': route_map - } - else: return frappe.throw('Docs Not Published') @@ -103,6 +106,32 @@ def get_commit_docs_details(route:str): return frappe.throw('Docs Not Found') +def parse_commit_docs(commit_docs): + # Maintain route_map from the sidebar where key is the route and value is the name of the page + route_map = {} + + # Get the Sidebar Items + sidebar_items, route_map = get_sidebar_items(commit_docs.sidebar,route_map) + + # Get the Footer Items + footer_items = get_footer_items(commit_docs.footer) + + # Get the Navbar Items + navbar_items = get_navbar_items(commit_docs.navbar_items) + + # remove the sidebar from the commit_docs as it is not needed + commit_docs.pop('sidebar') + commit_docs.pop('footer') + commit_docs.pop('navbar_items') + + return { + 'commit_docs': commit_docs, + 'sidebar_items': sidebar_items, + 'footer_items': footer_items, + 'navbar_items': navbar_items, + 'route_map': route_map + } + def get_footer_items(footer): ''' Get the Footer Items diff --git a/commit/www/commit.py b/commit/www/commit.py index 4bbf913..ced1b6a 100644 --- a/commit/www/commit.py +++ b/commit/www/commit.py @@ -3,6 +3,7 @@ import frappe.sessions import re from commit.api.meta_data import get_installed_apps +from commit.commit.doctype.commit_docs.commit_docs import get_all_commit_docs_detail no_cache = 1 SCRIPT_TAG_PATTERN = re.compile(r"\") @@ -34,6 +35,7 @@ def get_boot(): boot["show_system_apps"] = show_system_apps boot["get_installed_apps"] = get_installed_apps() + boot["get_all_commit_docs_detail"] = get_all_commit_docs_detail() boot_json = frappe.as_json(boot, indent=None, separators=(",", ":")) boot_json = SCRIPT_TAG_PATTERN.sub("", boot_json) diff --git a/dashboard/index.html b/dashboard/index.html index bf666cf..4d0e54f 100644 --- a/dashboard/index.html +++ b/dashboard/index.html @@ -10,7 +10,7 @@ + href="/api/method/commit.api.commit_project.commit_project.get_project_list_with_branches"> Commit - Developer tooling for the Frappeverse diff --git a/dashboard/src/components/features/meta_apps/useGetCommitDocsDetails.ts b/dashboard/src/components/features/meta_apps/useGetCommitDocsDetails.ts new file mode 100644 index 0000000..cb79be9 --- /dev/null +++ b/dashboard/src/components/features/meta_apps/useGetCommitDocsDetails.ts @@ -0,0 +1,35 @@ +import { useMemo } from 'react'; +import { useFrappeGetCall } from 'frappe-react-sdk'; +import { Docs } from '@/pages/features/docs/docs'; + +export const useGetCommitDocsDetails = (ID: string) => { + // First, check if the data is already available in window.frappe.boot + const bootCommitDocsDetails: Docs = useMemo(() => { + // @ts-expect-error + return window?.frappe?.boot?.get_all_commit_docs_detail?.[ID] || null; + }, [ID]); + + // Use the API call hook with conditional fetching + const { + data: apiCommitDocsDetails, + error, + isLoading + } = useFrappeGetCall<{ message: Docs }>( + 'commit.commit.doctype.commit_docs.commit_docs.get_commit_docs_details', + { + route: ID, + }, + bootCommitDocsDetails === null ? 'get_commit_docs_details' : null, + { + // Only fetch if boot data is not available + revalidateOnFocus: false, + revalidateIfStale: false, + revalidateOnReconnect: false, + } + ); + + // Return the data from boot if available, otherwise from the API call + const data = bootCommitDocsDetails || apiCommitDocsDetails?.message; + + return { data, error, isLoading }; +}; \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/ViewDocs.tsx b/dashboard/src/pages/features/docs/ViewDocs.tsx index 9c06ffb..741ff47 100644 --- a/dashboard/src/pages/features/docs/ViewDocs.tsx +++ b/dashboard/src/pages/features/docs/ViewDocs.tsx @@ -1,12 +1,11 @@ import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; -import { useFrappeGetCall } from "frappe-react-sdk"; import { useNavigate, useParams } from "react-router-dom"; -import { Docs } from "./docs"; import { Sidebar } from "./Sidebar"; import { Navbar } from "./Navbar"; import { Footer } from "./Footer"; import { PageContent } from "./PageContent"; +import { useGetCommitDocsDetails } from "@/components/features/meta_apps/useGetCommitDocsDetails"; const ViewDocs = () => { const { ID, pageID } = useParams(); @@ -20,17 +19,7 @@ const ViewDocs = () => { const ViewDocsDetails = ({ ID, pageID }: { ID: string, pageID: string }) => { const navigate = useNavigate(); - const { data, error, isLoading } = useFrappeGetCall<{ - message: Docs; - }>("commit.commit.doctype.commit_docs.commit_docs.get_commit_docs_details", - { - route: ID, - }, - undefined, - { - revalidateOnFocus: false, - revalidateIfStale: false, - }); + const { data, error, isLoading } = useGetCommitDocsDetails(ID); const onPageChange = (pageID: string) => { navigate(`/docs/${ID}/${pageID}`); @@ -43,18 +32,18 @@ const ViewDocsDetails = ({ ID, pageID }: { ID: string, pageID: string }) => { return ; } - if (data && data?.message) { + if (data) { return (
      - +
      {/* Sidebar */}
      -
      +
      ); From 72a5e187aa2c86491b6453af961c9c553604e74c Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Fri, 20 Dec 2024 14:07:36 +0530 Subject: [PATCH 104/110] style: remove background color from MarkdownRenderer for improved styling --- dashboard/src/components/common/MarkdownRenderer/markdown.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/components/common/MarkdownRenderer/markdown.css b/dashboard/src/components/common/MarkdownRenderer/markdown.css index d452b8d..82a488f 100644 --- a/dashboard/src/components/common/MarkdownRenderer/markdown.css +++ b/dashboard/src/components/common/MarkdownRenderer/markdown.css @@ -127,7 +127,7 @@ -webkit-text-size-adjust: 100%; margin: 0; color: var(--fgColor-default); - background-color: var(--bgColor-default); + /* background-color: var(--bgColor-default); */ font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; font-size: 16px; line-height: 1.5; From 9dc69b859f255ca1bc21942814e415fe75fdd1ad Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 24 Dec 2024 12:12:37 +0530 Subject: [PATCH 105/110] feat: enhance MarkdownRenderer with rehype-pretty-code and improve CustomCodeBlock styling --- dashboard/package.json | 2 + .../common/MarkdownRenderer/MDX.tsx | 3 +- .../common/MarkdownRenderer/markdown.css | 16 +-- .../custommdxcomponent/CustomCodeBlock.tsx | 28 ++-- dashboard/yarn.lock | 120 +++++++++++++++++- 5 files changed, 142 insertions(+), 27 deletions(-) diff --git a/dashboard/package.json b/dashboard/package.json index 93a2f28..d97d157 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -62,11 +62,13 @@ "react-router-dom": "^6.14.1", "reactflow": "^11.11.4", "rehype-katex": "^7.0.1", + "rehype-pretty-code": "^0.14.0", "rehype-raw": "^7.0.0", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", "shadcn-ui": "^0.8.0", + "shiki": "^1.24.3", "socket.io-client": "^4.5.1", "swr": "^2.1.5", "tailwind-merge": "^1.13.2", diff --git a/dashboard/src/components/common/MarkdownRenderer/MDX.tsx b/dashboard/src/components/common/MarkdownRenderer/MDX.tsx index 01953e7..d859546 100644 --- a/dashboard/src/components/common/MarkdownRenderer/MDX.tsx +++ b/dashboard/src/components/common/MarkdownRenderer/MDX.tsx @@ -13,6 +13,7 @@ import rehypeKatex from 'rehype-katex'; import rehypeSlug from 'rehype-slug'; import CustomHeading from '@/components/features/custommdxcomponent/CustomHeading'; import CustomCodeBlock from '@/components/features/custommdxcomponent/CustomCodeBlock'; +import rehypePrettyCode from "rehype-pretty-code"; // Custom components const CustomParagraph = ({ children }: { children?: React.ReactNode }) => { @@ -42,7 +43,7 @@ const compileMDX = async (mdxContent: string) => { const compiled = await compile(mdxContent, { outputFormat: 'function-body', remarkPlugins: [remarkMdx, remarkMath, remarkBreaks, remarkGfm], - rehypePlugins: [rehypeSlug, rehypeKatex], + rehypePlugins: [rehypeSlug, rehypeKatex, rehypePrettyCode], }); return String(compiled); }; diff --git a/dashboard/src/components/common/MarkdownRenderer/markdown.css b/dashboard/src/components/common/MarkdownRenderer/markdown.css index 82a488f..6ceaff0 100644 --- a/dashboard/src/components/common/MarkdownRenderer/markdown.css +++ b/dashboard/src/components/common/MarkdownRenderer/markdown.css @@ -127,7 +127,7 @@ -webkit-text-size-adjust: 100%; margin: 0; color: var(--fgColor-default); - /* background-color: var(--bgColor-default); */ + background-color: var(--bgColor-default); font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; font-size: 16px; line-height: 1.5; @@ -237,10 +237,10 @@ font-size: 1em; } - .markdown-body figure { + /* .markdown-body figure { margin: 1em var(--base-size-40); } - + */ .markdown-body hr { box-sizing: content-box; overflow: hidden; @@ -829,7 +829,7 @@ text-decoration: inherit; } - .markdown-body samp { + .markdown-body samp { font-size: 85%; } @@ -838,10 +838,10 @@ } .markdown-body pre>code { - padding: 0; + padding: 4px; margin: 0; word-break: normal; - white-space: pre; + /* white-space: pre; */ background: transparent; border: 0; } @@ -870,8 +870,8 @@ .markdown-body pre tt { display: inline; max-width: auto; - padding: 0; - margin: 0; + padding: 2px; + margin: 2px; overflow: visible; line-height: inherit; word-wrap: normal; diff --git a/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx index 20cfee9..065a030 100644 --- a/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx +++ b/dashboard/src/components/features/custommdxcomponent/CustomCodeBlock.tsx @@ -1,11 +1,11 @@ -import { Button } from "@/components/ui/button"; import { useToast } from "@/components/ui/use-toast"; import { CheckIcon, CopyIcon } from "@radix-ui/react-icons"; -import { useState } from "react"; +import { useRef, useState } from "react"; // Custom Code Block Component -const CustomCodeBlock = ({ children }: { children: React.ReactNode }) => { +const CustomCodeBlock = ({ children, ...props }: { children: React.ReactNode, props?: any }) => { const [isCopied, setIsCopied] = useState(false); + const preRef = useRef(null); const { toast } = useToast() @@ -24,14 +24,9 @@ const CustomCodeBlock = ({ children }: { children: React.ReactNode }) => { return ( -
      -
      -                {children}
      -            
      - -
      + + {children} +
    ); }; diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index 0c2381a..1339c7f 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -1509,6 +1509,48 @@ estree-walker "^2.0.2" picomatch "^4.0.2" +"@shikijs/core@1.24.3": + version "1.24.3" + resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.24.3.tgz#ac8f400a9d66cb68d61a46d0c949adb0dd03fee6" + integrity sha512-VRcf4GYUIkxIchGM9DrapRcxtgojg4IWKUtX5EtW+4PJiGzF2xQqZSv27PJt+WLc18KT3CNLpNWow9JYV5n+Rg== + dependencies: + "@shikijs/engine-javascript" "1.24.3" + "@shikijs/engine-oniguruma" "1.24.3" + "@shikijs/types" "1.24.3" + "@shikijs/vscode-textmate" "^9.3.1" + "@types/hast" "^3.0.4" + hast-util-to-html "^9.0.4" + +"@shikijs/engine-javascript@1.24.3": + version "1.24.3" + resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-1.24.3.tgz#84fd518ef0067a6f4e60a527e3b2fa675a59ec2c" + integrity sha512-De8tNLvYjeK6V0Gb47jIH2M+OKkw+lWnSV1j3HVDFMlNIglmVcTMG2fASc29W0zuFbfEEwKjO8Fe4KYSO6Ce3w== + dependencies: + "@shikijs/types" "1.24.3" + "@shikijs/vscode-textmate" "^9.3.1" + oniguruma-to-es "0.8.0" + +"@shikijs/engine-oniguruma@1.24.3": + version "1.24.3" + resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.3.tgz#e549cb6f2050113ac65994b4e98f4704c3e427e8" + integrity sha512-iNnx950gs/5Nk+zrp1LuF+S+L7SKEhn8k9eXgFYPGhVshKppsYwRmW8tpmAMvILIMSDfrgqZ0w+3xWVQB//1Xw== + dependencies: + "@shikijs/types" "1.24.3" + "@shikijs/vscode-textmate" "^9.3.1" + +"@shikijs/types@1.24.3": + version "1.24.3" + resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-1.24.3.tgz#6700007019cc5c2fa5db32ab1595f01b1e79d969" + integrity sha512-FPMrJ69MNxhRtldRk69CghvaGlbbN3pKRuvko0zvbfa2dXp4pAngByToqS5OY5jvN8D7LKR4RJE8UvzlCOuViw== + dependencies: + "@shikijs/vscode-textmate" "^9.3.1" + "@types/hast" "^3.0.4" + +"@shikijs/vscode-textmate@^9.3.1": + version "9.3.1" + resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-9.3.1.tgz#afda31f8f42cab70a26f3603f52eae3f1c35d2f7" + integrity sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g== + "@socket.io/component-emitter@~3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" @@ -1829,7 +1871,7 @@ dependencies: "@types/unist" "^2" -"@types/hast@^3.0.0": +"@types/hast@^3.0.0", "@types/hast@^3.0.4": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== @@ -2541,6 +2583,11 @@ electron-to-chromium@^1.5.41: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.60.tgz#29944afe568c58c40729e67af0f59f52d4d0ed32" integrity sha512-HcraRUkTKJ+8yA3b10i9qvhUlPBRDlKjn1XGek1zDGVfAKcvi8TsUnImGqLiEm9j6ZulxXIWWIo9BmbkbCTGgA== +emoji-regex-xs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz#e8af22e5d9dbd7f7f22d280af3d19d2aab5b0724" + integrity sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -3253,6 +3300,23 @@ hast-util-to-html@^9.0.0: stringify-entities "^4.0.0" zwitch "^2.0.4" +hast-util-to-html@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.4.tgz#d689c118c875aab1def692c58603e34335a0f5c5" + integrity sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^3.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + hast-util-to-jsx-runtime@^2.0.0: version "2.3.2" resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz#6d11b027473e69adeaa00ca4cfb5bb68e3d282fa" @@ -4494,6 +4558,15 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" +oniguruma-to-es@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-0.8.0.tgz#c61efa9c114a39a009fabccd61c583be28db6e53" + integrity sha512-rY+/a6b+uCgoYIL9itjY0x99UUDHXmGaw7Jjk5ZvM/3cxDJifyxFr/Zm4tTmF6Tre18gAakJo7AzhKUeMNLgHA== + dependencies: + emoji-regex-xs "^1.0.0" + regex "^5.0.2" + regex-recursion "^5.0.0" + optionator@^0.9.3: version "0.9.4" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" @@ -4972,6 +5045,25 @@ regenerator-runtime@^0.14.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== +regex-recursion@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/regex-recursion/-/regex-recursion-5.0.0.tgz#330c14e9e448394210dfd063c6a757d7a293e9bb" + integrity sha512-UwyOqeobrCCqTXPcsSqH4gDhOjD5cI/b8kjngWgSZbxYh5yVjAwTjO5+hAuPRNiuR70+5RlWSs+U9PVcVcW9Lw== + dependencies: + regex-utilities "^2.3.0" + +regex-utilities@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/regex-utilities/-/regex-utilities-2.3.0.tgz#87163512a15dce2908cf079c8960d5158ff43280" + integrity sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng== + +regex@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/regex/-/regex-5.0.2.tgz#291d960467e6499a79ceec022d20a4e0df67c54f" + integrity sha512-/pczGbKIQgfTMRV0XjABvc5RzLqQmwqxLHdQao2RTXPk+pmTXB2P0IaUHYdYyk412YLwUIkaeMd5T+RzVgTqnQ== + dependencies: + regex-utilities "^2.3.0" + rehype-attr@~3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/rehype-attr/-/rehype-attr-3.0.3.tgz#36b9c3d2bd91708f0c56080bc3005cba60dec4a7" @@ -5023,6 +5115,18 @@ rehype-parse@^9.0.0: hast-util-from-html "^2.0.0" unified "^11.0.0" +rehype-pretty-code@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/rehype-pretty-code/-/rehype-pretty-code-0.14.0.tgz#bdf828af4575737cc02204fb24d8097e6f010d37" + integrity sha512-hBeKF/Wkkf3zyUS8lal9RCUuhypDWLQc+h9UrP9Pav25FUm/AQAVh4m5gdvJxh4Oz+U+xKvdsV01p1LdvsZTiQ== + dependencies: + "@types/hast" "^3.0.4" + hast-util-to-string "^3.0.0" + parse-numeric-range "^1.3.0" + rehype-parse "^9.0.0" + unified "^11.0.5" + unist-util-visit "^5.0.0" + rehype-prism-plus@2.0.0, rehype-prism-plus@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/rehype-prism-plus/-/rehype-prism-plus-2.0.0.tgz#75b1e2d0dd7496125987a1732cb7d560de02a0fd" @@ -5271,6 +5375,18 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shiki@^1.24.3: + version "1.24.3" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.24.3.tgz#50eeacd8ce88d054b3ecc6c542283bf7a77a12f6" + integrity sha512-eMeX/ehE2IDKVs71kB4zVcDHjutNcOtm+yIRuR4sA6ThBbdFI0DffGJiyoKCodj0xRGxIoWC3pk/Anmm5mzHmA== + dependencies: + "@shikijs/core" "1.24.3" + "@shikijs/engine-javascript" "1.24.3" + "@shikijs/engine-oniguruma" "1.24.3" + "@shikijs/types" "1.24.3" + "@shikijs/vscode-textmate" "^9.3.1" + "@types/hast" "^3.0.4" + signal-exit@^3.0.2, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -5591,7 +5707,7 @@ undici-types@~6.19.2: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== -unified@^11.0.0, unified@^11.0.3, unified@~11.0.0: +unified@^11.0.0, unified@^11.0.3, unified@^11.0.5, unified@~11.0.0: version "11.0.5" resolved "https://registry.yarnpkg.com/unified/-/unified-11.0.5.tgz#f66677610a5c0a9ee90cab2b8d4d66037026d9e1" integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA== From 6cc7f4741fc3bb3aafdd8c2692ebce3f3b65b474 Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Tue, 24 Dec 2024 14:26:58 +0530 Subject: [PATCH 106/110] chore: update vite version to ^6.0.5 in package.json --- dashboard/package.json | 2 +- dashboard/yarn.lock | 428 ++++++++++++++++++++++++++--------------- 2 files changed, 279 insertions(+), 151 deletions(-) diff --git a/dashboard/package.json b/dashboard/package.json index d97d157..50a9ef8 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -88,6 +88,6 @@ "postcss": "^8.4.26", "tailwindcss": "^3.3.3", "typescript": "^5.0.2", - "vite": "^4.4.0" + "vite": "^6.0.5" } } diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index 1339c7f..a8edf41 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -262,115 +262,125 @@ resolved "https://registry.yarnpkg.com/@dagrejs/graphlib/-/graphlib-2.2.4.tgz#d77bfa9ff49e2307c0c6e6b8b26b5dd3c05816c4" integrity sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw== -"@esbuild/android-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" - integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== - -"@esbuild/android-arm@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" - integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== - -"@esbuild/android-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" - integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== - -"@esbuild/darwin-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" - integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== - -"@esbuild/darwin-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" - integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== - -"@esbuild/freebsd-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" - integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== - -"@esbuild/freebsd-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" - integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== - -"@esbuild/linux-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" - integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== - -"@esbuild/linux-arm@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" - integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== - -"@esbuild/linux-ia32@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" - integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== - -"@esbuild/linux-loong64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" - integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== - -"@esbuild/linux-mips64el@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" - integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== - -"@esbuild/linux-ppc64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" - integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== - -"@esbuild/linux-riscv64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" - integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== - -"@esbuild/linux-s390x@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" - integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== - -"@esbuild/linux-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" - integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== - -"@esbuild/netbsd-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" - integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== - -"@esbuild/openbsd-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" - integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== - -"@esbuild/sunos-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" - integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== - -"@esbuild/win32-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" - integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== - -"@esbuild/win32-ia32@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" - integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== - -"@esbuild/win32-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" - integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== +"@esbuild/aix-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" + integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== + +"@esbuild/android-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" + integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== + +"@esbuild/android-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" + integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== + +"@esbuild/android-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" + integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== + +"@esbuild/darwin-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" + integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== + +"@esbuild/darwin-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" + integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== + +"@esbuild/freebsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" + integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== + +"@esbuild/freebsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" + integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== + +"@esbuild/linux-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" + integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== + +"@esbuild/linux-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" + integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== + +"@esbuild/linux-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" + integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== + +"@esbuild/linux-loong64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" + integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== + +"@esbuild/linux-mips64el@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" + integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== + +"@esbuild/linux-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" + integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== + +"@esbuild/linux-riscv64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" + integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== + +"@esbuild/linux-s390x@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" + integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== + +"@esbuild/linux-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" + integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== + +"@esbuild/netbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" + integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== + +"@esbuild/openbsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" + integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== + +"@esbuild/openbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" + integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== + +"@esbuild/sunos-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" + integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== + +"@esbuild/win32-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" + integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== + +"@esbuild/win32-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" + integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== + +"@esbuild/win32-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" + integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== "@eslint-community/eslint-utils@^4.2.0": version "4.4.1" @@ -1509,6 +1519,101 @@ estree-walker "^2.0.2" picomatch "^4.0.2" +"@rollup/rollup-android-arm-eabi@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz#9bd38df6a29afb7f0336d988bc8112af0c8816c0" + integrity sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw== + +"@rollup/rollup-android-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz#bd1a98390e15b76eeef907175a37c5f0f9e4d214" + integrity sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew== + +"@rollup/rollup-darwin-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz#bc6fa8a2cc77b5f367424e5e994e3537524e6879" + integrity sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw== + +"@rollup/rollup-darwin-x64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz#76059c91f06b17406347b127df10f065283b2e61" + integrity sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng== + +"@rollup/rollup-freebsd-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz#83178315c0be4b4c8c1fd835e1952d2dc1eb4e6e" + integrity sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw== + +"@rollup/rollup-freebsd-x64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz#1ef24fa0576bf7899a0a0a649156606dbd7a0d46" + integrity sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w== + +"@rollup/rollup-linux-arm-gnueabihf@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz#443a6f5681bf4611caae42988994a6d8ee676216" + integrity sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A== + +"@rollup/rollup-linux-arm-musleabihf@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz#9738b27184102228637a683e5f35b22ea352394f" + integrity sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ== + +"@rollup/rollup-linux-arm64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz#b5e9d5e30ff36a19bedd29c715ba18a1889ff269" + integrity sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA== + +"@rollup/rollup-linux-arm64-musl@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz#1d8f68f0829b57f746ec03432ad046f1af014a98" + integrity sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA== + +"@rollup/rollup-linux-loongarch64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz#07027feb883408e74a3002c8e50caaedd288ae38" + integrity sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz#544ce1b0847a9c1240425e86f33daceac7ec4e12" + integrity sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w== + +"@rollup/rollup-linux-riscv64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz#64be13d51852ec1e2dfbd25d997ed5f42f35ea6d" + integrity sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ== + +"@rollup/rollup-linux-s390x-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz#31f51e1e05c6264552d03875d9e2e673f0fd86e3" + integrity sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g== + +"@rollup/rollup-linux-x64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz#f4c95b26f4ad69ebdb64b42f0ae4da2a0f617958" + integrity sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ== + +"@rollup/rollup-linux-x64-musl@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz#ab7be89192f72beb9ea6e2386186fefde4f69d82" + integrity sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA== + +"@rollup/rollup-win32-arm64-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz#7f12efb8240b238346951559998802722944421e" + integrity sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig== + +"@rollup/rollup-win32-ia32-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz#353d14d6eee943004d129796e4feddd3aa260921" + integrity sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng== + +"@rollup/rollup-win32-x64-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz#c82f04a09ba481e13857d6f2516e072aaa51b7f4" + integrity sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg== + "@shikijs/core@1.24.3": version "1.24.3" resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.24.3.tgz#ac8f400a9d66cb68d61a46d0c949adb0dd03fee6" @@ -1854,7 +1959,7 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0": +"@types/estree@*", "@types/estree@1.0.6", "@types/estree@^1.0.0": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== @@ -2657,33 +2762,35 @@ esast-util-from-js@^2.0.0: esast-util-from-estree "^2.0.0" vfile-message "^4.0.0" -esbuild@^0.18.10: - version "0.18.20" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" - integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== +esbuild@0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.0.tgz#f2d470596885fcb2e91c21eb3da3b3c89c0b55e7" + integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== optionalDependencies: - "@esbuild/android-arm" "0.18.20" - "@esbuild/android-arm64" "0.18.20" - "@esbuild/android-x64" "0.18.20" - "@esbuild/darwin-arm64" "0.18.20" - "@esbuild/darwin-x64" "0.18.20" - "@esbuild/freebsd-arm64" "0.18.20" - "@esbuild/freebsd-x64" "0.18.20" - "@esbuild/linux-arm" "0.18.20" - "@esbuild/linux-arm64" "0.18.20" - "@esbuild/linux-ia32" "0.18.20" - "@esbuild/linux-loong64" "0.18.20" - "@esbuild/linux-mips64el" "0.18.20" - "@esbuild/linux-ppc64" "0.18.20" - "@esbuild/linux-riscv64" "0.18.20" - "@esbuild/linux-s390x" "0.18.20" - "@esbuild/linux-x64" "0.18.20" - "@esbuild/netbsd-x64" "0.18.20" - "@esbuild/openbsd-x64" "0.18.20" - "@esbuild/sunos-x64" "0.18.20" - "@esbuild/win32-arm64" "0.18.20" - "@esbuild/win32-ia32" "0.18.20" - "@esbuild/win32-x64" "0.18.20" + "@esbuild/aix-ppc64" "0.24.0" + "@esbuild/android-arm" "0.24.0" + "@esbuild/android-arm64" "0.24.0" + "@esbuild/android-x64" "0.24.0" + "@esbuild/darwin-arm64" "0.24.0" + "@esbuild/darwin-x64" "0.24.0" + "@esbuild/freebsd-arm64" "0.24.0" + "@esbuild/freebsd-x64" "0.24.0" + "@esbuild/linux-arm" "0.24.0" + "@esbuild/linux-arm64" "0.24.0" + "@esbuild/linux-ia32" "0.24.0" + "@esbuild/linux-loong64" "0.24.0" + "@esbuild/linux-mips64el" "0.24.0" + "@esbuild/linux-ppc64" "0.24.0" + "@esbuild/linux-riscv64" "0.24.0" + "@esbuild/linux-s390x" "0.24.0" + "@esbuild/linux-x64" "0.24.0" + "@esbuild/netbsd-x64" "0.24.0" + "@esbuild/openbsd-arm64" "0.24.0" + "@esbuild/openbsd-x64" "0.24.0" + "@esbuild/sunos-x64" "0.24.0" + "@esbuild/win32-arm64" "0.24.0" + "@esbuild/win32-ia32" "0.24.0" + "@esbuild/win32-x64" "0.24.0" escalade@^3.2.0: version "3.2.0" @@ -3039,7 +3146,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: +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== @@ -4768,7 +4875,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^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.26, postcss@^8.4.27, postcss@^8.4.47: +postcss@^8.4.26, postcss@^8.4.47, postcss@^8.4.49: version "8.4.49" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== @@ -5306,11 +5413,32 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rollup@^3.27.1: - version "3.29.5" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.5.tgz#8a2e477a758b520fb78daf04bca4c522c1da8a54" - integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w== +rollup@^4.23.0: + version "4.29.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.29.1.tgz#a9aaaece817e5f778489e5bf82e379cc8a5c05bc" + integrity sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw== + dependencies: + "@types/estree" "1.0.6" optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.29.1" + "@rollup/rollup-android-arm64" "4.29.1" + "@rollup/rollup-darwin-arm64" "4.29.1" + "@rollup/rollup-darwin-x64" "4.29.1" + "@rollup/rollup-freebsd-arm64" "4.29.1" + "@rollup/rollup-freebsd-x64" "4.29.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.29.1" + "@rollup/rollup-linux-arm-musleabihf" "4.29.1" + "@rollup/rollup-linux-arm64-gnu" "4.29.1" + "@rollup/rollup-linux-arm64-musl" "4.29.1" + "@rollup/rollup-linux-loongarch64-gnu" "4.29.1" + "@rollup/rollup-linux-powerpc64le-gnu" "4.29.1" + "@rollup/rollup-linux-riscv64-gnu" "4.29.1" + "@rollup/rollup-linux-s390x-gnu" "4.29.1" + "@rollup/rollup-linux-x64-gnu" "4.29.1" + "@rollup/rollup-linux-x64-musl" "4.29.1" + "@rollup/rollup-win32-arm64-msvc" "4.29.1" + "@rollup/rollup-win32-ia32-msvc" "4.29.1" + "@rollup/rollup-win32-x64-msvc" "4.29.1" fsevents "~2.3.2" run-parallel@^1.1.9: @@ -5859,16 +5987,16 @@ vfile@^6.0.0: "@types/unist" "^3.0.0" vfile-message "^4.0.0" -vite@^4.4.0: - version "4.5.5" - resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.5.tgz#639b9feca5c0a3bfe3c60cb630ef28bf219d742e" - integrity sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ== +vite@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.5.tgz#1d0fbdb3ffe61e944089abeddb7d2c509420acfd" + integrity sha512-akD5IAH/ID5imgue2DYhzsEwCi0/4VKY31uhMLEYJwPP4TiUp8pL5PIK+Wo7H8qT8JY9i+pVfPydcFPYD1EL7g== dependencies: - esbuild "^0.18.10" - postcss "^8.4.27" - rollup "^3.27.1" + esbuild "0.24.0" + postcss "^8.4.49" + rollup "^4.23.0" optionalDependencies: - fsevents "~2.3.2" + fsevents "~2.3.3" wcwidth@^1.0.1: version "1.0.1" From f7f41555ec87aa8f05f0789280b15ed4947ebf4b Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 28 Dec 2024 16:59:11 +0530 Subject: [PATCH 107/110] feat: add Milkdown MarkdownEditor component and related styles --- dashboard/package.json | 4 + .../common/MarkdownEditor/MarkdownEditor.tsx | 37 + .../common/MarkdownEditor/markdown.css | 7 + dashboard/yarn.lock | 1250 ++++++++++++++++- 4 files changed, 1296 insertions(+), 2 deletions(-) create mode 100644 dashboard/src/components/common/MarkdownEditor/MarkdownEditor.tsx create mode 100644 dashboard/src/components/common/MarkdownEditor/markdown.css diff --git a/dashboard/package.json b/dashboard/package.json index 50a9ef8..956e378 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -18,6 +18,10 @@ "@mdx-js/mdx": "^3.1.0", "@mdx-js/react": "^3.1.0", "@mdx-js/rollup": "^3.1.0", + "@milkdown/crepe": "^7.5.9", + "@milkdown/kit": "^7.5.9", + "@milkdown/react": "^7.5.9", + "@milkdown/theme-nord": "^7.5.9", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.0.4", "@radix-ui/react-avatar": "^1.0.3", diff --git a/dashboard/src/components/common/MarkdownEditor/MarkdownEditor.tsx b/dashboard/src/components/common/MarkdownEditor/MarkdownEditor.tsx new file mode 100644 index 0000000..7a22fee --- /dev/null +++ b/dashboard/src/components/common/MarkdownEditor/MarkdownEditor.tsx @@ -0,0 +1,37 @@ +import { Crepe } from '@milkdown/crepe'; +import '@milkdown/crepe/theme/common/style.css' +import '@milkdown/crepe/theme/frame.css'; +import { useEffect } from 'react'; +import { Editor } from '@milkdown/kit/core'; +import './markdown.css' + +export interface MarkdownEditorProps { + value: string; + setCrepeInstance: React.Dispatch | null>> +} + +const MarkdownEditor = ({ value, setCrepeInstance }: MarkdownEditorProps) => { + + useEffect(() => { + const crepe = new Crepe({ + root: '#editor', + defaultValue: value, + }).create() + setCrepeInstance(crepe); + + return () => { + crepe.then((editor) => { + editor.destroy(); + }); + }; + }, []); + + return ( +
    + {/* The editor will be initialized here */} +
    + + ); +}; + +export default MarkdownEditor \ No newline at end of file diff --git a/dashboard/src/components/common/MarkdownEditor/markdown.css b/dashboard/src/components/common/MarkdownEditor/markdown.css new file mode 100644 index 0000000..7bbf3ba --- /dev/null +++ b/dashboard/src/components/common/MarkdownEditor/markdown.css @@ -0,0 +1,7 @@ +.milkdown .ProseMirror { + padding:0 !important; +} +.milkdown .ProseMirror h1, .milkdown .ProseMirror h2, .milkdown .ProseMirror h3, .milkdown .ProseMirror h4, .milkdown .ProseMirror h5, .milkdown .ProseMirror h6 { + font-family: inherit; + font-weight: 600; +} \ No newline at end of file diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index a8edf41..f0041ad 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -20,6 +20,237 @@ resolved "https://registry.yarnpkg.com/@antfu/ni/-/ni-0.21.12.tgz#54d33cf0e6d35cb2ec12ab3d5092e4904540b7c0" integrity sha512-2aDL3WUv8hMJb2L3r/PIQWsTLyq7RQr3v9xD16fiz6O8ys1xEyLhhTOv8gxtZvJiTzjTF5pHoArvRdesGL1DMQ== +"@atomico/hooks@^4.1.2": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@atomico/hooks/-/hooks-4.4.1.tgz#cd9f7aece04d8436c7e008825f5f2b042fc2052c" + integrity sha512-Q5q7X6tdCoqov75mAIAeTXUqHJGx/alfBCmYSwdEsWmAdGeDWmikB2UkWJwtJ32n13MMY5Ny+VNiiaEHLafdoA== + dependencies: + "@atomico/use-attributes" "^2.0.1" + "@atomico/use-child-nodes" "^1.0.1" + "@atomico/use-click-coordinates" "^1.0.1" + "@atomico/use-click-press" "^1.0.1" + "@atomico/use-copy" "^1.0.1" + "@atomico/use-css-light-dom" "^1.0.1" + "@atomico/use-current-value" "^1.0.1" + "@atomico/use-debounce-state" "^1.0.1" + "@atomico/use-disabled" "^2.0.1" + "@atomico/use-drag-resize" "^1.0.0" + "@atomico/use-form" "^1.0.1" + "@atomico/use-internals" "^1.0.1" + "@atomico/use-intersection-observer" "^1.1.0" + "@atomico/use-keyboard" "^1.1.0" + "@atomico/use-listener" "^1.1.0" + "@atomico/use-media-query" "^1.0.1" + "@atomico/use-mutation-observer" "^2.0.2" + "@atomico/use-parallax" "^1.0.1" + "@atomico/use-parent" "^1.1.1" + "@atomico/use-prop-proxy" "^1.0.1" + "@atomico/use-reflect-event" "^1.0.1" + "@atomico/use-render" "^1.1.1" + "@atomico/use-resize-observer" "^1.1.0" + "@atomico/use-resize-state" "^1.0.1" + "@atomico/use-responsive-state" "^1.0.1" + "@atomico/use-router" "^1.2.0" + "@atomico/use-script" "^1.0.1" + "@atomico/use-slot" "^1.0.2" + "@atomico/use-value-history" "^1.0.1" + +"@atomico/use-attributes@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-attributes/-/use-attributes-2.0.1.tgz#94cd46aef6dbf8964b82061d9f1dabf0aebe21b6" + integrity sha512-YmnUYJAoQsNmY0zK55E7DijvvSl5EilWirHVzyeRVacphKAWYiphj5S0lz+8d2ZQDebw/noWG8PdSLsk84z3wA== + dependencies: + "@atomico/use-mutation-observer" "*" + +"@atomico/use-child-nodes@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-child-nodes/-/use-child-nodes-1.0.1.tgz#25c3fadc6497e7e2f5cdd511fc0ba945e6208001" + integrity sha512-Mjz0al79bh2TrLB6wuNImylhePtVQ5PpGYrVazGwzzmlBSRh1LYJq0QcvcvlUw2DKPkd697yFVaNgMwtQMrkjQ== + +"@atomico/use-click-coordinates@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-click-coordinates/-/use-click-coordinates-1.0.1.tgz#846deffd47f8cd9c16d50dc178d60c54f68c3c7c" + integrity sha512-u+6DpSDsFyby5+krDF4a+8xhDibFmCNPUTMRElYey9/D+khgBiw9anuYniKJyplXMkI5ns3ev7dxMQPMfMj5lA== + dependencies: + "@atomico/use-current-value" "*" + "@atomico/use-listener" "*" + +"@atomico/use-click-press@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-click-press/-/use-click-press-1.0.1.tgz#c77868cb79976d6f02afec978d5379b9b81e3d0a" + integrity sha512-vLhoStp1RXX0AysqolS8RYd1vSDKhOJU9QK45D/vtu4uqb1pZoT7sWMcQUIR7XgM4xoUkEI8Z/8ej1UrLpZhyA== + dependencies: + "@atomico/use-listener" "*" + +"@atomico/use-copy@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-copy/-/use-copy-1.0.1.tgz#36d8da2618842820230e22d538e7b63b12587c9c" + integrity sha512-ces7MxytvCpDuGHHpeap2uZ+CJeKi++tWMKK5uwQ8LjsyuFAi7EP/JkBmaSoQzYp4N9uWlNkJnL9zJfoi+CaQQ== + +"@atomico/use-css-light-dom@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-css-light-dom/-/use-css-light-dom-1.0.1.tgz#f093dc32c2d685ad08ef8ae315327f914c1e864b" + integrity sha512-sClSNYbrnTTUqW9LiJrSi5BjVyPP1bxWWvWT+kiYIU+e6UX6gaR7wCoZ8m7B/ezTukMXjcQdOLlq4RsqxUGnXQ== + +"@atomico/use-current-value@*", "@atomico/use-current-value@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-current-value/-/use-current-value-1.0.1.tgz#880f11d5ded2b12d2df9379029c6664ead21ab93" + integrity sha512-d59warzhAmWyOi2VSWzXH1hw3Pafnao30y5h0D6IFs+NMPibLLybeupdwHqtsjTQlAov7Ak7Q940tzKdgGasDw== + +"@atomico/use-debounce-state@*", "@atomico/use-debounce-state@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-debounce-state/-/use-debounce-state-1.0.1.tgz#cfab0ac2114ce32d3dd82daf958624e000e94398" + integrity sha512-vCBGP0nDxxU+RTJ4yHI0JeGeWawEf/6UMj5X0tt0Gk5XKLE/kqKBgWG0uFUh33bbhW1eXuGboeB+/qcm2b8FYw== + +"@atomico/use-disabled@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-disabled/-/use-disabled-2.0.1.tgz#f0a19e574449ede64b2ca361d108bef003167e76" + integrity sha512-73IcqP2Rpd41j5TVjB823J/J5q6i1F2ZEs2BZuDRy0YRbUYAkDsi+agsuqWWiWNAxezI4zc+wYWj8GOeqilXNA== + dependencies: + "@atomico/use-mutation-observer" "*" + "@atomico/use-parent" "*" + +"@atomico/use-drag-resize@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@atomico/use-drag-resize/-/use-drag-resize-1.0.0.tgz#841d5622b43d181cecaac3055300ea5da976ee58" + integrity sha512-+wSCARzFmOrURQKbqS0ki+fyQdNnQQosg3/Ov/PJMFLkdkCyHw9lgNjIhyHRo71AqN2hudiLC1Gtfgs5oQe/fA== + dependencies: + "@atomico/use-debounce-state" "*" + "@atomico/use-listener" "*" + +"@atomico/use-form@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-form/-/use-form-1.0.1.tgz#44235dbfd4a814d80ed8cf546f5b3f59e34e8ec2" + integrity sha512-N3RTdUHQlJsJNF4fPV3qj1fK9HPYRrKIYyq410PGICfm4VrTsU2Dbl/eBBnWXIH3MT4VXpUsy3jRk3EFJ8wYDA== + dependencies: + "@atomico/use-listener" "*" + "@atomico/use-parent" "*" + "@atomico/use-render" "*" + +"@atomico/use-internals@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-internals/-/use-internals-1.0.1.tgz#2eca8c798250982dccfbd1ca9ac1f90710792360" + integrity sha512-qLHWzW/lsq9KyoC6v8HM+WiVsbGd2oUy7rl4x/dsouEW/E9qcTsTVeB8tMGL6O+ixYq5fj9BxCuGl49sU2zqIQ== + +"@atomico/use-intersection-observer@*", "@atomico/use-intersection-observer@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@atomico/use-intersection-observer/-/use-intersection-observer-1.1.0.tgz#6c6bf845f8c60f11ae4a909ddf6350965baa27ff" + integrity sha512-0p1X6PSpoztM1wcL0wcO//g2fODSwqWETS4cL+X+3nW5Yjc5d++kjvHq0q2GvhN4VvCAZX9jod3I8iM2eXWWZg== + +"@atomico/use-keyboard@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@atomico/use-keyboard/-/use-keyboard-1.1.0.tgz#d386b418640ad6168928832535778c7eab4b5a02" + integrity sha512-VGA2jDh5nD361IColbRztN4/Wcydhx0MhLZ9emIPtvPsfzUyOdI7mm47OvlnzliaCUnu96G2DuMih9AnR+XzeA== + dependencies: + "@atomico/use-current-value" "*" + "@atomico/use-listener" "*" + +"@atomico/use-listener@*", "@atomico/use-listener@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@atomico/use-listener/-/use-listener-1.1.0.tgz#8db9cd9355320cb79f1147e96518ecca1a3c220b" + integrity sha512-d7LcW/Rvokfpb/FBBDaBedLygNJmIaznIgDc2xkUxfQFiXyzMAzsNAAHzY0ZEddiYKtxdbkwrZotDDWkhC6/ug== + dependencies: + "@atomico/use-current-value" "*" + +"@atomico/use-media-query@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-media-query/-/use-media-query-1.0.1.tgz#214e4e9d609cda3d80790ad6ae3a640826945e03" + integrity sha512-7mWFsfs1PzoFXjpa08SZuAN5Ut9UXGNSc/5U9odAJgGvSRnbAoVTguDpHsHVyEAKVt6lRGJPGIytWaVpuzyyWg== + +"@atomico/use-mutation-observer@*", "@atomico/use-mutation-observer@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@atomico/use-mutation-observer/-/use-mutation-observer-2.0.2.tgz#fcf83fbefa65350580e934479f8cd263372475ca" + integrity sha512-l5upQLTMSDvwCEq0oXL56vKtmg4SykKSMcNJsgA503hZ35AXmB0LJMz4+dfBCVcahxV7kT0RUnAb9ZE0Q+8rwA== + dependencies: + "@atomico/use-current-value" "*" + "@atomico/use-ref-values" "*" + +"@atomico/use-parallax@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-parallax/-/use-parallax-1.0.1.tgz#dc4ceb0dcae57080e116cceb8e01d3474614d1d1" + integrity sha512-0swK5Wr6ZD19gCql9iDSE8FlhJ67Ji+odVzhu4CdmU909e1B4Ob16rU5UuHnbDphAh2NZQ780O9CRhuxOUqWRw== + dependencies: + "@atomico/use-debounce-state" "*" + "@atomico/use-intersection-observer" "*" + "@atomico/use-listener" "*" + +"@atomico/use-parent@*", "@atomico/use-parent@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@atomico/use-parent/-/use-parent-1.1.1.tgz#5157854363cfaaad60a0e3e10b281f0a0ce873a8" + integrity sha512-a/gaEH9lVUgoc/ufyLCTjAZiOjRLBtZQLTV4V2DD9MKHQQsL6PColeDk9Qbf6RONo77cfJ60MN+ctjhu98Y8Ow== + +"@atomico/use-prop-proxy@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-prop-proxy/-/use-prop-proxy-1.0.1.tgz#51910110f661010d77c61b7eece2208bfd60e8bb" + integrity sha512-20j1nn8HL52iSo6Y0v210/I90+usm3N7VNcHOYQIjRhiB7YwOqAJhKlbWQwXSEV5pFBhwUGu+Ks9FQdvJG3Esg== + dependencies: + "@atomico/use-current-value" "*" + +"@atomico/use-ref-values@*": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-ref-values/-/use-ref-values-1.0.1.tgz#6678ed5784db4fe9629d9b47d53bb86668d95bf1" + integrity sha512-IFuwav8IkZ9uSFGscPiubYZnfSbdz2yV4xXdEClBq6IiViP0j8cBisE6YB7eAATJ/EHf7uhIBQGL5LOCk8Vi7A== + +"@atomico/use-reflect-event@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-reflect-event/-/use-reflect-event-1.0.1.tgz#41b2004c03da61b127c0d216f6928ac5543ed3cb" + integrity sha512-HFAREdUlGp48PlhQ9UNfPX7DNI6GgqfmK61yoq3/F9KJow/48ZYnEPlyYy1/GxAeHOTnCK4C8OhclHH2jg8Gzw== + dependencies: + "@atomico/use-listener" "*" + +"@atomico/use-render@*", "@atomico/use-render@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@atomico/use-render/-/use-render-1.1.1.tgz#1b3902e293dd2f4ad871896fab6d727a0d243dd0" + integrity sha512-SkXTapKVDU/8PzP2z3psOPi3hoKWckSo0T/Q/HSxeu7TGbIpLTsn9jugWZG/rqzTOToOnhLaZ8s0qEEXCsL7ag== + +"@atomico/use-resize-observer@*", "@atomico/use-resize-observer@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@atomico/use-resize-observer/-/use-resize-observer-1.1.0.tgz#3b71a2614e9f395e7b2a7a1497b9a82c6ba8cae7" + integrity sha512-NcFs6G4dFwckO4IPrCzEpPEn1btuHZlHrrvaJnDCW+mf0UuEynwpCUD/264rkVIp5jfdAq4WTE3CBmBm7Nk89g== + dependencies: + "@atomico/use-current-value" "*" + +"@atomico/use-resize-state@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-resize-state/-/use-resize-state-1.0.1.tgz#858a17549f4f3971c2c19131633847cffa9a178b" + integrity sha512-4gAklY6MxluHCPvC+4oM1c4ArqzDhPRMoSx1egM4OopEew9MwPJymKCCKbKpMe0SIjayAZv9Y2ZdYopn0xrwhQ== + dependencies: + "@atomico/use-resize-observer" "*" + "@uppercod/match-media" "*" + +"@atomico/use-responsive-state@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-responsive-state/-/use-responsive-state-1.0.1.tgz#6d2145c2cd029eb71c37b626d9f1ece6de106d2a" + integrity sha512-OXjVEBtZRAO5S+mEHe7Lb0r3eDonzGhDCLK1slQwc0N09oxUbz18lSrOPvWB05ezL9fitrxfY+auAIB7AIAUPA== + dependencies: + "@uppercod/match-media" "^1.1.0" + +"@atomico/use-router@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@atomico/use-router/-/use-router-1.2.0.tgz#354f419f594138a73304cd03ef8ee79bce7e8879" + integrity sha512-FgrS4g/4usVZFw+rukVUnlHdV6oNUPXW/+2syB0Tbe+XlrXZQlCpu2yw79B3TNazlky5uAnXLEdRbrPtkWzjxA== + dependencies: + "@atomico/use-current-value" "*" + "@atomico/use-listener" "*" + "@uppercod/exp-route" "^1.4.2" + +"@atomico/use-script@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-script/-/use-script-1.0.1.tgz#ea23fe1bfece8a458d9a4fb2d04836200948d64c" + integrity sha512-FXVlQrXVfkbqHzgOkkoE9RmuTlZ2m6Kp64JgM1+jsHL+LpHFtAI7vIRnzyfGA0XvLXESgU8391qPY5z8lxpY7Q== + +"@atomico/use-slot@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@atomico/use-slot/-/use-slot-1.0.2.tgz#0e92818c3e7267790b8f70d67a667885a822d421" + integrity sha512-FLtqpbG1p4c3HSOWiNiGlj6cRbzZks+Nmu04uOZE1gZWqUgun024rqHKLsYcsNlumjPvr4Z/XtioUoFEZuowtQ== + dependencies: + "@atomico/use-listener" "*" + +"@atomico/use-value-history@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@atomico/use-value-history/-/use-value-history-1.0.1.tgz#74ba40c382936f835c80435d2e67235216f32286" + integrity sha512-a0mtNNQ7AXOtJF93ySqp0sw1AQg6GiAEtoThpePEH/CCU07tyW2lKsAINU4/SYxZKYhyMbqBTuziK4D7gixFXg== + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": version "7.26.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" @@ -250,6 +481,341 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.3.2", "@codemirror/autocomplete@^6.7.1": + version "6.18.4" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.4.tgz#4394f55d6771727179f2e28a871ef46bbbeb11b1" + integrity sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.17.0" + "@lezer/common" "^1.0.0" + +"@codemirror/commands@^6.0.0", "@codemirror/commands@^6.2.4": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.7.1.tgz#04561e95bc0779eaa49efd63e916c4efb3bbf6d6" + integrity sha512-llTrboQYw5H4THfhN4U3qCnSZ1SOJ60ohhz+SzU0ADGtwlc533DtklQP0vSFaQuCPDn3BPpOd1GbbnUtwNjsrw== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.4.0" + "@codemirror/view" "^6.27.0" + "@lezer/common" "^1.1.0" + +"@codemirror/lang-angular@^0.1.0": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@codemirror/lang-angular/-/lang-angular-0.1.3.tgz#83035e7e9e1f0e2ba466e83d778407b519089a28" + integrity sha512-xgeWGJQQl1LyStvndWtruUvb4SnBZDAu/gvFH/ZU+c0W25tQR8e5hq7WTwiIY2dNxnf+49mRiGI/9yxIwB6f5w== + dependencies: + "@codemirror/lang-html" "^6.0.0" + "@codemirror/lang-javascript" "^6.1.2" + "@codemirror/language" "^6.0.0" + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.3.3" + +"@codemirror/lang-cpp@^6.0.0": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-cpp/-/lang-cpp-6.0.2.tgz#076c98340c3beabde016d7d83e08eebe17254ef9" + integrity sha512-6oYEYUKHvrnacXxWxYa6t4puTlbN3dgV662BDfSH8+MfjQjVmP697/KYTDOqpxgerkvoNm7q5wlFMBeX8ZMocg== + dependencies: + "@codemirror/language" "^6.0.0" + "@lezer/cpp" "^1.0.0" + +"@codemirror/lang-css@^6.0.0", "@codemirror/lang-css@^6.2.0": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-css/-/lang-css-6.3.1.tgz#763ca41aee81bb2431be55e3cfcc7cc8e91421a3" + integrity sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@lezer/common" "^1.0.2" + "@lezer/css" "^1.1.7" + +"@codemirror/lang-go@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-go/-/lang-go-6.0.1.tgz#598222c90f56eae28d11069c612ca64d0306b057" + integrity sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.6.0" + "@codemirror/state" "^6.0.0" + "@lezer/common" "^1.0.0" + "@lezer/go" "^1.0.0" + +"@codemirror/lang-html@^6.0.0": + version "6.4.9" + resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-6.4.9.tgz#d586f2cc9c341391ae07d1d7c545990dfa069727" + integrity sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/lang-css" "^6.0.0" + "@codemirror/lang-javascript" "^6.0.0" + "@codemirror/language" "^6.4.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.17.0" + "@lezer/common" "^1.0.0" + "@lezer/css" "^1.1.0" + "@lezer/html" "^1.3.0" + +"@codemirror/lang-java@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-java/-/lang-java-6.0.1.tgz#03bd06334da7c8feb9dff6db01ac6d85bd2e48bb" + integrity sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg== + dependencies: + "@codemirror/language" "^6.0.0" + "@lezer/java" "^1.0.0" + +"@codemirror/lang-javascript@^6.0.0", "@codemirror/lang-javascript@^6.1.2": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz#7141090b22994bef85bcc5608a3bc1257f2db2ad" + integrity sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.6.0" + "@codemirror/lint" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.17.0" + "@lezer/common" "^1.0.0" + "@lezer/javascript" "^1.0.0" + +"@codemirror/lang-json@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-json/-/lang-json-6.0.1.tgz#0a0be701a5619c4b0f8991f9b5e95fe33f462330" + integrity sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ== + dependencies: + "@codemirror/language" "^6.0.0" + "@lezer/json" "^1.0.0" + +"@codemirror/lang-less@^6.0.0": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-less/-/lang-less-6.0.2.tgz#2e3d82a3ddb8710e6409689cd4a28c66558d0cb8" + integrity sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ== + dependencies: + "@codemirror/lang-css" "^6.2.0" + "@codemirror/language" "^6.0.0" + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@codemirror/lang-liquid@^6.0.0": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-liquid/-/lang-liquid-6.2.2.tgz#5b5a2391ac14b6af85c520b8b81ea1f344d40a62" + integrity sha512-7Dm841fk37+JQW6j2rI1/uGkJyESrjzyhiIkaLjbbR0U6aFFQvMrJn35WxQreRMADMhzkyVkZM4467OR7GR8nQ== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/lang-html" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/common" "^1.0.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.3.1" + +"@codemirror/lang-markdown@^6.0.0": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-markdown/-/lang-markdown-6.3.1.tgz#067e4e18993fa3520e2a980d2dce5fe23dd245a0" + integrity sha512-y3sSPuQjBKZQbQwe3ZJKrSW6Silyl9PnrU/Mf0m2OQgIlPoSYTtOvEL7xs94SVMkb8f4x+SQFnzXPdX4Wk2lsg== + dependencies: + "@codemirror/autocomplete" "^6.7.1" + "@codemirror/lang-html" "^6.0.0" + "@codemirror/language" "^6.3.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/common" "^1.2.1" + "@lezer/markdown" "^1.0.0" + +"@codemirror/lang-php@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-php/-/lang-php-6.0.1.tgz#fa34cc75562178325861a5731f79bd621f57ffaa" + integrity sha512-ublojMdw/PNWa7qdN5TMsjmqkNuTBD3k6ndZ4Z0S25SBAiweFGyY68AS3xNcIOlb6DDFDvKlinLQ40vSLqf8xA== + dependencies: + "@codemirror/lang-html" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@lezer/common" "^1.0.0" + "@lezer/php" "^1.0.0" + +"@codemirror/lang-python@^6.0.0": + version "6.1.6" + resolved "https://registry.yarnpkg.com/@codemirror/lang-python/-/lang-python-6.1.6.tgz#0c55e7e2dfa85b68be93b9692e5d3f76f284bbb2" + integrity sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg== + dependencies: + "@codemirror/autocomplete" "^6.3.2" + "@codemirror/language" "^6.8.0" + "@codemirror/state" "^6.0.0" + "@lezer/common" "^1.2.1" + "@lezer/python" "^1.1.4" + +"@codemirror/lang-rust@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@codemirror/lang-rust/-/lang-rust-6.0.1.tgz#d6829fc7baa39a15bcd174a41a9e0a1bf7cf6ba8" + integrity sha512-344EMWFBzWArHWdZn/NcgkwMvZIWUR1GEBdwG8FEp++6o6vT6KL9V7vGs2ONsKxxFUPXKI0SPcWhyYyl2zPYxQ== + dependencies: + "@codemirror/language" "^6.0.0" + "@lezer/rust" "^1.0.0" + +"@codemirror/lang-sass@^6.0.0": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz#38c1b0a1326cc9f5cb2741d2cd51cfbcd7abc0b2" + integrity sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q== + dependencies: + "@codemirror/lang-css" "^6.2.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@lezer/common" "^1.0.2" + "@lezer/sass" "^1.0.0" + +"@codemirror/lang-sql@^6.0.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@codemirror/lang-sql/-/lang-sql-6.8.0.tgz#1ae68ad49f378605ff88a4cc428ba667ce056068" + integrity sha512-aGLmY4OwGqN3TdSx3h6QeA1NrvaYtF7kkoWR/+W7/JzB0gQtJ+VJxewlnE3+VImhA4WVlhmkJr109PefOOhjLg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@codemirror/lang-vue@^0.1.1": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz#bf79b9152cc18b4903d64c1f67e186ae045c8a97" + integrity sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug== + dependencies: + "@codemirror/lang-html" "^6.0.0" + "@codemirror/lang-javascript" "^6.1.2" + "@codemirror/language" "^6.0.0" + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.3.1" + +"@codemirror/lang-wast@^6.0.0": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz#d2b14175e5e80d7878cbbb29e20ec90dc12d3a2b" + integrity sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q== + dependencies: + "@codemirror/language" "^6.0.0" + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@codemirror/lang-xml@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz#e3e786e1a89fdc9520efe75c1d6d3de1c40eb91c" + integrity sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.4.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/common" "^1.0.0" + "@lezer/xml" "^1.0.0" + +"@codemirror/lang-yaml@^6.0.0": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-yaml/-/lang-yaml-6.1.2.tgz#c84280c68fa7af456a355d91183b5e537e9b7038" + integrity sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.2.0" + "@lezer/lr" "^1.0.0" + "@lezer/yaml" "^1.0.0" + +"@codemirror/language-data@^6.3.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@codemirror/language-data/-/language-data-6.5.1.tgz#5cb9413d5225ef27a577c23781bbc0b36c58bb67" + integrity sha512-0sWxeUSNlBr6OmkqybUTImADFUP0M3P0IiSde4nc24bz/6jIYzqYSgkOSLS+CBIoW1vU8Q9KUWXscBXeoMVC9w== + dependencies: + "@codemirror/lang-angular" "^0.1.0" + "@codemirror/lang-cpp" "^6.0.0" + "@codemirror/lang-css" "^6.0.0" + "@codemirror/lang-go" "^6.0.0" + "@codemirror/lang-html" "^6.0.0" + "@codemirror/lang-java" "^6.0.0" + "@codemirror/lang-javascript" "^6.0.0" + "@codemirror/lang-json" "^6.0.0" + "@codemirror/lang-less" "^6.0.0" + "@codemirror/lang-liquid" "^6.0.0" + "@codemirror/lang-markdown" "^6.0.0" + "@codemirror/lang-php" "^6.0.0" + "@codemirror/lang-python" "^6.0.0" + "@codemirror/lang-rust" "^6.0.0" + "@codemirror/lang-sass" "^6.0.0" + "@codemirror/lang-sql" "^6.0.0" + "@codemirror/lang-vue" "^0.1.1" + "@codemirror/lang-wast" "^6.0.0" + "@codemirror/lang-xml" "^6.0.0" + "@codemirror/lang-yaml" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/legacy-modes" "^6.4.0" + +"@codemirror/language@^6.0.0", "@codemirror/language@^6.10.1", "@codemirror/language@^6.3.0", "@codemirror/language@^6.4.0", "@codemirror/language@^6.6.0", "@codemirror/language@^6.8.0": + version "6.10.8" + resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.10.8.tgz#3e3a346a2b0a8cf63ee1cfe03349eb1965dce5f9" + integrity sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.23.0" + "@lezer/common" "^1.1.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + style-mod "^4.0.0" + +"@codemirror/legacy-modes@^6.4.0": + version "6.4.2" + resolved "https://registry.yarnpkg.com/@codemirror/legacy-modes/-/legacy-modes-6.4.2.tgz#723a55aae21304d4c112575943d3467c9040d217" + integrity sha512-HsvWu08gOIIk303eZQCal4H4t65O/qp1V4ul4zVa3MHK5FJ0gz3qz3O55FIkm+aQUcshUOjBx38t2hPiJwW5/g== + dependencies: + "@codemirror/language" "^6.0.0" + +"@codemirror/lint@^6.0.0": + version "6.8.4" + resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.4.tgz#7d8aa5d1a6dec89ffcc23ad45ddca2e12e90982d" + integrity sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.35.0" + crelt "^1.0.5" + +"@codemirror/search@^6.0.0": + version "6.5.8" + resolved "https://registry.yarnpkg.com/@codemirror/search/-/search-6.5.8.tgz#b59b3659b46184cc75d6108d7c050a4ca344c3a0" + integrity sha512-PoWtZvo7c1XFeZWmmyaOp2G0XVbOnm+fJzvghqGAktBW3cufwJUWvSCcNG0ppXiBEM05mZu6RhMtXPv2hpllig== + dependencies: + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + crelt "^1.0.5" + +"@codemirror/state@^6.0.0", "@codemirror/state@^6.4.0", "@codemirror/state@^6.4.1", "@codemirror/state@^6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.0.tgz#e98dde85620618651543152fe1c2483300a0ccc9" + integrity sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw== + dependencies: + "@marijn/find-cluster-break" "^1.0.0" + +"@codemirror/theme-one-dark@^6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz#fcef9f9cfc17a07836cb7da17c9f6d7231064df8" + integrity sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + "@lezer/highlight" "^1.0.0" + +"@codemirror/view@^6.0.0", "@codemirror/view@^6.16.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.27.0", "@codemirror/view@^6.35.0": + version "6.36.1" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.36.1.tgz#3c543b8fd72c96b30c4b2b1464d1ebce7e0c5c4b" + integrity sha512-miD1nyT4m4uopZaDdO2uXU/LLHliKNYL9kB1C1wJHrunHLm/rpkb5QVSokqgw9hFqEZakrdlb/VGWX8aYZTslQ== + dependencies: + "@codemirror/state" "^6.5.0" + style-mod "^4.1.0" + w3c-keyname "^2.2.4" + "@dagrejs/dagre@^1.0.2": version "1.1.4" resolved "https://registry.yarnpkg.com/@dagrejs/dagre/-/dagre-1.1.4.tgz#66f9c0e2b558308f2c268f60e2c28f22ee17e339" @@ -421,7 +987,7 @@ dependencies: "@floating-ui/utils" "^0.2.8" -"@floating-ui/dom@^1.0.0": +"@floating-ui/dom@^1.0.0", "@floating-ui/dom@^1.5.1": version "1.6.12" resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.12.tgz#6333dcb5a8ead3b2bf82f33d6bc410e95f54e556" integrity sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w== @@ -522,6 +1088,155 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@lezer/common@^1.0.0", "@lezer/common@^1.0.2", "@lezer/common@^1.1.0", "@lezer/common@^1.2.0", "@lezer/common@^1.2.1": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.2.3.tgz#138fcddab157d83da557554851017c6c1e5667fd" + integrity sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA== + +"@lezer/cpp@^1.0.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@lezer/cpp/-/cpp-1.1.2.tgz#1db93b09e011e8a7a08c347c9d5b7749971253bf" + integrity sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/css@^1.1.0", "@lezer/css@^1.1.7": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@lezer/css/-/css-1.1.9.tgz#404563d361422c5a1fe917295f1527ee94845ed1" + integrity sha512-TYwgljcDv+YrV0MZFFvYFQHCfGgbPMR6nuqLabBdmZoFH3EP1gvw8t0vae326Ne3PszQkbXfVBjCnf3ZVCr0bA== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/go@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@lezer/go/-/go-1.0.0.tgz#26cd2463f8583e630f52e714dca6d7420c5f7d7e" + integrity sha512-co9JfT3QqX1YkrMmourYw2Z8meGC50Ko4d54QEcQbEYpvdUvN4yb0NBZdn/9ertgvjsySxHsKzH3lbm3vqJ4Jw== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/highlight@^1.0.0", "@lezer/highlight@^1.1.3", "@lezer/highlight@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.2.1.tgz#596fa8f9aeb58a608be0a563e960c373cbf23f8b" + integrity sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA== + dependencies: + "@lezer/common" "^1.0.0" + +"@lezer/html@^1.3.0": + version "1.3.10" + resolved "https://registry.yarnpkg.com/@lezer/html/-/html-1.3.10.tgz#1be9a029a6fe835c823b20a98a449a630416b2af" + integrity sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/java@^1.0.0": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@lezer/java/-/java-1.1.3.tgz#9efd6a29b4142d07f211076a6fb5e8061c85e147" + integrity sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/javascript@^1.0.0": + version "1.4.21" + resolved "https://registry.yarnpkg.com/@lezer/javascript/-/javascript-1.4.21.tgz#8ebf7d1f891c70e3d00864f5a03ac42c75d19492" + integrity sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.1.3" + "@lezer/lr" "^1.3.0" + +"@lezer/json@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@lezer/json/-/json-1.0.2.tgz#bdc849e174113e2d9a569a5e6fb1a27e2f703eaf" + integrity sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/lr@^1.0.0", "@lezer/lr@^1.1.0", "@lezer/lr@^1.3.0", "@lezer/lr@^1.3.1", "@lezer/lr@^1.3.3", "@lezer/lr@^1.4.0": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-1.4.2.tgz#931ea3dea8e9de84e90781001dae30dea9ff1727" + integrity sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA== + dependencies: + "@lezer/common" "^1.0.0" + +"@lezer/markdown@^1.0.0": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@lezer/markdown/-/markdown-1.3.2.tgz#9d648b2a6cb47523f3d7ab494eee8c7be4f1ea9e" + integrity sha512-Wu7B6VnrKTbBEohqa63h5vxXjiC4pO5ZQJ/TDbhJxPQaaIoRD/6UVDhSDtVsCwVZV12vvN9KxuLL3ATMnlG0oQ== + dependencies: + "@lezer/common" "^1.0.0" + "@lezer/highlight" "^1.0.0" + +"@lezer/php@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@lezer/php/-/php-1.0.2.tgz#7c291631fc1e7f7efe99977522bc48bdc732658a" + integrity sha512-GN7BnqtGRpFyeoKSEqxvGvhJQiI4zkgmYnDk/JIyc7H7Ifc1tkPnUn/R2R8meH3h/aBf5rzjvU8ZQoyiNDtDrA== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.1.0" + +"@lezer/python@^1.1.4": + version "1.1.15" + resolved "https://registry.yarnpkg.com/@lezer/python/-/python-1.1.15.tgz#14a21b3bf1997d1b578f0bb959bf2062641798a2" + integrity sha512-aVQ43m2zk4FZYedCqL0KHPEUsqZOrmAvRhkhHlVPnDD1HODDyyQv5BRIuod4DadkgBEZd53vQOtXTonNbEgjrQ== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/rust@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@lezer/rust/-/rust-1.0.2.tgz#cc9a75605d67182a0e799ac40b1965a61dcc6ef0" + integrity sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/sass@^1.0.0": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@lezer/sass/-/sass-1.0.7.tgz#e90066b1d386eee6160edc88a39293844e4ba106" + integrity sha512-8HLlOkuX/SMHOggI2DAsXUw38TuURe+3eQ5hiuk9QmYOUyC55B1dYEIMkav5A4IELVaW4e1T4P9WRiI5ka4mdw== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/xml@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@lezer/xml/-/xml-1.0.5.tgz#4bb7fd3e527f41b78372477aa753f035b41c3846" + integrity sha512-VFouqOzmUWfIg+tfmpcdV33ewtK+NSwd4ngSe1aG7HFb4BN0ExyY1b8msp+ndFrnlG4V4iC8yXacjFtrwERnaw== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.0.0" + +"@lezer/yaml@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@lezer/yaml/-/yaml-1.0.3.tgz#b23770ab42b390056da6b187d861b998fd60b1ff" + integrity sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA== + dependencies: + "@lezer/common" "^1.2.0" + "@lezer/highlight" "^1.0.0" + "@lezer/lr" "^1.4.0" + +"@marijn/find-cluster-break@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8" + integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g== + "@mdx-js/mdx@^3.0.0", "@mdx-js/mdx@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-3.1.0.tgz#10235cab8ad7d356c262e8c21c68df5850a97dc3" @@ -569,6 +1284,269 @@ source-map "^0.7.0" vfile "^6.0.0" +"@milkdown/components@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/components/-/components-7.5.9.tgz#9d9bc996f6c55e07bc9e9e506736c5e83cfd254e" + integrity sha512-HO9cSW6rZDkOA9H9W7otQBPYc7BEYtylcsyMVr3rMKC8lTwoD+m/djBUHA39j3ZSFyCA1f2FeUWsI6neOpfx4Q== + dependencies: + "@atomico/hooks" "^4.1.2" + "@floating-ui/dom" "^1.5.1" + "@milkdown/exception" "7.5.9" + "@types/lodash.debounce" "^4.0.7" + "@types/lodash.throttle" "^4.1.9" + atomico "^1.75.1" + clsx "^2.0.0" + lodash.debounce "^4.0.8" + lodash.throttle "^4.1.1" + tslib "^2.5.0" + unist-util-visit "^5.0.0" + +"@milkdown/core@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/core/-/core-7.5.9.tgz#8802618f9a237666f798331a859fe122916b8470" + integrity sha512-SEoOBVhLxTjpDhEn7BwpVdN/DQ05RGpCax5rOj2ldLdYt4rpQNNkITtZFMoEKjakbd7wtuLd10xJKtGgm+VzZw== + dependencies: + "@milkdown/exception" "7.5.9" + remark-parse "^11.0.0" + remark-stringify "^11.0.0" + tslib "^2.5.0" + unified "^11.0.3" + +"@milkdown/crepe@^7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/crepe/-/crepe-7.5.9.tgz#ecea05990c39f0fa06b6013b538db57f75329937" + integrity sha512-yQEyB29w22tN1YSFIIrUSSge8IM1idontcqiLt7ojhw78mJ2/pCvCdEhYLyiw0v34QOoJxMlhHVdo/MatqzVmQ== + dependencies: + "@codemirror/commands" "^6.2.4" + "@codemirror/language" "^6.10.1" + "@codemirror/language-data" "^6.3.1" + "@codemirror/state" "^6.4.1" + "@codemirror/theme-one-dark" "^6.1.2" + "@codemirror/view" "^6.16.0" + "@milkdown/kit" "7.5.9" + atomico "^1.75.1" + clsx "^2.0.0" + codemirror "^6.0.1" + nanoid "^5.0.0" + tslib "^2.5.0" + +"@milkdown/ctx@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/ctx/-/ctx-7.5.9.tgz#5e7251dd8bb300c7911f689d31a671e26a540a28" + integrity sha512-xMobLTHxza6qRxGBJujupIJwnY/Lr6wWzDMKZJF10vw8VZWwRHIwH+VwAgOmHTbZqiKXkLW39ogNjwUCoMumBw== + dependencies: + "@milkdown/exception" "7.5.9" + tslib "^2.5.0" + +"@milkdown/exception@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/exception/-/exception-7.5.9.tgz#57e72c15f94af67d5a5f6ba2604eae52c1367287" + integrity sha512-9g+WpiRjgLsVlHt7DotlUmKK9oT6Lsr5TgxE0NdDvtr81CC43mgNtoekI6rg/PatEBBXifDK1GJJ4LKnRSseVQ== + dependencies: + tslib "^2.5.0" + +"@milkdown/kit@7.5.9", "@milkdown/kit@^7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/kit/-/kit-7.5.9.tgz#c0d05c5b688b9a592940d4988173a7bd38390229" + integrity sha512-AxDX15+lVw5zAdFO73KE3VT/8TNzkkHfsGC6Nm5hv3qgTARNuTKs5m7o0PwhdlPoPH9JJjDdy0v0Eqw5LFxkbA== + dependencies: + "@milkdown/components" "7.5.9" + "@milkdown/core" "7.5.9" + "@milkdown/ctx" "7.5.9" + "@milkdown/plugin-block" "7.5.9" + "@milkdown/plugin-clipboard" "7.5.9" + "@milkdown/plugin-cursor" "7.5.9" + "@milkdown/plugin-history" "7.5.9" + "@milkdown/plugin-indent" "7.5.9" + "@milkdown/plugin-listener" "7.5.9" + "@milkdown/plugin-slash" "7.5.9" + "@milkdown/plugin-tooltip" "7.5.9" + "@milkdown/plugin-trailing" "7.5.9" + "@milkdown/plugin-upload" "7.5.9" + "@milkdown/preset-commonmark" "7.5.9" + "@milkdown/preset-gfm" "7.5.9" + "@milkdown/prose" "7.5.9" + "@milkdown/transformer" "7.5.9" + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/plugin-block@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-block/-/plugin-block-7.5.9.tgz#ff1fe675d545d7219a97ee03167ff236e4693fd1" + integrity sha512-YosoNhxXsE1/NZQzuoY+E37TU+rQSjCCg33EgCPqjwGr+3Js7dTFo3Pw8d13tLFyNhfFYXcsZeaA4LUV1v+ucw== + dependencies: + "@floating-ui/dom" "^1.5.1" + "@milkdown/exception" "7.5.9" + "@milkdown/utils" "7.5.9" + "@types/lodash.throttle" "^4.1.9" + lodash.throttle "^4.1.1" + tslib "^2.5.0" + +"@milkdown/plugin-clipboard@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-clipboard/-/plugin-clipboard-7.5.9.tgz#695a59433f5ec39f9ab299519111b3830cf3efeb" + integrity sha512-LAwVf4vS0G0ncwFrsGv/k6Htk/hOL+AkZI1nqMeFSLbv1GLHAJoZxYkQ7hHYL3FHxWjCZNNOs2Y9Wrs4zf06pg== + dependencies: + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/plugin-cursor@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-cursor/-/plugin-cursor-7.5.9.tgz#8e6b75329dd090ab0cd63ea5f97dcf880488972a" + integrity sha512-xwfHVVuowys8g3kn9WvsDoK4fPkesQIX5ciPfAeS+X5PmE/gMYpH0AYKqIbpZlwttmO8YgkUfHXIFQmcVVumiA== + dependencies: + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/plugin-history@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-history/-/plugin-history-7.5.9.tgz#8816521e49519bc86f73de29a16b731684795fbd" + integrity sha512-1bQw7kQuMRlRfb+lTjHw2dGPxjeKj5rTfsJAhp1FIIbUXFQOzNXwvBbhNi+eHyo9gP/VaRWe/MAUvB9aSZZZTw== + dependencies: + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/plugin-indent@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-indent/-/plugin-indent-7.5.9.tgz#32fe4a8204d5c04e218f513c95f0d95ea6bbba54" + integrity sha512-9gVzftuGaIEcCKa6ZfVoTjR9f0L2fn0/QRY7R85p8YXdFNo2ta/Ot07a2iHrxXQV2xFD6e8/L3giS1STLoh2mQ== + dependencies: + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/plugin-listener@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-listener/-/plugin-listener-7.5.9.tgz#5e103cd97e37db3e3a95ed4052b87e4ffa7f3eab" + integrity sha512-UljHyZLmOranNF/QVZ4Jpc67tr/CsYgW/ctgnZEWg3ldgZicuZrwlTzPYym3KJkNpIYcqYeuMvmV9cO9nrivvw== + dependencies: + "@milkdown/utils" "7.5.9" + "@types/lodash.debounce" "^4.0.7" + lodash.debounce "^4.0.8" + tslib "^2.5.0" + +"@milkdown/plugin-slash@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-slash/-/plugin-slash-7.5.9.tgz#f9a7f9a9a3d46182029da3eeb205f7469cfb035e" + integrity sha512-luGKs/3ztVjxxfW6hFo+ngu/HT8YHmwakCAOdA+8Sg1LwM9pVWEkSTPnxRaDBDif3hf8GdF6nTPsot3qIT6LtA== + dependencies: + "@floating-ui/dom" "^1.5.1" + "@milkdown/exception" "7.5.9" + "@milkdown/utils" "7.5.9" + "@types/lodash.debounce" "^4.0.7" + lodash.debounce "^4.0.8" + tslib "^2.5.0" + +"@milkdown/plugin-tooltip@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-tooltip/-/plugin-tooltip-7.5.9.tgz#7885da5fc4ddb54dbb1b5f762145ea154cf296ee" + integrity sha512-kot5o3CDA7VaZ+lDnGQRQD5SEsqdXfhaoD9oiJCAmRkrIeBXnb7jeBEO0O9VciGQe3b1AZkirH+ARfrJMd23hg== + dependencies: + "@floating-ui/dom" "^1.5.1" + "@milkdown/exception" "7.5.9" + "@milkdown/utils" "7.5.9" + "@types/lodash.debounce" "^4.0.7" + lodash.debounce "^4.0.8" + tippy.js "^6.3.7" + tslib "^2.5.0" + +"@milkdown/plugin-trailing@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-trailing/-/plugin-trailing-7.5.9.tgz#0460070ad04253f67a6a83c46cfdbe855a54d1c4" + integrity sha512-8XFs2qodFbsUhA8gDaLvdG80y7ArYCDzdVGt/1IQFxhHbsZhmezzrrbb1alvZBolPhqTw8kfDWOo9AXQaNDgLA== + dependencies: + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/plugin-upload@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/plugin-upload/-/plugin-upload-7.5.9.tgz#6064eefc2cfbd1f9bf9e00899d43704a3e9b2bb2" + integrity sha512-VH4Bwj8Tq8gV0u10/CabOsRstwvl5t6nUKdgSin7DuMJMkuxfuqlQzvnI30wclY+ZZUz7A9p1TNzOoaD6qUdjA== + dependencies: + "@milkdown/exception" "7.5.9" + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/preset-commonmark@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/preset-commonmark/-/preset-commonmark-7.5.9.tgz#8933994d62b2e1cf2c6d51cc2040d4bdcff3ada2" + integrity sha512-RWs3qkj5DdLy7/LaGztc7lRlyI6KS6a/5Afrkcgo/mcWTQqpYPQxVq0oTwJsYyaRfuwxqJeXu2i/UPcdHA7Ifw== + dependencies: + "@milkdown/exception" "7.5.9" + "@milkdown/utils" "7.5.9" + "@sindresorhus/slugify" "^2.2.0" + remark-inline-links "^7.0.0" + tslib "^2.5.0" + unist-util-visit "^5.0.0" + +"@milkdown/preset-gfm@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/preset-gfm/-/preset-gfm-7.5.9.tgz#b33fe15ed141d1d7701f2fa59588494c3621ab4d" + integrity sha512-rtPcCT8HnL+BUW4H+740y6h+ZKrP9jLrGEihVGjCeAkRH4TFEMhFnFNGWRT8JMxpCN0VHQKy44s6Wsa82yp9Uw== + dependencies: + "@milkdown/exception" "7.5.9" + "@milkdown/utils" "7.5.9" + prosemirror-safari-ime-span "^1.0.1" + remark-gfm "^4.0.0" + tslib "^2.5.0" + +"@milkdown/prose@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/prose/-/prose-7.5.9.tgz#2f7be3d5a4879f446d6994c39e8cfa533c8e56c7" + integrity sha512-y8/9mt3gXeyThK9v5joZYfsGbyQjCCRGWKZgvpYu97P+98ht6sNFqtRxvVasirqrJGLCzx8RsJAC6tSe2e/wCQ== + dependencies: + "@milkdown/exception" "7.5.9" + prosemirror-changeset "^2.2.1" + prosemirror-commands "^1.5.2" + prosemirror-dropcursor "^1.8.1" + prosemirror-gapcursor "^1.3.2" + prosemirror-history "^1.3.2" + prosemirror-inputrules "^1.2.1" + prosemirror-keymap "^1.2.2" + prosemirror-model "^1.19.3" + prosemirror-schema-list "^1.3.0" + prosemirror-state "^1.4.3" + prosemirror-tables "^1.3.7" + prosemirror-transform "^1.7.5" + prosemirror-view "^1.31.7" + tslib "^2.5.0" + +"@milkdown/react@^7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/react/-/react-7.5.9.tgz#68e2d4430d3a7e2c4e37b76134dcbec6f9dc37b3" + integrity sha512-qj8BS+Q2dbHlfKkPBVCnD05GrlG3vQVxYk+DTvIiLMYLppEe8XzSbE8ml4mqngRjOfhjenpcL7BTWBCMwj+qVw== + dependencies: + "@milkdown/utils" "7.5.9" + tslib "^2.5.0" + +"@milkdown/theme-nord@^7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/theme-nord/-/theme-nord-7.5.9.tgz#a31b0923493f5f4cdcdc19521d93b869eb4a0dd2" + integrity sha512-aVWyBvrhMyVRX7yzkArQ6XeNbgKjVawAANKDgyAatgph79DpfOYFu4MsCy765uxxIMmHINTD+iJLTlgIDRri5A== + dependencies: + clsx "^2.0.0" + tslib "^2.5.0" + +"@milkdown/transformer@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/transformer/-/transformer-7.5.9.tgz#3628e326deb79d742ca0ac60e9b6739ea1c00419" + integrity sha512-JwR5QvppncouRVcdx8/2RfTEvb2GtG2QdO9urZomrDnF0uJC6nNM/8dreOuD0fMYWPJmi/RgD+V6fMmro75E8Q== + dependencies: + "@milkdown/exception" "7.5.9" + remark "^15.0.1" + remark-parse "^11.0.0" + remark-stringify "^11.0.0" + tslib "^2.5.0" + unified "^11.0.3" + +"@milkdown/utils@7.5.9": + version "7.5.9" + resolved "https://registry.yarnpkg.com/@milkdown/utils/-/utils-7.5.9.tgz#9107b4de4d7000468cba981ee3e431a56be021ac" + integrity sha512-udxaIdKm6pOiNACIKR7+NQ7Vj+QivhA5jcRqksEuQOfDFQBFcGaAhGEEiU1cKwE7fmP2ayigfD0IZ01rjLS2fA== + dependencies: + "@milkdown/exception" "7.5.9" + nanoid "^5.0.0" + tslib "^2.5.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -595,6 +1573,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@popperjs/core@^2.9.0": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + "@radix-ui/number@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.0.1.tgz#644161a3557f46ed38a042acf4a770e826021674" @@ -1656,6 +2639,21 @@ resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-9.3.1.tgz#afda31f8f42cab70a26f3603f52eae3f1c35d2f7" integrity sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g== +"@sindresorhus/slugify@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@sindresorhus/slugify/-/slugify-2.2.1.tgz#fa2e2e25d6e1e74a2eeb5e2c37f5ccc516ed2c4b" + integrity sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw== + dependencies: + "@sindresorhus/transliterate" "^1.0.0" + escape-string-regexp "^5.0.0" + +"@sindresorhus/transliterate@^1.0.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz#2309fff65a868047e6d2dd70dec747c5b36a8327" + integrity sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ== + dependencies: + escape-string-regexp "^5.0.0" + "@socket.io/component-emitter@~3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" @@ -1988,6 +2986,25 @@ resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.16.7.tgz#03ab680ab4fa4fbc6cb46ecf987ecad5d8019868" integrity sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ== +"@types/lodash.debounce@^4.0.7": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz#0f5f21c507bce7521b5e30e7a24440975ac860a5" + integrity sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash.throttle@^4.1.9": + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/lodash.throttle/-/lodash.throttle-4.1.9.tgz#f17a6ae084f7c0117bd7df145b379537bc9615c5" + integrity sha512-PCPVfpfueguWZQB7pJQK890F2scYKoDUL3iM522AptHWn7d5NQmeS/LTEHIcLr5PaTzl3dK2Z0xSUHHTHwaL5g== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb" + integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg== + "@types/mdast@^4.0.0": version "4.0.4" resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" @@ -2086,6 +3103,16 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== +"@uppercod/exp-route@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@uppercod/exp-route/-/exp-route-1.4.2.tgz#4a19a3d7b8f20fb23963b526feec476145643a4e" + integrity sha512-rRljihqBd3fBdWSKi4F+ev7OVJfjQyXSfwAxtjaA6PUcpBPbT0GjlJrXKa3wcFAMqE5brAjW0rMxTpXwbKv0pQ== + +"@uppercod/match-media@*", "@uppercod/match-media@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@uppercod/match-media/-/match-media-1.1.1.tgz#0d50a56212c41f69fb1d383a4acc5e5dceca5f7d" + integrity sha512-ITGhdyxadb1ypwow3TkXGdF6vWAmRZWxxfUysZz2kvsGjgaCNSuJzbfLTeWEC+BeL651U18RwZlgpX93ZCRTFg== + "@vitejs/plugin-react@^4.0.1": version "4.3.3" resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz#28301ac6d7aaf20b73a418ee5c65b05519b4836c" @@ -2193,6 +3220,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +atomico@^1.75.1: + version "1.79.2" + resolved "https://registry.yarnpkg.com/atomico/-/atomico-1.79.2.tgz#eebff0e65fe12fdf2d751f57ec66e8057e923ddc" + integrity sha512-mshhLRMeIltNYbnQnqgnrvJ/uDa8XDfTQcjw3ymOygQqwHIQ4Sp0LcNYMCbACkV3DtV+eDXb9szwU4qMUuGwYQ== + attr-accept@^2.2.4: version "2.2.5" resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e" @@ -2420,6 +3452,11 @@ clsx@1.2.1, clsx@^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: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + cmdk@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/cmdk/-/cmdk-0.2.1.tgz#aa8e1332bb0b8d8484e793017c82537351188d9a" @@ -2432,6 +3469,19 @@ code-block-writer@^12.0.0: resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770" integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w== +codemirror@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-6.0.1.tgz#62b91142d45904547ee3e0e0e4c1a79158035a29" + integrity sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg== + dependencies: + "@codemirror/autocomplete" "^6.0.0" + "@codemirror/commands" "^6.0.0" + "@codemirror/language" "^6.0.0" + "@codemirror/lint" "^6.0.0" + "@codemirror/search" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.0.0" + collapse-white-space@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-2.1.0.tgz#640257174f9f42c740b40f3b55ee752924feefca" @@ -2501,6 +3551,11 @@ cosmiconfig@^8.1.3: parse-json "^5.2.0" path-type "^4.0.0" +crelt@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.6.tgz#7cc898ea74e190fb6ef9dae57f8f81cf7302df72" + integrity sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g== + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.5.tgz#910aac880ff5243da96b728bc6521a5f6c2f2f82" @@ -3808,6 +4863,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -3833,6 +4893,11 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -3885,6 +4950,15 @@ markdown-table@^3.0.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a" integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw== +mdast-util-definitions@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz#c1bb706e5e76bb93f9a09dd7af174002ae69ac24" + integrity sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ== + dependencies: + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + unist-util-visit "^5.0.0" + mdast-util-find-and-replace@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz#a6fc7b62f0994e973490e45262e4bc07607b04e0" @@ -4586,6 +5660,11 @@ nanoid@^3.3.7: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +nanoid@^5.0.0: + version "5.0.9" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.9.tgz#977dcbaac055430ce7b1e19cf0130cea91a20e50" + integrity sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -4701,6 +5780,11 @@ ora@^6.1.2: strip-ansi "^7.0.1" wcwidth "^1.0.1" +orderedmap@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.1.1.tgz#61481269c44031c449915497bf5a4ad273c512d2" + integrity sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g== + p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -4911,6 +5995,127 @@ property-information@^6.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.5.0.tgz#6212fbb52ba757e92ef4fb9d657563b933b7ffec" integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig== +prosemirror-changeset@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz#dae94b63aec618fac7bb9061648e6e2a79988383" + integrity sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ== + dependencies: + prosemirror-transform "^1.0.0" + +prosemirror-commands@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.6.2.tgz#d9cf6654912442cff47daa1677eb43ebd0b1f117" + integrity sha512-0nDHH++qcf/BuPLYvmqZTUUsPJUCPBUXt0J1ErTcDIS369CTp773itzLGIgIXG4LJXOlwYCr44+Mh4ii6MP1QA== + dependencies: + prosemirror-model "^1.0.0" + prosemirror-state "^1.0.0" + prosemirror-transform "^1.10.2" + +prosemirror-dropcursor@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz#49b9fb2f583e0d0f4021ff87db825faa2be2832d" + integrity sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw== + dependencies: + prosemirror-state "^1.0.0" + prosemirror-transform "^1.1.0" + prosemirror-view "^1.1.0" + +prosemirror-gapcursor@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz#5fa336b83789c6199a7341c9493587e249215cb4" + integrity sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ== + dependencies: + prosemirror-keymap "^1.0.0" + prosemirror-model "^1.0.0" + prosemirror-state "^1.0.0" + prosemirror-view "^1.0.0" + +prosemirror-history@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.4.1.tgz#cc370a46fb629e83a33946a0e12612e934ab8b98" + integrity sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ== + dependencies: + prosemirror-state "^1.2.2" + prosemirror-transform "^1.0.0" + prosemirror-view "^1.31.0" + rope-sequence "^1.3.0" + +prosemirror-inputrules@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz#ef1519bb2cb0d1e0cec74bad1a97f1c1555068bb" + integrity sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg== + dependencies: + prosemirror-state "^1.0.0" + prosemirror-transform "^1.0.0" + +prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz#14a54763a29c7b2704f561088ccf3384d14eb77e" + integrity sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ== + dependencies: + prosemirror-state "^1.0.0" + w3c-keyname "^2.2.0" + +prosemirror-model@^1.0.0, prosemirror-model@^1.19.3, prosemirror-model@^1.20.0, prosemirror-model@^1.21.0, prosemirror-model@^1.24.1: + version "1.24.1" + resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.24.1.tgz#b445e4f9b9cfc8c1a699215057b506842ebff1a9" + integrity sha512-YM053N+vTThzlWJ/AtPtF1j0ebO36nvbmDy4U7qA2XQB8JVaQp1FmB9Jhrps8s+z+uxhhVTny4m20ptUvhk0Mg== + dependencies: + orderedmap "^2.0.0" + +prosemirror-safari-ime-span@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/prosemirror-safari-ime-span/-/prosemirror-safari-ime-span-1.0.2.tgz#20c9dcb33dfd68b2e59de8923b6506f9dc07c356" + integrity sha512-QJqD8s1zE/CuK56kDsUhndh5hiHh/gFnAuPOA9ytva2s85/ZEt2tNWeALTJN48DtWghSKOmiBsvVn2OlnJ5H2w== + dependencies: + prosemirror-state "^1.4.3" + prosemirror-view "^1.33.8" + +prosemirror-schema-list@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.5.0.tgz#f05ddbe2e71efc9157a0dbedf80761c08bda5192" + integrity sha512-gg1tAfH1sqpECdhIHOA/aLg2VH3ROKBWQ4m8Qp9mBKrOxQRW61zc+gMCI8nh22gnBzd1t2u1/NPLmO3nAa3ssg== + dependencies: + prosemirror-model "^1.0.0" + prosemirror-state "^1.0.0" + prosemirror-transform "^1.7.3" + +prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.3.tgz#94aecf3ffd54ec37e87aa7179d13508da181a080" + integrity sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q== + dependencies: + prosemirror-model "^1.0.0" + prosemirror-transform "^1.0.0" + prosemirror-view "^1.27.0" + +prosemirror-tables@^1.3.7: + version "1.6.2" + resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.6.2.tgz#cec9e9ac6ecf81d67147c19ab39125d56c8351ae" + integrity sha512-97dKocVLrEVTQjZ4GBLdrrMw7Gv3no8H8yMwf5IRM9OoHrzbWpcH5jJxYgNQIRCtdIqwDctT1HdMHrGTiwp1dQ== + dependencies: + prosemirror-keymap "^1.2.2" + prosemirror-model "^1.24.1" + prosemirror-state "^1.4.3" + prosemirror-transform "^1.10.2" + prosemirror-view "^1.37.1" + +prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.10.2, prosemirror-transform@^1.7.3, prosemirror-transform@^1.7.5: + version "1.10.2" + resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz#8ebac4e305b586cd96595aa028118c9191bbf052" + integrity sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ== + dependencies: + prosemirror-model "^1.21.0" + +prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.31.7, prosemirror-view@^1.33.8, prosemirror-view@^1.37.1: + version "1.37.1" + resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.37.1.tgz#3ccd67cd3d831eb37a2505dd34151932462172fb" + integrity sha512-MEAnjOdXU1InxEmhjgmEzQAikaS6lF3hD64MveTPpjOGNTl87iRLA1HupC/DEV6YuK7m4Q9DHFNTjwIVtqz5NA== + dependencies: + prosemirror-model "^1.20.0" + prosemirror-state "^1.0.0" + prosemirror-transform "^1.1.0" + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -5331,6 +6536,15 @@ remark-github-blockquote-alert@^1.0.0: dependencies: unist-util-visit "^5.0.0" +remark-inline-links@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/remark-inline-links/-/remark-inline-links-7.0.0.tgz#77fbff8061abc3d0ec34187ab71678a710df05e1" + integrity sha512-4uj1pPM+F495ySZhTIB6ay2oSkTsKgmYaKk/q5HIdhX2fuyLEegpjWa0VdJRJ01sgOqAFo7MBKdDUejIYBMVMQ== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-definitions "^6.0.0" + unist-util-visit "^5.0.0" + remark-math@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-6.0.0.tgz#0acdf74675f1c195fea6efffa78582f7ed7fc0d7" @@ -5379,6 +6593,16 @@ remark-stringify@^11.0.0: mdast-util-to-markdown "^2.0.0" unified "^11.0.0" +remark@^15.0.1: + version "15.0.1" + resolved "https://registry.yarnpkg.com/remark/-/remark-15.0.1.tgz#ac7e7563260513b66426bc47f850e7aa5862c37c" + integrity sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A== + dependencies: + "@types/mdast" "^4.0.0" + remark-parse "^11.0.0" + remark-stringify "^11.0.0" + unified "^11.0.0" + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -5441,6 +6665,11 @@ rollup@^4.23.0: "@rollup/rollup-win32-x64-msvc" "4.29.1" fsevents "~2.3.2" +rope-sequence@^1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.4.tgz#df85711aaecd32f1e756f76e43a415171235d425" + integrity sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ== + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -5648,6 +6877,11 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-mod@^4.0.0, style-mod@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.2.tgz#ca238a1ad4786520f7515a8539d5a63691d7bf67" + integrity sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw== + style-to-object@^0.4.0: version "0.4.4" resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec" @@ -5769,6 +7003,13 @@ tiny-invariant@^1.3.3: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== +tippy.js@^6.3.7: + version "6.3.7" + resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c" + integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ== + dependencies: + "@popperjs/core" "^2.9.0" + 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" @@ -5808,7 +7049,7 @@ tsconfig-paths@^4.2.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.7.0: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.2, tslib@^2.7.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -5998,6 +7239,11 @@ vite@^6.0.5: optionalDependencies: fsevents "~2.3.3" +w3c-keyname@^2.2.0, w3c-keyname@^2.2.4: + version "2.2.8" + resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz#7b17c8c6883d4e8b86ac8aba79d39e880f8869c5" + integrity sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ== + wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" From 49a2540ae2a49b439ed2ec48928ab653f03363ab Mon Sep 17 00:00:00 2001 From: Sumit Jain Date: Sat, 28 Dec 2024 17:00:24 +0530 Subject: [PATCH 108/110] feat: add FormHelperText component and refactor APIClientContent and ViewDocs components for improved functionality --- .../src/components/common/Checkbox/Check.tsx | 2 +- .../common/Forms/FormControl/FormElement.tsx | 4 + .../features/APIClient/APIClientContent.tsx | 5 +- dashboard/src/pages/features/docs/Footer.tsx | 157 ++++++++++++------ dashboard/src/pages/features/docs/Navbar.tsx | 107 ++++++++---- .../src/pages/features/docs/PageContent.tsx | 47 ++++-- dashboard/src/pages/features/docs/Sidebar.tsx | 121 +++++++++----- .../src/pages/features/docs/ViewDocs.tsx | 78 ++++----- dashboard/src/utils/removeFrappeFields.ts | 24 +++ 9 files changed, 342 insertions(+), 203 deletions(-) create mode 100644 dashboard/src/utils/removeFrappeFields.ts diff --git a/dashboard/src/components/common/Checkbox/Check.tsx b/dashboard/src/components/common/Checkbox/Check.tsx index 9385f1d..8a023e9 100644 --- a/dashboard/src/components/common/Checkbox/Check.tsx +++ b/dashboard/src/components/common/Checkbox/Check.tsx @@ -23,7 +23,7 @@ export const Check = ({ name, label, controllerProps, alignWithLabel = false, ru name={name} rules={rules} render={({ field: { name, onChange, ref, value } }) => ( - + )} {...controllerProps} /> diff --git a/dashboard/src/components/common/Forms/FormControl/FormElement.tsx b/dashboard/src/components/common/Forms/FormControl/FormElement.tsx index fdf44d5..4780cc4 100644 --- a/dashboard/src/components/common/Forms/FormControl/FormElement.tsx +++ b/dashboard/src/components/common/Forms/FormControl/FormElement.tsx @@ -62,3 +62,7 @@ export const FormElement = ({ name, label, children, tooltip, ...props }: FormEl ) }; + +export const FormHelperText = ({ children }: { children: React.ReactNode }) => { + return
    {children}
    +} \ No newline at end of file diff --git a/dashboard/src/components/features/APIClient/APIClientContent.tsx b/dashboard/src/components/features/APIClient/APIClientContent.tsx index 8472e78..eea2be4 100644 --- a/dashboard/src/components/features/APIClient/APIClientContent.tsx +++ b/dashboard/src/components/features/APIClient/APIClientContent.tsx @@ -137,10 +137,7 @@ const APIClientContent = ({ endpoint, open, parameters }: APIClientContentProps) return obj } else { - return Object.keys(data)?.filter((key) => !(key.includes('key') || key.includes('value'))).reduce((acc, key) => { - acc[key] = data[key] - return acc - }, {} as Record) + return data } } diff --git a/dashboard/src/pages/features/docs/Footer.tsx b/dashboard/src/pages/features/docs/Footer.tsx index 628ecc2..32a015d 100644 --- a/dashboard/src/pages/features/docs/Footer.tsx +++ b/dashboard/src/pages/features/docs/Footer.tsx @@ -1,68 +1,78 @@ -import { CommitDocs } from "@/types/commit/CommitDocs"; -import { DocsFooterItem } from "./docs"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { Bird, Github, Linkedin, Send, Slack, Twitter, Youtube } from "lucide-react"; +import { useGetCommitDocsDetails } from "@/components/features/meta_apps/useGetCommitDocsDetails"; -export const Footer = ({ commit_docs, footer_items }: { commit_docs: Omit, footer_items: Record }) => { +export const Footer = ({ ID }: { ID: string }) => { - const social_links = { - 'raven': commit_docs.raven, - 'twitter': commit_docs.twitter_url, - 'linkedin': commit_docs.linkedin, - 'slack': commit_docs.slack, - 'github': commit_docs.github, - 'youtube': commit_docs.youtube, - 'telegram': commit_docs.telegram, - } - return ( -
    -
    -
    -
    -
    - {commit_docs.light_mode_logo && ( - Logo - )} - {commit_docs.header && ( -

    {commit_docs.header}

    - )} -
    + const { data, isLoading } = useGetCommitDocsDetails(ID); -
    - {Object.keys(footer_items).map((section) => ( -
    -
    {section}
    - -
    - ))} -
    + if (data) { + const commit_docs = data.commit_docs; + const footer_items = data.footer_items + + const social_links = { + 'raven': commit_docs.raven, + 'twitter': commit_docs.twitter_url, + 'linkedin': commit_docs.linkedin, + 'slack': commit_docs.slack, + 'github': commit_docs.github, + 'youtube': commit_docs.youtube, + 'telegram': commit_docs.telegram, + } + return ( +
    +
    +
    +
    +
    + {commit_docs.light_mode_logo && ( + Logo + )} + {commit_docs.header && ( +

    {commit_docs.header}

    + )} +
    + +
    + {Object.keys(footer_items).map((section) => ( +
    +
    {section}
    + +
    + ))} +
    -
    - {Object.entries(social_links).map(([field, url]) => - url ? : null - )} +
    + {Object.entries(social_links).map(([field, url]) => + url ? : null + )} +
    +
    + Copyright © {new Date().getFullYear()} {commit_docs.company_name}, Build with commit. +
    -
    - Copyright © {new Date().getFullYear()} {commit_docs.company_name}, Build with commit. -
    -
    -
    - ) +
    + ) + } + if (isLoading) { + return ; + } + return null } @@ -101,4 +111,41 @@ const SocialMediaIcon: React.FC = ({ field, url }) => { ); +}; + +const FooterSkeleton = () => { + return ( +
    +
    +
    + {/* Links Section Skeleton */} +
    +
    +
      +
    • +
    • +
    • +
    +
    +
    +
    +
      +
    • +
    • +
    • +
    +
    + {/* Social Media Icons Skeleton */} +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + ); }; \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/Navbar.tsx b/dashboard/src/pages/features/docs/Navbar.tsx index ce88d29..b980cd0 100644 --- a/dashboard/src/pages/features/docs/Navbar.tsx +++ b/dashboard/src/pages/features/docs/Navbar.tsx @@ -4,50 +4,60 @@ import { Input } from "@/components/ui/input"; import { DocsNavbarItem } from "./docs"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; import { ChevronDown, Search } from "lucide-react"; +import { useGetCommitDocsDetails } from "@/components/features/meta_apps/useGetCommitDocsDetails"; -export const Navbar = ({ navbar_items }: { navbar_items: Record }) => { - return ( -
    -
    -
    +export const Navbar = ({ ID }: { ID: string }) => { + const { data, isLoading } = useGetCommitDocsDetails(ID); + if (data) { + const navbar_items = data.navbar_items; + return ( +
    -
    -
    - {/* Left side: Search bar */} -
    - - -
    - {/* Right side: Navbar items */} -
    - {Object.keys(navbar_items).reverse().map((key) => ( -
    - {navbar_items[key]?.type === 'Button' ? ( - - ) : ( - - )} -
    - ))} +
    +
    +
    +
    + {/* Left side: Search bar */} +
    + + +
    + {/* Right side: Navbar items */} +
    + {Object.keys(navbar_items).reverse().map((key) => ( +
    + {navbar_items[key]?.type === 'Button' ? ( + + ) : ( + + )} +
    + ))} +
    -
    - ); + ); + } + if (isLoading) { + return ; + } + return null }; + const MenuButton = ({ item }: { item: DocsNavbarItem }) => { return ( @@ -71,4 +81,31 @@ const MenuButton = ({ item }: { item: DocsNavbarItem }) => { ); -}; \ No newline at end of file +}; + +const NavbarSkeleton = () => { + return ( +
    +
    +
    +
    +
    +
    + {/* Left side: Search bar skeleton */} +
    +
    +
    +
    + {/* Right side: Navbar items skeleton */} +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + ); +}; diff --git a/dashboard/src/pages/features/docs/PageContent.tsx b/dashboard/src/pages/features/docs/PageContent.tsx index 071165a..caaaa30 100644 --- a/dashboard/src/pages/features/docs/PageContent.tsx +++ b/dashboard/src/pages/features/docs/PageContent.tsx @@ -1,11 +1,13 @@ import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; -import { OnThisPage } from "@/components/features/documentation/OnThisPage"; import { CommitDocsPage } from "@/types/commit/CommitDocsPage"; import { useFrappeGetCall } from "frappe-react-sdk"; -import { lazy, Suspense } from "react"; +import { useState } from "react"; +import { Renderer } from "./Renderer"; +import { EditorComponent } from "./EditorComponent"; +import { useGetCommitDocsDetails } from "@/components/features/meta_apps/useGetCommitDocsDetails"; +import { useParams } from "react-router-dom"; -const MDXRenderer = lazy(() => import('@/components/common/MarkdownRenderer/MDX')); export interface PageData { doc: CommitDocsPage toc_obj: TocObj @@ -24,14 +26,34 @@ export interface TocObj { [key: string]: TocItem; }; -export const PageContent = ({ selectedEndpoint, route_map }: { selectedEndpoint: string, route_map: Record }) => { +export const PageContent = ({ ID }: { ID: string }) => { + const { data } = useGetCommitDocsDetails(ID); + + const { pageID } = useParams(); + + if (data && pageID) { + return ( + + ) + } + return null; +} + +const PageContentFetch = ({ selectedEndpoint, route_map }: { selectedEndpoint: string, route_map: Record }) => { const selectedEndpointRoute = route_map[selectedEndpoint]; - const { data, error, isLoading } = useFrappeGetCall<{ message: PageData; }>("commit.commit.doctype.commit_docs_page.commit_docs_page.get_commit_docs_page", { + const { data, error, isLoading, mutate } = useFrappeGetCall<{ message: PageData; }>("commit.commit.doctype.commit_docs_page.commit_docs_page.get_commit_docs_page", { name: selectedEndpointRoute + }, undefined, { + revalidateOnFocus: false, + revalidateIfStale: false, + revalidateOnReconnect: false, + keepPreviousData: true }); + const [edit, setEdit] = useState(false); + if (isLoading) { return ; } @@ -44,18 +66,9 @@ export const PageContent = ({ selectedEndpoint, route_map }: { selectedEndpoint: if (data && data?.message) { return ( -
    -
    -
    {data?.message?.doc?.title}
    - }> - - -
    -
    - -
    -
    + <> + {edit ? : } + ) } - } \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/Sidebar.tsx b/dashboard/src/pages/features/docs/Sidebar.tsx index 00d19fb..51f661a 100644 --- a/dashboard/src/pages/features/docs/Sidebar.tsx +++ b/dashboard/src/pages/features/docs/Sidebar.tsx @@ -6,44 +6,45 @@ import { useState } from "react"; import classNames from "classnames"; import { cn } from "@/lib/utils"; import { ChevronDown, ChevronRight } from "lucide-react"; +import { useParams } from "react-router-dom"; +import { useGetCommitDocsDetails } from "@/components/features/meta_apps/useGetCommitDocsDetails"; -export const Sidebar = ({ - commit_docs, - sidebar_items, - selectedEndpoint, - setSelectedEndpoint, -}: { - commit_docs: Omit; - sidebar_items: Record; - selectedEndpoint: string; - setSelectedEndpoint: (selectedEndpoint: string) => void; -}) => { - return ( -
    -
    - {/* Header */} -
    - {commit_docs.light_mode_logo && ( - logo - )} - {commit_docs.header &&
    {commit_docs.header}
    } +export const Sidebar = ({ ID }: { ID: string }) => { + + const { data, isLoading } = useGetCommitDocsDetails(ID); + + if (data) { + const commit_docs: CommitDocs = data.commit_docs; + const sidebar_items = data.sidebar_items; + return ( +
    +
    + {/* Header */} +
    + {commit_docs.light_mode_logo && ( + logo + )} + {commit_docs.header &&
    {commit_docs.header}
    } +
    + {/* Sidebar Items */} + {Object.keys(sidebar_items).map((key) => ( + + ))}
    - {/* Sidebar Items */} - {Object.keys(sidebar_items).map((key) => ( - - ))}
    -
    - ); + ); + } + if (isLoading) { + return ; + } }; -const SidebarGroup = ({ groupName, items, selectedEndpoint, setSelectedEndpoint }: { groupName: string, items: DocsSidebarItem[], selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void }) => { +const SidebarGroup = ({ groupName, items }: { groupName: string, items: DocsSidebarItem[] }) => { const [isExpanded, setIsExpanded] = useState(true); return ( @@ -55,7 +56,7 @@ const SidebarGroup = ({ groupName, items, selectedEndpoint, setSelectedEndpoint {isExpanded && items.length > 0 && (
      {items.map((item) => ( - + ))}
    )} @@ -63,17 +64,17 @@ const SidebarGroup = ({ groupName, items, selectedEndpoint, setSelectedEndpoint ) } -const SidebarItem = ({ item, selectedEndpoint, setSelectedEndpoint, className, level = 1 }: { item: DocsSidebarItem, selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void, className?: string, level?: number }) => { +const SidebarItem = ({ item, className, level = 1 }: { item: DocsSidebarItem, className?: string, level?: number }) => { if (item.is_group_page && item.group_items?.length) { const [isExpanded, setIsExpanded] = useState(false); return (
  • - + {isExpanded && item.group_items.length &&
      {item.group_items.map((groupItem) => ( - + ))}
    } @@ -83,14 +84,15 @@ const SidebarItem = ({ item, selectedEndpoint, setSelectedEndpoint, className, l return (
  • - +
  • ) } -const SidebarTitle = ({ item, selectedEndpoint, setSelectedEndpoint, className, isExpanded, setIsExpanded }: { item: DocsSidebarItem, selectedEndpoint: string, setSelectedEndpoint: (selectedEndpoint: string) => void, className?: string, isExpanded?: boolean, setIsExpanded?: (isExpanded: boolean) => void }) => { +const SidebarTitle = ({ item, className, isExpanded, setIsExpanded }: { item: DocsSidebarItem, className?: string, isExpanded?: boolean, setIsExpanded?: (isExpanded: boolean) => void }) => { - const isSelected = item.route === selectedEndpoint; + const { pageID, ID } = useParams(); + const isSelected = item.route === pageID; const badgeClass = classNames({ 'text-[10px] px-1 py-0': true, @@ -119,19 +121,52 @@ const SidebarTitle = ({ item, selectedEndpoint, setSelectedEndpoint, className, isSelected ? 'border-blue-600 dark:border-primary-light text-blue-600 dark:text-primary-light' : '', className )} - onClick={item.is_group_page ? () => setIsExpanded && setIsExpanded(!isExpanded) : () => setSelectedEndpoint(item.route)} + onClick={item.is_group_page ? () => setIsExpanded && setIsExpanded(!isExpanded) : () => { }} >
    -
    + {item.is_group_page ?
    {item.icon && } {item.badge && {item.badge}}
    {item.title}
    -
    +
    : + {item.icon && } + {item.badge && {item.badge}} +
    + {item.title} +
    +
    } {item.is_group_page && item.group_items?.length ? {isExpanded ? : } : null}
    ) } + +const SidebarSkeleton = () => { + return ( +
    + {/* Header Skeleton */} +
    +
    +
    +
    + {/* Sidebar Groups Skeleton */} + {[...Array(5)].map((_, groupIndex) => ( +
    +
    +
    + +
    +
      + {[...Array(3 + Math.floor(Math.random() * 2))].map((_, itemIndex) => ( +
    • + ))} +
    +
    + ))} +
    + ); +}; \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/ViewDocs.tsx b/dashboard/src/pages/features/docs/ViewDocs.tsx index 741ff47..0e8a4f6 100644 --- a/dashboard/src/pages/features/docs/ViewDocs.tsx +++ b/dashboard/src/pages/features/docs/ViewDocs.tsx @@ -1,6 +1,5 @@ import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; -import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; -import { useNavigate, useParams } from "react-router-dom"; +import { useParams } from "react-router-dom"; import { Sidebar } from "./Sidebar"; import { Navbar } from "./Navbar"; import { Footer } from "./Footer"; @@ -8,60 +7,43 @@ import { PageContent } from "./PageContent"; import { useGetCommitDocsDetails } from "@/components/features/meta_apps/useGetCommitDocsDetails"; const ViewDocs = () => { - const { ID, pageID } = useParams(); + const { ID } = useParams(); - if (ID && pageID) { - return ; + if (ID) { + return ; } return null; }; -const ViewDocsDetails = ({ ID, pageID }: { ID: string, pageID: string }) => { - const navigate = useNavigate(); +const ViewDocsDetails = ({ ID }: { ID: string }) => { - const { data, error, isLoading } = useGetCommitDocsDetails(ID); - - const onPageChange = (pageID: string) => { - navigate(`/docs/${ID}/${pageID}`); - } - - if (isLoading) { - return ; - } - if (error) { - return ; - } - - if (data) { - return ( -
    -
    - -
    -
    - {/* Sidebar */} - - - {/* Main Content */} -
    -
    - -
    -
    -
    - -