@mhamz.01/easyflow-texteditor 0.1.32 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/ui/sidebar.tsx","../src/hooks/use-mobile.ts","../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/input.tsx","../src/components/ui/separator.tsx","../src/components/ui/sheet.tsx","../src/components/ui/tooltip.tsx","../src/components/editor-shell/EditorShell.tsx","../src/components/editorLayout/editorLayout.tsx","../src/components/sidebar/EditorSidebar.tsx","../src/components/ui/dropdown-menu.tsx","../src/contexts/EditorBridge.tsx","../src/lib/editorStorage.ts","../src/components/tiptap-templates/simple/simple-editor.tsx","../../node_modules/@tiptap/extension-document/src/document.ts","../../node_modules/@tiptap/extension-document/src/index.ts","../../node_modules/@tiptap/extension-paragraph/src/paragraph.ts","../../node_modules/@tiptap/extension-paragraph/src/index.ts","../../node_modules/@tiptap/extension-text/src/text.ts","../../node_modules/@tiptap/extension-text/src/index.ts","../src/components/extensions/font-size-stepper.ts","../src/components/tiptap-ui-primitive/button/button.tsx","../src/components/tiptap-ui-primitive/tooltip/tooltip.tsx","../src/lib/tiptap-utils.ts","../src/components/tiptap-ui-primitive/spacer/spacer.tsx","../src/components/tiptap-ui-primitive/toolbar/toolbar.tsx","../src/components/tiptap-ui-primitive/separator/separator.tsx","../src/hooks/use-menu-navigation.ts","../src/hooks/use-composed-ref.ts","../src/components/tiptap-ui-primitive/bubble-menu/bubble-menu.tsx","../src/components/tiptap-node/image-upload-node/image-upload-node-extension.ts","../src/components/tiptap-node/image-upload-node/image-upload-node.tsx","../src/components/tiptap-icons/close-icon.tsx","../src/components/tiptap-node/horizontal-rule-node/horizontal-rule-node-extension.ts","../src/components/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.tsx","../src/components/tiptap-icons/chevron-down-icon.tsx","../src/hooks/use-tiptap-editor.ts","../src/components/tiptap-ui/heading-button/heading-button.tsx","../src/components/tiptap-ui-primitive/badge/badge.tsx","../src/components/tiptap-ui/heading-button/use-heading.ts","../src/components/tiptap-icons/heading-one-icon.tsx","../src/components/tiptap-icons/heading-two-icon.tsx","../src/components/tiptap-icons/heading-three-icon.tsx","../src/components/tiptap-icons/heading-four-icon.tsx","../src/components/tiptap-icons/heading-five-icon.tsx","../src/components/tiptap-icons/heading-six-icon.tsx","../src/components/tiptap-ui-primitive/dropdown-menu/dropdown-menu.tsx","../src/components/tiptap-ui-primitive/card/card.tsx","../src/components/tiptap-ui/heading-dropdown-menu/use-heading-dropdown-menu.ts","../src/components/tiptap-icons/heading-icon.tsx","../src/components/tiptap-ui/image-upload-button/image-upload-button.tsx","../src/components/tiptap-ui/image-upload-button/use-image-upload.ts","../src/hooks/use-is-breakpoint.ts","../src/components/tiptap-icons/image-plus-icon.tsx","../src/components/tiptap-ui/list-dropdown-menu/list-dropdown-menu.tsx","../src/components/tiptap-ui/list-button/list-button.tsx","../src/components/tiptap-ui/list-button/use-list.ts","../src/components/tiptap-icons/list-icon.tsx","../src/components/tiptap-icons/list-ordered-icon.tsx","../src/components/tiptap-icons/list-todo-icon.tsx","../src/components/tiptap-ui/list-dropdown-menu/use-list-dropdown-menu.ts","../src/components/tiptap-ui/blockquote-button/blockquote-button.tsx","../src/components/tiptap-ui/blockquote-button/use-blockquote.ts","../src/components/tiptap-icons/blockquote-icon.tsx","../src/components/tiptap-ui/color-highlight-popover/color-highlight-popover.tsx","../src/components/tiptap-icons/ban-icon.tsx","../src/components/tiptap-icons/highlighter-icon.tsx","../src/components/tiptap-ui-primitive/popover/popover.tsx","../src/components/tiptap-ui/color-highlight-button/color-highlight-button.tsx","../src/components/tiptap-ui/color-highlight-button/use-color-highlight.ts","../src/components/tiptap-ui/link-popover/link-popover.tsx","../src/components/tiptap-icons/corner-down-left-icon.tsx","../src/components/tiptap-icons/external-link-icon.tsx","../src/components/tiptap-icons/link-icon.tsx","../src/components/tiptap-icons/trash-icon.tsx","../src/components/tiptap-ui-primitive/input/input.tsx","../src/components/tiptap-ui/link-popover/use-link-popover.ts","../src/components/tiptap-ui/mark-button/mark-button.tsx","../src/components/tiptap-ui/mark-button/use-mark.ts","../src/components/tiptap-icons/bold-icon.tsx","../src/components/tiptap-icons/code2-icon.tsx","../src/components/tiptap-icons/italic-icon.tsx","../src/components/tiptap-icons/strike-icon.tsx","../src/components/tiptap-icons/subscript-icon.tsx","../src/components/tiptap-icons/superscript-icon.tsx","../src/components/tiptap-icons/underline-icon.tsx","../src/components/tiptap-ui/text-align-button/text-align-button.tsx","../src/components/tiptap-ui/text-align-button/use-text-align.ts","../src/components/tiptap-icons/align-center-icon.tsx","../src/components/tiptap-icons/align-justify-icon.tsx","../src/components/tiptap-icons/align-left-icon.tsx","../src/components/tiptap-icons/align-right-icon.tsx","../src/components/tiptap-ui/undo-redo-button/undo-redo-button.tsx","../src/components/tiptap-ui/undo-redo-button/use-undo-redo.ts","../src/components/tiptap-icons/redo2-icon.tsx","../src/components/tiptap-icons/undo2-icon.tsx","../src/components/tiptap-ui/font-family-dropdown/font-family-dropdown.tsx","../src/lib/font.ts","../src/components/ui/command.tsx","../src/components/ui/popover.tsx","../src/components/tiptap-ui/color-picker/color-picker.tsx","../src/lib/colors.ts","../src/components/ui/label.tsx","../src/components/tiptap-ui/table-dropdown-menu/table-dropdown-menu.tsx","../src/components/tiptap-icons/arrow-left-icon.tsx","../src/hooks/use-window-size.ts","../src/hooks/use-throttled-callback.ts","../src/hooks/use-unmount.ts","../src/hooks/use-element-rect.ts","../src/hooks/use-cursor-visibility.ts","../src/components/editor/editor.tsx","../src/hooks/use-scrolling.ts","../src/lib/local-image.ts"],"sourcesContent":["// Export components\r\nexport { Editor } from \"../src/components/editor/editor\"\r\n\r\n// types are OK to export\r\nexport type {\r\n EditorChangePayload,\r\n EditorChangeSource,\r\n} from \"./types/editor-payload\"\r\n\r\n// Export hooks / context\r\nexport * from './hooks'\r\nexport * from './contexts'\r\nexport * from './lib'\r\nexport * from \"./types/editor-payload\"\r\nimport './styles/index.scss'\r\nimport './styles/_variables.scss'\r\n// Import global CSS\r\nimport './styles/globals.css';\r\nexport * from './components/editor/editor'","\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { PanelLeftIcon } from \"lucide-react\"\n\nimport { useIsMobile } from \"../../hooks/use-mobile\"\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"../../components/ui/button\"\nimport { Input } from \"../../components/ui/input\"\nimport { Separator } from \"../../components/ui/separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"../../components/ui/sheet\"\nimport { Skeleton } from \"../../components/ui/skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../../components/ui/tooltip\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n // React.useEffect(() => {\n // const handleKeyDown = (event: KeyboardEvent) => {\n // if (\n // event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n // (event.metaKey || event.ctrlKey)\n // ) {\n // event.preventDefault()\n // toggleSidebar()\n // }\n // }\n\n // window.addEventListener(\"keydown\", handleKeyDown)\n // return () => window.removeEventListener(\"keydown\", handleKeyDown)\n // }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer text-sidebar-foreground hidden md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"size-7\", className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"bg-background relative flex w-full flex-1 flex-col\",\n \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"bg-background h-8 w-full shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"bg-sidebar-border mx-2 w-auto\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"div\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n \"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot : \"button\"\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n showOnHover &&\n \"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none\",\n \"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n }, [])\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean\n size?: \"sm\" | \"md\"\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n \"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground\",\n size === \"sm\" && \"text-xs\",\n size === \"md\" && \"text-sm\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n","import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outlineFontFamily:\n \"border rounded-sm text-left bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-transparent dark:border-[#a3a3a8] dark:hover:bg-input/50\",\n outline:\n \"border bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-transparent dark:border-input dark:hover:bg-input/50\",\n tableButton:\n \"bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-transparent dark:border-input dark:hover:bg-input/50\",\n secondary: \n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-7 px-4 py-2 has-[>svg]:px-3\",\n colorbuttonsize: \" px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n side === \"right\" &&\n \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n side === \"left\" &&\n \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n side === \"top\" &&\n \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b\",\n side === \"bottom\" &&\n \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t\",\n className\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none\">\n <XIcon className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n )\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","\"use client\"\r\n\r\nimport type { ReactNode } from \"react\"\r\nimport { SidebarProvider } from \"../../components/ui/sidebar\"\r\n\r\ninterface EditorShellProps {\r\n children: ReactNode\r\n}\r\n\r\nexport function EditorShell({ children }: EditorShellProps) {\r\n return (\r\n <div\r\n className=\"\r\n relative\r\n w-full\r\n h-full\r\n overflow-hidden\r\n border\r\n rounded-md\r\n bg-background\r\n \"\r\n data-easyflow-editor\r\n >\r\n <SidebarProvider>\r\n {children}\r\n </SidebarProvider>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\n\r\nimport { useState, useEffect, useRef, useCallback } from \"react\"\r\nimport type { ReactNode } from \"react\"\r\nimport type { Editor } from \"@tiptap/core\"\r\n\r\nimport {\r\n SidebarProvider,\r\n SidebarTrigger,\r\n SidebarInset,\r\n} from \"../../components/ui/sidebar\"\r\n\r\nimport { AppSidebar } from \"../sidebar/EditorSidebar\"\r\nimport { EditorBridgeProvider } from \"../../contexts/EditorBridge\"\r\nimport { loadTabs, saveTabs } from \"../../lib/editorStorage\"\r\n\r\nimport type { EditorTab } from \"../../components/types/editor-tabs\"\r\nimport type { EditorChangePayload, EditorChangeSource } from \"../../types/editor-payload\"\r\n\r\n\r\ninterface EditorLayoutProps {\r\n children: ReactNode\r\n onChange?: (payload: EditorChangePayload) => void\r\n}\r\n\r\nexport function EditorLayout({ children, onChange }: EditorLayoutProps) {\r\n const [editor, setEditor] = useState<Editor | null>(null)\r\n const [tabs, setTabs] = useState<EditorTab[]>([])\r\n const [activeTabId, setActiveTabId] = useState(\"\")\r\n const [activeSubTabId, setActiveSubTabId] = useState<string | null>(null)\r\n\r\n const debouncedSaveRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n const lastRestoredRef = useRef<{ tabId: string; subTabId: string | null } | null>(null)\r\n const isRestoringRef = useRef(false)\r\n const onChangeDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n\r\n\r\n // Debounced onChange to prevent duplicate calls\r\n const emitChangeDebounced = useCallback(\r\n (payload: EditorChangePayload) => {\r\n if (!onChange) return\r\n\r\n // Clear any pending onChange calls\r\n if (onChangeDebounceRef.current) {\r\n clearTimeout(onChangeDebounceRef.current)\r\n }\r\n\r\n // Debounce onChange calls to avoid duplicates\r\n onChangeDebounceRef.current = setTimeout(() => {\r\n onChange(payload)\r\n }, 100)\r\n },\r\n [onChange]\r\n )\r\n\r\n\r\n const emitChange = useCallback(\r\n (source: EditorChangeSource) => {\r\n if (!onChange) return\r\n\r\n emitChangeDebounced({\r\n tabs,\r\n activeTabId,\r\n activeSubTabId,\r\n source,\r\n })\r\n },\r\n [emitChangeDebounced, tabs, activeTabId, activeSubTabId]\r\n )\r\n /* ---------------- LOAD ---------------- */\r\n\r\n useEffect(() => {\r\n const initialTabs = loadTabs()\r\n\r\n if (initialTabs.length === 0) {\r\n setTabs([{ id: \"1\", title: \"Tab 1\", content: null, subtabs: [] }])\r\n setActiveTabId(\"1\")\r\n } else {\r\n setTabs(initialTabs)\r\n setActiveTabId(initialTabs[0].id)\r\n }\r\n }, [])\r\n\r\n /* ---------------- SAVE TO LOCALSTORAGE ---------------- */\r\n useEffect(() => {\r\n // Only save to localStorage, don't call onChange here\r\n saveTabs(tabs)\r\n }, [tabs])\r\n\r\n /* ---------------- HELPERS ---------------- */\r\n \r\n \r\n // Synchronous save that returns updated tabs\r\n const saveCurrentContent = useCallback(() => {\r\n if (!editor) return tabs\r\n\r\n const json = editor.getJSON()\r\n\r\n const updatedTabs = tabs.map(tab => {\r\n if (tab.id !== activeTabId) return tab\r\n\r\n if (activeSubTabId) {\r\n return {\r\n ...tab,\r\n subtabs: tab.subtabs.map(st =>\r\n st.id === activeSubTabId ? { ...st, content: json } : st\r\n ),\r\n }\r\n }\r\n\r\n return { ...tab, content: json }\r\n })\r\n\r\n return updatedTabs\r\n }, [editor, tabs, activeTabId, activeSubTabId])\r\n\r\n \r\n const saveFromEditor = useCallback(\r\n (editorInstance: Editor, source: EditorChangeSource = \"editor\") => {\r\n const json = editorInstance.getJSON()\r\n \r\n setTabs(prev => {\r\n const updatedTabs = prev.map(tab => {\r\n if (tab.id !== activeTabId) return tab\r\n \r\n if (activeSubTabId) {\r\n return {\r\n ...tab,\r\n subtabs: tab.subtabs.map(st =>\r\n st.id === activeSubTabId\r\n ? { ...st, content: json }\r\n : st\r\n ),\r\n }\r\n }\r\n \r\n return { ...tab, content: json }\r\n })\r\n \r\n // Only emit for editor changes (user typing)\r\n if (source === \"editor\") {\r\n emitChangeDebounced({\r\n tabs: updatedTabs,\r\n activeTabId,\r\n activeSubTabId,\r\n source,\r\n })\r\n }\r\n \r\n return updatedTabs\r\n })\r\n },\r\n [activeTabId, activeSubTabId, emitChangeDebounced]\r\n )\r\n \r\n // Debounced save to avoid excessive writes\r\n \r\n const debouncedSave = useCallback(\r\n (editorInstance: Editor) => {\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n }\r\n \r\n debouncedSaveRef.current = setTimeout(() => {\r\n saveFromEditor(editorInstance, \"editor\")\r\n }, 800)\r\n },\r\n [saveFromEditor]\r\n )\r\n \r\n const addTab = () => {\r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // ✅ Get updated tabs with current content saved\r\n const updatedTabs = saveCurrentContent()\r\n \r\n const id = Date.now().toString()\r\n const newTabs = [\r\n ...updatedTabs,\r\n { id, title: `Tab ${updatedTabs.length + 1}`, content: null, subtabs: [] },\r\n ]\r\n \r\n // Update everything together\r\n setTabs(newTabs)\r\n setActiveTabId(id)\r\n setActiveSubTabId(null)\r\n \r\n // Clear editor after state update\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n\r\n // Single debounced onChange call\r\n emitChangeDebounced({\r\n tabs: newTabs,\r\n activeTabId: id,\r\n activeSubTabId: null,\r\n source: \"add-tab\",\r\n })\r\n }\r\n \r\n const addSubTab = (tabId: string) => {\r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // ✅ Get updated tabs with current content saved\r\n const updatedTabs = saveCurrentContent()\r\n \r\n const subId = Date.now().toString()\r\n \r\n const newTabs = updatedTabs.map(tab =>\r\n tab.id === tabId\r\n ? {\r\n ...tab,\r\n subtabs: [\r\n ...tab.subtabs,\r\n { id: subId, title: \"New Subtab\", content: null },\r\n ],\r\n }\r\n : tab\r\n )\r\n \r\n setTabs(newTabs)\r\n setActiveTabId(tabId)\r\n setActiveSubTabId(subId)\r\n \r\n // Clear editor after state update\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n\r\n emitChangeDebounced({\r\n tabs: newTabs,\r\n activeTabId: tabId,\r\n activeSubTabId: subId,\r\n source: \"add-subtab\",\r\n })\r\n }\r\n \r\n const selectNode = (tabId: string, subId?: string) => {\r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // ✅ Save current content before switching\r\n const updatedTabs = saveCurrentContent()\r\n \r\n setTabs(updatedTabs)\r\n setActiveTabId(tabId)\r\n setActiveSubTabId(subId ?? null)\r\n\r\n emitChangeDebounced({\r\n tabs: updatedTabs,\r\n activeTabId: tabId,\r\n activeSubTabId: subId ?? null,\r\n source: \"tab-switch\",\r\n })\r\n }\r\n \r\n\r\n const renameTab = (id: string, title: string) => {\r\n setTabs((prev) => prev.map((t) => (t.id === id ? { ...t, title } : t)))\r\n }\r\n\r\n const deleteSubTab = (tabId: string, subTabId: string) => {\r\n console.log(\"🗑️ Deleting subtab:\", subTabId)\r\n setTabs((prev) =>\r\n prev.map((tab) => {\r\n if (tab.id !== tabId) return tab\r\n\r\n const remainingSubTabs = tab.subtabs.filter((st) => st.id !== subTabId)\r\n\r\n if (subTabId === activeSubTabId) {\r\n setActiveSubTabId(null)\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n }\r\n \r\n return {\r\n ...tab,\r\n subtabs: remainingSubTabs,\r\n }\r\n })\r\n )\r\n emitChange(\"delete-subtab\")\r\n }\r\n\r\n const renameSubTab = (tabId: string, subTabId: string, title: string) => {\r\n setTabs((prev) =>\r\n prev.map((tab) =>\r\n tab.id === tabId\r\n ? {\r\n ...tab,\r\n subtabs: tab.subtabs.map((st) =>\r\n st.id === subTabId ? { ...st, title } : st\r\n ),\r\n }\r\n : tab\r\n )\r\n )\r\n }\r\n\r\n const deleteTab = (id: string) => {\r\n console.log(\"🗑️ Deleting tab:\", id)\r\n \r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // Save current content if we're deleting a different tab\r\n const updatedTabs = id === activeTabId ? tabs : saveCurrentContent()\r\n \r\n setTabs((prev) => {\r\n const remaining = (id === activeTabId ? prev : updatedTabs).filter((t) => t.id !== id)\r\n\r\n if (id === activeTabId) {\r\n const next = remaining[0]\r\n setActiveTabId(next?.id ?? \"\")\r\n setActiveSubTabId(null)\r\n if (!next) {\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n }\r\n }\r\n\r\n return remaining\r\n })\r\n \r\n emitChange(\"delete-tab\")\r\n }\r\n\r\n /* ---------------- RESTORE CONTENT ---------------- */\r\n useEffect(() => {\r\n if (!editor) return\r\n\r\n const key = { tabId: activeTabId, subTabId: activeSubTabId }\r\n\r\n if (\r\n lastRestoredRef.current &&\r\n lastRestoredRef.current.tabId === key.tabId &&\r\n lastRestoredRef.current.subTabId === key.subTabId\r\n ) {\r\n return\r\n }\r\n\r\n // Prevent restore during save operations\r\n if (isRestoringRef.current) return\r\n isRestoringRef.current = true\r\n\r\n const tab = tabs.find(t => t.id === activeTabId)\r\n const node = activeSubTabId\r\n ? tab?.subtabs.find(st => st.id === activeSubTabId)\r\n : tab\r\n\r\n if (node?.content) {\r\n editor.commands.setContent(node.content)\r\n } else {\r\n editor.commands.clearContent()\r\n }\r\n\r\n lastRestoredRef.current = key\r\n isRestoringRef.current = false\r\n }, [editor, tabs, activeTabId, activeSubTabId])\r\n\r\n\r\n\r\n return (\r\n <EditorBridgeProvider value={{ \r\n editorContent: editor, \r\n setEditorContent: setEditor,\r\n debouncedSave \r\n }}>\r\n <SidebarProvider>\r\n <div className=\"flex h-screen w-full min-h-0\">\r\n <AppSidebar\r\n tabs={tabs}\r\n activeTabId={activeTabId}\r\n activeSubTabId={activeSubTabId}\r\n canDeleteTab={tabs.length > 1}\r\n onAddTab={addTab}\r\n onAddSubTab={addSubTab}\r\n onSelect={selectNode}\r\n onRename={renameTab}\r\n onDelete={deleteTab}\r\n onRenameSubTab={renameSubTab}\r\n onDeleteSubTab={deleteSubTab}\r\n />\r\n\r\n <SidebarInset className=\"flex flex-col flex-1 min-h-0\">\r\n <header className=\"h-12 flex-shrink-0 border-b\">\r\n <SidebarTrigger />\r\n </header>\r\n\r\n {children}\r\n </SidebarInset>\r\n </div>\r\n </SidebarProvider>\r\n </EditorBridgeProvider>\r\n )\r\n}","\"use client\";\r\n\r\nimport { useState } from \"react\";\r\nimport { MoreHorizontal, Plus, FileText } from \"lucide-react\";\r\nimport { motion, AnimatePresence, Variant } from \"framer-motion\"; // ✨ ADD THIS\r\n\r\nimport {\r\n Sidebar,\r\n SidebarContent,\r\n SidebarGroup,\r\n SidebarGroupLabel,\r\n SidebarMenu,\r\n SidebarMenuItem,\r\n} from \"../../components/ui/sidebar\";\r\n\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n} from \"../../components/ui/dropdown-menu\";\r\n\r\nimport { ChevronRight } from \"lucide-react\";\r\n\r\nimport { Input } from \"../../components/ui/input\";\r\nimport { EditorTab } from \"../../components/types/editor-tabs\";\r\n\r\ninterface EditorSidebarProps {\r\n tabs: EditorTab[];\r\n activeTabId: string;\r\n activeSubTabId: string | null;\r\n canDeleteTab: boolean;\r\n onAddTab: () => void;\r\n onAddSubTab: (tabId: string) => void;\r\n onSelect: (tabId: string, subId?: string) => void;\r\n onRename: (id: string, title: string) => void;\r\n onDelete: (id: string) => void;\r\n onRenameSubTab: (tabId: string, subTabId: string, title: string) => void;\r\n onDeleteSubTab: (tabId: string, subTabId: string) => void;\r\n}\r\n\r\n// ✨ Animation variants\r\nconst tabVariants : any = {\r\n initial: { opacity: 0, x: -20, height: 0 },\r\n animate: { \r\n opacity: 1, \r\n x: 0, \r\n height: \"auto\",\r\n transition: {\r\n duration: 0.3,\r\n ease: \"easeOut\"\r\n }\r\n },\r\n exit: { \r\n opacity: 0, \r\n x: -20, \r\n height: 0,\r\n transition: {\r\n duration: 0.2,\r\n ease: \"easeIn\"\r\n }\r\n }\r\n};\r\n\r\nconst subtabVariants : any = {\r\n initial: { opacity: 0, x: -10, height: 0 },\r\n animate: { \r\n opacity: 1, \r\n x: 0, \r\n height: \"auto\",\r\n transition: {\r\n duration: 0.25,\r\n ease: \"easeOut\"\r\n }\r\n },\r\n exit: { \r\n opacity: 0, \r\n x: -10, \r\n height: 0,\r\n transition: {\r\n duration: 0.15,\r\n ease: \"easeIn\"\r\n }\r\n }\r\n};\r\n\r\nexport function AppSidebar({\r\n tabs,\r\n activeTabId,\r\n activeSubTabId,\r\n canDeleteTab,\r\n onAddTab,\r\n onAddSubTab,\r\n onSelect,\r\n onRename,\r\n onDelete,\r\n onRenameSubTab,\r\n onDeleteSubTab,\r\n}: EditorSidebarProps) {\r\n const [editingId, setEditingId] = useState<string | null>(null);\r\n const [editingSubId, setEditingSubId] = useState<string | null>(null);\r\n const [tempTitle, setTempTitle] = useState(\"\");\r\n const [openTabs, setOpenTabs] = useState<Record<string, boolean>>({});\r\n\r\n /* ---------- Rename helpers ---------- */\r\n\r\n const startRenameTab = (id: string, title: string) => {\r\n setEditingId(id);\r\n setEditingSubId(null);\r\n setTempTitle(title);\r\n };\r\n\r\n const startRenameSubTab = (id: string, title: string) => {\r\n setEditingSubId(id);\r\n setEditingId(null);\r\n setTempTitle(title);\r\n };\r\n\r\n const commitRenameTab = () => {\r\n if (!editingId) return;\r\n onRename(editingId, tempTitle.trim() || \"Untitled\");\r\n setEditingId(null);\r\n };\r\n\r\n const commitRenameSubTab = (tabId: string) => {\r\n if (!editingSubId || !onRenameSubTab) return;\r\n onRenameSubTab(tabId, editingSubId, tempTitle.trim() || \"Untitled\");\r\n setEditingSubId(null);\r\n };\r\n\r\n const toggleTabOpen = (tabId: string) => {\r\n setOpenTabs((prev) => ({\r\n ...prev,\r\n [tabId]: !prev[tabId],\r\n }));\r\n };\r\n\r\n return (\r\n <Sidebar>\r\n <SidebarContent>\r\n <SidebarGroup>\r\n <SidebarGroupLabel className=\"flex items-center justify-between\">\r\n Documents\r\n <button\r\n onClick={onAddTab}\r\n className=\"rounded p-1 transition-all duration-200 hover:bg-accent hover:scale-110\"\r\n aria-label=\"Add new document\"\r\n >\r\n <Plus size={16} />\r\n </button>\r\n </SidebarGroupLabel>\r\n\r\n <SidebarMenu>\r\n {/* ✨ Wrap with AnimatePresence for exit animations */}\r\n <AnimatePresence mode=\"popLayout\">\r\n {tabs.map((tab) => {\r\n const isOpen = openTabs[tab.id];\r\n const hasSubtabs = tab.subtabs.length > 0;\r\n const isActiveTab = tab.id === activeTabId && !activeSubTabId;\r\n\r\n return (\r\n <motion.div\r\n key={tab.id}\r\n variants={tabVariants}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n layout // ✨ Smooth layout shifts\r\n >\r\n <SidebarMenuItem className=\"list-none\">\r\n {/* ---------- TAB ROW ---------- */}\r\n <div\r\n className={`\r\n group flex items-center gap-2 rounded-md px-2 py-1.5\r\n transition-all duration-200 ease-in-out\r\n ${isActiveTab ? \"bg-accent\" : \"hover:bg-accent/50\"}\r\n `}\r\n >\r\n {/* DROPDOWN CHEVRON */}\r\n {hasSubtabs && (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n toggleTabOpen(tab.id);\r\n }}\r\n className=\"flex h-5 w-5 items-center justify-center rounded transition-all duration-200 hover:bg-accent/80\"\r\n aria-label={\r\n isOpen ? \"Collapse subtabs\" : \"Expand subtabs\"\r\n }\r\n >\r\n <ChevronRight\r\n size={14}\r\n className={`transition-transform duration-300 ease-in-out ${\r\n isOpen ? \"rotate-90\" : \"\"\r\n }`}\r\n />\r\n </button>\r\n )}\r\n\r\n {/* DOC ICON */}\r\n <FileText\r\n size={16}\r\n className={`flex-shrink-0 transition-all duration-200 ${\r\n hasSubtabs ? \"\" : \"ml-5\"\r\n } ${\r\n isActiveTab\r\n ? \"opacity-100\"\r\n : \"opacity-60 group-hover:opacity-100\"\r\n }`}\r\n />\r\n\r\n {/* TAB TITLE / RENAME */}\r\n <div className=\"flex-1 min-w-0\">\r\n {editingId === tab.id ? (\r\n <Input\r\n value={tempTitle}\r\n autoFocus\r\n onChange={(e) => setTempTitle(e.target.value)}\r\n onBlur={commitRenameTab}\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\") commitRenameTab();\r\n if (e.key === \"Escape\") setEditingId(null);\r\n }}\r\n className=\"h-7 transition-all duration-200\"\r\n />\r\n ) : (\r\n <button\r\n className=\"w-full truncate text-left text-sm transition-colors duration-200\"\r\n onClick={() => onSelect(tab.id)}\r\n onDoubleClick={() =>\r\n startRenameTab(tab.id, tab.title)\r\n }\r\n >\r\n {tab.title}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* TAB MENU */}\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <button\r\n className=\"opacity-0 group-hover:opacity-100 rounded p-1 transition-all duration-200 hover:bg-accent/80\"\r\n aria-label=\"Tab options\"\r\n >\r\n <MoreHorizontal size={14} />\r\n </button>\r\n </DropdownMenuTrigger>\r\n\r\n <DropdownMenuContent align=\"end\" className=\"w-40\">\r\n <DropdownMenuItem\r\n onClick={() => {\r\n onAddSubTab(tab.id);\r\n setOpenTabs((prev) => ({\r\n ...prev,\r\n [tab.id]: true,\r\n }));\r\n }}\r\n className=\"cursor-pointer transition-colors duration-150\"\r\n >\r\n Add subtab\r\n </DropdownMenuItem>\r\n\r\n {canDeleteTab && (\r\n <DropdownMenuItem\r\n className=\"text-red-500 cursor-pointer transition-colors duration-150 focus:text-red-600\"\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n onDelete(tab.id);\r\n }}\r\n >\r\n Delete\r\n </DropdownMenuItem>\r\n )}\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n </div>\r\n\r\n {/* ---------- SUBTABS ---------- */}\r\n {hasSubtabs && (\r\n <div\r\n className={`\r\n grid transition-all duration-300 ease-in-out\r\n ${\r\n isOpen\r\n ? \"grid-rows-[1fr] opacity-100\"\r\n : \"grid-rows-[0fr] opacity-0\"\r\n }\r\n `}\r\n >\r\n <div className=\"overflow-hidden\">\r\n <div className=\"pt-1 space-y-1\">\r\n {/* ✨ AnimatePresence for subtabs */}\r\n <AnimatePresence mode=\"popLayout\">\r\n {tab.subtabs.map((st) => {\r\n const isActiveSubTab = st.id === activeSubTabId;\r\n\r\n return (\r\n <motion.div\r\n key={st.id}\r\n variants={subtabVariants}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n layout\r\n className={`\r\n group ml-9 flex items-center gap-2 rounded-md px-2 py-1.5 text-sm\r\n transition-all duration-200 ease-in-out\r\n ${\r\n isActiveSubTab\r\n ? \"bg-accent\"\r\n : \"hover:bg-accent/50\"\r\n }\r\n `}\r\n >\r\n {/* SUBDOC ICON */}\r\n <FileText\r\n size={14}\r\n className={`flex-shrink-0 transition-all duration-200 ${\r\n isActiveSubTab\r\n ? \"opacity-100\"\r\n : \"opacity-50 group-hover:opacity-100\"\r\n }`}\r\n />\r\n\r\n {/* SUBTAB TITLE / RENAME */}\r\n <div className=\"flex-1 min-w-0\">\r\n {editingSubId === st.id ? (\r\n <Input\r\n value={tempTitle}\r\n autoFocus\r\n onChange={(e) =>\r\n setTempTitle(e.target.value)\r\n }\r\n onBlur={() => commitRenameSubTab(tab.id)}\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\")\r\n commitRenameSubTab(tab.id);\r\n if (e.key === \"Escape\")\r\n setEditingSubId(null);\r\n }}\r\n className=\"h-6 transition-all duration-200\"\r\n />\r\n ) : (\r\n <button\r\n className=\"w-full truncate text-left transition-colors duration-200\"\r\n onClick={() => onSelect(tab.id, st.id)}\r\n onDoubleClick={() =>\r\n startRenameSubTab(st.id, st.title)\r\n }\r\n >\r\n {st.title}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* SUBTAB MENU */}\r\n {onDeleteSubTab && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <button\r\n className=\"opacity-0 group-hover:opacity-100 rounded p-1 transition-all duration-200 hover:bg-accent/80\"\r\n aria-label=\"Subtab options\"\r\n >\r\n <MoreHorizontal size={14} />\r\n </button>\r\n </DropdownMenuTrigger>\r\n\r\n <DropdownMenuContent\r\n align=\"end\"\r\n className=\"w-40\"\r\n >\r\n <DropdownMenuItem\r\n className=\"text-red-500 cursor-pointer transition-colors duration-150 focus:text-red-600\"\r\n onClick={() =>\r\n onDeleteSubTab(tab.id, st.id)\r\n }\r\n >\r\n Delete\r\n </DropdownMenuItem>\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </motion.div>\r\n );\r\n })}\r\n </AnimatePresence>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </SidebarMenuItem>\r\n </motion.div>\r\n );\r\n })}\r\n </AnimatePresence>\r\n </SidebarMenu>\r\n </SidebarGroup>\r\n </SidebarContent>\r\n </Sidebar>\r\n );\r\n}\r\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n )\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","\"use client\";\r\n\r\nimport React, { createContext, useContext } from \"react\";\r\nimport type { Editor } from \"@tiptap/core\";\r\n\r\nexport type EditorBridgeValue = {\r\n editorContent: Editor | null;\r\n setEditorContent: (editor: Editor | null) => void;\r\n debouncedSave: (editor: Editor) => void;\r\n};\r\n\r\nconst EditorBridgeContext = createContext<EditorBridgeValue | undefined>(\r\n undefined\r\n);\r\n\r\nexport function EditorBridgeProvider({\r\n children,\r\n value,\r\n}: {\r\n children: React.ReactNode;\r\n value: EditorBridgeValue;\r\n}) {\r\n return (\r\n <EditorBridgeContext.Provider value={value}>\r\n {children}\r\n </EditorBridgeContext.Provider>\r\n );\r\n}\r\n\r\nexport function useEditorBridge() {\r\n const ctx = useContext(EditorBridgeContext);\r\n if (!ctx) {\r\n throw new Error(\"useEditorBridge must be used within EditorBridgeProvider\");\r\n }\r\n return ctx;\r\n}\r\n","// src/lib/editorStorage.ts\r\nimport { EditorTab } from \"../components/types/editor-tabs\";\r\nexport type TabContent = any;\r\n\r\n\r\n\r\nconst STORAGE_KEY = \"tiptap-tabs-v1\";\r\nconst ACTIVE_TAB_KEY = \"tiptap-active-tab\";\r\n\r\n\r\nexport function loadTabs(): EditorTab[] {\r\n if (typeof window === \"undefined\") return [];\r\n\r\n try {\r\n const raw = localStorage.getItem(\"tiptap-tabs-v1\");\r\n if (!raw) return [];\r\n\r\n const parsed = JSON.parse(raw);\r\n\r\n // runtime safety\r\n if (!Array.isArray(parsed)) return [];\r\n\r\n return parsed as EditorTab[];\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\nexport function saveTabs(tabs: EditorTab[]) {\r\n if (typeof window === \"undefined\") return;\r\n localStorage.setItem(STORAGE_KEY, JSON.stringify(tabs));\r\n}\r\n\r\nexport function loadActiveTab(): string {\r\n if (typeof window === \"undefined\") return \"1\";\r\n return localStorage.getItem(ACTIVE_TAB_KEY) ?? \"1\";\r\n}\r\n\r\nexport function saveActiveTab(id: string) {\r\n if (typeof window === \"undefined\") return;\r\n localStorage.setItem(ACTIVE_TAB_KEY, id);\r\n}\r\n\r\n","\"use client\";\r\n\r\nimport { useEffect, useRef, useState } from \"react\";\r\nimport { EditorContent, EditorContext, useEditor } from \"@tiptap/react\";\r\nimport { useEditorBridge } from \"../../../contexts/EditorBridge\";\r\n\r\n// --- Tiptap Core Extensions ---\r\nimport { StarterKit } from \"@tiptap/starter-kit\";\r\nimport ImageResize from \"tiptap-extension-resize-image\";\r\nimport Image from \"@tiptap/extension-image\";\r\nimport { TaskItem, TaskList } from \"@tiptap/extension-list\";\r\nimport { TextAlign } from \"@tiptap/extension-text-align\";\r\nimport { Typography } from \"@tiptap/extension-typography\";\r\nimport { Highlight } from \"@tiptap/extension-highlight\";\r\nimport { Subscript } from \"@tiptap/extension-subscript\";\r\nimport { Superscript } from \"@tiptap/extension-superscript\";\r\nimport { Gapcursor, Selection } from \"@tiptap/extensions\";\r\nimport { TextStyleKit } from \"@tiptap/extension-text-style\";\r\nimport Document from \"@tiptap/extension-document\";\r\nimport Paragraph from \"@tiptap/extension-paragraph\";\r\nimport Text from \"@tiptap/extension-text\";\r\nimport { FontFamily, TextStyle } from \"@tiptap/extension-text-style\";\r\nimport Color from \"@tiptap/extension-color\";\r\nimport { TableKit } from \"@tiptap/extension-table\";\r\nimport { Dropcursor } from \"@tiptap/extensions\";\r\nimport { FontSizeStepper } from \"../../extensions/font-size-stepper\";\r\n\r\n// --- UI Primitives ---\r\nimport { Button } from \"../../tiptap-ui-primitive/button/button\";\r\nimport { Spacer } from \"../../tiptap-ui-primitive/spacer/spacer\";\r\nimport {\r\n Toolbar,\r\n ToolbarGroup,\r\n ToolbarSeparator,\r\n} from \"../../tiptap-ui-primitive/toolbar/toolbar\";\r\nimport { BubbleMenuInline } from \"../../tiptap-ui-primitive/bubble-menu/bubble-menu\";\r\n\r\n// --- Tiptap Node ---\r\nimport { ImageUploadNode } from \"../../tiptap-node/image-upload-node/image-upload-node-extension\";\r\nimport { HorizontalRule } from \"../../tiptap-node/horizontal-rule-node/horizontal-rule-node-extension\";\r\nimport \"../../tiptap-node/blockquote-node/blockquote-node.scss\";\r\nimport \"../../tiptap-node/code-block-node/code-block-node.scss\";\r\nimport \"../../tiptap-node/horizontal-rule-node/horizontal-rule-node.scss\";\r\nimport \"../../tiptap-node/list-node/list-node.scss\";\r\nimport \"../../tiptap-node/image-node/image-node.scss\";\r\nimport \"../../tiptap-node/heading-node/heading-node.scss\";\r\n\r\n// --- Tiptap UI ---\r\nimport { HeadingDropdownMenu } from \"../../tiptap-ui/heading-dropdown-menu\";\r\nimport { ImageUploadButton } from \"../../tiptap-ui/image-upload-button\";\r\nimport { ListDropdownMenu } from \"../../tiptap-ui/list-dropdown-menu\";\r\nimport { BlockquoteButton } from \"../../tiptap-ui/blockquote-button\";\r\nimport { CodeBlockButton } from \"../../tiptap-ui/code-block-button\";\r\nimport {\r\n ColorHighlightPopover,\r\n ColorHighlightPopoverContent,\r\n ColorHighlightPopoverButton,\r\n} from \"../../tiptap-ui/color-highlight-popover\";\r\nimport {\r\n LinkPopover,\r\n LinkContent,\r\n LinkButton,\r\n} from \"../../tiptap-ui/link-popover\";\r\nimport { MarkButton } from \"../../tiptap-ui/mark-button\";\r\nimport { TextAlignButton } from \"../../tiptap-ui/text-align-button\";\r\nimport { UndoRedoButton } from \"../../tiptap-ui/undo-redo-button\";\r\nimport { FontFamilyDropdown } from \"../../tiptap-ui/font-family-dropdown/font-family-dropdown\";\r\nimport { ColorPicker } from \"../../tiptap-ui/color-picker/color-picker\";\r\nimport { TableDropdownMenu } from \"../../tiptap-ui/table-dropdown-menu/table-dropdown-menu\";\r\n// --- Icons ---\r\nimport { ArrowLeftIcon } from \"../../tiptap-icons/arrow-left-icon\";\r\nimport { HighlighterIcon } from \"../../tiptap-icons/highlighter-icon\";\r\nimport { LinkIcon } from \"../../tiptap-icons/link-icon\";\r\n\r\n// --- Hooks ---\r\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\";\r\nimport { useWindowSize } from \"../../../hooks/use-window-size\";\r\nimport { useCursorVisibility } from \"../../../hooks/use-cursor-visibility\";\r\n\r\n// --- Components ---\r\nimport { ThemeToggle } from \"../../tiptap-templates/simple/theme-toggle\";\r\n\r\n// --- Lib ---\r\nimport { handleImageUpload, MAX_FILE_SIZE } from \"../../../lib/tiptap-utils\";\r\n\r\n// --- Styles ---\r\nimport \"../simple/simple-editor.scss\";\r\n\r\n\r\n\r\nconst MainToolbarContent = ({\r\n onHighlighterClick,\r\n onLinkClick,\r\n isMobile,\r\n}: {\r\n onHighlighterClick: () => void;\r\n onLinkClick: () => void;\r\n isMobile: boolean;\r\n}) => {\r\n return (\r\n <>\r\n <Spacer />\r\n <FontFamilyDropdown />\r\n <ColorPicker type=\"text\" />\r\n <ToolbarGroup>\r\n <MarkButton type=\"bold\" />\r\n <MarkButton type=\"italic\" />\r\n <MarkButton type=\"strike\" />\r\n <MarkButton type=\"code\" />\r\n <MarkButton type=\"underline\" />\r\n <UndoRedoButton action=\"undo\" />\r\n <UndoRedoButton action=\"redo\" />\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n <ToolbarGroup>\r\n <TextAlignButton align=\"left\" />\r\n <TextAlignButton align=\"center\" />\r\n <TextAlignButton align=\"right\" />\r\n <TextAlignButton align=\"justify\" />\r\n {/* <HeadingDropdownMenu levels={[1, 2, 3, 4]} portal={isMobile} />\r\n <ListDropdownMenu\r\n types={[\"bulletList\", \"orderedList\", \"taskList\"]}\r\n portal={isMobile}\r\n />\r\n <BlockquoteButton />\r\n <CodeBlockButton /> */}\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n <ToolbarGroup>\r\n <HeadingDropdownMenu levels={[1, 2, 3, 4]} portal={isMobile} />\r\n <ListDropdownMenu\r\n types={[\"bulletList\", \"orderedList\", \"taskList\"]}\r\n portal={isMobile}\r\n />\r\n <BlockquoteButton />\r\n {/* <ColorPicker type=\"background\" /> */}\r\n </ToolbarGroup>\r\n <ToolbarGroup>\r\n <TableDropdownMenu />\r\n {/* {!isMobile ? (\r\n <ColorHighlightPopover />\r\n ) : (\r\n <ColorHighlightPopoverButton onClick={onHighlighterClick} />\r\n )}\r\n {!isMobile ? <LinkPopover /> : <LinkButton onClick={onLinkClick} />} */}\r\n {/* <MarkButton type=\"superscript\" />\r\n <MarkButton type=\"subscript\" /> */}\r\n </ToolbarGroup>\r\n\r\n <ToolbarGroup>\r\n {/* <TextAlignButton align=\"left\" />\r\n <TextAlignButton align=\"center\" />\r\n <TextAlignButton align=\"right\" />\r\n <TextAlignButton align=\"justify\" /> */}\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n <ToolbarGroup>\r\n <ImageUploadButton text=\"Add\" />\r\n </ToolbarGroup>\r\n\r\n <Spacer />\r\n\r\n {isMobile && <ToolbarSeparator />}\r\n\r\n {/* <ToolbarGroup>\r\n <ThemeToggle />\r\n </ToolbarGroup> */}\r\n </>\r\n );\r\n};\r\n\r\nconst MobileToolbarContent = ({\r\n type,\r\n onBack,\r\n}: {\r\n type: \"highlighter\" | \"link\";\r\n onBack: () => void;\r\n}) => (\r\n <>\r\n <ToolbarGroup>\r\n <Button data-style=\"ghost\" onClick={onBack}>\r\n <ArrowLeftIcon className=\"tiptap-button-icon\" />\r\n {type === \"highlighter\" ? (\r\n <HighlighterIcon className=\"tiptap-button-icon\" />\r\n ) : (\r\n <LinkIcon className=\"tiptap-button-icon\" />\r\n )}\r\n </Button>\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n {type === \"highlighter\" ? (\r\n <ColorHighlightPopoverContent />\r\n ) : (\r\n <LinkContent />\r\n )}\r\n </>\r\n);\r\n\r\nexport function SimpleEditor() {\r\n const { setEditorContent, debouncedSave} = useEditorBridge();\r\n const isMobile = useIsBreakpoint();\r\n const { height } = useWindowSize();\r\n const [mobileView, setMobileView] = useState<\"main\" | \"highlighter\" | \"link\">(\r\n \"main\"\r\n );\r\n const toolbarRef = useRef<HTMLDivElement>(null);\r\n\r\n\r\n const editor = useEditor({\r\n immediatelyRender: false,\r\n editorProps: {\r\n attributes: {\r\n autocomplete: \"off\",\r\n autocorrect: \"off\",\r\n autocapitalize: \"off\",\r\n \"aria-label\": \"Main content area, start typing to enter text.\",\r\n class: \"simple-editor\",\r\n },\r\n },\r\n extensions: [\r\n StarterKit.configure({\r\n horizontalRule: false,\r\n link: {\r\n openOnClick: false,\r\n enableClickSelection: true,\r\n },\r\n }),\r\n HorizontalRule,\r\n Document,\r\n Paragraph,\r\n Text,\r\n Gapcursor,\r\n TextStyle,\r\n FontSizeStepper.configure({ step: 2, min: 8, defaultSize: 16 }),\r\n FontFamily.configure({\r\n types: [\"textStyle\"],\r\n }),\r\n Color.configure({ types: [\"textStyle\"] }),\r\n Highlight.configure({ multicolor: true }),\r\n TableKit.configure({\r\n table: { resizable: true },\r\n }),\r\n TextStyleKit,\r\n TextAlign.configure({ types: [\"heading\", \"paragraph\"] }),\r\n TaskList,\r\n TaskItem.configure({ nested: true }),\r\n Highlight.configure({ multicolor: true }),\r\n Image,\r\n Dropcursor,\r\n Typography,\r\n Superscript,\r\n Subscript,\r\n Selection,\r\n ImageUploadNode.configure({\r\n accept: \"image/*\",\r\n maxSize: MAX_FILE_SIZE,\r\n limit: 3,\r\n upload: handleImageUpload,\r\n onError: (error) => console.error(\"Upload failed:\", error),\r\n }),\r\n ],\r\n content: \"\",\r\n onCreate: ({ editor }) => {\r\n console.log(\"🟢 Editor created\");\r\n setEditorContent(editor);\r\n },\r\n onUpdate: ({ editor }) => {\r\n console.log(\"✏️ Editor updated - triggering debounced save\");\r\n debouncedSave(editor);\r\n },\r\n });\r\n\r\n\r\n useEffect(() => {\r\n if (editor) {\r\n console.log(\"🔧 Setting editor content in context\");\r\n setEditorContent(editor);\r\n }\r\n }, [editor, setEditorContent]);\r\n\r\n\r\n \r\n const rect = useCursorVisibility({\r\n editor,\r\n overlayHeight: toolbarRef.current?.getBoundingClientRect().height ?? 0,\r\n });\r\n\r\n \r\n \r\n\r\n useEffect(() => {\r\n if (!isMobile && mobileView !== \"main\") {\r\n setMobileView(\"main\");\r\n }\r\n }, [isMobile, mobileView]);\r\n useEffect(() => {\r\n if (editor) {\r\n editor.commands.focus(\"start\"); // or \"end\"\r\n }\r\n }, [editor]);\r\n\r\n useEffect(() => {\r\n if (!window?.visualViewport) return;\r\n\r\n const toolbar = document.querySelector(\r\n \".tiptap-toolbar[data-variant='fixed']\"\r\n ) as HTMLElement | null;\r\n\r\n if (!toolbar) return;\r\n\r\n const updatePosition = () => {\r\n toolbar.style.top = `${window.visualViewport?.offsetTop}px`;\r\n };\r\n\r\n window.visualViewport.addEventListener(\"resize\", updatePosition);\r\n window.visualViewport.addEventListener(\"scroll\", updatePosition);\r\n\r\n updatePosition();\r\n\r\n return () => {\r\n window.visualViewport?.removeEventListener(\"resize\", updatePosition);\r\n window.visualViewport?.removeEventListener(\"scroll\", updatePosition);\r\n };\r\n }, []);\r\n\r\n return (\r\n <div className=\"simple-editor-wrapper\">\r\n <EditorContext.Provider value={{ editor }}>\r\n <Toolbar\r\n ref={toolbarRef}\r\n style={{\r\n ...(isMobile\r\n ? {\r\n bottom: `calc(100% - ${height - rect.y}px)`,\r\n }\r\n : {}),\r\n }}\r\n >\r\n {mobileView === \"main\" ? (\r\n <MainToolbarContent\r\n onHighlighterClick={() => setMobileView(\"highlighter\")}\r\n onLinkClick={() => setMobileView(\"link\")}\r\n isMobile={isMobile}\r\n />\r\n ) : (\r\n <MobileToolbarContent\r\n type={mobileView === \"highlighter\" ? \"highlighter\" : \"link\"}\r\n onBack={() => setMobileView(\"main\")}\r\n />\r\n )}\r\n </Toolbar>\r\n\r\n <EditorContent\r\n editor={editor}\r\n role=\"presentation\"\r\n autoFocus\r\n className=\"simple-editor-content\"\r\n >\r\n {editor && <BubbleMenuInline />}\r\n </EditorContent>\r\n </EditorContext.Provider>\r\n </div>\r\n );\r\n}\r\n","import { Node } from '@tiptap/core'\n\n/**\n * The default document node which represents the top level node of the editor.\n * @see https://tiptap.dev/api/nodes/document\n */\nexport const Document = Node.create({\n name: 'doc',\n topNode: true,\n content: 'block+',\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n return h.renderChildren(node.content, '\\n\\n')\n },\n})\n","import { Document } from './document.js'\n\nexport * from './document.js'\n\nexport default Document\n","import { mergeAttributes, Node } from '@tiptap/core'\n\nexport interface ParagraphOptions {\n /**\n * The HTML attributes for a paragraph node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n paragraph: {\n /**\n * Toggle a paragraph\n * @example editor.commands.toggleParagraph()\n */\n setParagraph: () => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to create paragraphs.\n * @see https://www.tiptap.dev/api/nodes/paragraph\n */\nexport const Paragraph = Node.create<ParagraphOptions>({\n name: 'paragraph',\n\n priority: 1000,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n group: 'block',\n\n content: 'inline*',\n\n parseHTML() {\n return [{ tag: 'p' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['p', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n parseMarkdown: (token, helpers) => {\n const tokens = token.tokens || []\n\n // Special case: if paragraph contains only a single image token,\n // unwrap it to avoid nesting block elements incorrectly\n if (tokens.length === 1 && tokens[0].type === 'image') {\n // Parse the image token directly as a block element\n return helpers.parseChildren([tokens[0]])\n }\n\n // Convert 'paragraph' token to paragraph node\n return helpers.createNode(\n 'paragraph',\n undefined, // no attributes for paragraph\n helpers.parseInline(tokens),\n )\n },\n\n renderMarkdown: (node, h) => {\n if (!node || !Array.isArray(node.content)) {\n return ''\n }\n\n return h.renderChildren(node.content)\n },\n\n addCommands() {\n return {\n setParagraph:\n () =>\n ({ commands }) => {\n return commands.setNode(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Alt-0': () => this.editor.commands.setParagraph(),\n }\n },\n})\n","import { Paragraph } from './paragraph.js'\n\nexport * from './paragraph.js'\n\nexport default Paragraph\n","import { Node } from '@tiptap/core'\n\n/**\n * This extension allows you to create text nodes.\n * @see https://www.tiptap.dev/api/nodes/text\n */\nexport const Text = Node.create({\n name: 'text',\n group: 'inline',\n\n parseMarkdown: token => {\n // Convert 'text' token to text node - text nodes are special as they store text directly\n return {\n type: 'text',\n text: token.text || '',\n }\n },\n\n renderMarkdown: node => node.text || '',\n})\n","import { Text } from './text.js'\n\nexport * from './text.js'\n\nexport default Text\n","// extensions/font-size-stepper.ts\r\nimport { Extension } from \"@tiptap/core\";\r\n\r\nfunction parsePx(value?: string | null): number | null {\r\n if (!value) return null;\r\n const m = /(-?\\d+\\.?\\d*)px/.exec(String(value));\r\n if (!m) return null;\r\n const n = parseFloat(m[1]);\r\n return Number.isFinite(n) ? Math.round(n) : null;\r\n}\r\n\r\nfunction getFontSizeFromResolvedPos(editor: any): number | null {\r\n const { $from } = editor.state.selection;\r\n // Check marks at the resolved position\r\n const marks = $from.marks();\r\n for (const m of marks) {\r\n if (m.type && m.type.name === \"textStyle\" && m.attrs && m.attrs.fontSize) {\r\n const parsed = parsePx(m.attrs.fontSize);\r\n if (parsed !== null) return parsed;\r\n }\r\n }\r\n\r\n // As a last resort, check node attrs (rare)\r\n const node = editor.state.doc.nodeAt($from.pos);\r\n if (node && node.attrs && node.attrs.style) {\r\n const style = node.attrs.style;\r\n const m = /font-size\\s*:\\s*([^;]+)/i.exec(style);\r\n if (m && m[1]) {\r\n const parsed = parsePx(m[1].trim());\r\n if (parsed !== null) return parsed;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport const FontSizeStepper = Extension.create({\r\n name: \"fontSizeStepper\",\r\n\r\n // configuration option to control step & min size\r\n addOptions() {\r\n return {\r\n step: 2,\r\n min: 8,\r\n defaultSize: 16,\r\n };\r\n },\r\n\r\n addCommands() {\r\n return {\r\n increaseFontSize:\r\n () =>\r\n ({ commands, editor }) => {\r\n if (!editor) return false;\r\n\r\n // 1) prefer active textStyle attribute\r\n const attrs = editor.getAttributes(\"textStyle\") || {};\r\n let currentPx = parsePx(attrs.fontSize ?? null);\r\n\r\n // 2) fallback to marks/node at selection\r\n if (currentPx === null) {\r\n currentPx = getFontSizeFromResolvedPos(editor);\r\n }\r\n\r\n // 3) final fallback to sensible default (not tiny 8px)\r\n if (currentPx === null) {\r\n currentPx = this.options.defaultSize;\r\n }\r\n\r\n const newSize = currentPx + this.options.step;\r\n return commands.setFontSize(`${newSize}px`);\r\n },\r\n\r\n decreaseFontSize:\r\n () =>\r\n ({ commands, editor }) => {\r\n if (!editor) return false;\r\n\r\n const attrs = editor.getAttributes(\"textStyle\") || {};\r\n let currentPx = parsePx(attrs.fontSize ?? null);\r\n\r\n if (currentPx === null) {\r\n currentPx = getFontSizeFromResolvedPos(editor);\r\n }\r\n\r\n \r\n if (currentPx === null) {\r\n currentPx = this.options.defaultSize;\r\n }\r\n\r\n const newSize = Math.max(this.options.min, currentPx! - this.options.step);\r\n return commands.setFontSize(`${newSize}px`);\r\n \r\n },\r\n };\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n // Increase: Mod + Shift + . => '>' (Shift + .) — Mod maps to Ctrl/Cmd\r\n \"Mod-Shift-.\": () => this.editor.commands.increaseFontSize(),\r\n // Decrease: Mod + Shift + , => '<' (Shift + ,)\r\n \"Mod-Shift-,\": () => this.editor.commands.decreaseFontSize(),\r\n // Optional extra bindings for explicit Ctrl (if you want):\r\n // \"Ctrl-Shift-.\": () => this.editor.commands.increaseFontSize(),\r\n // \"Ctrl-Shift-,\": () => this.editor.commands.decreaseFontSize(),\r\n };\r\n },\r\n});\r\n","\"use client\"\n\nimport { forwardRef, Fragment, useMemo } from \"react\"\n\n// --- Tiptap UI Primitive ---\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../../../components/tiptap-ui-primitive/tooltip\"\n\n// --- Lib ---\nimport { cn, parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\nimport \"../../../components/tiptap-ui-primitive/button/button-colors.scss\"\nimport \"../../../components/tiptap-ui-primitive/button/button-group.scss\"\nimport \"../../../components/tiptap-ui-primitive/button/button.scss\"\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string\n showTooltip?: boolean\n tooltip?: React.ReactNode\n shortcutKeys?: string\n}\n\nexport const ShortcutDisplay: React.FC<{ shortcuts: string[] }> = ({\n shortcuts,\n}) => {\n if (shortcuts.length === 0) return null\n\n return (\n <div>\n {shortcuts.map((key, index) => (\n <Fragment key={index}>\n {index > 0 && <kbd>+</kbd>}\n <kbd>{key}</kbd>\n </Fragment>\n ))}\n </div>\n )\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n children,\n tooltip,\n showTooltip = true,\n shortcutKeys,\n \"aria-label\": ariaLabel,\n ...props\n },\n ref\n ) => {\n const shortcuts = useMemo<string[]>(\n () => parseShortcutKeys({ shortcutKeys }),\n [shortcutKeys]\n )\n\n if (!tooltip || !showTooltip) {\n return (\n <button\n className={cn(\"tiptap-button\", className)}\n ref={ref}\n aria-label={ariaLabel}\n {...props}\n >\n {children}\n </button>\n )\n }\n\n return (\n <Tooltip delay={200}>\n <TooltipTrigger\n className={cn(\"tiptap-button\", className)}\n ref={ref}\n aria-label={ariaLabel}\n {...props}\n >\n {children}\n </TooltipTrigger>\n <TooltipContent>\n {tooltip}\n <ShortcutDisplay shortcuts={shortcuts} />\n </TooltipContent>\n </Tooltip>\n )\n }\n)\n\nButton.displayName = \"Button\"\n\nexport const ButtonGroup = forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> & {\n orientation?: \"horizontal\" | \"vertical\"\n }\n>(({ className, children, orientation = \"vertical\", ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-button-group\", className)}\n data-orientation={orientation}\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n )\n})\nButtonGroup.displayName = \"ButtonGroup\"\n\nexport default Button\n","\"use client\"\n\nimport {\n cloneElement,\n createContext,\n forwardRef,\n isValidElement,\n useContext,\n useMemo,\n useState,\n version,\n} from \"react\"\nimport {\n useFloating,\n autoUpdate,\n offset,\n flip,\n shift,\n useHover,\n useFocus,\n useDismiss,\n useRole,\n useInteractions,\n useMergeRefs,\n FloatingPortal,\n type Placement,\n type UseFloatingReturn,\n type ReferenceType,\n FloatingDelayGroup,\n} from \"@floating-ui/react\"\nimport \"../../../components/tiptap-ui-primitive/tooltip/tooltip.scss\"\n\ninterface TooltipProviderProps {\n children: React.ReactNode\n initialOpen?: boolean\n placement?: Placement\n open?: boolean\n onOpenChange?: (open: boolean) => void\n delay?: number\n closeDelay?: number\n timeout?: number\n useDelayGroup?: boolean\n}\n\ninterface TooltipTriggerProps\n extends Omit<React.HTMLProps<HTMLElement>, \"ref\"> {\n asChild?: boolean\n children: React.ReactNode\n}\n\ninterface TooltipContentProps\n extends Omit<React.HTMLProps<HTMLDivElement>, \"ref\"> {\n children?: React.ReactNode\n portal?: boolean\n portalProps?: Omit<React.ComponentProps<typeof FloatingPortal>, \"children\">\n}\n\ninterface TooltipContextValue extends UseFloatingReturn<ReferenceType> {\n open: boolean\n setOpen: (open: boolean) => void\n getReferenceProps: (\n userProps?: React.HTMLProps<HTMLElement>\n ) => Record<string, unknown>\n getFloatingProps: (\n userProps?: React.HTMLProps<HTMLDivElement>\n ) => Record<string, unknown>\n}\n\nfunction useTooltip({\n initialOpen = false,\n placement = \"top\",\n open: controlledOpen,\n onOpenChange: setControlledOpen,\n delay = 600,\n closeDelay = 0,\n}: Omit<TooltipProviderProps, \"children\"> = {}) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState<boolean>(initialOpen)\n\n const open = controlledOpen ?? uncontrolledOpen\n const setOpen = setControlledOpen ?? setUncontrolledOpen\n\n const data = useFloating({\n placement,\n open,\n onOpenChange: setOpen,\n whileElementsMounted: autoUpdate,\n middleware: [\n offset(4),\n flip({\n crossAxis: placement.includes(\"-\"),\n fallbackAxisSideDirection: \"start\",\n padding: 4,\n }),\n shift({ padding: 4 }),\n ],\n })\n\n const context = data.context\n\n const hover = useHover(context, {\n mouseOnly: true,\n move: false,\n restMs: delay,\n enabled: controlledOpen == null,\n delay: {\n close: closeDelay,\n },\n })\n const focus = useFocus(context, {\n enabled: controlledOpen == null,\n })\n const dismiss = useDismiss(context)\n const role = useRole(context, { role: \"tooltip\" })\n\n const interactions = useInteractions([hover, focus, dismiss, role])\n\n return useMemo(\n () => ({\n open,\n setOpen,\n ...interactions,\n ...data,\n }),\n [open, setOpen, interactions, data]\n )\n}\n\nconst TooltipContext = createContext<TooltipContextValue | null>(null)\n\nfunction useTooltipContext() {\n const context = useContext(TooltipContext)\n\n if (context == null) {\n throw new Error(\"Tooltip components must be wrapped in <TooltipProvider />\")\n }\n\n return context\n}\n\nexport function Tooltip({ children, ...props }: TooltipProviderProps) {\n const tooltip = useTooltip(props)\n\n if (!props.useDelayGroup) {\n return (\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n )\n }\n\n return (\n <FloatingDelayGroup\n delay={{ open: props.delay ?? 0, close: props.closeDelay ?? 0 }}\n timeoutMs={props.timeout}\n >\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n </FloatingDelayGroup>\n )\n}\n\nexport const TooltipTrigger = forwardRef<HTMLElement, TooltipTriggerProps>(\n function TooltipTrigger({ children, asChild = false, ...props }, propRef) {\n const context = useTooltipContext()\n const childrenRef = isValidElement(children)\n ? parseInt(version, 10) >= 19\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (children as { props: { ref?: React.Ref<any> } }).props.ref\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (children as any).ref\n : undefined\n const ref = useMergeRefs([context.refs.setReference, propRef, childrenRef])\n\n if (asChild && isValidElement(children)) {\n const dataAttributes = {\n \"data-tooltip-state\": context.open ? \"open\" : \"closed\",\n }\n\n return cloneElement(\n children,\n context.getReferenceProps({\n ref,\n ...props,\n ...(typeof children.props === \"object\" ? children.props : {}),\n ...dataAttributes,\n })\n )\n }\n\n return (\n <button\n ref={ref}\n data-tooltip-state={context.open ? \"open\" : \"closed\"}\n {...context.getReferenceProps(props)}\n >\n {children}\n </button>\n )\n }\n)\n\nexport const TooltipContent = forwardRef<HTMLDivElement, TooltipContentProps>(\n function TooltipContent(\n { style, children, portal = true, portalProps = {}, ...props },\n propRef\n ) {\n const context = useTooltipContext()\n const ref = useMergeRefs([context.refs.setFloating, propRef])\n\n if (!context.open) return null\n\n const content = (\n <div\n ref={ref}\n style={{\n ...context.floatingStyles,\n ...style,\n }}\n {...context.getFloatingProps(props)}\n className=\"tiptap-tooltip\"\n >\n {children}\n </div>\n )\n\n if (portal) {\n return <FloatingPortal {...portalProps}>{content}</FloatingPortal>\n }\n\n return content\n }\n)\n\nTooltip.displayName = \"Tooltip\"\nTooltipTrigger.displayName = \"TooltipTrigger\"\nTooltipContent.displayName = \"TooltipContent\"\n","import type { Node as TiptapNode } from \"@tiptap/pm/model\"\nimport type { Transaction } from \"@tiptap/pm/state\"\nimport {\n AllSelection,\n NodeSelection,\n Selection,\n TextSelection,\n} from \"@tiptap/pm/state\"\nimport type { Editor, NodeWithPos } from \"@tiptap/react\"\nimport { Extension } from \"@tiptap/core\"\n\nexport const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB\n\nexport const MAC_SYMBOLS: Record<string, string> = {\n mod: \"⌘\",\n command: \"⌘\",\n meta: \"⌘\",\n ctrl: \"⌃\",\n control: \"⌃\",\n alt: \"⌥\",\n option: \"⌥\",\n shift: \"⇧\",\n backspace: \"Del\",\n delete: \"⌦\",\n enter: \"⏎\",\n escape: \"⎋\",\n capslock: \"⇪\",\n} as const\n\nexport const SR_ONLY = {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n borderWidth: 0,\n} as const\n\nexport function cn(\n ...classes: (string | boolean | undefined | null)[]\n): string {\n return classes.filter(Boolean).join(\" \")\n}\n\n/**\n * Determines if the current platform is macOS\n * @returns boolean indicating if the current platform is Mac\n */\nexport function isMac(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.platform.toLowerCase().includes(\"mac\")\n )\n}\n\n/**\n * Formats a shortcut key based on the platform (Mac or non-Mac)\n * @param key - The key to format (e.g., \"ctrl\", \"alt\", \"shift\")\n * @param isMac - Boolean indicating if the platform is Mac\n * @param capitalize - Whether to capitalize the key (default: true)\n * @returns Formatted shortcut key symbol\n */\nexport const formatShortcutKey = (\n key: string,\n isMac: boolean,\n capitalize: boolean = true\n) => {\n if (isMac) {\n const lowerKey = key.toLowerCase()\n return MAC_SYMBOLS[lowerKey] || (capitalize ? key.toUpperCase() : key)\n }\n\n return capitalize ? key.charAt(0).toUpperCase() + key.slice(1) : key\n}\n\n/**\n * Parses a shortcut key string into an array of formatted key symbols\n * @param shortcutKeys - The string of shortcut keys (e.g., \"ctrl-alt-shift\")\n * @param delimiter - The delimiter used to split the keys (default: \"-\")\n * @param capitalize - Whether to capitalize the keys (default: true)\n * @returns Array of formatted shortcut key symbols\n */\nexport const parseShortcutKeys = (props: {\n shortcutKeys: string | undefined\n delimiter?: string\n capitalize?: boolean\n}) => {\n const { shortcutKeys, delimiter = \"+\", capitalize = true } = props\n\n if (!shortcutKeys) return []\n\n return shortcutKeys\n .split(delimiter)\n .map((key) => key.trim())\n .map((key) => formatShortcutKey(key, isMac(), capitalize))\n}\n\n/**\n * Checks if a mark exists in the editor schema\n * @param markName - The name of the mark to check\n * @param editor - The editor instance\n * @returns boolean indicating if the mark exists in the schema\n */\nexport const isMarkInSchema = (\n markName: string,\n editor: Editor | null\n): boolean => {\n if (!editor?.schema) return false\n return editor.schema.spec.marks.get(markName) !== undefined\n}\n\n/**\n * Checks if a node exists in the editor schema\n * @param nodeName - The name of the node to check\n * @param editor - The editor instance\n * @returns boolean indicating if the node exists in the schema\n */\nexport const isNodeInSchema = (\n nodeName: string,\n editor: Editor | null\n): boolean => {\n if (!editor?.schema) return false\n return editor.schema.spec.nodes.get(nodeName) !== undefined\n}\n\n/**\n * Moves the focus to the next node in the editor\n * @param editor - The editor instance\n * @returns boolean indicating if the focus was moved\n */\nexport function focusNextNode(editor: Editor) {\n const { state, view } = editor\n const { doc, selection } = state\n\n const nextSel = Selection.findFrom(selection.$to, 1, true)\n if (nextSel) {\n view.dispatch(state.tr.setSelection(nextSel).scrollIntoView())\n return true\n }\n\n const paragraphType = state.schema.nodes.paragraph\n if (!paragraphType) {\n console.warn(\"No paragraph node type found in schema.\")\n return false\n }\n\n const end = doc.content.size\n const para = paragraphType.create()\n let tr = state.tr.insert(end, para)\n\n // Place the selection inside the new paragraph\n const $inside = tr.doc.resolve(end + 1)\n tr = tr.setSelection(TextSelection.near($inside)).scrollIntoView()\n view.dispatch(tr)\n return true\n}\n\n/**\n * Checks if a value is a valid number (not null, undefined, or NaN)\n * @param value - The value to check\n * @returns boolean indicating if the value is a valid number\n */\nexport function isValidPosition(pos: number | null | undefined): pos is number {\n return typeof pos === \"number\" && pos >= 0\n}\n\n/**\n * Checks if one or more extensions are registered in the Tiptap editor.\n * @param editor - The Tiptap editor instance\n * @param extensionNames - A single extension name or an array of names to check\n * @returns True if at least one of the extensions is available, false otherwise\n */\nexport function isExtensionAvailable(\n editor: Editor | null,\n extensionNames: string | string[]\n): boolean {\n if (!editor) return false\n\n const names = Array.isArray(extensionNames)\n ? extensionNames\n : [extensionNames]\n\n const found = names.some((name) =>\n editor.extensionManager.extensions.some((ext) => ext.name === name)\n )\n\n if (!found) {\n console.warn(\n `None of the extensions [${names.join(\", \")}] were found in the editor schema. Ensure they are included in the editor configuration.`\n )\n }\n\n return found\n}\n\n/**\n * Finds a node at the specified position with error handling\n * @param editor The Tiptap editor instance\n * @param position The position in the document to find the node\n * @returns The node at the specified position, or null if not found\n */\nexport function findNodeAtPosition(editor: Editor, position: number) {\n try {\n const node = editor.state.doc.nodeAt(position)\n if (!node) {\n console.warn(`No node found at position ${position}`)\n return null\n }\n return node\n } catch (error) {\n console.error(`Error getting node at position ${position}:`, error)\n return null\n }\n}\n\n/**\n * Finds the position and instance of a node in the document\n * @param props Object containing editor, node (optional), and nodePos (optional)\n * @param props.editor The Tiptap editor instance\n * @param props.node The node to find (optional if nodePos is provided)\n * @param props.nodePos The position of the node to find (optional if node is provided)\n * @returns An object with the position and node, or null if not found\n */\nexport function findNodePosition(props: {\n editor: Editor | null\n node?: TiptapNode | null\n nodePos?: number | null\n}): { pos: number; node: TiptapNode } | null {\n const { editor, node, nodePos } = props\n\n if (!editor || !editor.state?.doc) return null\n\n // Zero is valid position\n const hasValidNode = node !== undefined && node !== null\n const hasValidPos = isValidPosition(nodePos)\n\n if (!hasValidNode && !hasValidPos) {\n return null\n }\n\n // First search for the node in the document if we have a node\n if (hasValidNode) {\n let foundPos = -1\n let foundNode: TiptapNode | null = null\n\n editor.state.doc.descendants((currentNode, pos) => {\n // TODO: Needed?\n // if (currentNode.type && currentNode.type.name === node!.type.name) {\n if (currentNode === node) {\n foundPos = pos\n foundNode = currentNode\n return false\n }\n return true\n })\n\n if (foundPos !== -1 && foundNode !== null) {\n return { pos: foundPos, node: foundNode }\n }\n }\n\n // If we have a valid position, use findNodeAtPosition\n if (hasValidPos) {\n const nodeAtPos = findNodeAtPosition(editor, nodePos!)\n if (nodeAtPos) {\n return { pos: nodePos!, node: nodeAtPos }\n }\n }\n\n return null\n}\n\n/**\n * Determines whether the current selection contains a node whose type matches\n * any of the provided node type names.\n * @param editor Tiptap editor instance\n * @param nodeTypeNames List of node type names to match against\n * @param checkAncestorNodes Whether to check ancestor node types up the depth chain\n */\nexport function isNodeTypeSelected(\n editor: Editor | null,\n nodeTypeNames: string[] = [],\n checkAncestorNodes: boolean = false\n): boolean {\n if (!editor || !editor.state.selection) return false\n\n const { selection } = editor.state\n if (selection.empty) return false\n\n // Direct node selection check\n if (selection instanceof NodeSelection) {\n const selectedNode = selection.node\n return selectedNode ? nodeTypeNames.includes(selectedNode.type.name) : false\n }\n\n // Depth-based ancestor node check\n if (checkAncestorNodes) {\n const { $from } = selection\n for (let depth = $from.depth; depth > 0; depth--) {\n const ancestorNode = $from.node(depth)\n if (nodeTypeNames.includes(ancestorNode.type.name)) {\n return true\n }\n }\n }\n\n return false\n}\n\n/**\n * Check whether the current selection is fully within nodes\n * whose type names are in the provided `types` list.\n *\n * - NodeSelection → checks the selected node.\n * - Text/AllSelection → ensures all textblocks within [from, to) are allowed.\n */\nexport function selectionWithinConvertibleTypes(\n editor: Editor,\n types: string[] = []\n): boolean {\n if (!editor || types.length === 0) return false\n\n const { state } = editor\n const { selection } = state\n const allowed = new Set(types)\n\n if (selection instanceof NodeSelection) {\n const nodeType = selection.node?.type?.name\n return !!nodeType && allowed.has(nodeType)\n }\n\n if (selection instanceof TextSelection || selection instanceof AllSelection) {\n let valid = true\n state.doc.nodesBetween(selection.from, selection.to, (node) => {\n if (node.isTextblock && !allowed.has(node.type.name)) {\n valid = false\n return false // stop early\n }\n return valid\n })\n return valid\n }\n\n return false\n}\n\n/**\n * Handles image upload with progress tracking and abort capability\n * @param file The file to upload\n * @param onProgress Optional callback for tracking upload progress\n * @param abortSignal Optional AbortSignal for cancelling the upload\n * @returns Promise resolving to the URL of the uploaded image\n */\nexport const handleImageUpload = async (\n file: File,\n onProgress?: (event: { progress: number }) => void,\n abortSignal?: AbortSignal\n): Promise<string> => {\n // Validate file\n if (!file) {\n throw new Error(\"No file provided\")\n }\n\n if (file.size > MAX_FILE_SIZE) {\n throw new Error(\n `File size exceeds maximum allowed (${MAX_FILE_SIZE / (1024 * 1024)}MB)`\n )\n }\n\n // For demo/testing: Simulate upload progress. In production, replace the following code\n // with your own upload implementation.\n for (let progress = 0; progress <= 100; progress += 10) {\n if (abortSignal?.aborted) {\n throw new Error(\"Upload cancelled\")\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n onProgress?.({ progress })\n }\n\n return \"/images/tiptap-ui-placeholder-image.jpg\"\n}\n\ntype ProtocolOptions = {\n /**\n * The protocol scheme to be registered.\n * @default '''\n * @example 'ftp'\n * @example 'git'\n */\n scheme: string\n\n /**\n * If enabled, it allows optional slashes after the protocol.\n * @default false\n * @example true\n */\n optionalSlashes?: boolean\n}\n\ntype ProtocolConfig = Array<ProtocolOptions | string>\n\nconst ATTR_WHITESPACE =\n // eslint-disable-next-line no-control-regex\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g\n\nexport function isAllowedUri(\n uri: string | undefined,\n protocols?: ProtocolConfig\n) {\n const allowedProtocols: string[] = [\n \"http\",\n \"https\",\n \"ftp\",\n \"ftps\",\n \"mailto\",\n \"tel\",\n \"callto\",\n \"sms\",\n \"cid\",\n \"xmpp\",\n ]\n\n if (protocols) {\n protocols.forEach((protocol) => {\n const nextProtocol =\n typeof protocol === \"string\" ? protocol : protocol.scheme\n\n if (nextProtocol) {\n allowedProtocols.push(nextProtocol)\n }\n })\n }\n\n return (\n !uri ||\n uri.replace(ATTR_WHITESPACE, \"\").match(\n new RegExp(\n // eslint-disable-next-line no-useless-escape\n `^(?:(?:${allowedProtocols.join(\"|\")}):|[^a-z]|[a-z0-9+.\\-]+(?:[^a-z+.\\-:]|$))`,\n \"i\"\n )\n )\n )\n}\n\nexport function sanitizeUrl(\n inputUrl: string,\n baseUrl: string,\n protocols?: ProtocolConfig\n): string {\n try {\n const url = new URL(inputUrl, baseUrl)\n\n if (isAllowedUri(url.href, protocols)) {\n return url.href\n }\n } catch {\n // If URL creation fails, it's considered invalid\n }\n return \"#\"\n}\n\n/**\n * Update a single attribute on multiple nodes.\n *\n * @param tr - The transaction to mutate\n * @param targets - Array of { node, pos }\n * @param attrName - Attribute key to update\n * @param next - New value OR updater function receiving previous value\n * Pass `undefined` to remove the attribute.\n * @returns true if at least one node was updated, false otherwise\n */\nexport function updateNodesAttr<A extends string = string, V = unknown>(\n tr: Transaction,\n targets: readonly NodeWithPos[],\n attrName: A,\n next: V | ((prev: V | undefined) => V | undefined)\n): boolean {\n if (!targets.length) return false\n\n let changed = false\n\n for (const { pos } of targets) {\n // Always re-read from the transaction's current doc\n const currentNode = tr.doc.nodeAt(pos)\n if (!currentNode) continue\n\n const prevValue = (currentNode.attrs as Record<string, unknown>)[\n attrName\n ] as V | undefined\n const resolvedNext =\n typeof next === \"function\"\n ? (next as (p: V | undefined) => V | undefined)(prevValue)\n : next\n\n if (prevValue === resolvedNext) continue\n\n const nextAttrs: Record<string, unknown> = { ...currentNode.attrs }\n if (resolvedNext === undefined) {\n // Remove the key entirely instead of setting null\n delete nextAttrs[attrName]\n } else {\n nextAttrs[attrName] = resolvedNext\n }\n\n tr.setNodeMarkup(pos, undefined, nextAttrs)\n changed = true\n }\n\n return changed\n}\n\n/**\n * Selects the entire content of the current block node if the selection is empty.\n * If the selection is not empty, it does nothing.\n * @param editor The Tiptap editor instance\n */\nexport function selectCurrentBlockContent(editor: Editor) {\n const { selection, doc } = editor.state\n\n if (!selection.empty) return\n\n const $pos = selection.$from\n let blockNode = null\n let blockPos = -1\n\n for (let depth = $pos.depth; depth >= 0; depth--) {\n const node = $pos.node(depth)\n const pos = $pos.start(depth)\n\n if (node.isBlock && node.textContent.trim()) {\n blockNode = node\n blockPos = pos\n break\n }\n }\n\n if (blockNode && blockPos >= 0) {\n const from = blockPos\n const to = blockPos + blockNode.nodeSize - 2 // -2 to exclude the closing tag\n\n if (from < to) {\n const $from = doc.resolve(from)\n const $to = doc.resolve(to)\n const newSelection = TextSelection.between($from, $to, 1)\n\n if (newSelection && !selection.eq(newSelection)) {\n editor.view.dispatch(editor.state.tr.setSelection(newSelection))\n }\n }\n }\n}\n\nexport const FONT_SIZES = [\n \"8px\",\n \"10px\",\n \"12px\",\n \"14px\",\n \"16px\",\n \"18px\",\n \"20px\",\n \"24px\",\n \"28px\",\n \"32px\",\n \"36px\",\n \"40px\",\n \"48px\",\n \"56px\",\n \"64px\",\n]\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType\n increaseFontSize: () => ReturnType\n decreaseFontSize: () => ReturnType\n }\n }\n}\n\nexport const FontSizeExtension = Extension.create({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n }\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize || element.getAttribute(\"data-font-size\"),\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {}\n }\n\n return {\n style: `font-size: ${attributes.fontSize}`,\n }\n },\n },\n },\n },\n ]\n },\n\n addCommands() {\n return {\n setFontSize:\n (fontSize: string) =>\n ({ commands }) => {\n return commands.setMark(\"textStyle\", { fontSize })\n },\n\n increaseFontSize:\n () =>\n ({ editor }) => {\n const currentSize = editor.getAttributes(\"textStyle\").fontSize\n const currentIndex = FONT_SIZES.indexOf(currentSize || \"16px\")\n const nextIndex = Math.min(currentIndex + 1, FONT_SIZES.length - 1)\n const nextSize = FONT_SIZES[nextIndex]\n\n return editor.chain().focus().setFontSize(nextSize).run()\n },\n\n decreaseFontSize:\n () =>\n ({ editor }) => {\n const currentSize = editor.getAttributes(\"textStyle\").fontSize\n const currentIndex = FONT_SIZES.indexOf(currentSize || \"16px\")\n const nextIndex = Math.max(currentIndex - 1, 0)\n const nextSize = FONT_SIZES[nextIndex]\n\n return editor.chain().focus().setFontSize(nextSize).run()\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n \"mod+shift+>\": () => this.editor.commands.increaseFontSize(),\n \"mod+shift+<\": () => this.editor.commands.decreaseFontSize(),\n }\n },\n})\n","\"use client\"\n\nexport type SpacerOrientation = \"horizontal\" | \"vertical\"\n\nexport interface SpacerProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: SpacerOrientation\n size?: string | number\n}\n\nexport function Spacer({\n orientation = \"horizontal\",\n size,\n style = {},\n ...props\n}: SpacerProps) {\n const computedStyle = {\n ...style,\n ...(orientation === \"horizontal\" && !size && { flex: 1 }),\n ...(size && {\n width: orientation === \"vertical\" ? \"1px\" : size,\n height: orientation === \"horizontal\" ? \"1px\" : size,\n }),\n }\n\n return <div {...props} style={computedStyle} />\n}\n","\"use client\"\n\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\"\nimport { Separator } from \"../../../components/tiptap-ui-primitive/separator\"\nimport \"../../../components/tiptap-ui-primitive/toolbar/toolbar.scss\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation\"\nimport { useComposedRef } from \"../../../hooks/use-composed-ref\"\n\ntype BaseProps = React.HTMLAttributes<HTMLDivElement>\n\ninterface ToolbarProps extends BaseProps {\n variant?: \"floating\" | \"fixed\"\n}\n\nconst useToolbarNavigation = (\n toolbarRef: React.RefObject<HTMLDivElement | null>\n) => {\n const [items, setItems] = useState<HTMLElement[]>([])\n\n const collectItems = useCallback(() => {\n if (!toolbarRef.current) return []\n return Array.from(\n toolbarRef.current.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [role=\"button\"]:not([disabled]), [tabindex=\"0\"]:not([disabled])'\n )\n )\n }, [toolbarRef])\n\n useEffect(() => {\n const toolbar = toolbarRef.current\n if (!toolbar) return\n\n const updateItems = () => setItems(collectItems())\n\n updateItems()\n const observer = new MutationObserver(updateItems)\n observer.observe(toolbar, { childList: true, subtree: true })\n\n return () => observer.disconnect()\n }, [collectItems, toolbarRef])\n\n const { selectedIndex } = useMenuNavigation<HTMLElement>({\n containerRef: toolbarRef,\n items,\n orientation: \"horizontal\",\n onSelect: (el) => el.click(),\n autoSelectFirstItem: false,\n })\n\n useEffect(() => {\n const toolbar = toolbarRef.current\n if (!toolbar) return\n\n const handleFocus = (e: FocusEvent) => {\n const target = e.target as HTMLElement\n if (toolbar.contains(target))\n target.setAttribute(\"data-focus-visible\", \"true\")\n }\n\n const handleBlur = (e: FocusEvent) => {\n const target = e.target as HTMLElement\n if (toolbar.contains(target)) target.removeAttribute(\"data-focus-visible\")\n }\n\n toolbar.addEventListener(\"focus\", handleFocus, true)\n toolbar.addEventListener(\"blur\", handleBlur, true)\n\n return () => {\n toolbar.removeEventListener(\"focus\", handleFocus, true)\n toolbar.removeEventListener(\"blur\", handleBlur, true)\n }\n }, [toolbarRef])\n\n useEffect(() => {\n if (selectedIndex !== undefined && items[selectedIndex]) {\n items[selectedIndex].focus()\n }\n }, [selectedIndex, items])\n}\n\nexport const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(\n ({ children, className, variant = \"fixed\", ...props }, ref) => {\n const toolbarRef = useRef<HTMLDivElement>(null)\n const composedRef = useComposedRef(toolbarRef, ref)\n useToolbarNavigation(toolbarRef)\n\n return (\n <div\n ref={composedRef}\n role=\"toolbar\"\n aria-label=\"toolbar\"\n data-variant={variant}\n className={cn(\"tiptap-toolbar\", className)}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nToolbar.displayName = \"Toolbar\"\n\nexport const ToolbarGroup = forwardRef<HTMLDivElement, BaseProps>(\n ({ children, className, ...props }, ref) => (\n <div\n ref={ref}\n role=\"group\"\n className={cn(\"tiptap-toolbar-group\", className)}\n {...props}\n >\n {children}\n </div>\n )\n)\nToolbarGroup.displayName = \"ToolbarGroup\"\n\nexport const ToolbarSeparator = forwardRef<HTMLDivElement, BaseProps>(\n ({ ...props }, ref) => (\n <Separator ref={ref} orientation=\"vertical\" decorative {...props} />\n )\n)\nToolbarSeparator.displayName = \"ToolbarSeparator\"\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport \"../../../components/tiptap-ui-primitive/separator/separator.scss\"\nimport { cn } from \"../../../lib/tiptap-utils\"\n\nexport type Orientation = \"horizontal\" | \"vertical\"\n\nexport interface SeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: Orientation\n decorative?: boolean\n}\n\nexport const Separator = forwardRef<HTMLDivElement, SeparatorProps>(\n ({ decorative, orientation = \"vertical\", className, ...divProps }, ref) => {\n const ariaOrientation = orientation === \"vertical\" ? orientation : undefined\n const semanticProps = decorative\n ? { role: \"none\" }\n : { \"aria-orientation\": ariaOrientation, role: \"separator\" }\n\n return (\n <div\n className={cn(\"tiptap-separator\", className)}\n data-orientation={orientation}\n {...semanticProps}\n {...divProps}\n ref={ref}\n />\n )\n }\n)\n\nSeparator.displayName = \"Separator\"\n","\"use client\"\n\nimport type { Editor } from \"@tiptap/react\"\nimport { useEffect, useState } from \"react\"\n\ntype Orientation = \"horizontal\" | \"vertical\" | \"both\"\n\ninterface MenuNavigationOptions<T> {\n /**\n * The Tiptap editor instance, if using with a Tiptap editor.\n */\n editor?: Editor | null\n /**\n * Reference to the container element for handling keyboard events.\n */\n containerRef?: React.RefObject<HTMLElement | null>\n /**\n * Search query that affects the selected item.\n */\n query?: string\n /**\n * Array of items to navigate through.\n */\n items: T[]\n /**\n * Callback fired when an item is selected.\n */\n onSelect?: (item: T) => void\n /**\n * Callback fired when the menu should close.\n */\n onClose?: () => void\n /**\n * The navigation orientation of the menu.\n * @default \"vertical\"\n */\n orientation?: Orientation\n /**\n * Whether to automatically select the first item when the menu opens.\n * @default true\n */\n autoSelectFirstItem?: boolean\n}\n\n/**\n * Hook that implements keyboard navigation for dropdown menus and command palettes.\n *\n * Handles arrow keys, tab, home/end, enter for selection, and escape to close.\n * Works with both Tiptap editors and regular DOM elements.\n *\n * @param options - Configuration options for the menu navigation\n * @returns Object containing the selected index and a setter function\n */\nexport function useMenuNavigation<T>({\n editor,\n containerRef,\n query,\n items,\n onSelect,\n onClose,\n orientation = \"vertical\",\n autoSelectFirstItem = true,\n}: MenuNavigationOptions<T>) {\n const [selectedIndex, setSelectedIndex] = useState<number>(\n autoSelectFirstItem ? 0 : -1\n )\n\n useEffect(() => {\n const handleKeyboardNavigation = (event: KeyboardEvent) => {\n if (!items.length) return false\n\n const moveNext = () =>\n setSelectedIndex((currentIndex) => {\n if (currentIndex === -1) return 0\n return (currentIndex + 1) % items.length\n })\n\n const movePrev = () =>\n setSelectedIndex((currentIndex) => {\n if (currentIndex === -1) return items.length - 1\n return (currentIndex - 1 + items.length) % items.length\n })\n\n switch (event.key) {\n case \"ArrowUp\": {\n if (orientation === \"horizontal\") return false\n event.preventDefault()\n movePrev()\n return true\n }\n\n case \"ArrowDown\": {\n if (orientation === \"horizontal\") return false\n event.preventDefault()\n moveNext()\n return true\n }\n\n case \"ArrowLeft\": {\n if (orientation === \"vertical\") return false\n event.preventDefault()\n movePrev()\n return true\n }\n\n case \"ArrowRight\": {\n if (orientation === \"vertical\") return false\n event.preventDefault()\n moveNext()\n return true\n }\n\n case \"Tab\": {\n event.preventDefault()\n if (event.shiftKey) {\n movePrev()\n } else {\n moveNext()\n }\n return true\n }\n\n case \"Home\": {\n event.preventDefault()\n setSelectedIndex(0)\n return true\n }\n\n case \"End\": {\n event.preventDefault()\n setSelectedIndex(items.length - 1)\n return true\n }\n\n case \"Enter\": {\n if (event.isComposing) return false\n event.preventDefault()\n if (selectedIndex !== -1 && items[selectedIndex]) {\n onSelect?.(items[selectedIndex])\n }\n return true\n }\n\n case \"Escape\": {\n event.preventDefault()\n onClose?.()\n return true\n }\n\n default:\n return false\n }\n }\n\n let targetElement: HTMLElement | null = null\n\n if (editor) {\n targetElement = editor.view.dom\n } else if (containerRef?.current) {\n targetElement = containerRef.current\n }\n\n if (targetElement) {\n targetElement.addEventListener(\"keydown\", handleKeyboardNavigation, true)\n\n return () => {\n targetElement?.removeEventListener(\n \"keydown\",\n handleKeyboardNavigation,\n true\n )\n }\n }\n\n return undefined\n }, [\n editor,\n containerRef,\n items,\n selectedIndex,\n onSelect,\n onClose,\n orientation,\n ])\n\n useEffect(() => {\n if (query) {\n setSelectedIndex(autoSelectFirstItem ? 0 : -1)\n }\n }, [query, autoSelectFirstItem])\n\n return {\n selectedIndex: items.length ? selectedIndex : undefined,\n setSelectedIndex,\n }\n}\n","\"use client\"\n\nimport { useCallback, useRef } from \"react\"\n\n// basically Exclude<React.ClassAttributes<T>[\"ref\"], string>\ntype UserRef<T> =\n | ((instance: T | null) => void)\n | React.RefObject<T | null>\n | null\n | undefined\n\nconst updateRef = <T>(ref: NonNullable<UserRef<T>>, value: T | null) => {\n if (typeof ref === \"function\") {\n ref(value)\n } else if (ref && typeof ref === \"object\" && \"current\" in ref) {\n // Safe assignment without MutableRefObject\n ;(ref as { current: T | null }).current = value\n }\n}\n\nexport const useComposedRef = <T extends HTMLElement>(\n libRef: React.RefObject<T | null>,\n userRef: UserRef<T>\n) => {\n const prevUserRef = useRef<UserRef<T>>(null)\n\n return useCallback(\n (instance: T | null) => {\n if (libRef && \"current\" in libRef) {\n ;(libRef as { current: T | null }).current = instance\n }\n\n if (prevUserRef.current) {\n updateRef(prevUserRef.current, null)\n }\n\n prevUserRef.current = userRef\n\n if (userRef) {\n updateRef(userRef, instance)\n }\n },\n [libRef, userRef]\n )\n}\n\nexport default useComposedRef\n","\"use client\";\r\n\r\nimport { BubbleMenu } from '@tiptap/react/menus';\r\nimport { useCurrentEditor } from \"@tiptap/react\";\r\nimport { Button } from \"../../../components/ui/button\";\r\nimport { Separator } from \"../../../components/ui/separator\";\r\nimport { \r\n List, \r\n ListOrdered, \r\n CheckSquare, \r\n Heading1, \r\n Heading2, \r\n Heading3, \r\n Quote, \r\n Code \r\n} from \"lucide-react\";\r\n\r\nexport function BubbleMenuInline() {\r\n const { editor } = useCurrentEditor();\r\n\r\n if (!editor) return null;\r\n\r\n return (\r\n <BubbleMenu\r\n editor={editor}\r\n updateDelay={100}\r\n shouldShow={({ editor, state }) => {\r\n const { from, to, empty } = state.selection;\r\n \r\n // Don't show if no selection\r\n if (empty) return false;\r\n \r\n // Don't show if editor is not editable\r\n if (!editor.isEditable) return false;\r\n \r\n // ✨ Check if any image node exists in the selection\r\n let hasImage = false;\r\n state.doc.nodesBetween(from, to, (node) => {\r\n if (node.type.name === 'image' || node.type.name === 'Image') {\r\n hasImage = true;\r\n return false; // stop traversing\r\n }\r\n });\r\n \r\n if (hasImage) return false;\r\n \r\n return true;\r\n }}\r\n >\r\n <div \r\n className=\"relative flex items-center gap-1 rounded-md border bg-popover p-1 shadow-md z-[15]\r\n animate-in fade-in slide-in-from-top-2 duration-200\"\r\n >\r\n {/* Headings */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}\r\n className={editor.isActive(\"heading\", { level: 1 }) ? \"bg-accent\" : \"\"}\r\n >\r\n <Heading1 size={15} />\r\n </Button>\r\n \r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}\r\n className={editor.isActive(\"heading\", { level: 2 }) ? \"bg-accent\" : \"\"}\r\n >\r\n <Heading2 size={15} />\r\n </Button>\r\n \r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}\r\n className={editor.isActive(\"heading\", { level: 3 }) ? \"bg-accent\" : \"\"}\r\n >\r\n <Heading3 size={15} />\r\n </Button>\r\n\r\n <Separator orientation=\"vertical\" className=\"mx-1\" />\r\n\r\n {/* Bullet List */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleBulletList().run()}\r\n className={editor.isActive(\"bulletList\") ? \"bg-accent\" : \"\"}\r\n >\r\n <List size={15} />\r\n </Button>\r\n\r\n {/* Ordered List */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\r\n className={editor.isActive(\"orderedList\") ? \"bg-accent\" : \"\"}\r\n >\r\n <ListOrdered size={15} />\r\n </Button>\r\n\r\n {/* Task List */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleTaskList().run()}\r\n className={editor.isActive(\"taskList\") ? \"bg-accent\" : \"\"}\r\n >\r\n <CheckSquare size={15} />\r\n </Button>\r\n\r\n <Separator orientation=\"vertical\" className=\"mx-1\" />\r\n\r\n {/* Code Block */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleCodeBlock().run()}\r\n className={editor.isActive(\"codeBlock\") ? \"bg-accent\" : \"\"}\r\n >\r\n <Code size={15} />\r\n </Button>\r\n </div>\r\n </BubbleMenu>\r\n );\r\n}\r\n","import { mergeAttributes, Node } from \"@tiptap/react\"\nimport { ReactNodeViewRenderer } from \"@tiptap/react\"\nimport { ImageUploadNode as ImageUploadNodeComponent } from \"./image-upload-node\"\nimport type { NodeType } from \"@tiptap/pm/model\"\n\nexport type UploadFunction = (\n file: File,\n onProgress?: (event: { progress: number }) => void,\n abortSignal?: AbortSignal\n) => Promise<string>\n\nexport interface ImageUploadNodeOptions {\n /**\n * The type of the node.\n * @default 'image'\n */\n type?: string | NodeType | undefined\n /**\n * Acceptable file types for upload.\n * @default 'image/*'\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded.\n * @default 1\n */\n limit?: number\n /**\n * Maximum file size in bytes (0 for unlimited).\n * @default 0\n */\n maxSize?: number\n /**\n * Function to handle the upload process.\n */\n upload?: UploadFunction\n /**\n * Callback for upload errors.\n */\n onError?: (error: Error) => void\n /**\n * Callback for successful uploads.\n */\n onSuccess?: (url: string) => void\n /**\n * HTML attributes to add to the image element.\n * @default {}\n * @example { class: 'foo' }\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n HTMLAttributes: Record<string, any>\n}\n\ndeclare module \"@tiptap/react\" {\n interface Commands<ReturnType> {\n imageUpload: {\n setImageUploadNode: (options?: ImageUploadNodeOptions) => ReturnType\n }\n }\n}\n\n/**\n * A Tiptap node extension that creates an image upload component.\n * @see registry/tiptap-node/image-upload-node/image-upload-node\n */\nexport const ImageUploadNode = Node.create<ImageUploadNodeOptions>({\n name: \"imageUpload\",\n\n group: \"block\",\n\n draggable: true,\n\n selectable: true,\n\n atom: true,\n\n addOptions() {\n return {\n type: \"image\",\n accept: \"image/*\",\n limit: 1,\n maxSize: 0,\n upload: undefined,\n onError: undefined,\n onSuccess: undefined,\n HTMLAttributes: {},\n }\n },\n\n addAttributes() {\n return {\n accept: {\n default: this.options.accept,\n },\n limit: {\n default: this.options.limit,\n },\n maxSize: {\n default: this.options.maxSize,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"image-upload\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"div\",\n mergeAttributes({ \"data-type\": \"image-upload\" }, HTMLAttributes),\n ]\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(ImageUploadNodeComponent)\n },\n\n addCommands() {\n return {\n setImageUploadNode:\n (options) =>\n ({ commands }) => {\n return commands.insertContent({\n type: this.name,\n attrs: options,\n })\n },\n }\n },\n\n /**\n * Adds Enter key handler to trigger the upload component when it's selected.\n */\n addKeyboardShortcuts() {\n return {\n Enter: ({ editor }) => {\n const { selection } = editor.state\n const { nodeAfter } = selection.$from\n\n if (\n nodeAfter &&\n nodeAfter.type.name === \"imageUpload\" &&\n editor.isActive(\"imageUpload\")\n ) {\n const nodeEl = editor.view.nodeDOM(selection.$from.pos)\n if (nodeEl && nodeEl instanceof HTMLElement) {\n // Since NodeViewWrapper is wrapped with a div, we need to click the first child\n const firstChild = nodeEl.firstChild\n if (firstChild && firstChild instanceof HTMLElement) {\n firstChild.click()\n return true\n }\n }\n }\n return false\n },\n }\n },\n})\n\nexport default ImageUploadNode\n","\"use client\"\n\nimport { useRef, useState } from \"react\"\nimport type { NodeViewProps } from \"@tiptap/react\"\nimport { NodeViewWrapper } from \"@tiptap/react\"\nimport { Button } from \"../../tiptap-ui-primitive/button/button\"\nimport { CloseIcon } from \"../../tiptap-icons/close-icon\"\nimport \"./image-upload-node.scss\"\nimport { focusNextNode, isValidPosition } from \"../../../lib/tiptap-utils\"\n\nexport interface FileItem {\n /**\n * Unique identifier for the file item\n */\n id: string\n /**\n * The actual File object being uploaded\n */\n file: File\n /**\n * Current upload progress as a percentage (0-100)\n */\n progress: number\n /**\n * Current status of the file upload process\n * @default \"uploading\"\n */\n status: \"uploading\" | \"success\" | \"error\"\n\n /**\n * URL to the uploaded file, available after successful upload\n * @optional\n */\n url?: string\n /**\n * Controller that can be used to abort the upload process\n * @optional\n */\n abortController?: AbortController\n}\n\nexport interface UploadOptions {\n /**\n * Maximum allowed file size in bytes\n */\n maxSize: number\n /**\n * Maximum number of files that can be uploaded\n */\n limit: number\n /**\n * String specifying acceptable file types (MIME types or extensions)\n * @example \".jpg,.png,image/jpeg\" or \"image/*\"\n */\n accept: string\n /**\n * Function that handles the actual file upload process\n * @param {File} file - The file to be uploaded\n * @param {Function} onProgress - Callback function to report upload progress\n * @param {AbortSignal} signal - Signal that can be used to abort the upload\n * @returns {Promise<string>} Promise resolving to the URL of the uploaded file\n */\n upload: (\n file: File,\n onProgress: (event: { progress: number }) => void,\n signal: AbortSignal\n ) => Promise<string>\n /**\n * Callback triggered when a file is uploaded successfully\n * @param {string} url - URL of the successfully uploaded file\n * @optional\n */\n onSuccess?: (url: string) => void\n /**\n * Callback triggered when an error occurs during upload\n * @param {Error} error - The error that occurred\n * @optional\n */\n onError?: (error: Error) => void\n}\n\n/**\n * Custom hook for managing multiple file uploads with progress tracking and cancellation\n */\nfunction useFileUpload(options: UploadOptions) {\n const [fileItems, setFileItems] = useState<FileItem[]>([])\n\n const uploadFile = async (file: File): Promise<string | null> => {\n if (file.size > options.maxSize) {\n const error = new Error(\n `File size exceeds maximum allowed (${options.maxSize / 1024 / 1024}MB)`\n )\n options.onError?.(error)\n return null\n }\n\n const abortController = new AbortController()\n const fileId = crypto.randomUUID()\n\n const newFileItem: FileItem = {\n id: fileId,\n file,\n progress: 0,\n status: \"uploading\",\n abortController,\n }\n\n setFileItems((prev) => [...prev, newFileItem])\n\n try {\n if (!options.upload) {\n throw new Error(\"Upload function is not defined\")\n }\n\n const url = await options.upload(\n file,\n (event: { progress: number }) => {\n setFileItems((prev) =>\n prev.map((item) =>\n item.id === fileId ? { ...item, progress: event.progress } : item\n )\n )\n },\n abortController.signal\n )\n\n if (!url) throw new Error(\"Upload failed: No URL returned\")\n\n if (!abortController.signal.aborted) {\n setFileItems((prev) =>\n prev.map((item) =>\n item.id === fileId\n ? { ...item, status: \"success\", url, progress: 100 }\n : item\n )\n )\n options.onSuccess?.(url)\n return url\n }\n\n return null\n } catch (error) {\n if (!abortController.signal.aborted) {\n setFileItems((prev) =>\n prev.map((item) =>\n item.id === fileId\n ? { ...item, status: \"error\", progress: 0 }\n : item\n )\n )\n options.onError?.(\n error instanceof Error ? error : new Error(\"Upload failed\")\n )\n }\n return null\n }\n }\n\n const uploadFiles = async (files: File[]): Promise<string[]> => {\n if (!files || files.length === 0) {\n options.onError?.(new Error(\"No files to upload\"))\n return []\n }\n\n if (options.limit && files.length > options.limit) {\n options.onError?.(\n new Error(\n `Maximum ${options.limit} file${options.limit === 1 ? \"\" : \"s\"} allowed`\n )\n )\n return []\n }\n\n // Upload all files concurrently\n const uploadPromises = files.map((file) => uploadFile(file))\n const results = await Promise.all(uploadPromises)\n\n // Filter out null results (failed uploads)\n return results.filter((url): url is string => url !== null)\n }\n\n const removeFileItem = (fileId: string) => {\n setFileItems((prev) => {\n const fileToRemove = prev.find((item) => item.id === fileId)\n if (fileToRemove?.abortController) {\n fileToRemove.abortController.abort()\n }\n if (fileToRemove?.url) {\n URL.revokeObjectURL(fileToRemove.url)\n }\n return prev.filter((item) => item.id !== fileId)\n })\n }\n\n const clearAllFiles = () => {\n fileItems.forEach((item) => {\n if (item.abortController) {\n item.abortController.abort()\n }\n if (item.url) {\n URL.revokeObjectURL(item.url)\n }\n })\n setFileItems([])\n }\n\n return {\n fileItems,\n uploadFiles,\n removeFileItem,\n clearAllFiles,\n }\n}\n\nconst CloudUploadIcon: React.FC = () => (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n className=\"tiptap-image-upload-icon\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M11.1953 4.41771C10.3478 4.08499 9.43578 3.94949 8.5282 4.02147C7.62062 4.09345 6.74133 4.37102 5.95691 4.83316C5.1725 5.2953 4.50354 5.92989 4.00071 6.68886C3.49788 7.44783 3.17436 8.31128 3.05465 9.2138C2.93495 10.1163 3.0222 11.0343 3.3098 11.8981C3.5974 12.7619 4.07781 13.5489 4.71463 14.1995C5.10094 14.5942 5.09414 15.2274 4.69945 15.6137C4.30476 16 3.67163 15.9932 3.28532 15.5985C2.43622 14.731 1.79568 13.6816 1.41221 12.5299C1.02875 11.3781 0.91241 10.1542 1.07201 8.95084C1.23162 7.74748 1.66298 6.59621 2.33343 5.58425C3.00387 4.57229 3.89581 3.72617 4.9417 3.10998C5.98758 2.4938 7.15998 2.1237 8.37008 2.02773C9.58018 1.93176 10.7963 2.11243 11.9262 2.55605C13.0561 2.99968 14.0703 3.69462 14.8919 4.58825C15.5423 5.29573 16.0585 6.11304 16.4177 7.00002H17.4999C18.6799 6.99991 19.8288 7.37933 20.7766 8.08222C21.7245 8.78515 22.4212 9.7743 22.7637 10.9036C23.1062 12.0328 23.0765 13.2423 22.6788 14.3534C22.2812 15.4644 21.5367 16.4181 20.5554 17.0736C20.0962 17.3803 19.4752 17.2567 19.1684 16.7975C18.8617 16.3382 18.9853 15.7172 19.4445 15.4105C20.069 14.9934 20.5427 14.3865 20.7958 13.6794C21.0488 12.9724 21.0678 12.2027 20.8498 11.4841C20.6318 10.7655 20.1885 10.136 19.5853 9.6887C18.9821 9.24138 18.251 8.99993 17.5001 9.00002H15.71C15.2679 9.00002 14.8783 8.70973 14.7518 8.28611C14.4913 7.41374 14.0357 6.61208 13.4195 5.94186C12.8034 5.27164 12.0427 4.75043 11.1953 4.41771Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M11 14.4142V21C11 21.5523 11.4477 22 12 22C12.5523 22 13 21.5523 13 21V14.4142L15.2929 16.7071C15.6834 17.0976 16.3166 17.0976 16.7071 16.7071C17.0976 16.3166 17.0976 15.6834 16.7071 15.2929L12.7078 11.2936C12.7054 11.2912 12.703 11.2888 12.7005 11.2864C12.5208 11.1099 12.2746 11.0008 12.003 11L12 11L11.997 11C11.8625 11.0004 11.7343 11.0273 11.6172 11.0759C11.502 11.1236 11.3938 11.1937 11.2995 11.2864C11.297 11.2888 11.2946 11.2912 11.2922 11.2936L7.29289 15.2929C6.90237 15.6834 6.90237 16.3166 7.29289 16.7071C7.68342 17.0976 8.31658 17.0976 8.70711 16.7071L11 14.4142Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\nconst FileIcon: React.FC = () => (\n <svg\n width=\"43\"\n height=\"57\"\n viewBox=\"0 0 43 57\"\n fill=\"currentColor\"\n className=\"tiptap-image-upload-dropzone-rect-primary\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0.75 10.75C0.75 5.64137 4.89137 1.5 10 1.5H32.3431C33.2051 1.5 34.0317 1.84241 34.6412 2.4519L40.2981 8.10876C40.9076 8.71825 41.25 9.5449 41.25 10.4069V46.75C41.25 51.8586 37.1086 56 32 56H10C4.89137 56 0.75 51.8586 0.75 46.75V10.75Z\"\n fill=\"currentColor\"\n fillOpacity=\"0.11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n </svg>\n)\n\nconst FileCornerIcon: React.FC = () => (\n <svg\n width=\"10\"\n height=\"10\"\n className=\"tiptap-image-upload-dropzone-rect-secondary\"\n viewBox=\"0 0 10 10\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0.75H0.343146C1.40401 0.75 2.42143 1.17143 3.17157 1.92157L8.82843 7.57843C9.57857 8.32857 10 9.34599 10 10.4069V10.75H4C1.79086 10.75 0 8.95914 0 6.75V0.75Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\ninterface ImageUploadDragAreaProps {\n /**\n * Callback function triggered when files are dropped or selected\n * @param {File[]} files - Array of File objects that were dropped or selected\n */\n onFile: (files: File[]) => void\n /**\n * Optional child elements to render inside the drag area\n * @optional\n * @default undefined\n */\n children?: React.ReactNode\n}\n\n/**\n * A component that creates a drag-and-drop area for image uploads\n */\nconst ImageUploadDragArea: React.FC<ImageUploadDragAreaProps> = ({\n onFile,\n children,\n}) => {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isDragActive, setIsDragActive] = useState(false)\n\n const handleDragEnter = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(true)\n }\n\n const handleDragLeave = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!e.currentTarget.contains(e.relatedTarget as Node)) {\n setIsDragActive(false)\n setIsDragOver(false)\n }\n }\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(true)\n }\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(false)\n setIsDragOver(false)\n\n const files = Array.from(e.dataTransfer.files)\n if (files.length > 0) {\n onFile(files)\n }\n }\n\n return (\n <div\n className={`tiptap-image-upload-drag-area ${isDragActive ? \"drag-active\" : \"\"} ${isDragOver ? \"drag-over\" : \"\"}`}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {children}\n </div>\n )\n}\n\ninterface ImageUploadPreviewProps {\n /**\n * The file item to preview\n */\n fileItem: FileItem\n /**\n * Callback to remove this file from upload queue\n */\n onRemove: () => void\n}\n\n/**\n * Component that displays a preview of an uploading file with progress\n */\nconst ImageUploadPreview: React.FC<ImageUploadPreviewProps> = ({\n fileItem,\n onRemove,\n}) => {\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return \"0 Bytes\"\n const k = 1024\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"]\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`\n }\n\n return (\n <div className=\"tiptap-image-upload-preview\">\n {fileItem.status === \"uploading\" && (\n <div\n className=\"tiptap-image-upload-progress\"\n style={{ width: `${fileItem.progress}%` }}\n />\n )}\n\n <div className=\"tiptap-image-upload-preview-content\">\n <div className=\"tiptap-image-upload-file-info\">\n <div className=\"tiptap-image-upload-file-icon\">\n <CloudUploadIcon />\n </div>\n <div className=\"tiptap-image-upload-details\">\n <span className=\"tiptap-image-upload-text\">\n {fileItem.file.name}\n </span>\n <span className=\"tiptap-image-upload-subtext\">\n {formatFileSize(fileItem.file.size)}\n </span>\n </div>\n </div>\n <div className=\"tiptap-image-upload-actions\">\n {fileItem.status === \"uploading\" && (\n <span className=\"tiptap-image-upload-progress-text\">\n {fileItem.progress}%\n </span>\n )}\n <Button\n type=\"button\"\n data-style=\"ghost\"\n onClick={(e) => {\n e.stopPropagation()\n onRemove()\n }}\n >\n <CloseIcon className=\"tiptap-button-icon\" />\n </Button>\n </div>\n </div>\n </div>\n )\n}\n\nconst DropZoneContent: React.FC<{ maxSize: number; limit: number }> = ({\n maxSize,\n limit,\n}) => (\n <>\n <div className=\"tiptap-image-upload-dropzone\">\n <FileIcon />\n <FileCornerIcon />\n <div className=\"tiptap-image-upload-icon-container\">\n <CloudUploadIcon />\n </div>\n </div>\n\n <div className=\"tiptap-image-upload-content\">\n <span className=\"tiptap-image-upload-text\">\n <em>Click to upload</em> or drag and drop\n </span>\n <span className=\"tiptap-image-upload-subtext\">\n Maximum {limit} file{limit === 1 ? \"\" : \"s\"}, {maxSize / 1024 / 1024}MB\n each.\n </span>\n </div>\n </>\n)\n\nexport const ImageUploadNode: React.FC<NodeViewProps> = (props) => {\n const { accept, limit, maxSize } = props.node.attrs\n const inputRef = useRef<HTMLInputElement>(null)\n const extension = props.extension\n\n const uploadOptions: UploadOptions = {\n maxSize,\n limit,\n accept,\n upload: extension.options.upload,\n onSuccess: extension.options.onSuccess,\n onError: extension.options.onError,\n }\n\n const { fileItems, uploadFiles, removeFileItem, clearAllFiles } =\n useFileUpload(uploadOptions)\n\n const handleUpload = async (files: File[]) => {\n const urls = await uploadFiles(files)\n\n if (urls.length > 0) {\n const pos = props.getPos()\n\n if (isValidPosition(pos)) {\n const imageNodes = urls.map((url, index) => {\n const filename =\n files[index]?.name.replace(/\\.[^/.]+$/, \"\") || \"unknown\"\n return {\n type: extension.options.type,\n attrs: {\n ...extension.options,\n src: url,\n alt: filename,\n title: filename,\n },\n }\n })\n\n props.editor\n .chain()\n .focus()\n .deleteRange({ from: pos, to: pos + props.node.nodeSize })\n .insertContentAt(pos, imageNodes)\n .run()\n\n focusNextNode(props.editor)\n }\n }\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files\n if (!files || files.length === 0) {\n extension.options.onError?.(new Error(\"No file selected\"))\n return\n }\n handleUpload(Array.from(files))\n }\n\n const handleClick = () => {\n if (inputRef.current && fileItems.length === 0) {\n inputRef.current.value = \"\"\n inputRef.current.click()\n }\n }\n\n const hasFiles = fileItems.length > 0\n\n return (\n <NodeViewWrapper\n className=\"tiptap-image-upload\"\n tabIndex={0}\n onClick={handleClick}\n >\n {!hasFiles && (\n <ImageUploadDragArea onFile={handleUpload}>\n <DropZoneContent maxSize={maxSize} limit={limit} />\n </ImageUploadDragArea>\n )}\n\n {hasFiles && (\n <div className=\"tiptap-image-upload-previews\">\n {fileItems.length > 1 && (\n <div className=\"tiptap-image-upload-header\">\n <span>Uploading {fileItems.length} files</span>\n <Button\n type=\"button\"\n data-style=\"ghost\"\n onClick={(e) => {\n e.stopPropagation()\n clearAllFiles()\n }}\n >\n Clear All\n </Button>\n </div>\n )}\n {fileItems.map((fileItem) => (\n <ImageUploadPreview\n key={fileItem.id}\n fileItem={fileItem}\n onRemove={() => removeFileItem(fileItem.id)}\n />\n ))}\n </div>\n )}\n\n <input\n ref={inputRef}\n name=\"file\"\n accept={accept}\n type=\"file\"\n multiple={limit > 1}\n onChange={handleChange}\n onClick={(e: React.MouseEvent<HTMLInputElement>) => e.stopPropagation()}\n />\n </NodeViewWrapper>\n )\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const CloseIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.29289 17.2929C4.90237 17.6834 4.90237 18.3166 5.29289 18.7071C5.68342 19.0976 6.31658 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nCloseIcon.displayName = \"CloseIcon\"\n","import { mergeAttributes } from \"@tiptap/react\"\nimport TiptapHorizontalRule from \"@tiptap/extension-horizontal-rule\"\n\nexport const HorizontalRule = TiptapHorizontalRule.extend({\n renderHTML() {\n return [\n \"div\",\n mergeAttributes(this.options.HTMLAttributes, { \"data-type\": this.name }),\n [\"hr\"],\n ]\n },\n})\n\nexport default HorizontalRule\n","\"use client\"\n\nimport { forwardRef, useCallback, useState } from \"react\"\n\n// --- Icons ---\nimport { ChevronDownIcon } from \"../../../components/tiptap-icons/chevron-down-icon\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport { HeadingButton } from \"../../../components/tiptap-ui/heading-button\"\nimport type { UseHeadingDropdownMenuConfig } from \"../../../components/tiptap-ui/heading-dropdown-menu\"\nimport { useHeadingDropdownMenu } from \"../../../components/tiptap-ui/heading-dropdown-menu\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n} from \"../../../components/tiptap-ui-primitive/dropdown-menu\"\nimport { Card, CardBody } from \"../../../components/tiptap-ui-primitive/card\"\n\nexport interface HeadingDropdownMenuProps\n extends Omit<ButtonProps, \"type\">,\n UseHeadingDropdownMenuConfig {\n /**\n * Whether to render the dropdown menu in a portal\n * @default false\n */\n portal?: boolean\n /**\n * Callback for when the dropdown opens or closes\n */\n onOpenChange?: (isOpen: boolean) => void\n}\n\n/**\n * Dropdown menu component for selecting heading levels in a Tiptap editor.\n *\n * For custom dropdown implementations, use the `useHeadingDropdownMenu` hook instead.\n */\nexport const HeadingDropdownMenu = forwardRef<\n HTMLButtonElement,\n HeadingDropdownMenuProps\n>(\n (\n {\n editor: providedEditor,\n levels = [1, 2, 3, 4, 5, 6],\n hideWhenUnavailable = false,\n portal = false,\n onOpenChange,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState<boolean>(false)\n const { isVisible, isActive, canToggle, Icon } = useHeadingDropdownMenu({\n editor,\n levels,\n hideWhenUnavailable,\n })\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!editor || !canToggle) return\n setIsOpen(open)\n onOpenChange?.(open)\n },\n [canToggle, editor, onOpenChange]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <DropdownMenu modal open={isOpen} onOpenChange={handleOpenChange}>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label=\"Format text as heading\"\n aria-pressed={isActive}\n tooltip=\"Heading\"\n {...buttonProps}\n ref={ref}\n >\n <Icon className=\"tiptap-button-icon\" />\n <ChevronDownIcon className=\"tiptap-button-dropdown-small\" />\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"start\" portal={portal}>\n <Card>\n <CardBody>\n <ButtonGroup>\n {levels.map((level) => (\n <DropdownMenuItem key={`heading-${level}`} asChild>\n <HeadingButton\n editor={editor}\n level={level}\n text={`Heading ${level}`}\n showTooltip={false}\n />\n </DropdownMenuItem>\n ))}\n </ButtonGroup>\n </CardBody>\n </Card>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n)\n\nHeadingDropdownMenu.displayName = \"HeadingDropdownMenu\"\n\nexport default HeadingDropdownMenu\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ChevronDownIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.29289 8.29289C5.68342 7.90237 6.31658 7.90237 6.70711 8.29289L12 13.5858L17.2929 8.29289C17.6834 7.90237 18.3166 7.90237 18.7071 8.29289C19.0976 8.68342 19.0976 9.31658 18.7071 9.70711L12.7071 15.7071C12.3166 16.0976 11.6834 16.0976 11.2929 15.7071L5.29289 9.70711C4.90237 9.31658 4.90237 8.68342 5.29289 8.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nChevronDownIcon.displayName = \"ChevronDownIcon\"\n","\"use client\"\n\nimport type { Editor } from \"@tiptap/react\"\nimport { useCurrentEditor, useEditorState } from \"@tiptap/react\"\nimport { useMemo } from \"react\"\n\n/**\n * Hook that provides access to a Tiptap editor instance.\n *\n * Accepts an optional editor instance directly, or falls back to retrieving\n * the editor from the Tiptap context if available. This allows components\n * to work both when given an editor directly and when used within a Tiptap\n * editor context.\n *\n * @param providedEditor - Optional editor instance to use instead of the context editor\n * @returns The provided editor or the editor from context, whichever is available\n */\nexport function useTiptapEditor(providedEditor?: Editor | null): {\n editor: Editor | null\n editorState?: Editor[\"state\"]\n canCommand?: Editor[\"can\"]\n} {\n const { editor: coreEditor } = useCurrentEditor()\n const mainEditor = useMemo(\n () => providedEditor || coreEditor,\n [providedEditor, coreEditor]\n )\n\n const editorState = useEditorState({\n editor: mainEditor,\n selector(context) {\n if (!context.editor) {\n return {\n editor: null,\n editorState: undefined,\n canCommand: undefined,\n }\n }\n\n return {\n editor: context.editor,\n editorState: context.editor.state,\n canCommand: context.editor.can,\n }\n },\n })\n\n return editorState || { editor: null }\n}\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Tiptap UI ---\nimport type {\n Level,\n UseHeadingConfig,\n} from \"../../../components/tiptap-ui/heading-button\"\nimport {\n HEADING_SHORTCUT_KEYS,\n useHeading,\n} from \"../../../components/tiptap-ui/heading-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\nexport interface HeadingButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseHeadingConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function HeadingShortcutBadge({\n level,\n shortcutKeys = HEADING_SHORTCUT_KEYS[level],\n}: {\n level: Level\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for toggling heading in a Tiptap editor.\n *\n * For custom button implementations, use the `useHeading` hook instead.\n */\nexport const HeadingButton = forwardRef<HTMLButtonElement, HeadingButtonProps>(\n (\n {\n editor: providedEditor,\n level,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = true,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canToggle,\n isActive,\n handleToggle,\n label,\n Icon,\n shortcutKeys,\n } = useHeading({\n editor,\n level,\n hideWhenUnavailable,\n onToggled,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <HeadingShortcutBadge level={level} shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nHeadingButton.displayName = \"HeadingButton\"\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport \"../../../components/tiptap-ui-primitive/badge/badge-colors.scss\"\nimport \"../../../components/tiptap-ui-primitive/badge/badge-group.scss\"\nimport \"../../../components/tiptap-ui-primitive/badge/badge.scss\"\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"ghost\" | \"white\" | \"gray\" | \"green\" | \"default\"\n size?: \"default\" | \"small\"\n appearance?: \"default\" | \"subdued\" | \"emphasized\"\n trimText?: boolean\n}\n\nexport const Badge = forwardRef<HTMLDivElement, BadgeProps>(\n (\n {\n variant,\n size = \"default\",\n appearance = \"default\",\n trimText = false,\n className,\n children,\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={`tiptap-badge ${className || \"\"}`}\n data-style={variant}\n data-size={size}\n data-appearance={appearance}\n data-text-trim={trimText ? \"on\" : \"off\"}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\n\nBadge.displayName = \"Badge\"\n\nexport default Badge\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\nimport { NodeSelection, TextSelection } from \"@tiptap/pm/state\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport {\n findNodePosition,\n isNodeInSchema,\n isNodeTypeSelected,\n isValidPosition,\n selectionWithinConvertibleTypes,\n} from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { HeadingOneIcon } from \"../../../components/tiptap-icons/heading-one-icon\"\nimport { HeadingTwoIcon } from \"../../../components/tiptap-icons/heading-two-icon\"\nimport { HeadingThreeIcon } from \"../../../components/tiptap-icons/heading-three-icon\"\nimport { HeadingFourIcon } from \"../../../components/tiptap-icons/heading-four-icon\"\nimport { HeadingFiveIcon } from \"../../../components/tiptap-icons/heading-five-icon\"\nimport { HeadingSixIcon } from \"../../../components/tiptap-icons/heading-six-icon\"\n\nexport type Level = 1 | 2 | 3 | 4 | 5 | 6\n\n/**\n * Configuration for the heading functionality\n */\nexport interface UseHeadingConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The heading level.\n */\n level: Level\n /**\n * Whether the button should hide when heading is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful heading toggle.\n */\n onToggled?: () => void\n}\n\nexport const headingIcons = {\n 1: HeadingOneIcon,\n 2: HeadingTwoIcon,\n 3: HeadingThreeIcon,\n 4: HeadingFourIcon,\n 5: HeadingFiveIcon,\n 6: HeadingSixIcon,\n}\n\nexport const HEADING_SHORTCUT_KEYS: Record<Level, string> = {\n 1: \"ctrl+alt+1\",\n 2: \"ctrl+alt+2\",\n 3: \"ctrl+alt+3\",\n 4: \"ctrl+alt+4\",\n 5: \"ctrl+alt+5\",\n 6: \"ctrl+alt+6\",\n}\n\n/**\n * Checks if heading can be toggled in the current editor state\n */\nexport function canToggle(\n editor: Editor | null,\n level?: Level,\n turnInto: boolean = true\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (\n !isNodeInSchema(\"heading\", editor) ||\n isNodeTypeSelected(editor, [\"image\"])\n )\n return false\n\n if (!turnInto) {\n return level\n ? editor.can().setNode(\"heading\", { level })\n : editor.can().setNode(\"heading\")\n }\n\n // Ensure selection is in nodes we're allowed to convert\n if (\n !selectionWithinConvertibleTypes(editor, [\n \"paragraph\",\n \"heading\",\n \"bulletList\",\n \"orderedList\",\n \"taskList\",\n \"blockquote\",\n \"codeBlock\",\n ])\n )\n return false\n\n // Either we can set heading directly on the selection,\n // or we can clear formatting/nodes to arrive at a heading.\n return level\n ? editor.can().setNode(\"heading\", { level }) || editor.can().clearNodes()\n : editor.can().setNode(\"heading\") || editor.can().clearNodes()\n}\n\n/**\n * Checks if heading is currently active\n */\nexport function isHeadingActive(\n editor: Editor | null,\n level?: Level | Level[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n if (Array.isArray(level)) {\n return level.some((l) => editor.isActive(\"heading\", { level: l }))\n }\n\n return level\n ? editor.isActive(\"heading\", { level })\n : editor.isActive(\"heading\")\n}\n\n/**\n * Toggles heading in the editor\n */\nexport function toggleHeading(\n editor: Editor | null,\n level: Level | Level[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n const levels = Array.isArray(level) ? level : [level]\n const toggleLevel = levels.find((l) => canToggle(editor, l))\n\n if (!toggleLevel) return false\n\n try {\n const view = editor.view\n let state = view.state\n let tr = state.tr\n\n // No selection, find the cursor position\n if (state.selection.empty || state.selection instanceof TextSelection) {\n const pos = findNodePosition({\n editor,\n node: state.selection.$anchor.node(1),\n })?.pos\n if (!isValidPosition(pos)) return false\n\n tr = tr.setSelection(NodeSelection.create(state.doc, pos))\n view.dispatch(tr)\n state = view.state\n }\n\n const selection = state.selection\n let chain = editor.chain().focus()\n\n // Handle NodeSelection\n if (selection instanceof NodeSelection) {\n const firstChild = selection.node.firstChild?.firstChild\n const lastChild = selection.node.lastChild?.lastChild\n\n const from = firstChild\n ? selection.from + firstChild.nodeSize\n : selection.from + 1\n\n const to = lastChild\n ? selection.to - lastChild.nodeSize\n : selection.to - 1\n\n const resolvedFrom = state.doc.resolve(from)\n const resolvedTo = state.doc.resolve(to)\n\n chain = chain\n .setTextSelection(TextSelection.between(resolvedFrom, resolvedTo))\n .clearNodes()\n }\n\n const isActive = levels.some((l) =>\n editor.isActive(\"heading\", { level: l })\n )\n\n const toggle = isActive\n ? chain.setNode(\"paragraph\")\n : chain.setNode(\"heading\", { level: toggleLevel })\n\n toggle.run()\n\n editor.chain().focus().selectTextblockEnd().run()\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Determines if the heading button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n level?: Level | Level[]\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, level, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(\"heading\", editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n if (Array.isArray(level)) {\n return level.some((l) => canToggle(editor, l))\n }\n return canToggle(editor, level)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides heading functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleHeadingButton() {\n * const { isVisible, isActive, handleToggle, Icon } = useHeading({ level: 1 })\n *\n * if (!isVisible) return null\n *\n * return (\n * <button\n * onClick={handleToggle}\n * aria-pressed={isActive}\n * >\n * <Icon />\n * Heading 1\n * </button>\n * )\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedHeadingButton() {\n * const { isVisible, isActive, handleToggle, label, Icon } = useHeading({\n * level: 2,\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onToggled: (isActive) => console.log('Heading toggled:', isActive)\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleToggle}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * <Icon />\n * Toggle Heading 2\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useHeading(config: UseHeadingConfig) {\n const {\n editor: providedEditor,\n level,\n hideWhenUnavailable = false,\n onToggled,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggleState = canToggle(editor, level)\n const isActive = isHeadingActive(editor, level)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, level, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, level, hideWhenUnavailable])\n\n const handleToggle = useCallback(() => {\n if (!editor) return false\n\n const success = toggleHeading(editor, level)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, level, onToggled])\n\n return {\n isVisible,\n isActive,\n handleToggle,\n canToggle: canToggleState,\n label: `Heading ${level}`,\n shortcutKeys: HEADING_SHORTCUT_KEYS[level],\n Icon: headingIcons[level],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingOneIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M21.0001 10C21.0001 9.63121 20.7971 9.29235 20.472 9.11833C20.1468 8.94431 19.7523 8.96338 19.4454 9.16795L16.4454 11.168C15.9859 11.4743 15.8617 12.0952 16.1681 12.5547C16.4744 13.0142 17.0953 13.1384 17.5548 12.8321L19.0001 11.8685V18C19.0001 18.5523 19.4478 19 20.0001 19C20.5524 19 21.0001 18.5523 21.0001 18V10Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingOneIcon.displayName = \"HeadingOneIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingTwoIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M22.0001 12C22.0001 10.7611 21.1663 9.79297 20.0663 9.42632C18.9547 9.05578 17.6171 9.28724 16.4001 10.2C15.9582 10.5314 15.8687 11.1582 16.2001 11.6C16.5314 12.0418 17.1582 12.1314 17.6001 11.8C18.383 11.2128 19.0455 11.1942 19.4338 11.3237C19.8339 11.457 20.0001 11.7389 20.0001 12C20.0001 12.4839 19.8554 12.7379 19.6537 12.9481C19.4275 13.1837 19.1378 13.363 18.7055 13.6307C18.6313 13.6767 18.553 13.7252 18.4701 13.777C17.9572 14.0975 17.3128 14.5261 16.8163 15.2087C16.3007 15.9177 16.0001 16.8183 16.0001 18C16.0001 18.5523 16.4478 19 17.0001 19H21.0001C21.5523 19 22.0001 18.5523 22.0001 18C22.0001 17.4477 21.5523 17 21.0001 17H18.131C18.21 16.742 18.3176 16.5448 18.4338 16.385C18.6873 16.0364 19.0429 15.7775 19.5301 15.473C19.5898 15.4357 19.6536 15.3966 19.7205 15.3556C20.139 15.0992 20.6783 14.7687 21.0964 14.3332C21.6447 13.7621 22.0001 13.0161 22.0001 12Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingTwoIcon.displayName = \"HeadingTwoIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingThreeIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M4 5C4.55228 5 5 5.44772 5 6V11H11V6C11 5.44772 11.4477 5 12 5C12.5523 5 13 5.44772 13 6V18C13 18.5523 12.5523 19 12 19C11.4477 19 11 18.5523 11 18V13H5V18C5 18.5523 4.55228 19 4 19C3.44772 19 3 18.5523 3 18V6C3 5.44772 3.44772 5 4 5Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M19.4608 11.2169C19.1135 11.0531 18.5876 11.0204 18.0069 11.3619C17.5309 11.642 16.918 11.4831 16.638 11.007C16.358 10.531 16.5169 9.91809 16.9929 9.63807C18.1123 8.97962 19.3364 8.94691 20.314 9.40808C21.2839 9.86558 21.9999 10.818 21.9999 12C21.9999 12.7957 21.6838 13.5587 21.1212 14.1213C20.5586 14.6839 19.7956 15 18.9999 15C18.4476 15 17.9999 14.5523 17.9999 14C17.9999 13.4477 18.4476 13 18.9999 13C19.2651 13 19.5195 12.8947 19.707 12.7071C19.8946 12.5196 19.9999 12.2652 19.9999 12C19.9999 11.6821 19.8159 11.3844 19.4608 11.2169Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M18.0001 14C18.0001 13.4477 18.4478 13 19.0001 13C19.7957 13 20.5588 13.3161 21.1214 13.8787C21.684 14.4413 22.0001 15.2043 22.0001 16C22.0001 17.2853 21.2767 18.3971 20.1604 18.8994C19.0257 19.41 17.642 19.2315 16.4001 18.3C15.9582 17.9686 15.8687 17.3418 16.2001 16.9C16.5314 16.4582 17.1582 16.3686 17.6001 16.7C18.3581 17.2685 18.9744 17.24 19.3397 17.0756C19.7234 16.9029 20.0001 16.5147 20.0001 16C20.0001 15.7348 19.8947 15.4804 19.7072 15.2929C19.5196 15.1054 19.2653 15 19.0001 15C18.4478 15 18.0001 14.5523 18.0001 14Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingThreeIcon.displayName = \"HeadingThreeIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingFourIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M4 5C4.55228 5 5 5.44772 5 6V11H11V6C11 5.44772 11.4477 5 12 5C12.5523 5 13 5.44772 13 6V18C13 18.5523 12.5523 19 12 19C11.4477 19 11 18.5523 11 18V13H5V18C5 18.5523 4.55228 19 4 19C3.44772 19 3 18.5523 3 18V6C3 5.44772 3.44772 5 4 5Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M17 9C17.5523 9 18 9.44772 18 10V13H20V10C20 9.44772 20.4477 9 21 9C21.5523 9 22 9.44772 22 10V18C22 18.5523 21.5523 19 21 19C20.4477 19 20 18.5523 20 18V15H17C16.4477 15 16 14.5523 16 14V10C16 9.44772 16.4477 9 17 9Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingFourIcon.displayName = \"HeadingFourIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingFiveIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M16 10C16 9.44772 16.4477 9 17 9H21C21.5523 9 22 9.44772 22 10C22 10.5523 21.5523 11 21 11H18V12H18.3C20.2754 12 22 13.4739 22 15.5C22 17.5261 20.2754 19 18.3 19C17.6457 19 17.0925 18.8643 16.5528 18.5944C16.0588 18.3474 15.8586 17.7468 16.1055 17.2528C16.3525 16.7588 16.9532 16.5586 17.4472 16.8056C17.7074 16.9357 17.9542 17 18.3 17C19.3246 17 20 16.2739 20 15.5C20 14.7261 19.3246 14 18.3 14H17C16.4477 14 16 13.5523 16 13L16 12.9928V10Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingFiveIcon.displayName = \"HeadingFiveIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingSixIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M20.7071 9.29289C21.0976 9.68342 21.0976 10.3166 20.7071 10.7071C19.8392 11.575 19.2179 12.2949 18.7889 13.0073C18.8587 13.0025 18.929 13 19 13C20.6569 13 22 14.3431 22 16C22 17.6569 20.6569 19 19 19C17.3431 19 16 17.6569 16 16C16 14.6007 16.2837 13.4368 16.8676 12.3419C17.4384 11.2717 18.2728 10.3129 19.2929 9.29289C19.6834 8.90237 20.3166 8.90237 20.7071 9.29289ZM19 17C18.4477 17 18 16.5523 18 16C18 15.4477 18.4477 15 19 15C19.5523 15 20 15.4477 20 16C20 16.5523 19.5523 17 19 17Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingSixIcon.displayName = \"HeadingSixIcon\"\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/dropdown-menu/dropdown-menu.scss\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root modal={false} {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return <DropdownMenuPrimitive.Portal {...props} />\n}\n\nconst DropdownMenuTrigger = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>\n>(({ ...props }, ref) => <DropdownMenuPrimitive.Trigger ref={ref} {...props} />)\nDropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownMenuItem = DropdownMenuPrimitive.Item\n\nconst DropdownMenuSubTrigger = DropdownMenuPrimitive.SubTrigger\n\nconst DropdownMenuSubContent = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent> & {\n portal?: boolean | React.ComponentProps<typeof DropdownMenuPortal>\n }\n>(({ className, portal = true, ...props }, ref) => {\n const content = (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\"tiptap-dropdown-menu\", className)}\n {...props}\n />\n )\n\n return portal ? (\n <DropdownMenuPortal {...(typeof portal === \"object\" ? portal : {})}>\n {content}\n </DropdownMenuPortal>\n ) : (\n content\n )\n})\nDropdownMenuSubContent.displayName =\n DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownMenuContent = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {\n portal?: boolean\n }\n>(({ className, sideOffset = 4, portal = false, ...props }, ref) => {\n const content = (\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n onCloseAutoFocus={(e) => e.preventDefault()}\n className={cn(\"tiptap-dropdown-menu\", className)}\n {...props}\n />\n )\n\n return portal ? (\n <DropdownMenuPortal {...(typeof portal === \"object\" ? portal : {})}>\n {content}\n </DropdownMenuPortal>\n ) : (\n content\n )\n})\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuGroup,\n DropdownMenuSub,\n DropdownMenuPortal,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n}\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/card/card.scss\"\n\nconst Card = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return <div ref={ref} className={cn(\"tiptap-card\", className)} {...props} />\n }\n)\nCard.displayName = \"Card\"\n\nconst CardHeader = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-header\", className)}\n {...props}\n />\n )\n }\n)\nCardHeader.displayName = \"CardHeader\"\n\nconst CardBody = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"tiptap-card-body\", className)} {...props} />\n )\n }\n)\nCardBody.displayName = \"CardBody\"\n\nconst CardItemGroup = forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> & {\n orientation?: \"horizontal\" | \"vertical\"\n }\n>(({ className, orientation = \"vertical\", ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-orientation={orientation}\n className={cn(\"tiptap-card-item-group\", className)}\n {...props}\n />\n )\n})\nCardItemGroup.displayName = \"CardItemGroup\"\n\nconst CardGroupLabel = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-group-label\", className)}\n {...props}\n />\n )\n }\n)\nCardGroupLabel.displayName = \"CardGroupLabel\"\n\nconst CardFooter = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-footer\", className)}\n {...props}\n />\n )\n }\n)\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardBody, CardItemGroup, CardGroupLabel }\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { HeadingIcon } from \"../../../components/tiptap-icons/heading-icon\"\n\n// --- Tiptap UI ---\nimport {\n headingIcons,\n type Level,\n isHeadingActive,\n canToggle,\n shouldShowButton,\n} from \"../../../components/tiptap-ui/heading-button\"\n\n/**\n * Configuration for the heading dropdown menu functionality\n */\nexport interface UseHeadingDropdownMenuConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Available heading levels to show in the dropdown\n * @default [1, 2, 3, 4, 5, 6]\n */\n levels?: Level[]\n /**\n * Whether the dropdown should hide when headings are not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n}\n\n/**\n * Gets the currently active heading level from the available levels\n */\nexport function getActiveHeadingLevel(\n editor: Editor | null,\n levels: Level[] = [1, 2, 3, 4, 5, 6]\n): Level | undefined {\n if (!editor || !editor.isEditable) return undefined\n return levels.find((level) => isHeadingActive(editor, level))\n}\n\n/**\n * Custom hook that provides heading dropdown menu functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MyHeadingDropdown() {\n * const {\n * isVisible,\n * activeLevel,\n * isAnyHeadingActive,\n * canToggle,\n * levels,\n * } = useHeadingDropdownMenu()\n *\n * if (!isVisible) return null\n *\n * return (\n * <DropdownMenu>\n * // dropdown content\n * </DropdownMenu>\n * )\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedHeadingDropdown() {\n * const {\n * isVisible,\n * activeLevel,\n * } = useHeadingDropdownMenu({\n * editor: myEditor,\n * levels: [1, 2, 3],\n * hideWhenUnavailable: true,\n * })\n *\n * // component implementation\n * }\n * ```\n */\nexport function useHeadingDropdownMenu(config?: UseHeadingDropdownMenuConfig) {\n const {\n editor: providedEditor,\n levels = [1, 2, 3, 4, 5, 6],\n hideWhenUnavailable = false,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState(true)\n\n const activeLevel = getActiveHeadingLevel(editor, levels)\n const isActive = isHeadingActive(editor)\n const canToggleState = canToggle(editor)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(\n shouldShowButton({ editor, hideWhenUnavailable, level: levels })\n )\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable, levels])\n\n return {\n isVisible,\n activeLevel,\n isActive,\n canToggle: canToggleState,\n levels,\n label: \"Heading\",\n Icon: activeLevel ? headingIcons[activeLevel] : HeadingIcon,\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M6 3C6.55228 3 7 3.44772 7 4V11H17V4C17 3.44772 17.4477 3 18 3C18.5523 3 19 3.44772 19 4V20C19 20.5523 18.5523 21 18 21C17.4477 21 17 20.5523 17 20V13H7V20C7 20.5523 6.55228 21 6 21C5.44772 21 5 20.5523 5 20V4C5 3.44772 5.44772 3 6 3Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingIcon.displayName = \"HeadingIcon\"\n"," \"use client\"\n\n import { forwardRef, useCallback } from \"react\"\n\n // --- Lib ---\n import { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n // --- Hooks ---\n import { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n // --- Tiptap UI ---\n import type { UseImageUploadConfig } from \"../../../components/tiptap-ui/image-upload-button\"\n import {\n IMAGE_UPLOAD_SHORTCUT_KEY,\n useImageUpload,\n } from \"../../../components/tiptap-ui/image-upload-button\"\n\n // --- UI Primitives ---\n import type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\n import { Button } from \"../../../components/tiptap-ui-primitive/button\"\n import { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\n type IconProps = React.SVGProps<SVGSVGElement>\n type IconComponent = ({ className, ...props }: IconProps) => React.ReactElement\n\n export interface ImageUploadButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseImageUploadConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default true\n */\n showShortcut?: boolean\n /**\n * Optional custom icon component to render instead of the default.\n */\n icon?: React.MemoExoticComponent<IconComponent> | React.FC<IconProps>\n }\n\n export function ImageShortcutBadge({\n shortcutKeys = IMAGE_UPLOAD_SHORTCUT_KEY,\n }: {\n shortcutKeys?: string\n }) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n }\n\n /**\n * Button component for uploading/inserting images in a Tiptap editor.\n *\n * For custom button implementations, use the `useImage` hook instead.\n */\n export const ImageUploadButton = forwardRef<\n HTMLButtonElement,\n ImageUploadButtonProps\n >(\n (\n {\n editor: providedEditor,\n text,\n hideWhenUnavailable = false,\n onInserted,\n showShortcut = false,\n onClick,\n icon: CustomIcon,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canInsert,\n handleImage,\n label,\n isActive,\n shortcutKeys,\n Icon,\n } = useImageUpload({\n editor,\n hideWhenUnavailable,\n onInserted,\n })\n\n const handleClick = useCallback(\n async (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n await handleImage() // 👈 important\n },\n [handleImage, onClick]\n )\n \n\n if (!isVisible) {\n return null\n }\n\n const RenderIcon = CustomIcon ?? Icon\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canInsert}\n data-disabled={!canInsert}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <RenderIcon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && <ImageShortcutBadge shortcutKeys={shortcutKeys} />}\n </>\n )}\n </Button>\n )\n }\n )\n\n ImageUploadButton.displayName = \"ImageUploadButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { useHotkeys } from \"react-hotkeys-hook\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\n\n// --- Lib ---\nimport { isExtensionAvailable } from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { ImagePlusIcon } from \"../../../components/tiptap-icons/image-plus-icon\"\n\nexport const IMAGE_UPLOAD_SHORTCUT_KEY = \"mod+shift+i\"\n\n/**\n * Configuration for the image upload functionality\n */\nexport interface UseImageUploadConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Whether the button should hide when insertion is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful image insertion.\n */\n onInserted?: () => void\n}\n\n/**\n * Checks if image can be inserted in the current editor state\n */\nexport function canInsertImage(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n if (!isExtensionAvailable(editor, \"imageUpload\")) return false\n\n return editor.can().insertContent({ type: \"imageUpload\" })\n}\n\n/**\n * Checks if image is currently active\n */\nexport function isImageActive(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive(\"imageUpload\")\n}\n\n/**\n * Inserts an image in the editor\n */\nexport async function insertImage(editor: Editor | null): Promise<boolean> {\n if (!editor || !editor.isEditable) return false\n if (!canInsertImage(editor)) return false\n\n try {\n // 1) pick file\n const input = document.createElement(\"input\")\n input.type = \"file\"\n input.accept = \"image/*\"\n\n return new Promise((resolve) => {\n input.onchange = async () => {\n const file = input.files?.[0]\n if (!file) return resolve(false)\n\n // 2) convert to base64\n const reader = new FileReader()\n reader.onload = () => {\n const base64 = reader.result as string\n\n // 3) store in localStorage\n const images = JSON.parse(localStorage.getItem(\"tiptap-images\") || \"[]\")\n images.push(base64)\n localStorage.setItem(\"tiptap-images\", JSON.stringify(images))\n\n // 4) insert into editor\n editor\n .chain()\n .focus()\n .insertContent({\n type: \"image\",\n attrs: { src: base64 },\n })\n .run()\n\n resolve(true)\n }\n reader.onerror = () => resolve(false)\n reader.readAsDataURL(file)\n }\n input.click()\n })\n } catch {\n return false\n }\n}\n\n\n/**\n * Determines if the image button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isExtensionAvailable(editor, \"imageUpload\")) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canInsertImage(editor)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides image functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage - no params needed\n * function MySimpleImageButton() {\n * const { isVisible, handleImage } = useImage()\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleImage}>Add Image</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedImageButton() {\n * const { isVisible, handleImage, label, isActive } = useImage({\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onInserted: () => console.log('Image inserted!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleImage}\n * aria-pressed={isActive}\n * aria-label={label}\n * >\n * Add Image\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useImageUpload(config?: UseImageUploadConfig) {\n const {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onInserted,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const isMobile = useIsBreakpoint()\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canInsert = canInsertImage(editor)\n const isActive = isImageActive(editor)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable])\n\n const handleImage = useCallback(async () => {\n if (!editor) return false\n\n const success = insertImage(editor)\n if (await success) {\n onInserted?.()\n }\n return success\n }, [editor, onInserted])\n\n useHotkeys(\n IMAGE_UPLOAD_SHORTCUT_KEY,\n (event) => {\n event.preventDefault()\n handleImage()\n },\n {\n enabled: isVisible && canInsert,\n enableOnContentEditable: !isMobile,\n enableOnFormTags: true,\n }\n )\n\n return {\n isVisible,\n isActive,\n handleImage,\n canInsert,\n label: \"Add image\",\n shortcutKeys: IMAGE_UPLOAD_SHORTCUT_KEY,\n Icon: ImagePlusIcon,\n }\n}\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\n\ntype BreakpointMode = \"min\" | \"max\"\n\n/**\n * Hook to detect whether the current viewport matches a given breakpoint rule.\n * Example:\n * useIsBreakpoint(\"max\", 768) // true when width < 768\n * useIsBreakpoint(\"min\", 1024) // true when width >= 1024\n */\nexport function useIsBreakpoint(\n mode: BreakpointMode = \"max\",\n breakpoint = 768\n) {\n const [matches, setMatches] = useState<boolean | undefined>(undefined)\n\n useEffect(() => {\n const query =\n mode === \"min\"\n ? `(min-width: ${breakpoint}px)`\n : `(max-width: ${breakpoint - 1}px)`\n\n const mql = window.matchMedia(query)\n const onChange = (e: MediaQueryListEvent) => setMatches(e.matches)\n\n // Set initial value\n setMatches(mql.matches)\n\n // Add listener\n mql.addEventListener(\"change\", onChange)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [mode, breakpoint])\n\n return !!matches\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ImagePlusIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M20 2C20 1.44772 19.5523 1 19 1C18.4477 1 18 1.44772 18 2V4H16C15.4477 4 15 4.44772 15 5C15 5.55228 15.4477 6 16 6H18V8C18 8.55228 18.4477 9 19 9C19.5523 9 20 8.55228 20 8V6H22C22.5523 6 23 5.55228 23 5C23 4.44772 22.5523 4 22 4H20V2ZM5 4C4.73478 4 4.48043 4.10536 4.29289 4.29289C4.10536 4.48043 4 4.73478 4 5V19C4 19.2652 4.10536 19.5196 4.29289 19.7071C4.48043 19.8946 4.73478 20 5 20H5.58579L14.379 11.2068C14.9416 10.6444 15.7045 10.3284 16.5 10.3284C17.2955 10.3284 18.0584 10.6444 18.621 11.2068L20 12.5858V12C20 11.4477 20.4477 11 21 11C21.5523 11 22 11.4477 22 12V14.998C22 14.9994 22 15.0007 22 15.002V19C22 19.7957 21.6839 20.5587 21.1213 21.1213C20.5587 21.6839 19.7957 22 19 22H6.00219C6.00073 22 5.99927 22 5.99781 22H5C4.20435 22 3.44129 21.6839 2.87868 21.1213C2.31607 20.5587 2 19.7957 2 19V5C2 4.20435 2.31607 3.44129 2.87868 2.87868C3.44129 2.31607 4.20435 2 5 2H12C12.5523 2 13 2.44772 13 3C13 3.55228 12.5523 4 12 4H5ZM8.41422 20H19C19.2652 20 19.5196 19.8946 19.7071 19.7071C19.8946 19.5196 20 19.2652 20 19V15.4142L17.207 12.6212C17.0195 12.4338 16.7651 12.3284 16.5 12.3284C16.2349 12.3284 15.9806 12.4337 15.7931 12.6211L8.41422 20ZM6.87868 6.87868C7.44129 6.31607 8.20435 6 9 6C9.79565 6 10.5587 6.31607 11.1213 6.87868C11.6839 7.44129 12 8.20435 12 9C12 9.79565 11.6839 10.5587 11.1213 11.1213C10.5587 11.6839 9.79565 12 9 12C8.20435 12 7.44129 11.6839 6.87868 11.1213C6.31607 10.5587 6 9.79565 6 9C6 8.20435 6.31607 7.44129 6.87868 6.87868ZM9 8C8.73478 8 8.48043 8.10536 8.29289 8.29289C8.10536 8.48043 8 8.73478 8 9C8 9.26522 8.10536 9.51957 8.29289 9.70711C8.48043 9.89464 8.73478 10 9 10C9.26522 10 9.51957 9.89464 9.70711 9.70711C9.89464 9.51957 10 9.26522 10 9C10 8.73478 9.89464 8.48043 9.70711 8.29289C9.51957 8.10536 9.26522 8 9 8Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nImagePlusIcon.displayName = \"ImagePlusIcon\"\n","\"use client\"\n\nimport { useCallback, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { ChevronDownIcon } from \"../../../components/tiptap-icons/chevron-down-icon\"\n\n// --- Tiptap UI ---\nimport { ListButton, type ListType } from \"../../../components/tiptap-ui/list-button\"\n\nimport { useListDropdownMenu } from \"../../../components/tiptap-ui/list-dropdown-menu/use-list-dropdown-menu\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n} from \"../../../components/tiptap-ui-primitive/dropdown-menu\"\nimport { Card, CardBody } from \"../../../components/tiptap-ui-primitive/card\"\n\nexport interface ListDropdownMenuProps extends Omit<ButtonProps, \"type\"> {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor\n /**\n * The list types to display in the dropdown.\n */\n types?: ListType[]\n /**\n * Whether the dropdown should be hidden when no list types are available\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback for when the dropdown opens or closes\n */\n onOpenChange?: (isOpen: boolean) => void\n /**\n * Whether to render the dropdown menu in a portal\n * @default false\n */\n portal?: boolean\n}\n\nexport function ListDropdownMenu({\n editor: providedEditor,\n types = [\"bulletList\", \"orderedList\", \"taskList\"],\n hideWhenUnavailable = false,\n onOpenChange,\n portal = false,\n ...props\n}: ListDropdownMenuProps) {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState(false)\n\n const { filteredLists, canToggle, isActive, isVisible, Icon } =\n useListDropdownMenu({\n editor,\n types,\n hideWhenUnavailable,\n })\n\n const handleOnOpenChange = useCallback(\n (open: boolean) => {\n setIsOpen(open)\n onOpenChange?.(open)\n },\n [onOpenChange]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <DropdownMenu open={isOpen} onOpenChange={handleOnOpenChange}>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label=\"List options\"\n tooltip=\"List\"\n {...props}\n >\n <Icon className=\"tiptap-button-icon\" />\n <ChevronDownIcon className=\"tiptap-button-dropdown-small\" />\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"start\" portal={portal}>\n <Card>\n <CardBody>\n <ButtonGroup>\n {filteredLists.map((option) => (\n <DropdownMenuItem key={option.type} asChild>\n <ListButton\n editor={editor}\n type={option.type}\n text={option.label}\n showTooltip={false}\n />\n </DropdownMenuItem>\n ))}\n </ButtonGroup>\n </CardBody>\n </Card>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nexport default ListDropdownMenu\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\n// --- Tiptap UI ---\nimport type { ListType, UseListConfig } from \"../../../components/tiptap-ui/list-button\"\nimport { LIST_SHORTCUT_KEYS, useList } from \"../../../components/tiptap-ui/list-button\"\n\nexport interface ListButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseListConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function ListShortcutBadge({\n type,\n shortcutKeys = LIST_SHORTCUT_KEYS[type],\n}: {\n type: ListType\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for toggling lists in a Tiptap editor.\n *\n * For custom button implementations, use the `useList` hook instead.\n */\nexport const ListButton = forwardRef<HTMLButtonElement, ListButtonProps>(\n (\n {\n editor: providedEditor,\n type,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = true ,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canToggle,\n isActive,\n handleToggle,\n label,\n shortcutKeys,\n Icon,\n } = useList({\n editor,\n type,\n hideWhenUnavailable,\n onToggled,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <ListShortcutBadge type={type} shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nListButton.displayName = \"ListButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\nimport { NodeSelection, TextSelection } from \"@tiptap/pm/state\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { ListIcon } from \"../../../components/tiptap-icons/list-icon\"\nimport { ListOrderedIcon } from \"../../../components/tiptap-icons/list-ordered-icon\"\nimport { ListTodoIcon } from \"../../../components/tiptap-icons/list-todo-icon\"\n\n// --- Lib ---\nimport {\n findNodePosition,\n isNodeInSchema,\n isNodeTypeSelected,\n isValidPosition,\n selectionWithinConvertibleTypes,\n} from \"../../../lib/tiptap-utils\"\n\nexport type ListType = \"bulletList\" | \"orderedList\" | \"taskList\"\n\n/**\n * Configuration for the list functionality\n */\nexport interface UseListConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The type of list to toggle.\n */\n type: ListType\n /**\n * Whether the button should hide when list is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful toggle.\n */\n onToggled?: () => void\n}\n\nexport const listIcons = {\n bulletList: ListIcon,\n orderedList: ListOrderedIcon,\n taskList: ListTodoIcon,\n}\n\nexport const listLabels: Record<ListType, string> = {\n bulletList: \"Bullet List\",\n orderedList: \"Ordered List\",\n taskList: \"Task List\",\n}\n\nexport const LIST_SHORTCUT_KEYS: Record<ListType, string> = {\n bulletList: \"mod+shift+8\",\n orderedList: \"mod+shift+7\",\n taskList: \"mod+shift+9\",\n}\n\n/**\n * Checks if a list can be toggled in the current editor state\n */\nexport function canToggleList(\n editor: Editor | null,\n type: ListType,\n turnInto: boolean = true\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(type, editor) || isNodeTypeSelected(editor, [\"image\"]))\n return false\n\n if (!turnInto) {\n switch (type) {\n case \"bulletList\":\n return editor.can().toggleBulletList()\n case \"orderedList\":\n return editor.can().toggleOrderedList()\n case \"taskList\":\n return editor.can().toggleList(\"taskList\", \"taskItem\")\n default:\n return false\n }\n }\n\n // Ensure selection is in nodes we're allowed to convert\n if (\n !selectionWithinConvertibleTypes(editor, [\n \"paragraph\",\n \"heading\",\n \"bulletList\",\n \"orderedList\",\n \"taskList\",\n \"blockquote\",\n \"codeBlock\",\n ])\n )\n return false\n\n // Either we can set list directly on the selection,\n // or we can clear formatting/nodes to arrive at a list.\n switch (type) {\n case \"bulletList\":\n return editor.can().toggleBulletList() || editor.can().clearNodes()\n case \"orderedList\":\n return editor.can().toggleOrderedList() || editor.can().clearNodes()\n case \"taskList\":\n return (\n editor.can().toggleList(\"taskList\", \"taskItem\") ||\n editor.can().clearNodes()\n )\n default:\n return false\n }\n}\n\n/**\n * Checks if list is currently active\n */\nexport function isListActive(editor: Editor | null, type: ListType): boolean {\n if (!editor || !editor.isEditable) return false\n\n switch (type) {\n case \"bulletList\":\n return editor.isActive(\"bulletList\")\n case \"orderedList\":\n return editor.isActive(\"orderedList\")\n case \"taskList\":\n return editor.isActive(\"taskList\")\n default:\n return false\n }\n}\n\n/**\n * Toggles list in the editor\n */\nexport function toggleList(editor: Editor | null, type: ListType): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canToggleList(editor, type)) return false\n\n try {\n const view = editor.view\n let state = view.state\n let tr = state.tr\n\n // No selection, find the the cursor position\n if (state.selection.empty || state.selection instanceof TextSelection) {\n const pos = findNodePosition({\n editor,\n node: state.selection.$anchor.node(1),\n })?.pos\n if (!isValidPosition(pos)) return false\n\n tr = tr.setSelection(NodeSelection.create(state.doc, pos))\n view.dispatch(tr)\n state = view.state\n }\n\n const selection = state.selection\n\n let chain = editor.chain().focus()\n\n // Handle NodeSelection\n if (selection instanceof NodeSelection) {\n const firstChild = selection.node.firstChild?.firstChild\n const lastChild = selection.node.lastChild?.lastChild\n\n const from = firstChild\n ? selection.from + firstChild.nodeSize\n : selection.from + 1\n\n const to = lastChild\n ? selection.to - lastChild.nodeSize\n : selection.to - 1\n\n const resolvedFrom = state.doc.resolve(from)\n const resolvedTo = state.doc.resolve(to)\n\n chain = chain\n .setTextSelection(TextSelection.between(resolvedFrom, resolvedTo))\n .clearNodes()\n }\n\n if (editor.isActive(type)) {\n // Unwrap list\n chain\n .liftListItem(\"listItem\")\n .lift(\"bulletList\")\n .lift(\"orderedList\")\n .lift(\"taskList\")\n .run()\n } else {\n // Wrap in specific list type\n const toggleMap: Record<ListType, () => typeof chain> = {\n bulletList: () => chain.toggleBulletList(),\n orderedList: () => chain.toggleOrderedList(),\n taskList: () => chain.toggleList(\"taskList\", \"taskItem\"),\n }\n\n const toggle = toggleMap[type]\n if (!toggle) return false\n\n toggle().run()\n }\n\n editor.chain().focus().selectTextblockEnd().run()\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Determines if the list button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n type: ListType\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, type, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(type, editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleList(editor, type)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides list functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleListButton() {\n * const { isVisible, handleToggle, isActive } = useList({ type: \"bulletList\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleToggle}>Bullet List</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedListButton() {\n * const { isVisible, handleToggle, label, isActive } = useList({\n * type: \"orderedList\",\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onToggled: () => console.log('List toggled!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleToggle}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * Toggle List\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useList(config: UseListConfig) {\n const {\n editor: providedEditor,\n type,\n hideWhenUnavailable = false,\n onToggled,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggle = canToggleList(editor, type)\n const isActive = isListActive(editor, type)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, type, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, type, hideWhenUnavailable])\n\n const handleToggle = useCallback(() => {\n if (!editor) return false\n\n const success = toggleList(editor, type)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, type, onToggled])\n\n return {\n isVisible,\n isActive,\n handleToggle,\n canToggle,\n label: listLabels[type],\n shortcutKeys: LIST_SHORTCUT_KEYS[type],\n Icon: listIcons[type],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ListIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 6C7 5.44772 7.44772 5 8 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H8C7.44772 7 7 6.55228 7 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 12C7 11.4477 7.44772 11 8 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H8C7.44772 13 7 12.5523 7 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 18C7 17.4477 7.44772 17 8 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H8C7.44772 19 7 18.5523 7 18Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H3.01C3.56228 5 4.01 5.44772 4.01 6C4.01 6.55228 3.56228 7 3.01 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 12C2 11.4477 2.44772 11 3 11H3.01C3.56228 11 4.01 11.4477 4.01 12C4.01 12.5523 3.56228 13 3.01 13H3C2.44772 13 2 12.5523 2 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 18C2 17.4477 2.44772 17 3 17H3.01C3.56228 17 4.01 17.4477 4.01 18C4.01 18.5523 3.56228 19 3.01 19H3C2.44772 19 2 18.5523 2 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nListIcon.displayName = \"ListIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ListOrderedIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9 6C9 5.44772 9.44772 5 10 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H10C9.44772 7 9 6.55228 9 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9 12C9 11.4477 9.44772 11 10 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H10C9.44772 13 9 12.5523 9 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9 18C9 17.4477 9.44772 17 10 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H10C9.44772 19 9 18.5523 9 18Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3 6C3 5.44772 3.44772 5 4 5H5C5.55228 5 6 5.44772 6 6V10C6 10.5523 5.55228 11 5 11C4.44772 11 4 10.5523 4 10V7C3.44772 7 3 6.55228 3 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3 10C3 9.44772 3.44772 9 4 9H6C6.55228 9 7 9.44772 7 10C7 10.5523 6.55228 11 6 11H4C3.44772 11 3 10.5523 3 10Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.82219 13.0431C6.54543 13.4047 6.99997 14.1319 6.99997 15C6.99997 15.5763 6.71806 16.0426 6.48747 16.35C6.31395 16.5814 6.1052 16.8044 5.91309 17H5.99997C6.55226 17 6.99997 17.4477 6.99997 18C6.99997 18.5523 6.55226 19 5.99997 19H3.99997C3.44769 19 2.99997 18.5523 2.99997 18C2.99997 17.4237 3.28189 16.9575 3.51247 16.65C3.74323 16.3424 4.03626 16.0494 4.26965 15.8161C4.27745 15.8083 4.2852 15.8006 4.29287 15.7929C4.55594 15.5298 4.75095 15.3321 4.88748 15.15C4.96287 15.0495 4.99021 14.9922 4.99911 14.9714C4.99535 14.9112 4.9803 14.882 4.9739 14.8715C4.96613 14.8588 4.95382 14.845 4.92776 14.8319C4.87723 14.8067 4.71156 14.7623 4.44719 14.8944C3.95321 15.1414 3.35254 14.9412 3.10555 14.4472C2.85856 13.9533 3.05878 13.3526 3.55276 13.1056C4.28839 12.7378 5.12272 12.6934 5.82219 13.0431Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nListOrderedIcon.displayName = \"ListOrderedIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ListTodoIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 4.89543 2.89543 4 4 4H8C9.10457 4 10 4.89543 10 6V10C10 11.1046 9.10457 12 8 12H4C2.89543 12 2 11.1046 2 10V6ZM8 6H4V10H8V6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.70711 14.2929C10.0976 14.6834 10.0976 15.3166 9.70711 15.7071L5.70711 19.7071C5.31658 20.0976 4.68342 20.0976 4.29289 19.7071L2.29289 17.7071C1.90237 17.3166 1.90237 16.6834 2.29289 16.2929C2.68342 15.9024 3.31658 15.9024 3.70711 16.2929L5 17.5858L8.29289 14.2929C8.68342 13.9024 9.31658 13.9024 9.70711 14.2929Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 6C12 5.44772 12.4477 5 13 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H13C12.4477 7 12 6.55228 12 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 12C12 11.4477 12.4477 11 13 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H13C12.4477 13 12 12.5523 12 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 18C12 17.4477 12.4477 17 13 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H13C12.4477 19 12 18.5523 12 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nListTodoIcon.displayName = \"ListTodoIcon\"\n","\"use client\"\n\nimport { useEffect, useMemo, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { ListIcon } from \"../../../components/tiptap-icons/list-icon\"\nimport { ListOrderedIcon } from \"../../../components/tiptap-icons/list-ordered-icon\"\nimport { ListTodoIcon } from \"../../../components/tiptap-icons/list-todo-icon\"\n\n// --- Lib ---\nimport { isNodeInSchema } from \"../../../lib/tiptap-utils\"\n\n// --- Tiptap UI ---\nimport {\n canToggleList,\n isListActive,\n listIcons,\n type ListType,\n} from \"../../../components/tiptap-ui/list-button\"\n\n/**\n * Configuration for the list dropdown menu functionality\n */\nexport interface UseListDropdownMenuConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The list types to display in the dropdown.\n * @default [\"bulletList\", \"orderedList\", \"taskList\"]\n */\n types?: ListType[]\n /**\n * Whether the dropdown should be hidden when no list types are available\n * @default false\n */\n hideWhenUnavailable?: boolean\n}\n\nexport interface ListOption {\n label: string\n type: ListType\n icon: React.ElementType\n}\n\nexport const listOptions: ListOption[] = [\n {\n label: \"Bullet List\",\n type: \"bulletList\",\n icon: ListIcon,\n },\n {\n label: \"Ordered List\",\n type: \"orderedList\",\n icon: ListOrderedIcon,\n },\n {\n label: \"Task List\",\n type: \"taskList\",\n icon: ListTodoIcon,\n },\n]\n\nexport function canToggleAnyList(\n editor: Editor | null,\n listTypes: ListType[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n return listTypes.some((type) => canToggleList(editor, type))\n}\n\nexport function isAnyListActive(\n editor: Editor | null,\n listTypes: ListType[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n return listTypes.some((type) => isListActive(editor, type))\n}\n\nexport function getFilteredListOptions(\n availableTypes: ListType[]\n): typeof listOptions {\n return listOptions.filter(\n (option) => !option.type || availableTypes.includes(option.type)\n )\n}\n\nexport function shouldShowListDropdown(params: {\n editor: Editor | null\n listTypes: ListType[]\n hideWhenUnavailable: boolean\n listInSchema: boolean\n canToggleAny: boolean\n}): boolean {\n const { editor, hideWhenUnavailable, listInSchema, canToggleAny } = params\n\n if (!listInSchema || !editor) {\n return false\n }\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleAny\n }\n\n return true\n}\n\n/**\n * Gets the currently active list type from the available types\n */\nexport function getActiveListType(\n editor: Editor | null,\n availableTypes: ListType[]\n): ListType | undefined {\n if (!editor || !editor.isEditable) return undefined\n return availableTypes.find((type) => isListActive(editor, type))\n}\n\n/**\n * Custom hook that provides list dropdown menu functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MyListDropdown() {\n * const {\n * isVisible,\n * activeType,\n * isAnyActive,\n * canToggleAny,\n * filteredLists,\n * } = useListDropdownMenu()\n *\n * if (!isVisible) return null\n *\n * return (\n * <DropdownMenu>\n * // dropdown content\n * </DropdownMenu>\n * )\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedListDropdown() {\n * const {\n * isVisible,\n * activeType,\n * } = useListDropdownMenu({\n * editor: myEditor,\n * types: [\"bulletList\", \"orderedList\"],\n * hideWhenUnavailable: true,\n * })\n *\n * // component implementation\n * }\n * ```\n */\nexport function useListDropdownMenu(config?: UseListDropdownMenuConfig) {\n const {\n editor: providedEditor,\n types = [\"bulletList\", \"orderedList\", \"taskList\"],\n hideWhenUnavailable = false,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState(true)\n\n const listInSchema = types.some((type) => isNodeInSchema(type, editor))\n\n const filteredLists = useMemo(() => getFilteredListOptions(types), [types])\n\n const canToggleAny = canToggleAnyList(editor, types)\n const isAnyActive = isAnyListActive(editor, types)\n const activeType = getActiveListType(editor, types)\n const activeList = filteredLists.find((option) => option.type === activeType)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(\n shouldShowListDropdown({\n editor,\n listTypes: types,\n hideWhenUnavailable,\n listInSchema,\n canToggleAny,\n })\n )\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [canToggleAny, editor, hideWhenUnavailable, listInSchema, types])\n\n return {\n isVisible,\n activeType,\n isActive: isAnyActive,\n canToggle: canToggleAny,\n types,\n filteredLists,\n label: \"List\",\n Icon: activeList ? listIcons[activeList.type] : ListIcon,\n }\n}\n","\"use client\";\n\nimport { forwardRef, useCallback } from \"react\";\n\n// --- Tiptap UI ---\nimport type { UseBlockquoteConfig } from \"../blockquote-button\";\nimport {\n BLOCKQUOTE_SHORTCUT_KEY,\n useBlockquote,\n} from \"../blockquote-button\";\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\";\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\";\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../tiptap-ui-primitive/button\";\nimport { Button } from \"../../tiptap-ui-primitive/button\";\nimport { Badge } from \"../../tiptap-ui-primitive/badge\";\n\nexport interface BlockquoteButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseBlockquoteConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string;\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean;\n}\n\nexport function BlockquoteShortcutBadge({\n shortcutKeys = BLOCKQUOTE_SHORTCUT_KEY,\n}: {\n shortcutKeys?: string;\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>;\n}\n\n/**\n * Button component for toggling blockquote in a Tiptap editor.\n *\n * For custom button implementations, use the `useBlockquote` hook instead.\n */\nexport const BlockquoteButton = forwardRef<\n HTMLButtonElement,\n BlockquoteButtonProps\n>(\n (\n {\n editor: providedEditor,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = false,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor);\n const {\n isVisible,\n canToggle,\n isActive,\n handleToggle,\n label,\n shortcutKeys,\n Icon,\n } = useBlockquote({\n editor,\n hideWhenUnavailable,\n onToggled,\n });\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n handleToggle();\n },\n [handleToggle, onClick]\n );\n\n if (!isVisible) {\n return null;\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={`${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")})`\n : \"\"\n }`}\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <BlockquoteShortcutBadge shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n );\n }\n);\n\nBlockquoteButton.displayName = \"BlockquoteButton\";\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\nimport { NodeSelection, TextSelection } from \"@tiptap/pm/state\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { BlockquoteIcon } from \"../../tiptap-icons/blockquote-icon\"\n\n// --- UI Utils ---\nimport {\n findNodePosition,\n isNodeInSchema,\n isNodeTypeSelected,\n isValidPosition,\n selectionWithinConvertibleTypes,\n} from \"../../../lib/tiptap-utils\"\n\nexport const BLOCKQUOTE_SHORTCUT_KEY = \"mod+shift+b\"\n\n/**\n * Configuration for the blockquote functionality\n */\nexport interface UseBlockquoteConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Whether the button should hide when blockquote is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful toggle.\n */\n onToggled?: () => void\n}\n\n/**\n * Checks if blockquote can be toggled in the current editor state\n */\nexport function canToggleBlockquote(\n editor: Editor | null,\n turnInto: boolean = true\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (\n !isNodeInSchema(\"blockquote\", editor) ||\n isNodeTypeSelected(editor, [\"image\"])\n )\n return false\n\n if (!turnInto) {\n return editor.can().toggleWrap(\"blockquote\")\n }\n\n // Ensure selection is in nodes we're allowed to convert\n if (\n !selectionWithinConvertibleTypes(editor, [\n \"paragraph\",\n \"heading\",\n \"bulletList\",\n \"orderedList\",\n \"taskList\",\n \"blockquote\",\n \"codeBlock\",\n ])\n )\n return false\n\n // Either we can wrap in blockquote directly on the selection,\n // or we can clear formatting/nodes to arrive at a blockquote.\n return editor.can().toggleWrap(\"blockquote\") || editor.can().clearNodes()\n}\n\n/**\n * Toggles blockquote formatting for a specific node or the current selection\n */\nexport function toggleBlockquote(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canToggleBlockquote(editor)) return false\n\n try {\n const view = editor.view\n let state = view.state\n let tr = state.tr\n\n // No selection, find the the cursor position\n if (state.selection.empty || state.selection instanceof TextSelection) {\n const pos = findNodePosition({\n editor,\n node: state.selection.$anchor.node(1),\n })?.pos\n if (!isValidPosition(pos)) return false\n\n tr = tr.setSelection(NodeSelection.create(state.doc, pos))\n view.dispatch(tr)\n state = view.state\n }\n\n const selection = state.selection\n\n let chain = editor.chain().focus()\n\n // Handle NodeSelection\n if (selection instanceof NodeSelection) {\n const firstChild = selection.node.firstChild?.firstChild\n const lastChild = selection.node.lastChild?.lastChild\n\n const from = firstChild\n ? selection.from + firstChild.nodeSize\n : selection.from + 1\n\n const to = lastChild\n ? selection.to - lastChild.nodeSize\n : selection.to - 1\n\n const resolvedFrom = state.doc.resolve(from)\n const resolvedTo = state.doc.resolve(to)\n\n chain = chain\n .setTextSelection(TextSelection.between(resolvedFrom, resolvedTo))\n .clearNodes()\n }\n\n const toggle = editor.isActive(\"blockquote\")\n ? chain.lift(\"blockquote\")\n : chain.wrapIn(\"blockquote\")\n\n toggle.run()\n\n editor.chain().focus().selectTextblockEnd().run()\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Determines if the blockquote button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(\"blockquote\", editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleBlockquote(editor)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides blockquote functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage - no params needed\n * function MySimpleBlockquoteButton() {\n * const { isVisible, handleToggle, isActive } = useBlockquote()\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleToggle}>Blockquote</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedBlockquoteButton() {\n * const { isVisible, handleToggle, label, isActive } = useBlockquote({\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onToggled: () => console.log('Blockquote toggled!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleToggle}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * Toggle Blockquote\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useBlockquote(config?: UseBlockquoteConfig) {\n const {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onToggled,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggle = canToggleBlockquote(editor)\n const isActive = editor?.isActive(\"blockquote\") || false\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable])\n\n const handleToggle = useCallback(() => {\n if (!editor) return false\n\n const success = toggleBlockquote(editor)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, onToggled])\n\n return {\n isVisible,\n isActive,\n handleToggle,\n canToggle,\n label: \"Blockquote\",\n shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,\n Icon: BlockquoteIcon,\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const BlockquoteIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 6C8 5.44772 8.44772 5 9 5H16C16.5523 5 17 5.44772 17 6C17 6.55228 16.5523 7 16 7H9C8.44772 7 8 6.55228 8 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4 3C4.55228 3 5 3.44772 5 4L5 20C5 20.5523 4.55229 21 4 21C3.44772 21 3 20.5523 3 20L3 4C3 3.44772 3.44772 3 4 3Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 12C8 11.4477 8.44772 11 9 11H20C20.5523 11 21 11.4477 21 12C21 12.5523 20.5523 13 20 13H9C8.44772 13 8 12.5523 8 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 18C8 17.4477 8.44772 17 9 17H16C16.5523 17 17 17.4477 17 18C17 18.5523 16.5523 19 16 19H9C8.44772 19 8 18.5523 8 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nBlockquoteIcon.displayName = \"BlockquoteIcon\"\n","\"use client\"\n\nimport { forwardRef, useMemo, useRef, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation\"\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { BanIcon } from \"../../../components/tiptap-icons/ban-icon\"\nimport { HighlighterIcon } from \"../../../components/tiptap-icons/highlighter-icon\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n} from \"../../../components/tiptap-ui-primitive/popover\"\nimport { Separator } from \"../../../components/tiptap-ui-primitive/separator\"\nimport {\n Card,\n CardBody,\n CardItemGroup,\n} from \"../../../components/tiptap-ui-primitive/card\"\n\n// --- Tiptap UI ---\nimport type {\n HighlightColor,\n UseColorHighlightConfig,\n} from \"../../../components/tiptap-ui/color-highlight-button\"\nimport {\n ColorHighlightButton,\n pickHighlightColorsByValue,\n useColorHighlight,\n} from \"../../../components/tiptap-ui/color-highlight-button\"\n\nexport interface ColorHighlightPopoverContentProps {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Optional colors to use in the highlight popover.\n * If not provided, defaults to a predefined set of colors.\n */\n colors?: HighlightColor[]\n}\n\nexport interface ColorHighlightPopoverProps\n extends Omit<ButtonProps, \"type\">,\n Pick<\n UseColorHighlightConfig,\n \"editor\" | \"hideWhenUnavailable\" | \"onApplied\"\n > {\n /**\n * Optional colors to use in the highlight popover.\n * If not provided, defaults to a predefined set of colors.\n */\n colors?: HighlightColor[]\n}\n\nexport const ColorHighlightPopoverButton = forwardRef<\n HTMLButtonElement,\n ButtonProps\n>(({ className, children, ...props }, ref) => (\n <Button\n type=\"button\"\n className={className}\n data-style=\"ghost\"\n data-appearance=\"default\"\n role=\"button\"\n tabIndex={-1}\n aria-label=\"Highlight text\"\n tooltip=\"Highlight\"\n ref={ref}\n {...props}\n >\n {children ?? <HighlighterIcon className=\"tiptap-button-icon\" />}\n </Button>\n))\n\nColorHighlightPopoverButton.displayName = \"ColorHighlightPopoverButton\"\n\nexport function ColorHighlightPopoverContent({\n editor,\n colors = pickHighlightColorsByValue([\n \"var(--tt-color-highlight-green)\",\n \"var(--tt-color-highlight-blue)\",\n \"var(--tt-color-highlight-red)\",\n \"var(--tt-color-highlight-purple)\",\n \"var(--tt-color-highlight-yellow)\",\n ]),\n}: ColorHighlightPopoverContentProps) {\n const { handleRemoveHighlight } = useColorHighlight({ editor })\n const isMobile = useIsBreakpoint()\n const containerRef = useRef<HTMLDivElement>(null)\n\n const menuItems = useMemo(\n () => [...colors, { label: \"Remove highlight\", value: \"none\" }],\n [colors]\n )\n\n const { selectedIndex } = useMenuNavigation({\n containerRef,\n items: menuItems,\n orientation: \"both\",\n onSelect: (item) => {\n if (!containerRef.current) return false\n const highlightedElement = containerRef.current.querySelector(\n '[data-highlighted=\"true\"]'\n ) as HTMLElement\n if (highlightedElement) highlightedElement.click()\n if (item.value === \"none\") handleRemoveHighlight()\n return true\n },\n autoSelectFirstItem: false,\n })\n\n return (\n <Card\n ref={containerRef}\n tabIndex={0}\n style={isMobile ? { boxShadow: \"none\", border: 0 } : {}}\n >\n <CardBody style={isMobile ? { padding: 0 } : {}}>\n <CardItemGroup orientation=\"horizontal\">\n <ButtonGroup orientation=\"horizontal\">\n {colors.map((color, index) => (\n <ColorHighlightButton\n key={color.value}\n editor={editor}\n highlightColor={color.value}\n tooltip={color.label}\n aria-label={`${color.label} highlight color`}\n tabIndex={index === selectedIndex ? 0 : -1}\n data-highlighted={selectedIndex === index}\n />\n ))}\n </ButtonGroup>\n <Separator />\n <ButtonGroup orientation=\"horizontal\">\n <Button\n onClick={handleRemoveHighlight}\n aria-label=\"Remove highlight\"\n tooltip=\"Remove highlight\"\n tabIndex={selectedIndex === colors.length ? 0 : -1}\n type=\"button\"\n role=\"menuitem\"\n data-style=\"ghost\"\n data-highlighted={selectedIndex === colors.length}\n >\n <BanIcon className=\"tiptap-button-icon\" />\n </Button>\n </ButtonGroup>\n </CardItemGroup>\n </CardBody>\n </Card>\n )\n}\n\nexport function ColorHighlightPopover({\n editor: providedEditor,\n colors = pickHighlightColorsByValue([\n \"var(--tt-color-highlight-green)\",\n \"var(--tt-color-highlight-blue)\",\n \"var(--tt-color-highlight-red)\",\n \"var(--tt-color-highlight-purple)\",\n \"var(--tt-color-highlight-yellow)\",\n ]),\n hideWhenUnavailable = false,\n onApplied,\n ...props\n}: ColorHighlightPopoverProps) {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState(false)\n const { isVisible, canColorHighlight, isActive, label, Icon } =\n useColorHighlight({\n editor,\n hideWhenUnavailable,\n onApplied,\n })\n\n if (!isVisible) return null\n\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild>\n <ColorHighlightPopoverButton\n disabled={!canColorHighlight}\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canColorHighlight}\n aria-pressed={isActive}\n aria-label={label}\n tooltip={label}\n {...props}\n >\n <Icon className=\"tiptap-button-icon\" />\n </ColorHighlightPopoverButton>\n </PopoverTrigger>\n <PopoverContent aria-label=\"Highlight colors\">\n <ColorHighlightPopoverContent editor={editor} colors={colors} />\n </PopoverContent>\n </Popover>\n )\n}\n\nexport default ColorHighlightPopover\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const BanIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4.43471 4.01458C4.34773 4.06032 4.26607 4.11977 4.19292 4.19292C4.11977 4.26607 4.06032 4.34773 4.01458 4.43471C2.14611 6.40628 1 9.0693 1 12C1 18.0751 5.92487 23 12 23C14.9306 23 17.5936 21.854 19.5651 19.9856C19.6522 19.9398 19.7339 19.8803 19.8071 19.8071C19.8803 19.7339 19.9398 19.6522 19.9856 19.5651C21.854 17.5936 23 14.9306 23 12C23 5.92487 18.0751 1 12 1C9.0693 1 6.40628 2.14611 4.43471 4.01458ZM6.38231 4.9681C7.92199 3.73647 9.87499 3 12 3C16.9706 3 21 7.02944 21 12C21 14.125 20.2635 16.078 19.0319 17.6177L6.38231 4.9681ZM17.6177 19.0319C16.078 20.2635 14.125 21 12 21C7.02944 21 3 16.9706 3 12C3 9.87499 3.73647 7.92199 4.9681 6.38231L17.6177 19.0319Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nBanIcon.displayName = \"BanIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HighlighterIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M14.7072 4.70711C15.0977 4.31658 15.0977 3.68342 14.7072 3.29289C14.3167 2.90237 13.6835 2.90237 13.293 3.29289L8.69294 7.89286L8.68594 7.9C8.13626 8.46079 7.82837 9.21474 7.82837 10C7.82837 10.2306 7.85491 10.4584 7.90631 10.6795L2.29289 16.2929C2.10536 16.4804 2 16.7348 2 17V20C2 20.5523 2.44772 21 3 21H12C12.2652 21 12.5196 20.8946 12.7071 20.7071L15.3205 18.0937C15.5416 18.1452 15.7695 18.1717 16.0001 18.1717C16.7853 18.1717 17.5393 17.8639 18.1001 17.3142L22.7072 12.7071C23.0977 12.3166 23.0977 11.6834 22.7072 11.2929C22.3167 10.9024 21.6835 10.9024 21.293 11.2929L16.6971 15.8887C16.5105 16.0702 16.2605 16.1717 16.0001 16.1717C15.7397 16.1717 15.4897 16.0702 15.303 15.8887L10.1113 10.697C9.92992 10.5104 9.82837 10.2604 9.82837 10C9.82837 9.73963 9.92992 9.48958 10.1113 9.30297L14.7072 4.70711ZM13.5858 17L9.00004 12.4142L4 17.4142V19H11.5858L13.5858 17Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHighlighterIcon.displayName = \"HighlighterIcon\"\n","\"use client\"\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/popover/popover.scss\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n align={align}\n sideOffset={sideOffset}\n className={cn(\"tiptap-popover\", className)}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverTrigger, PopoverContent }\n","\"use client\"\n\nimport { forwardRef, useCallback, useMemo } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type { UseColorHighlightConfig } from \"../../../components/tiptap-ui/color-highlight-button\"\nimport {\n COLOR_HIGHLIGHT_SHORTCUT_KEY,\n useColorHighlight,\n} from \"../../../components/tiptap-ui/color-highlight-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\n// --- Styles ---\nimport \"../../../components/tiptap-ui/color-highlight-button/color-highlight-button.scss\"\n\nexport interface ColorHighlightButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseColorHighlightConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function ColorHighlightShortcutBadge({\n shortcutKeys = COLOR_HIGHLIGHT_SHORTCUT_KEY,\n}: {\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for applying color highlights in a Tiptap editor.\n *\n * Supports two highlighting modes:\n * - \"mark\": Uses the highlight mark extension (default)\n * - \"node\": Uses the node background extension\n *\n * For custom button implementations, use the `useColorHighlight` hook instead.\n *\n * @example\n * ```tsx\n * // Mark-based highlighting (default)\n * <ColorHighlightButton highlightColor=\"yellow\" />\n *\n * // Node-based background coloring\n * <ColorHighlightButton\n * highlightColor=\"var(--tt-color-highlight-blue)\"\n * mode=\"node\"\n * />\n *\n * // With custom callback\n * <ColorHighlightButton\n * highlightColor=\"red\"\n * mode=\"mark\"\n * onApplied={({ color, mode }) => console.log(`Applied ${color} in ${mode} mode`)}\n * />\n * ```\n */\nexport const ColorHighlightButton = forwardRef<\n HTMLButtonElement,\n ColorHighlightButtonProps\n>(\n (\n {\n editor: providedEditor,\n highlightColor,\n text,\n hideWhenUnavailable = false,\n mode = \"mark\",\n onApplied,\n showShortcut = false,\n onClick,\n children,\n style,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canColorHighlight,\n isActive,\n handleColorHighlight,\n label,\n shortcutKeys,\n } = useColorHighlight({\n editor,\n highlightColor,\n label: text || `Toggle highlight (${highlightColor})`,\n hideWhenUnavailable,\n mode,\n onApplied,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleColorHighlight()\n },\n [handleColorHighlight, onClick]\n )\n\n const buttonStyle = useMemo(\n () =>\n ({\n ...style,\n \"--highlight-color\": highlightColor,\n }) as React.CSSProperties,\n [highlightColor, style]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canColorHighlight}\n data-disabled={!canColorHighlight}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={label}\n onClick={handleClick}\n style={buttonStyle}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <span\n className=\"tiptap-button-highlight\"\n style={\n { \"--highlight-color\": highlightColor } as React.CSSProperties\n }\n />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <ColorHighlightShortcutBadge shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nColorHighlightButton.displayName = \"ColorHighlightButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\nimport { useHotkeys } from \"react-hotkeys-hook\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\n\n// --- Lib ---\nimport {\n isMarkInSchema,\n isNodeTypeSelected,\n isExtensionAvailable,\n} from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { HighlighterIcon } from \"../../../components/tiptap-icons/highlighter-icon\"\n\nexport const COLOR_HIGHLIGHT_SHORTCUT_KEY = \"mod+shift+h\"\nexport const HIGHLIGHT_COLORS = [\n {\n label: \"Default background\",\n value: \"var(--tt-bg-color)\",\n border: \"var(--tt-bg-color-contrast)\",\n },\n {\n label: \"Gray background\",\n value: \"var(--tt-color-highlight-gray)\",\n border: \"var(--tt-color-highlight-gray-contrast)\",\n },\n {\n label: \"Brown background\",\n value: \"var(--tt-color-highlight-brown)\",\n border: \"var(--tt-color-highlight-brown-contrast)\",\n },\n {\n label: \"Orange background\",\n value: \"var(--tt-color-highlight-orange)\",\n border: \"var(--tt-color-highlight-orange-contrast)\",\n },\n {\n label: \"Yellow background\",\n value: \"var(--tt-color-highlight-yellow)\",\n border: \"var(--tt-color-highlight-yellow-contrast)\",\n },\n {\n label: \"Green background\",\n value: \"var(--tt-color-highlight-green)\",\n border: \"var(--tt-color-highlight-green-contrast)\",\n },\n {\n label: \"Blue background\",\n value: \"var(--tt-color-highlight-blue)\",\n border: \"var(--tt-color-highlight-blue-contrast)\",\n },\n {\n label: \"Purple background\",\n value: \"var(--tt-color-highlight-purple)\",\n border: \"var(--tt-color-highlight-purple-contrast)\",\n },\n {\n label: \"Pink background\",\n value: \"var(--tt-color-highlight-pink)\",\n border: \"var(--tt-color-highlight-pink-contrast)\",\n },\n {\n label: \"Red background\",\n value: \"var(--tt-color-highlight-red)\",\n border: \"var(--tt-color-highlight-red-contrast)\",\n },\n]\nexport type HighlightColor = (typeof HIGHLIGHT_COLORS)[number]\n\nexport type HighlightMode = \"mark\" | \"node\"\n\n/**\n * Configuration for the color highlight functionality\n */\nexport interface UseColorHighlightConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The color to apply when toggling the highlight.\n */\n highlightColor?: string\n /**\n * Optional label to display alongside the icon.\n */\n label?: string\n /**\n * Whether the button should hide when the mark is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * The highlighting mode to use.\n * - \"mark\": Uses the highlight mark extension (default)\n * - \"node\": Uses the node background extension\n * @default \"mark\"\n */\n mode?: HighlightMode\n /**\n * Called when the highlight is applied.\n */\n onApplied?: ({\n color,\n label,\n mode,\n }: {\n color: string\n label: string\n mode: HighlightMode\n }) => void\n}\n\nexport function pickHighlightColorsByValue(values: string[]) {\n const colorMap = new Map(\n HIGHLIGHT_COLORS.map((color) => [color.value, color])\n )\n return values\n .map((value) => colorMap.get(value))\n .filter((color): color is (typeof HIGHLIGHT_COLORS)[number] => !!color)\n}\n\n/**\n * Checks if highlight can be applied based on the mode and current editor state\n */\nexport function canColorHighlight(\n editor: Editor | null,\n mode: HighlightMode = \"mark\"\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n if (mode === \"mark\") {\n if (\n !isMarkInSchema(\"highlight\", editor) ||\n isNodeTypeSelected(editor, [\"image\"])\n )\n return false\n\n return editor.can().setMark(\"highlight\")\n } else {\n if (!isExtensionAvailable(editor, [\"nodeBackground\"])) return false\n\n try {\n return editor.can().setNode(\"nodeBackground\", { backgroundColor: \"test\" })\n } catch {\n return false\n }\n }\n}\n\n/**\n * Checks if highlight is currently active\n */\nexport function isColorHighlightActive(\n editor: Editor | null,\n highlightColor?: string,\n mode: HighlightMode = \"mark\"\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n if (mode === \"mark\") {\n return highlightColor\n ? editor.isActive(\"highlight\", { color: highlightColor })\n : editor.isActive(\"highlight\")\n } else {\n if (!highlightColor) return false\n\n try {\n const { state } = editor\n const { selection } = state\n\n const $pos = selection.$anchor\n for (let depth = $pos.depth; depth >= 0; depth--) {\n const node = $pos.node(depth)\n if (node && node.attrs?.backgroundColor === highlightColor) {\n return true\n }\n }\n return false\n } catch {\n return false\n }\n }\n}\n\n/**\n * Removes highlight based on the mode\n */\nexport function removeHighlight(\n editor: Editor | null,\n mode: HighlightMode = \"mark\"\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canColorHighlight(editor, mode)) return false\n\n if (mode === \"mark\") {\n return editor.chain().focus().unsetMark(\"highlight\").run()\n } else {\n return editor.chain().focus().unsetBackgroundColor().run()\n }\n}\n\n/**\n * Determines if the highlight button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n mode: HighlightMode\n}): boolean {\n const { editor, hideWhenUnavailable, mode } = props\n\n if (!editor || !editor.isEditable) return false\n\n if (mode === \"mark\") {\n if (!isMarkInSchema(\"highlight\", editor)) return false\n } else {\n if (!isExtensionAvailable(editor, [\"nodeBackground\"])) return false\n }\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canColorHighlight(editor, mode)\n }\n\n return true\n}\n\nexport function useColorHighlight(config: UseColorHighlightConfig) {\n const {\n editor: providedEditor,\n label,\n highlightColor,\n hideWhenUnavailable = false,\n mode = \"mark\",\n onApplied,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const isMobile = useIsBreakpoint()\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canColorHighlightState = canColorHighlight(editor, mode)\n const isActive = isColorHighlightActive(editor, highlightColor, mode)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable, mode }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable, mode])\n\n const handleColorHighlight = useCallback(() => {\n if (!editor || !canColorHighlightState || !highlightColor || !label)\n return false\n\n if (mode === \"mark\") {\n if (editor.state.storedMarks) {\n const highlightMarkType = editor.schema.marks.highlight\n if (highlightMarkType) {\n editor.view.dispatch(\n editor.state.tr.removeStoredMark(highlightMarkType)\n )\n }\n }\n\n setTimeout(() => {\n const success = editor\n .chain()\n .focus()\n .toggleMark(\"highlight\", { color: highlightColor })\n .run()\n if (success) {\n onApplied?.({ color: highlightColor, label, mode })\n }\n return success\n }, 0)\n\n return true\n } else {\n const success = editor\n .chain()\n .focus()\n .setNode(\"nodeBackground\", { backgroundColor: highlightColor })\n .run()\n\n if (success) {\n onApplied?.({ color: highlightColor, label, mode })\n }\n return success\n }\n }, [canColorHighlightState, highlightColor, editor, label, onApplied, mode])\n\n const handleRemoveHighlight = useCallback(() => {\n const success = removeHighlight(editor, mode)\n if (success) {\n onApplied?.({ color: \"\", label: \"Remove highlight\", mode })\n }\n return success\n }, [editor, onApplied, mode])\n\n useHotkeys(\n COLOR_HIGHLIGHT_SHORTCUT_KEY,\n (event) => {\n event.preventDefault()\n handleColorHighlight()\n },\n {\n enabled: isVisible && canColorHighlightState,\n enableOnContentEditable: !isMobile,\n enableOnFormTags: true,\n }\n )\n\n return {\n isVisible,\n isActive,\n handleColorHighlight,\n handleRemoveHighlight,\n canColorHighlight: canColorHighlightState,\n label: label || `Highlight`,\n shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,\n Icon: HighlighterIcon,\n mode,\n }\n}\n","\"use client\"\n\nimport { forwardRef, useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { CornerDownLeftIcon } from \"../../../components/tiptap-icons/corner-down-left-icon\"\nimport { ExternalLinkIcon } from \"../../../components/tiptap-icons/external-link-icon\"\nimport { LinkIcon } from \"../../../components/tiptap-icons/link-icon\"\nimport { TrashIcon } from \"../../../components/tiptap-icons/trash-icon\"\n\n// --- Tiptap UI ---\nimport type { UseLinkPopoverConfig } from \"../../../components/tiptap-ui/link-popover\"\nimport { useLinkPopover } from \"../../../components/tiptap-ui/link-popover\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../components/tiptap-ui-primitive/popover\"\nimport { Separator } from \"../../../components/tiptap-ui-primitive/separator\"\nimport {\n Card,\n CardBody,\n CardItemGroup,\n} from \"../../../components/tiptap-ui-primitive/card\"\nimport { Input, InputGroup } from \"../../../components/tiptap-ui-primitive/input\"\n\nexport interface LinkMainProps {\n /**\n * The URL to set for the link.\n */\n url: string\n /**\n * Function to update the URL state.\n */\n setUrl: React.Dispatch<React.SetStateAction<string | null>>\n /**\n * Function to set the link in the editor.\n */\n setLink: () => void\n /**\n * Function to remove the link from the editor.\n */\n removeLink: () => void\n /**\n * Function to open the link.\n */\n openLink: () => void\n /**\n * Whether the link is currently active in the editor.\n */\n isActive: boolean\n}\n\nexport interface LinkPopoverProps\n extends Omit<ButtonProps, \"type\">,\n UseLinkPopoverConfig {\n /**\n * Callback for when the popover opens or closes.\n */\n onOpenChange?: (isOpen: boolean) => void\n /**\n * Whether to automatically open the popover when a link is active.\n * @default true\n */\n autoOpenOnLinkActive?: boolean\n}\n\n/**\n * Link button component for triggering the link popover\n */\nexport const LinkButton = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <Button\n type=\"button\"\n className={className}\n data-style=\"ghost\"\n role=\"button\"\n tabIndex={-1}\n aria-label=\"Link\"\n tooltip=\"Link\"\n ref={ref}\n {...props}\n >\n {children || <LinkIcon className=\"tiptap-button-icon\" />}\n </Button>\n )\n }\n)\n\nLinkButton.displayName = \"LinkButton\"\n\n/**\n * Main content component for the link popover\n */\nconst LinkMain: React.FC<LinkMainProps> = ({\n url,\n setUrl,\n setLink,\n removeLink,\n openLink,\n isActive,\n}) => {\n const isMobile = useIsBreakpoint()\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Enter\") {\n event.preventDefault()\n setLink()\n }\n }\n\n return (\n <Card\n style={{\n ...(isMobile ? { boxShadow: \"none\", border: 0 } : {}),\n }}\n >\n <CardBody\n style={{\n ...(isMobile ? { padding: 0 } : {}),\n }}\n >\n <CardItemGroup orientation=\"horizontal\">\n <InputGroup>\n <Input\n type=\"url\"\n placeholder=\"Paste a link...\"\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n onKeyDown={handleKeyDown}\n autoFocus\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n />\n </InputGroup>\n\n <ButtonGroup orientation=\"horizontal\">\n <Button\n type=\"button\"\n onClick={setLink}\n title=\"Apply link\"\n disabled={!url && !isActive}\n data-style=\"ghost\"\n >\n <CornerDownLeftIcon className=\"tiptap-button-icon\" />\n </Button>\n </ButtonGroup>\n\n <Separator />\n\n <ButtonGroup orientation=\"horizontal\">\n <Button\n type=\"button\"\n onClick={openLink}\n title=\"Open in new window\"\n disabled={!url && !isActive}\n data-style=\"ghost\"\n >\n <ExternalLinkIcon className=\"tiptap-button-icon\" />\n </Button>\n\n <Button\n type=\"button\"\n onClick={removeLink}\n title=\"Remove link\"\n disabled={!url && !isActive}\n data-style=\"ghost\"\n >\n <TrashIcon className=\"tiptap-button-icon\" />\n </Button>\n </ButtonGroup>\n </CardItemGroup>\n </CardBody>\n </Card>\n )\n}\n\n/**\n * Link content component for standalone use\n */\nexport const LinkContent: React.FC<{\n editor?: Editor | null\n}> = ({ editor }) => {\n const linkPopover = useLinkPopover({\n editor,\n })\n\n return <LinkMain {...linkPopover} />\n}\n\n/**\n * Link popover component for Tiptap editors.\n *\n * For custom popover implementations, use the `useLinkPopover` hook instead.\n */\nexport const LinkPopover = forwardRef<HTMLButtonElement, LinkPopoverProps>(\n (\n {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onSetLink,\n onOpenChange,\n autoOpenOnLinkActive = true,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState(false)\n\n const {\n isVisible,\n canSet,\n isActive,\n url,\n setUrl,\n setLink,\n removeLink,\n openLink,\n label,\n Icon,\n } = useLinkPopover({\n editor,\n hideWhenUnavailable,\n onSetLink,\n })\n\n const handleOnOpenChange = useCallback(\n (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen)\n onOpenChange?.(nextIsOpen)\n },\n [onOpenChange]\n )\n\n const handleSetLink = useCallback(() => {\n setLink()\n setIsOpen(false)\n }, [setLink])\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n setIsOpen(!isOpen)\n },\n [onClick, isOpen]\n )\n\n useEffect(() => {\n if (autoOpenOnLinkActive && isActive) {\n setIsOpen(true)\n }\n }, [autoOpenOnLinkActive, isActive])\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Popover open={isOpen} onOpenChange={handleOnOpenChange}>\n <PopoverTrigger asChild>\n <LinkButton\n disabled={!canSet}\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canSet}\n aria-label={label}\n aria-pressed={isActive}\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? <Icon className=\"tiptap-button-icon\" />}\n </LinkButton>\n </PopoverTrigger>\n\n <PopoverContent>\n <LinkMain\n url={url}\n setUrl={setUrl}\n setLink={handleSetLink}\n removeLink={removeLink}\n openLink={openLink}\n isActive={isActive}\n />\n </PopoverContent>\n </Popover>\n )\n }\n)\n\nLinkPopover.displayName = \"LinkPopover\"\n\nexport default LinkPopover\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const CornerDownLeftIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M21 4C21 3.44772 20.5523 3 20 3C19.4477 3 19 3.44772 19 4V11C19 11.7956 18.6839 12.5587 18.1213 13.1213C17.5587 13.6839 16.7956 14 16 14H6.41421L9.70711 10.7071C10.0976 10.3166 10.0976 9.68342 9.70711 9.29289C9.31658 8.90237 8.68342 8.90237 8.29289 9.29289L3.29289 14.2929C2.90237 14.6834 2.90237 15.3166 3.29289 15.7071L8.29289 20.7071C8.68342 21.0976 9.31658 21.0976 9.70711 20.7071C10.0976 20.3166 10.0976 19.6834 9.70711 19.2929L6.41421 16H16C17.3261 16 18.5979 15.4732 19.5355 14.5355C20.4732 13.5979 21 12.3261 21 11V4Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nCornerDownLeftIcon.displayName = \"CornerDownLeftIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ExternalLinkIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M14 3C14 2.44772 14.4477 2 15 2H21C21.5523 2 22 2.44772 22 3V9C22 9.55228 21.5523 10 21 10C20.4477 10 20 9.55228 20 9V5.41421L10.7071 14.7071C10.3166 15.0976 9.68342 15.0976 9.29289 14.7071C8.90237 14.3166 8.90237 13.6834 9.29289 13.2929L18.5858 4H15C14.4477 4 14 3.55228 14 3Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M4.29289 7.29289C4.48043 7.10536 4.73478 7 5 7H11C11.5523 7 12 6.55228 12 6C12 5.44772 11.5523 5 11 5H5C4.20435 5 3.44129 5.31607 2.87868 5.87868C2.31607 6.44129 2 7.20435 2 8V19C2 19.7957 2.31607 20.5587 2.87868 21.1213C3.44129 21.6839 4.20435 22 5 22H16C16.7957 22 17.5587 21.6839 18.1213 21.1213C18.6839 20.5587 19 19.7957 19 19V13C19 12.4477 18.5523 12 18 12C17.4477 12 17 12.4477 17 13V19C17 19.2652 16.8946 19.5196 16.7071 19.7071C16.5196 19.8946 16.2652 20 16 20H5C4.73478 20 4.48043 19.8946 4.29289 19.7071C4.10536 19.5196 4 19.2652 4 19V8C4 7.73478 4.10536 7.48043 4.29289 7.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nExternalLinkIcon.displayName = \"ExternalLinkIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const LinkIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M16.9958 1.06669C15.4226 1.05302 13.907 1.65779 12.7753 2.75074L12.765 2.76086L11.045 4.47086C10.6534 4.86024 10.6515 5.49341 11.0409 5.88507C11.4303 6.27673 12.0634 6.27858 12.4551 5.88919L14.1697 4.18456C14.9236 3.45893 15.9319 3.05752 16.9784 3.06662C18.0272 3.07573 19.0304 3.49641 19.772 4.23804C20.5137 4.97967 20.9344 5.98292 20.9435 7.03171C20.9526 8.07776 20.5515 9.08563 19.8265 9.83941L16.833 12.8329C16.4274 13.2386 15.9393 13.5524 15.4019 13.7529C14.8645 13.9533 14.2903 14.0359 13.7181 13.9949C13.146 13.9539 12.5894 13.7904 12.0861 13.5154C11.5827 13.2404 11.1444 12.8604 10.8008 12.401C10.47 11.9588 9.84333 11.8685 9.40108 12.1993C8.95883 12.5301 8.86849 13.1568 9.1993 13.599C9.71464 14.288 10.3721 14.858 11.1272 15.2705C11.8822 15.683 12.7171 15.9283 13.5753 15.9898C14.4334 16.0513 15.2948 15.9274 16.1009 15.6267C16.907 15.326 17.639 14.8555 18.2473 14.247L21.2472 11.2471L21.2593 11.2347C22.3523 10.1031 22.9571 8.58751 22.9434 7.01433C22.9297 5.44115 22.2987 3.93628 21.1863 2.82383C20.0738 1.71138 18.5689 1.08036 16.9958 1.06669Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M10.4247 8.0102C9.56657 7.94874 8.70522 8.07256 7.89911 8.37326C7.09305 8.67395 6.36096 9.14458 5.75272 9.753L2.75285 12.7529L2.74067 12.7653C1.64772 13.8969 1.04295 15.4125 1.05662 16.9857C1.07029 18.5589 1.70131 20.0637 2.81376 21.1762C3.9262 22.2886 5.43108 22.9196 7.00426 22.9333C8.57744 22.947 10.0931 22.3422 11.2247 21.2493L11.2371 21.2371L12.9471 19.5271C13.3376 19.1366 13.3376 18.5034 12.9471 18.1129C12.5565 17.7223 11.9234 17.7223 11.5328 18.1129L9.82932 19.8164C9.07555 20.5414 8.06768 20.9425 7.02164 20.9334C5.97285 20.9243 4.9696 20.5036 4.22797 19.762C3.48634 19.0203 3.06566 18.0171 3.05655 16.9683C3.04746 15.9222 3.44851 14.9144 4.17355 14.1606L7.16719 11.167C7.5727 10.7613 8.06071 10.4476 8.59811 10.2471C9.13552 10.0467 9.70976 9.96412 10.2819 10.0051C10.854 10.0461 11.4106 10.2096 11.9139 10.4846C12.4173 10.7596 12.8556 11.1397 13.1992 11.599C13.53 12.0412 14.1567 12.1316 14.5989 11.8007C15.0412 11.4699 15.1315 10.8433 14.8007 10.401C14.2854 9.71205 13.6279 9.14198 12.8729 8.72948C12.1178 8.31697 11.2829 8.07166 10.4247 8.0102Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nLinkIcon.displayName = \"LinkIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const TrashIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 5V4C7 3.17477 7.40255 2.43324 7.91789 1.91789C8.43324 1.40255 9.17477 1 10 1H14C14.8252 1 15.5668 1.40255 16.0821 1.91789C16.5975 2.43324 17 3.17477 17 4V5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H20V20C20 20.8252 19.5975 21.5668 19.0821 22.0821C18.5668 22.5975 17.8252 23 17 23H7C6.17477 23 5.43324 22.5975 4.91789 22.0821C4.40255 21.5668 4 20.8252 4 20V7H3C2.44772 7 2 6.55228 2 6C2 5.44772 2.44772 5 3 5H7ZM9 4C9 3.82523 9.09745 3.56676 9.33211 3.33211C9.56676 3.09745 9.82523 3 10 3H14C14.1748 3 14.4332 3.09745 14.6679 3.33211C14.9025 3.56676 15 3.82523 15 4V5H9V4ZM6 7V20C6 20.1748 6.09745 20.4332 6.33211 20.6679C6.56676 20.9025 6.82523 21 7 21H17C17.1748 21 17.4332 20.9025 17.6679 20.6679C17.9025 20.4332 18 20.1748 18 20V7H6Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nTrashIcon.displayName = \"TrashIcon\"\n","\"use client\"\n\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/input/input.scss\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input type={type} className={cn(\"tiptap-input\", className)} {...props} />\n )\n}\n\nfunction InputGroup({\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div className={cn(\"tiptap-input-group\", className)} {...props}>\n {children}\n </div>\n )\n}\n\nexport { Input, InputGroup }\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { LinkIcon } from \"../../../components/tiptap-icons/link-icon\"\n\n// --- Lib ---\nimport {\n isMarkInSchema,\n isNodeTypeSelected,\n sanitizeUrl,\n} from \"../../../lib/tiptap-utils\"\n\n/**\n * Configuration for the link popover functionality\n */\nexport interface UseLinkPopoverConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Whether to hide the link popover when not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called when the link is set.\n */\n onSetLink?: () => void\n}\n\n/**\n * Configuration for the link handler functionality\n */\nexport interface LinkHandlerProps {\n /**\n * The Tiptap editor instance.\n */\n editor: Editor | null\n /**\n * Callback function called when the link is set.\n */\n onSetLink?: () => void\n}\n\n/**\n * Checks if a link can be set in the current editor state\n */\nexport function canSetLink(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n\n // The third argument 'true' checks whether the current selection is inside an image caption, and prevents setting a link there\n // If the selection is inside an image caption, we can't set a link\n if (isNodeTypeSelected(editor, [\"image\"], true)) return false\n return editor.can().setMark(\"link\")\n}\n\n/**\n * Checks if a link is currently active in the editor\n */\nexport function isLinkActive(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive(\"link\")\n}\n\n/**\n * Determines if the link button should be shown\n */\nexport function shouldShowLinkButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, hideWhenUnavailable } = props\n\n const linkInSchema = isMarkInSchema(\"link\", editor)\n\n if (!linkInSchema || !editor) {\n return false\n }\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canSetLink(editor)\n }\n\n return true\n}\n\n/**\n * Custom hook for handling link operations in a Tiptap editor\n */\nexport function useLinkHandler(props: LinkHandlerProps) {\n const { editor, onSetLink } = props\n const [url, setUrl] = useState<string | null>(null)\n\n useEffect(() => {\n if (!editor) return\n\n // Get URL immediately on mount\n const { href } = editor.getAttributes(\"link\")\n\n if (isLinkActive(editor) && url === null) {\n setUrl(href || \"\")\n }\n }, [editor, url])\n\n useEffect(() => {\n if (!editor) return\n\n const updateLinkState = () => {\n const { href } = editor.getAttributes(\"link\")\n setUrl(href || \"\")\n }\n\n editor.on(\"selectionUpdate\", updateLinkState)\n return () => {\n editor.off(\"selectionUpdate\", updateLinkState)\n }\n }, [editor])\n\n const setLink = useCallback(() => {\n if (!url || !editor) return\n\n const { selection } = editor.state\n const isEmpty = selection.empty\n\n let chain = editor.chain().focus()\n\n chain = chain.extendMarkRange(\"link\").setLink({ href: url })\n\n if (isEmpty) {\n chain = chain.insertContent({ type: \"text\", text: url })\n }\n\n chain.run()\n\n setUrl(null)\n\n onSetLink?.()\n }, [editor, onSetLink, url])\n\n const removeLink = useCallback(() => {\n if (!editor) return\n editor\n .chain()\n .focus()\n .extendMarkRange(\"link\")\n .unsetLink()\n .setMeta(\"preventAutolink\", true)\n .run()\n setUrl(\"\")\n }, [editor])\n\n const openLink = useCallback(\n (target: string = \"_blank\", features: string = \"noopener,noreferrer\") => {\n if (!url) return\n\n const safeUrl = sanitizeUrl(url, window.location.href)\n if (safeUrl !== \"#\") {\n window.open(safeUrl, target, features)\n }\n },\n [url]\n )\n\n return {\n url: url || \"\",\n setUrl,\n setLink,\n removeLink,\n openLink,\n }\n}\n\n/**\n * Custom hook for link popover state management\n */\nexport function useLinkState(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}) {\n const { editor, hideWhenUnavailable = false } = props\n\n const canSet = canSetLink(editor)\n const isActive = isLinkActive(editor)\n\n const [isVisible, setIsVisible] = useState(true)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(\n shouldShowLinkButton({\n editor,\n hideWhenUnavailable,\n })\n )\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable])\n\n return {\n isVisible,\n canSet,\n isActive,\n }\n}\n\n/**\n * Main hook that provides link popover functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MyLinkButton() {\n * const { isVisible, canSet, isActive, Icon, label } = useLinkPopover()\n *\n * if (!isVisible) return null\n *\n * return <button disabled={!canSet}>Link</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedLinkButton() {\n * const { isVisible, canSet, isActive, Icon, label } = useLinkPopover({\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onSetLink: () => console.log('Link set!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * disabled={!canSet}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * <Icon />\n * {label}\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useLinkPopover(config?: UseLinkPopoverConfig) {\n const {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onSetLink,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n\n const { isVisible, canSet, isActive } = useLinkState({\n editor,\n hideWhenUnavailable,\n })\n\n const linkHandler = useLinkHandler({\n editor,\n onSetLink,\n })\n\n return {\n isVisible,\n canSet,\n isActive,\n label: \"Link\",\n Icon: LinkIcon,\n ...linkHandler,\n }\n}\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type { Mark, UseMarkConfig } from \"../../../components/tiptap-ui/mark-button\"\nimport { MARK_SHORTCUT_KEYS, useMark } from \"../../../components/tiptap-ui/mark-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\nexport interface MarkButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseMarkConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function MarkShortcutBadge({\n type,\n shortcutKeys = MARK_SHORTCUT_KEYS[type],\n}: {\n type: Mark\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for toggling marks in a Tiptap editor.\n *\n * For custom button implementations, use the `useMark` hook instead.\n */\nexport const MarkButton = forwardRef<HTMLButtonElement, MarkButtonProps>(\n (\n {\n editor: providedEditor,\n type,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = false,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n handleMark,\n label,\n canToggle,\n isActive,\n Icon,\n shortcutKeys,\n } = useMark({\n editor,\n type,\n hideWhenUnavailable,\n onToggled,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleMark()\n },\n [handleMark, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n disabled={!canToggle}\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canToggle}\n role=\"button\"\n tabIndex={-1}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <MarkShortcutBadge type={type} shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nMarkButton.displayName = \"MarkButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport { isMarkInSchema, isNodeTypeSelected } from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { BoldIcon } from \"../../../components/tiptap-icons/bold-icon\"\nimport { Code2Icon } from \"../../../components/tiptap-icons/code2-icon\"\nimport { ItalicIcon } from \"../../../components/tiptap-icons/italic-icon\"\nimport { StrikeIcon } from \"../../../components/tiptap-icons/strike-icon\"\nimport { SubscriptIcon } from \"../../../components/tiptap-icons/subscript-icon\"\nimport { SuperscriptIcon } from \"../../../components/tiptap-icons/superscript-icon\"\nimport { UnderlineIcon } from \"../../../components/tiptap-icons/underline-icon\"\n\nexport type Mark =\n | \"bold\"\n | \"italic\"\n | \"strike\"\n | \"code\"\n | \"underline\"\n | \"superscript\"\n | \"subscript\"\n\n/**\n * Configuration for the mark functionality\n */\nexport interface UseMarkConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The type of mark to toggle\n */\n type: Mark\n /**\n * Whether the button should hide when mark is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful mark toggle.\n */\n onToggled?: () => void\n}\n\nexport const markIcons = {\n bold: BoldIcon,\n italic: ItalicIcon,\n underline: UnderlineIcon,\n strike: StrikeIcon,\n code: Code2Icon,\n superscript: SuperscriptIcon,\n subscript: SubscriptIcon,\n}\n\nexport const MARK_SHORTCUT_KEYS: Record<Mark, string> = {\n bold: \"mod+b\",\n italic: \"mod+i\",\n underline: \"mod+u\",\n strike: \"mod+shift+s\",\n code: \"mod+e\",\n superscript: \"mod+.\",\n subscript: \"mod+,\",\n}\n\n/**\n * Checks if a mark can be toggled in the current editor state\n */\nexport function canToggleMark(editor: Editor | null, type: Mark): boolean {\n if (!editor || !editor.isEditable) return false\n if (!isMarkInSchema(type, editor) || isNodeTypeSelected(editor, [\"image\"]))\n return false\n\n return editor.can().toggleMark(type)\n}\n\n/**\n * Checks if a mark is currently active\n */\nexport function isMarkActive(editor: Editor | null, type: Mark): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive(type)\n}\n\n/**\n * Toggles a mark in the editor\n */\nexport function toggleMark(editor: Editor | null, type: Mark): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canToggleMark(editor, type)) return false\n\n return editor.chain().focus().toggleMark(type).run()\n}\n\n/**\n * Determines if the mark button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n type: Mark\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, type, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isMarkInSchema(type, editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleMark(editor, type)\n }\n\n return true\n}\n\n/**\n * Gets the formatted mark name\n */\nexport function getFormattedMarkName(type: Mark): string {\n return type.charAt(0).toUpperCase() + type.slice(1)\n}\n\n/**\n * Custom hook that provides mark functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleBoldButton() {\n * const { isVisible, handleMark } = useMark({ type: \"bold\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleMark}>Bold</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedItalicButton() {\n * const { isVisible, handleMark, label, isActive } = useMark({\n * editor: myEditor,\n * type: \"italic\",\n * hideWhenUnavailable: true,\n * onToggled: () => console.log('Mark toggled!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleMark}\n * aria-pressed={isActive}\n * aria-label={label}\n * >\n * Italic\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useMark(config: UseMarkConfig) {\n const {\n editor: providedEditor,\n type,\n hideWhenUnavailable = false,\n onToggled,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggle = canToggleMark(editor, type)\n const isActive = isMarkActive(editor, type)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, type, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, type, hideWhenUnavailable])\n\n const handleMark = useCallback(() => {\n if (!editor) return false\n\n const success = toggleMark(editor, type)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, type, onToggled])\n\n return {\n isVisible,\n isActive,\n handleMark,\n canToggle,\n label: getFormattedMarkName(type),\n shortcutKeys: MARK_SHORTCUT_KEYS[type],\n Icon: markIcons[type],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const BoldIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M6 2.5C5.17157 2.5 4.5 3.17157 4.5 4V20C4.5 20.8284 5.17157 21.5 6 21.5H15C16.4587 21.5 17.8576 20.9205 18.8891 19.8891C19.9205 18.8576 20.5 17.4587 20.5 16C20.5 14.5413 19.9205 13.1424 18.8891 12.1109C18.6781 11.9 18.4518 11.7079 18.2128 11.5359C19.041 10.5492 19.5 9.29829 19.5 8C19.5 6.54131 18.9205 5.14236 17.8891 4.11091C16.8576 3.07946 15.4587 2.5 14 2.5H6ZM14 10.5C14.663 10.5 15.2989 10.2366 15.7678 9.76777C16.2366 9.29893 16.5 8.66304 16.5 8C16.5 7.33696 16.2366 6.70107 15.7678 6.23223C15.2989 5.76339 14.663 5.5 14 5.5H7.5V10.5H14ZM7.5 18.5V13.5H15C15.663 13.5 16.2989 13.7634 16.7678 14.2322C17.2366 14.7011 17.5 15.337 17.5 16C17.5 16.663 17.2366 17.2989 16.7678 17.7678C16.2989 18.2366 15.663 18.5 15 18.5H7.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nBoldIcon.displayName = \"BoldIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const Code2Icon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M15.4545 4.2983C15.6192 3.77115 15.3254 3.21028 14.7983 3.04554C14.2712 2.88081 13.7103 3.1746 13.5455 3.70175L8.54554 19.7017C8.38081 20.2289 8.6746 20.7898 9.20175 20.9545C9.72889 21.1192 10.2898 20.8254 10.4545 20.2983L15.4545 4.2983Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M6.70711 7.29289C7.09763 7.68342 7.09763 8.31658 6.70711 8.70711L3.41421 12L6.70711 15.2929C7.09763 15.6834 7.09763 16.3166 6.70711 16.7071C6.31658 17.0976 5.68342 17.0976 5.29289 16.7071L1.29289 12.7071C0.902369 12.3166 0.902369 11.6834 1.29289 11.2929L5.29289 7.29289C5.68342 6.90237 6.31658 6.90237 6.70711 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M17.2929 7.29289C17.6834 6.90237 18.3166 6.90237 18.7071 7.29289L22.7071 11.2929C23.0976 11.6834 23.0976 12.3166 22.7071 12.7071L18.7071 16.7071C18.3166 17.0976 17.6834 17.0976 17.2929 16.7071C16.9024 16.3166 16.9024 15.6834 17.2929 15.2929L20.5858 12L17.2929 8.70711C16.9024 8.31658 16.9024 7.68342 17.2929 7.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nCode2Icon.displayName = \"Code2Icon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ItalicIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M15.0222 3H19C19.5523 3 20 3.44772 20 4C20 4.55228 19.5523 5 19 5H15.693L10.443 19H14C14.5523 19 15 19.4477 15 20C15 20.5523 14.5523 21 14 21H9.02418C9.00802 21.0004 8.99181 21.0004 8.97557 21H5C4.44772 21 4 20.5523 4 20C4 19.4477 4.44772 19 5 19H8.30704L13.557 5H10C9.44772 5 9 4.55228 9 4C9 3.44772 9.44772 3 10 3H14.9782C14.9928 2.99968 15.0075 2.99967 15.0222 3Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nItalicIcon.displayName = \"ItalicIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const StrikeIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M9.00039 3H16.0001C16.5524 3 17.0001 3.44772 17.0001 4C17.0001 4.55229 16.5524 5 16.0001 5H9.00011C8.68006 4.99983 8.36412 5.07648 8.07983 5.22349C7.79555 5.37051 7.55069 5.5836 7.36585 5.84487C7.181 6.10614 7.06155 6.40796 7.01754 6.72497C6.97352 7.04198 7.00623 7.36492 7.11292 7.66667C7.29701 8.18737 7.02414 8.75872 6.50344 8.94281C5.98274 9.1269 5.4114 8.85403 5.2273 8.33333C5.01393 7.72984 4.94851 7.08396 5.03654 6.44994C5.12456 5.81592 5.36346 5.21229 5.73316 4.68974C6.10285 4.1672 6.59256 3.74101 7.16113 3.44698C7.72955 3.15303 8.36047 2.99975 9.00039 3Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M18 13H20C20.5523 13 21 12.5523 21 12C21 11.4477 20.5523 11 20 11H4C3.44772 11 3 11.4477 3 12C3 12.5523 3.44772 13 4 13H14C14.7956 13 15.5587 13.3161 16.1213 13.8787C16.6839 14.4413 17 15.2044 17 16C17 16.7956 16.6839 17.5587 16.1213 18.1213C15.5587 18.6839 14.7956 19 14 19H6C5.44772 19 5 19.4477 5 20C5 20.5523 5.44772 21 6 21H14C15.3261 21 16.5979 20.4732 17.5355 19.5355C18.4732 18.5979 19 17.3261 19 16C19 14.9119 18.6453 13.8604 18 13Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nStrikeIcon.displayName = \"StrikeIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const SubscriptIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29289 7.29289C3.68342 6.90237 4.31658 6.90237 4.70711 7.29289L12.7071 15.2929C13.0976 15.6834 13.0976 16.3166 12.7071 16.7071C12.3166 17.0976 11.6834 17.0976 11.2929 16.7071L3.29289 8.70711C2.90237 8.31658 2.90237 7.68342 3.29289 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12.7071 7.29289C13.0976 7.68342 13.0976 8.31658 12.7071 8.70711L4.70711 16.7071C4.31658 17.0976 3.68342 17.0976 3.29289 16.7071C2.90237 16.3166 2.90237 15.6834 3.29289 15.2929L11.2929 7.29289C11.6834 6.90237 12.3166 6.90237 12.7071 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M17.4079 14.3995C18.0284 14.0487 18.7506 13.9217 19.4536 14.0397C20.1566 14.1578 20.7977 14.5138 21.2696 15.0481L21.2779 15.0574L21.2778 15.0575C21.7439 15.5988 22 16.2903 22 17C22 18.0823 21.3962 18.8401 20.7744 19.3404C20.194 19.8073 19.4858 20.141 18.9828 20.378C18.9638 20.387 18.9451 20.3958 18.9266 20.4045C18.4473 20.6306 18.2804 20.7817 18.1922 20.918C18.1773 20.9412 18.1619 20.9681 18.1467 21H21C21.5523 21 22 21.4477 22 22C22 22.5523 21.5523 23 21 23H17C16.4477 23 16 22.5523 16 22C16 21.1708 16.1176 20.4431 16.5128 19.832C16.9096 19.2184 17.4928 18.8695 18.0734 18.5956C18.6279 18.334 19.138 18.0901 19.5207 17.7821C19.8838 17.49 20 17.2477 20 17C20 16.7718 19.9176 16.5452 19.7663 16.3672C19.5983 16.1792 19.3712 16.0539 19.1224 16.0121C18.8722 15.9701 18.6152 16.015 18.3942 16.1394C18.1794 16.2628 18.0205 16.4549 17.9422 16.675C17.7572 17.1954 17.1854 17.4673 16.665 17.2822C16.1446 17.0972 15.8728 16.5254 16.0578 16.005C16.2993 15.3259 16.7797 14.7584 17.4039 14.4018L17.4079 14.3995L17.4079 14.3995Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nSubscriptIcon.displayName = \"SubscriptIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const SuperscriptIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12.7071 7.29289C13.0976 7.68342 13.0976 8.31658 12.7071 8.70711L4.70711 16.7071C4.31658 17.0976 3.68342 17.0976 3.29289 16.7071C2.90237 16.3166 2.90237 15.6834 3.29289 15.2929L11.2929 7.29289C11.6834 6.90237 12.3166 6.90237 12.7071 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29289 7.29289C3.68342 6.90237 4.31658 6.90237 4.70711 7.29289L12.7071 15.2929C13.0976 15.6834 13.0976 16.3166 12.7071 16.7071C12.3166 17.0976 11.6834 17.0976 11.2929 16.7071L3.29289 8.70711C2.90237 8.31658 2.90237 7.68342 3.29289 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M17.405 1.40657C18.0246 1.05456 18.7463 0.92634 19.4492 1.04344C20.1521 1.16054 20.7933 1.51583 21.2652 2.0497L21.2697 2.05469L21.2696 2.05471C21.7431 2.5975 22 3.28922 22 4.00203C22 5.08579 21.3952 5.84326 20.7727 6.34289C20.1966 6.80531 19.4941 7.13675 18.9941 7.37261C18.9714 7.38332 18.9491 7.39383 18.9273 7.40415C18.4487 7.63034 18.2814 7.78152 18.1927 7.91844C18.1778 7.94155 18.1625 7.96834 18.1473 8.00003H21C21.5523 8.00003 22 8.44774 22 9.00003C22 9.55231 21.5523 10 21 10H17C16.4477 10 16 9.55231 16 9.00003C16 8.17007 16.1183 7.44255 16.5138 6.83161C16.9107 6.21854 17.4934 5.86971 18.0728 5.59591C18.6281 5.33347 19.1376 5.09075 19.5208 4.78316C19.8838 4.49179 20 4.25026 20 4.00203C20 3.77192 19.9178 3.54865 19.7646 3.37182C19.5968 3.18324 19.3696 3.05774 19.1205 3.01625C18.8705 2.97459 18.6137 3.02017 18.3933 3.14533C18.1762 3.26898 18.0191 3.45826 17.9406 3.67557C17.7531 4.19504 17.18 4.46414 16.6605 4.27662C16.141 4.0891 15.8719 3.51596 16.0594 2.99649C16.303 2.3219 16.7817 1.76125 17.4045 1.40689L17.405 1.40657Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nSuperscriptIcon.displayName = \"SuperscriptIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const UnderlineIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 4C7 3.44772 6.55228 3 6 3C5.44772 3 5 3.44772 5 4V10C5 11.8565 5.7375 13.637 7.05025 14.9497C8.36301 16.2625 10.1435 17 12 17C13.8565 17 15.637 16.2625 16.9497 14.9497C18.2625 13.637 19 11.8565 19 10V4C19 3.44772 18.5523 3 18 3C17.4477 3 17 3.44772 17 4V10C17 11.3261 16.4732 12.5979 15.5355 13.5355C14.5979 14.4732 13.3261 15 12 15C10.6739 15 9.40215 14.4732 8.46447 13.5355C7.52678 12.5979 7 11.3261 7 10V4ZM4 19C3.44772 19 3 19.4477 3 20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20C21 19.4477 20.5523 19 20 19H4Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nUnderlineIcon.displayName = \"UnderlineIcon\"\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type {\n TextAlign,\n UseTextAlignConfig,\n} from \"../../../components/tiptap-ui/text-align-button\"\nimport {\n TEXT_ALIGN_SHORTCUT_KEYS,\n useTextAlign,\n} from \"../../../components/tiptap-ui/text-align-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\ntype IconComponent = ({ className, ...props }: IconProps) => React.ReactElement\n\nexport interface TextAlignButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseTextAlignConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n /**\n * Optional custom icon component to render instead of the default.\n */\n icon?: React.MemoExoticComponent<IconComponent> | React.FC<IconProps>\n}\n\nexport function TextAlignShortcutBadge({\n align,\n shortcutKeys = TEXT_ALIGN_SHORTCUT_KEYS[align],\n}: {\n align: TextAlign\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for setting text alignment in a Tiptap editor.\n *\n * For custom button implementations, use the `useTextAlign` hook instead.\n */\nexport const TextAlignButton = forwardRef<\n HTMLButtonElement,\n TextAlignButtonProps\n>(\n (\n {\n editor: providedEditor,\n align,\n text,\n hideWhenUnavailable = false,\n onAligned,\n showShortcut = false,\n onClick,\n icon: CustomIcon,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n handleTextAlign,\n label,\n canAlign,\n isActive,\n Icon,\n shortcutKeys,\n } = useTextAlign({\n editor,\n align,\n hideWhenUnavailable,\n onAligned,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleTextAlign()\n },\n [handleTextAlign, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n const RenderIcon = CustomIcon ?? Icon\n\n return (\n <Button\n type=\"button\"\n disabled={!canAlign}\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canAlign}\n role=\"button\"\n tabIndex={-1}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <RenderIcon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <TextAlignShortcutBadge\n align={align}\n shortcutKeys={shortcutKeys}\n />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nTextAlignButton.displayName = \"TextAlignButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { ChainedCommands } from \"@tiptap/react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport {\n isExtensionAvailable,\n isNodeTypeSelected,\n} from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { AlignCenterIcon } from \"../../../components/tiptap-icons/align-center-icon\"\nimport { AlignJustifyIcon } from \"../../../components/tiptap-icons/align-justify-icon\"\nimport { AlignLeftIcon } from \"../../../components/tiptap-icons/align-left-icon\"\nimport { AlignRightIcon } from \"../../../components/tiptap-icons/align-right-icon\"\n\nexport type TextAlign = \"left\" | \"center\" | \"right\" | \"justify\"\n\n/**\n * Configuration for the text align functionality\n */\nexport interface UseTextAlignConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The text alignment to apply.\n */\n align: TextAlign\n /**\n * Whether the button should hide when alignment is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful alignment change.\n */\n onAligned?: () => void\n}\n\nexport const TEXT_ALIGN_SHORTCUT_KEYS: Record<TextAlign, string> = {\n left: \"mod+shift+l\",\n center: \"mod+shift+e\",\n right: \"mod+shift+r\",\n justify: \"mod+shift+j\",\n}\n\nexport const textAlignIcons = {\n left: AlignLeftIcon,\n center: AlignCenterIcon,\n right: AlignRightIcon,\n justify: AlignJustifyIcon,\n}\n\nexport const textAlignLabels: Record<TextAlign, string> = {\n left: \"Align left\",\n center: \"Align center\",\n right: \"Align right\",\n justify: \"Align justify\",\n}\n\n/**\n * Checks if text alignment can be performed in the current editor state\n */\nexport function canSetTextAlign(\n editor: Editor | null,\n align: TextAlign\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (\n !isExtensionAvailable(editor, \"textAlign\") ||\n isNodeTypeSelected(editor, [\"image\", \"horizontalRule\"])\n )\n return false\n\n return editor.can().setTextAlign(align)\n}\n\nexport function hasSetTextAlign(\n commands: ChainedCommands\n): commands is ChainedCommands & {\n setTextAlign: (align: TextAlign) => ChainedCommands\n} {\n return \"setTextAlign\" in commands\n}\n\n/**\n * Checks if the text alignment is currently active\n */\nexport function isTextAlignActive(\n editor: Editor | null,\n align: TextAlign\n): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive({ textAlign: align })\n}\n\n/**\n * Sets text alignment in the editor\n */\nexport function setTextAlign(editor: Editor | null, align: TextAlign): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canSetTextAlign(editor, align)) return false\n\n const chain = editor.chain().focus()\n if (hasSetTextAlign(chain)) {\n return chain.setTextAlign(align).run()\n }\n\n return false\n}\n\n/**\n * Determines if the text align button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n align: TextAlign\n}): boolean {\n const { editor, hideWhenUnavailable, align } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isExtensionAvailable(editor, \"textAlign\")) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canSetTextAlign(editor, align)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides text align functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleAlignButton() {\n * const { isVisible, handleTextAlign } = useTextAlign({ align: \"center\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleTextAlign}>Align Center</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedAlignButton() {\n * const { isVisible, handleTextAlign, label, isActive } = useTextAlign({\n * editor: myEditor,\n * align: \"right\",\n * hideWhenUnavailable: true,\n * onAligned: () => console.log('Text aligned!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleTextAlign}\n * aria-pressed={isActive}\n * aria-label={label}\n * >\n * Align Right\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useTextAlign(config: UseTextAlignConfig) {\n const {\n editor: providedEditor,\n align,\n hideWhenUnavailable = false,\n onAligned,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canAlign = canSetTextAlign(editor, align)\n const isActive = isTextAlignActive(editor, align)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, align, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable, align])\n\n const handleTextAlign = useCallback(() => {\n if (!editor) return false\n\n const success = setTextAlign(editor, align)\n if (success) {\n onAligned?.()\n }\n return success\n }, [editor, align, onAligned])\n\n return {\n isVisible,\n isActive,\n handleTextAlign,\n canAlign,\n label: textAlignLabels[align],\n shortcutKeys: TEXT_ALIGN_SHORTCUT_KEYS[align],\n Icon: textAlignIcons[align],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignCenterIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M6 12C6 11.4477 6.44772 11 7 11H17C17.5523 11 18 11.4477 18 12C18 12.5523 17.5523 13 17 13H7C6.44772 13 6 12.5523 6 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4 18C4 17.4477 4.44772 17 5 17H19C19.5523 17 20 17.4477 20 18C20 18.5523 19.5523 19 19 19H5C4.44772 19 4 18.5523 4 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignCenterIcon.displayName = \"AlignCenterIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignJustifyIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 12C2 11.4477 2.44772 11 3 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H3C2.44772 13 2 12.5523 2 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 18C2 17.4477 2.44772 17 3 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H3C2.44772 19 2 18.5523 2 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignJustifyIcon.displayName = \"AlignJustifyIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignLeftIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 12C2 11.4477 2.44772 11 3 11H15C15.5523 11 16 11.4477 16 12C16 12.5523 15.5523 13 15 13H3C2.44772 13 2 12.5523 2 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 18C2 17.4477 2.44772 17 3 17H17C17.5523 17 18 17.4477 18 18C18 18.5523 17.5523 19 17 19H3C2.44772 19 2 18.5523 2 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignLeftIcon.displayName = \"AlignLeftIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignRightIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 12C8 11.4477 8.44772 11 9 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H9C8.44772 13 8 12.5523 8 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M6 18C6 17.4477 6.44772 17 7 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H7C6.44772 19 6 18.5523 6 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignRightIcon.displayName = \"AlignRightIcon\"\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type {\n UndoRedoAction,\n UseUndoRedoConfig,\n} from \"../../../components/tiptap-ui/undo-redo-button\"\nimport {\n UNDO_REDO_SHORTCUT_KEYS,\n useUndoRedo,\n} from \"../../../components/tiptap-ui/undo-redo-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\nexport interface UndoRedoButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseUndoRedoConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function HistoryShortcutBadge({\n action,\n shortcutKeys = UNDO_REDO_SHORTCUT_KEYS[action],\n}: {\n action: UndoRedoAction\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for triggering undo/redo actions in a Tiptap editor.\n *\n * For custom button implementations, use the `useHistory` hook instead.\n */\nexport const UndoRedoButton = forwardRef<\n HTMLButtonElement,\n UndoRedoButtonProps\n>(\n (\n {\n editor: providedEditor,\n action,\n text,\n hideWhenUnavailable = false,\n onExecuted,\n showShortcut = false,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const { isVisible, handleAction, label, canExecute, Icon, shortcutKeys } =\n useUndoRedo({\n editor,\n action,\n hideWhenUnavailable,\n onExecuted,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleAction()\n },\n [handleAction, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n disabled={!canExecute}\n data-style=\"ghost\"\n data-disabled={!canExecute}\n role=\"button\"\n tabIndex={-1}\n aria-label={label}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <HistoryShortcutBadge\n action={action}\n shortcutKeys={shortcutKeys}\n />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nUndoRedoButton.displayName = \"UndoRedoButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport { isNodeTypeSelected } from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { Redo2Icon } from \"../../../components/tiptap-icons/redo2-icon\"\nimport { Undo2Icon } from \"../../../components/tiptap-icons/undo2-icon\"\n\nexport type UndoRedoAction = \"undo\" | \"redo\"\n\n/**\n * Configuration for the history functionality\n */\nexport interface UseUndoRedoConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The history action to perform (undo or redo).\n */\n action: UndoRedoAction\n /**\n * Whether the button should hide when action is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful action execution.\n */\n onExecuted?: () => void\n}\n\nexport const UNDO_REDO_SHORTCUT_KEYS: Record<UndoRedoAction, string> = {\n undo: \"mod+z\",\n redo: \"mod+shift+z\",\n}\n\nexport const historyActionLabels: Record<UndoRedoAction, string> = {\n undo: \"Undo\",\n redo: \"Redo\",\n}\n\nexport const historyIcons = {\n undo: Undo2Icon,\n redo: Redo2Icon,\n}\n\n/**\n * Checks if a history action can be executed\n */\nexport function canExecuteUndoRedoAction(\n editor: Editor | null,\n action: UndoRedoAction\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (isNodeTypeSelected(editor, [\"image\"])) return false\n\n return action === \"undo\" ? editor.can().undo() : editor.can().redo()\n}\n\n/**\n * Executes a history action on the editor\n */\nexport function executeUndoRedoAction(\n editor: Editor | null,\n action: UndoRedoAction\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canExecuteUndoRedoAction(editor, action)) return false\n\n const chain = editor.chain().focus()\n return action === \"undo\" ? chain.undo().run() : chain.redo().run()\n}\n\n/**\n * Determines if the history button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n action: UndoRedoAction\n}): boolean {\n const { editor, hideWhenUnavailable, action } = props\n\n if (!editor || !editor.isEditable) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canExecuteUndoRedoAction(editor, action)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides history functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleUndoButton() {\n * const { isVisible, handleAction } = useHistory({ action: \"undo\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleAction}>Undo</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedRedoButton() {\n * const { isVisible, handleAction, label } = useHistory({\n * editor: myEditor,\n * action: \"redo\",\n * hideWhenUnavailable: true,\n * onExecuted: () => console.log('Action executed!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleAction}\n * aria-label={label}\n * >\n * Redo\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useUndoRedo(config: UseUndoRedoConfig) {\n const {\n editor: providedEditor,\n action,\n hideWhenUnavailable = false,\n onExecuted,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canExecute = canExecuteUndoRedoAction(editor, action)\n\n useEffect(() => {\n if (!editor) return\n\n const handleUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable, action }))\n }\n\n handleUpdate()\n\n editor.on(\"transaction\", handleUpdate)\n\n return () => {\n editor.off(\"transaction\", handleUpdate)\n }\n }, [editor, hideWhenUnavailable, action])\n\n const handleAction = useCallback(() => {\n if (!editor) return false\n\n const success = executeUndoRedoAction(editor, action)\n if (success) {\n onExecuted?.()\n }\n return success\n }, [editor, action, onExecuted])\n\n return {\n isVisible,\n handleAction,\n canExecute,\n label: historyActionLabels[action],\n shortcutKeys: UNDO_REDO_SHORTCUT_KEYS[action],\n Icon: historyIcons[action],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const Redo2Icon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M15.7071 2.29289C15.3166 1.90237 14.6834 1.90237 14.2929 2.29289C13.9024 2.68342 13.9024 3.31658 14.2929 3.70711L17.5858 7H9.5C7.77609 7 6.12279 7.68482 4.90381 8.90381C3.68482 10.1228 3 11.7761 3 13.5C3 14.3536 3.16813 15.1988 3.49478 15.9874C3.82144 16.7761 4.30023 17.4926 4.90381 18.0962C6.12279 19.3152 7.77609 20 9.5 20H13C13.5523 20 14 19.5523 14 19C14 18.4477 13.5523 18 13 18H9.5C8.30653 18 7.16193 17.5259 6.31802 16.682C5.90016 16.2641 5.56869 15.768 5.34254 15.2221C5.1164 14.6761 5 14.0909 5 13.5C5 12.3065 5.47411 11.1619 6.31802 10.318C7.16193 9.47411 8.30653 9 9.5 9H17.5858L14.2929 12.2929C13.9024 12.6834 13.9024 13.3166 14.2929 13.7071C14.6834 14.0976 15.3166 14.0976 15.7071 13.7071L20.7071 8.70711C21.0976 8.31658 21.0976 7.68342 20.7071 7.29289L15.7071 2.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nRedo2Icon.displayName = \"Redo2Icon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const Undo2Icon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.70711 3.70711C10.0976 3.31658 10.0976 2.68342 9.70711 2.29289C9.31658 1.90237 8.68342 1.90237 8.29289 2.29289L3.29289 7.29289C2.90237 7.68342 2.90237 8.31658 3.29289 8.70711L8.29289 13.7071C8.68342 14.0976 9.31658 14.0976 9.70711 13.7071C10.0976 13.3166 10.0976 12.6834 9.70711 12.2929L6.41421 9H14.5C15.0909 9 15.6761 9.1164 16.2221 9.34254C16.768 9.56869 17.2641 9.90016 17.682 10.318C18.0998 10.7359 18.4313 11.232 18.6575 11.7779C18.8836 12.3239 19 12.9091 19 13.5C19 14.0909 18.8836 14.6761 18.6575 15.2221C18.4313 15.768 18.0998 16.2641 17.682 16.682C17.2641 17.0998 16.768 17.4313 16.2221 17.6575C15.6761 17.8836 15.0909 18 14.5 18H11C10.4477 18 10 18.4477 10 19C10 19.5523 10.4477 20 11 20H14.5C15.3536 20 16.1988 19.8319 16.9874 19.5052C17.7761 19.1786 18.4926 18.6998 19.0962 18.0962C19.6998 17.4926 20.1786 16.7761 20.5052 15.9874C20.8319 15.1988 21 14.3536 21 13.5C21 12.6464 20.8319 11.8012 20.5052 11.0126C20.1786 10.2239 19.6998 9.50739 19.0962 8.90381C18.4926 8.30022 17.7761 7.82144 16.9874 7.49478C16.1988 7.16813 15.3536 7 14.5 7H6.41421L9.70711 3.70711Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nUndo2Icon.displayName = \"Undo2Icon\"\n","\"use client\";\r\n\r\nimport { useCurrentEditor } from \"@tiptap/react\";\r\nimport { useState } from \"react\";\r\nimport { FONT_OPTIONS } from \"../../../lib/font\";\r\nimport { ChevronDown } from \"lucide-react\";\r\n\r\nimport { Button } from \"../../../components/ui/button\";\r\nimport {\r\n Command,\r\n CommandEmpty,\r\n CommandGroup,\r\n CommandInput,\r\n CommandItem,\r\n CommandList,\r\n} from \"../../../components/ui/command\";\r\nimport {\r\n Popover,\r\n PopoverContent,\r\n PopoverTrigger,\r\n} from \"../../../components/ui/popover\";\r\n\r\nexport function FontFamilyDropdown() {\r\n const { editor } = useCurrentEditor();\r\n const [open, setOpen] = useState(false);\r\n\r\n if (!editor) return null;\r\n\r\n // Always enabled — current applied or typing font\r\n const currentFont =\r\n editor.getAttributes(\"textStyle\").fontFamily || \"Font Family\";\r\n\r\n /**\r\n * APPLY FONT LOGIC:\r\n * - If no text selected → Tiptap applies mark, future typing uses same font\r\n * - If text selected → only that selection changes\r\n */\r\n const applyFont = (family: string) => {\r\n if (!editor) return;\r\n\r\n // Remove any stored textStyle marks to avoid conflicts\r\n if (editor.state.storedMarks) {\r\n const textStyleMark = editor.schema.marks.textStyle;\r\n if (textStyleMark) {\r\n editor.view.dispatch(editor.state.tr.removeStoredMark(textStyleMark));\r\n }\r\n }\r\n\r\n // Delay applying font to let Tiptap stabilize\r\n setTimeout(() => {\r\n const success = editor.chain().focus().setFontFamily(family).run();\r\n if (!success) {\r\n console.warn(\"Font not applied:\", family);\r\n }\r\n }, 0);\r\n };\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n variant=\"outlineFontFamily\"\r\n className=\"\r\n min-w-[90px] h-7 px-2 flex items-center justify-between rounded-sm\r\n border-[#a3a3a8] text-[#a3a3a8]\r\n hover:border-[#000] hover:text-[#fff] transition-colors\r\n \"\r\n >\r\n {currentFont}\r\n <ChevronDown className=\"w-4 h-4\" />\r\n </Button>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className=\"w-[300px] p-0\"\r\n align=\"start\"\r\n onInteractOutside={(e) => {\r\n const target = e.target as HTMLElement;\r\n if (target.closest(\".cmd-input-wrapper\")) {\r\n e.preventDefault(); // keep search input focus\r\n }\r\n }}\r\n >\r\n <Command>\r\n <div className=\"cmd-input-wrapper\">\r\n <CommandInput placeholder=\"Search font...\" />\r\n </div>\r\n\r\n <CommandList className=\"max-h-[220px]\">\r\n <CommandEmpty>No font found.</CommandEmpty>\r\n\r\n <CommandGroup>\r\n <CommandItem\r\n key=\"default\"\r\n onSelect={() => {\r\n if (!editor) return;\r\n\r\n if (editor.state.storedMarks) {\r\n const textStyleMark = editor.schema.marks.textStyle;\r\n if (textStyleMark) {\r\n editor.view.dispatch(\r\n editor.state.tr.removeStoredMark(textStyleMark)\r\n );\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n editor.chain().focus().unsetFontFamily().run();\r\n setOpen(false);\r\n }, 0);\r\n }}\r\n className=\"font-sans\"\r\n >\r\n Default\r\n </CommandItem>\r\n\r\n {FONT_OPTIONS.map(({ label, cssFontFamily }) => (\r\n <CommandItem\r\n key={label}\r\n onSelect={() => {\r\n applyFont(label);\r\n setOpen(false);\r\n }}\r\n style={{ fontFamily: cssFontFamily}}\r\n >\r\n {label}\r\n </CommandItem>\r\n ))}\r\n </CommandGroup>\r\n </CommandList>\r\n </Command>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n"," export type FontOption = {\r\n label: string\r\n cssFontFamily:string \r\n }\r\n // --- FINALLY, CREATE LIST ---\r\n export const FONT_OPTIONS: FontOption[] = [\r\n { label: \"Inter\", cssFontFamily: \"Inter\" },\r\n { label: \"Roboto\", cssFontFamily: \"Roboto\" },\r\n { label: \"Open Sans\", cssFontFamily: \"Opensans\" },\r\n { label: \"Poppins\", cssFontFamily: \"Poppins\" },\r\n { label: \"Montserrat\", cssFontFamily: \"Montserrat\" },\r\n { label: \"Lato\", cssFontFamily: \"Lato\" },\r\n { label: \"Oswald\", cssFontFamily: \"Oswald\" },\r\n { label: \"Raleway\", cssFontFamily: \"Raleway\" },\r\n { label: \"Merriweather\", cssFontFamily: \"Merriweather\" },\r\n { label: \"Playfair Display\", cssFontFamily: \"Playfair\" },\r\n { label: \"Ubuntu\", cssFontFamily: \"Ubuntu\" },\r\n { label: \"PT Sans\", cssFontFamily: \"Ptsans\" },\r\n { label: \"Barlow\", cssFontFamily: \"Barlow\" },\r\n { label: \"Fira Sans\", cssFontFamily: \"Fira\" },\r\n { label: \"Nunito\", cssFontFamily: \"Nunito\" },\r\n { label: \"Cabin\", cssFontFamily: \"Cabin\" },\r\n { label: \"Bebas Neue\", cssFontFamily: \"Bebas\" },\r\n { label: \"Source Serif Pro\", cssFontFamily: \"Sourceserif\" },\r\n { label: \"Libre Baskerville\", cssFontFamily: \"Librebask\" },\r\n { label: \"Rubik\", cssFontFamily: \"Rubik\" },\r\n { label: \"Inconsolata\", cssFontFamily: \"Inconsolata\" },\r\n { label: \"Work Sans\", cssFontFamily: \"Worksans\" },\r\n { label: \"Mulish\", cssFontFamily: \"Mulish\" },\r\n { label: \"Quicksand\", cssFontFamily: \"Quicksand\" },\r\n { label: \"Kanit\", cssFontFamily: \"Kanit\" },\r\n { label: \"Teko\", cssFontFamily: \"Teko\" },\r\n { label: \"Josefin Sans\", cssFontFamily: \"Josefin\" },\r\n { label: \"Philosopher\", cssFontFamily: \"Philosopher\" },\r\n { label: \"Dancing Script\", cssFontFamily: \"Dancing\" },\r\n { label: \"Noto Serif\", cssFontFamily: \"Notoserif\" },\r\n { label: \"Manrope\", cssFontFamily: \"Manrope\" },\r\n { label: \"Space Grotesk\", cssFontFamily: \"Spacegrotesk\" },\r\n ]\r\n ","\"use client\"\n\nimport * as React from \"react\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../../components/ui/dialog\"\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n className?: string\n showCloseButton?: boolean\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent\n className={cn(\"overflow-hidden p-0\", className)}\n showCloseButton={showCloseButton}\n >\n <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n data-slot=\"command-input-wrapper\"\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n </div>\n )\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm\"\n {...props}\n />\n )\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"bg-border -mx-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverAnchor({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }\n","\"use client\";\r\n\r\nimport { useState, useEffect } from \"react\";\r\nimport { useCurrentEditor } from \"@tiptap/react\";\r\nimport { HexColorPicker } from \"react-colorful\";\r\nimport { Button } from \"../../../components/ui/button\";\r\nimport { GRADIENT_ROWS_70 } from \"../../../lib/colors\";\r\nimport { debounce } from \"lodash\";\r\n\r\nimport {\r\n Popover,\r\n PopoverTrigger,\r\n PopoverContent,\r\n} from \"../../../components/ui/popover\";\r\nimport { Label } from \"../../../components/ui/label\";\r\nimport React from \"react\";\r\n\r\nexport function ColorPicker({ type = \"text\" }) {\r\n const { editor } = useCurrentEditor();\r\n\r\n const [open, setOpen] = useState(false);\r\n const [color, setColor] = useState(\"#000000\"); // committed color applied to editor\r\n const [showCustom, setShowCustom] = useState(false);\r\n\r\n // temp color inside the custom picker (only committed on OK)\r\n const [tempHex, setTempHex] = useState(\"#000000\");\r\n\r\n const [canApply, setCanApply] = useState(false);\r\n\r\n // ---- Sync editor color ----\r\n useEffect(() => {\r\n const current =\r\n type === \"text\"\r\n ? editor?.getAttributes(\"textStyle\").color || \"#000000\"\r\n : editor?.getAttributes(\"highlight\")?.color || \"#FFFF00\";\r\n\r\n setColor(current);\r\n setTempHex(current);\r\n }, [editor, type]);\r\n\r\n // ---- Selection validation ----\r\n useEffect(() => {\r\n const check = () => {\r\n try {\r\n setCanApply(!editor?.state.selection.empty);\r\n } catch {\r\n setCanApply(false);\r\n }\r\n };\r\n\r\n check();\r\n editor?.on(\"selectionUpdate\", check);\r\n editor?.on(\"transaction\", check);\r\n\r\n return () => {\r\n editor?.off(\"selectionUpdate\", check);\r\n editor?.off(\"transaction\", check);\r\n };\r\n }, [editor]);\r\n\r\n // ---- Apply color to Tiptap (committed) ----\r\n const applyColor = React.useCallback(\r\n (value: string) => {\r\n if (!editor) return;\r\n\r\n // try to remove any stored textStyle mark to avoid stale state (safety)\r\n if (editor.state.storedMarks) {\r\n const textStyleMark = editor.schema.marks.textStyle;\r\n if (textStyleMark) {\r\n editor.view.dispatch(editor.state.tr.removeStoredMark(textStyleMark));\r\n }\r\n }\r\n\r\n // apply color\r\n setTimeout(() => {\r\n editor.chain().focus().setColor(value).run();\r\n setColor(value);\r\n }, 0);\r\n },\r\n [editor]\r\n );\r\n\r\n // small debounce for input typing (doesn't apply to editor; only local use)\r\n const debouncedSetTemp = React.useMemo(\r\n () => debounce((v: string) => setTempHex(v), 50),\r\n []\r\n );\r\n\r\n if (!editor) return null;\r\n\r\n return (\r\n <Popover open={open} onOpenChange={(v) => setOpen(v)}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n variant=\"outlineFontFamily\"\r\n className=\"flex items-center h-7 rounded-sm px-2 border-[#a3a3a8] text-[#a3a3a8] hover:text-white\"\r\n >\r\n Color\r\n <span\r\n className=\"w-3 h-3 ml-2 rounded-sm border border-black/20\"\r\n style={{ backgroundColor: color }}\r\n />\r\n </Button>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className=\"w-[260px] p-3\"\r\n align=\"start\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <Label className=\"text-xs mb-2\">\r\n {type === \"text\" ? \"Text Color\" : \"Highlight Color\"}\r\n </Label>\r\n\r\n {/* ========== COLOR PALETTE ========== */}\r\n {!showCustom && (\r\n <div className=\"flex flex-col gap-3\">\r\n <div className=\"grid grid-cols-7 gap-1\">\r\n {GRADIENT_ROWS_70.map((c) => (\r\n <div\r\n key={c}\r\n onClick={() => {\r\n applyColor(c);\r\n setOpen(false); // keep previous behavior for presets\r\n }}\r\n className=\"w-5 h-5 rounded-lg cursor-pointer border border-black/10 hover:scale-105 transition\"\r\n style={{ backgroundColor: c }}\r\n />\r\n ))}\r\n </div>\r\n\r\n <Button\r\n size=\"sm\"\r\n variant=\"outline\"\r\n onClick={() => {\r\n // open custom picker; ensure tempHex reflects committed color\r\n setTempHex(color);\r\n setShowCustom(true);\r\n }}\r\n >\r\n Custom\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* ========== CUSTOM HEX PICKER ========== */}\r\n {showCustom && (\r\n // stop mouse/pointer events from bubbling so popover doesn't treat them as outside clicks\r\n <div\r\n className=\"flex flex-col gap-3\"\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onMouseUp={(e) => e.stopPropagation()}\r\n onPointerDown={(e) => e.stopPropagation()}\r\n onPointerUp={(e) => e.stopPropagation()}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {/* Only update tempHex on change — do NOT apply to editor yet */}\r\n <HexColorPicker\r\n color={tempHex}\r\n onChange={(v) => {\r\n // immediate local update (no editor apply)\r\n setTempHex(v);\r\n }}\r\n // ensure internal clicks don't bubble out\r\n onMouseDown={(e: any) => e.stopPropagation()}\r\n onMouseUp={(e: any) => e.stopPropagation()}\r\n />\r\n\r\n <div className=\"flex gap-2 items-center\">\r\n <input\r\n value={tempHex}\r\n onChange={(e) => {\r\n // accept typed hex locally; debounce assignment for UX\r\n debouncedSetTemp(e.target.value);\r\n setTempHex(e.target.value);\r\n }}\r\n className=\"w-full px-2 py-1 border rounded text-sm\"\r\n />\r\n\r\n <Button\r\n size=\"sm\"\r\n variant=\"outline\"\r\n onClick={() => {\r\n // discard changes and go back to palette (do not apply)\r\n setTempHex(color);\r\n setShowCustom(false);\r\n }}\r\n >\r\n Back\r\n </Button>\r\n </div>\r\n\r\n <div className=\"flex justify-end mt-2\">\r\n <Button\r\n size=\"sm\"\r\n onClick={() => {\r\n applyColor(tempHex);\r\n setShowCustom(false);\r\n setOpen(false);\r\n \r\n // 🔥 FIX: restore editor focus & selection after popover closes\r\n setTimeout(() => {\r\n editor?.commands.focus();\r\n }, 200);\r\n }}\r\n \r\n \r\n >\r\n OK\r\n </Button>\r\n </div>\r\n </div>\r\n )}\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n","export const GRADIENT_ROWS_70 = [\r\n // ROW 1 — GRAY (Neutral gradient)\r\n \"#ffffff\", \"#f2f2f2\", \"#e6e6e6\", \"#cccccc\", \"#b3b3b3\",\r\n \"#999999\", \"#808080\", \"#666666\", \"#4d4d4d\", \"#333333\",\r\n \r\n // ROW 2 — RED\r\n \"#ffe8e8\", \"#ffc4c4\", \"#ff9e9e\", \"#ff7878\", \"#ff5252\",\r\n \"#ff2d2d\", \"#ff0707\", \"#d30000\", \"#a80000\", \"#7d0000\",\r\n \r\n // ROW 3 — ORANGE\r\n \"#fff1e0\", \"#ffd9b3\", \"#ffc285\", \"#ffab57\", \"#ff9429\",\r\n \"#ff7d00\", \"#e66700\", \"#cc5500\", \"#b24400\", \"#803000\",\r\n \r\n // ROW 4 — YELLOW\r\n \"#fffbe0\", \"#fff4b3\", \"#ffec85\", \"#ffe457\", \"#ffdc29\",\r\n \"#ffd400\", \"#e6be00\", \"#cca900\", \"#b39400\", \"#806e00\",\r\n \r\n // ROW 5 — GREEN\r\n \"#e7ffe8\", \"#c4ffc7\", \"#9effa5\", \"#78ff83\", \"#52ff61\",\r\n \"#2dff3f\", \"#0afc22\", \"#00d51d\", \"#00ad18\", \"#008512\",\r\n \r\n // ROW 6 — BLUE\r\n \"#e4f2ff\", \"#bcdcff\", \"#94c5ff\", \"#6badff\", \"#4396ff\",\r\n \"#1b7eff\", \"#0065e6\", \"#0054bf\", \"#004499\", \"#003373\",\r\n \r\n // ROW 7 — PURPLE\r\n \"#f3e6ff\", \"#dfb5ff\", \"#cb85ff\", \"#b755ff\", \"#a326ff\",\r\n \"#8a0dff\", \"#7600e6\", \"#6300bf\", \"#4f0099\", \"#3c0073\",\r\n ];\r\n ","\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","\"use client\"\r\n\r\nimport { useState } from \"react\"\r\nimport { useCurrentEditor } from \"@tiptap/react\"\r\nimport { FiTable } from \"react-icons/fi\"\r\n\r\n// shadcn UI\r\nimport { Button } from \"../../../components/ui/button\"\r\nimport {\r\n Popover,\r\n PopoverTrigger,\r\n PopoverContent,\r\n} from \"../../../components/ui/popover\"\r\nimport {\r\n Command,\r\n CommandGroup,\r\n CommandItem,\r\n CommandInput,\r\n CommandList,\r\n} from \"../../../components/ui/command\"\r\n\r\nexport function TableDropdownMenu() {\r\n const { editor } = useCurrentEditor()\r\n const [open, setOpen] = useState(false)\r\n\r\n if (!editor) return null\r\n\r\n const handleAction = (action: string) => {\r\n switch (action) {\r\n case \"insert\":\r\n editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()\r\n break\r\n case \"addColBefore\":\r\n editor.chain().focus().addColumnBefore().run()\r\n break\r\n case \"addColAfter\":\r\n editor.chain().focus().addColumnAfter().run()\r\n break\r\n case \"delCol\":\r\n editor.chain().focus().deleteColumn().run()\r\n break\r\n case \"addRowBefore\":\r\n editor.chain().focus().addRowBefore().run()\r\n break\r\n case \"addRowAfter\":\r\n editor.chain().focus().addRowAfter().run()\r\n break\r\n case \"delRow\":\r\n editor.chain().focus().deleteRow().run()\r\n break\r\n case \"merge\":\r\n editor.chain().focus().mergeCells().run()\r\n break\r\n case \"split\":\r\n editor.chain().focus().splitCell().run()\r\n break\r\n case \"deleteTable\":\r\n editor.chain().focus().deleteTable().run()\r\n break\r\n default:\r\n break\r\n }\r\n\r\n setOpen(false) // close dropdown after click\r\n }\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button variant=\"tableButton\" size=\"sm\">\r\n <FiTable size={16} color=\"#a3a3a8\" />\r\n </Button>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent className=\"w-[220px] p-0\" align=\"start\">\r\n <Command>\r\n <CommandInput placeholder=\"Search table actions...\" />\r\n <CommandList className=\"max-h-[260px]\">\r\n <CommandGroup>\r\n\r\n <CommandItem onSelect={() => handleAction(\"insert\")}>\r\n Insert Table\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"addColBefore\")}>\r\n Add Column Before\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"addColAfter\")}>\r\n Add Column After\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"delCol\")}>\r\n Delete Column\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"addRowBefore\")}>\r\n Add Row Before\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"addRowAfter\")}>\r\n Add Row After\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"delRow\")}>\r\n Delete Row\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"merge\")}>\r\n Merge Cells\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"split\")}>\r\n Split Cells\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"deleteTable\")}>\r\n Delete Table\r\n </CommandItem>\r\n\r\n </CommandGroup>\r\n </CommandList>\r\n </Command>\r\n </PopoverContent>\r\n </Popover>\r\n )\r\n}\r\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ArrowLeftIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M12.7071 5.70711C13.0976 5.31658 13.0976 4.68342 12.7071 4.29289C12.3166 3.90237 11.6834 3.90237 11.2929 4.29289L4.29289 11.2929C3.90237 11.6834 3.90237 12.3166 4.29289 12.7071L11.2929 19.7071C11.6834 20.0976 12.3166 20.0976 12.7071 19.7071C13.0976 19.3166 13.0976 18.6834 12.7071 18.2929L7.41421 13L19 13C19.5523 13 20 12.5523 20 12C20 11.4477 19.5523 11 19 11L7.41421 11L12.7071 5.70711Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nArrowLeftIcon.displayName = \"ArrowLeftIcon\"\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\nimport { useThrottledCallback } from \"@/hooks/use-throttled-callback\"\n\nexport interface WindowSizeState {\n /**\n * The width of the window's visual viewport in pixels.\n */\n width: number\n /**\n * The height of the window's visual viewport in pixels.\n */\n height: number\n /**\n * The distance from the top of the visual viewport to the top of the layout viewport.\n * Particularly useful for handling mobile keyboard appearance.\n */\n offsetTop: number\n /**\n * The distance from the left of the visual viewport to the left of the layout viewport.\n */\n offsetLeft: number\n /**\n * The scale factor of the visual viewport.\n * This is useful for scaling elements based on the current zoom level.\n */\n scale: number\n}\n\n/**\n * Hook that tracks the window's visual viewport dimensions, position, and provides\n * a CSS transform for positioning elements.\n *\n * Uses the Visual Viewport API to get accurate measurements, especially important\n * for mobile devices where virtual keyboards can change the visible area.\n * Only updates state when values actually change to optimize performance.\n *\n * @returns An object containing viewport properties and a CSS transform string\n */\nexport function useWindowSize(): WindowSizeState {\n const [windowSize, setWindowSize] = useState<WindowSizeState>({\n width: 0,\n height: 0,\n offsetTop: 0,\n offsetLeft: 0,\n scale: 0,\n })\n\n const handleViewportChange = useThrottledCallback(() => {\n if (typeof window === \"undefined\") return\n\n const vp = window.visualViewport\n if (!vp) return\n\n const {\n width = 0,\n height = 0,\n offsetTop = 0,\n offsetLeft = 0,\n scale = 0,\n } = vp\n\n setWindowSize((prevState) => {\n if (\n width === prevState.width &&\n height === prevState.height &&\n offsetTop === prevState.offsetTop &&\n offsetLeft === prevState.offsetLeft &&\n scale === prevState.scale\n ) {\n return prevState\n }\n\n return { width, height, offsetTop, offsetLeft, scale }\n })\n }, 200)\n\n useEffect(() => {\n const visualViewport = window.visualViewport\n if (!visualViewport) return\n\n visualViewport.addEventListener(\"resize\", handleViewportChange)\n\n handleViewportChange()\n\n return () => {\n visualViewport.removeEventListener(\"resize\", handleViewportChange)\n }\n }, [handleViewportChange])\n\n return windowSize\n}\n","import throttle from \"lodash.throttle\"\n\nimport { useUnmount } from \"@/hooks/use-unmount\"\nimport { useMemo } from \"react\"\n\ninterface ThrottleSettings {\n leading?: boolean | undefined\n trailing?: boolean | undefined\n}\n\nconst defaultOptions: ThrottleSettings = {\n leading: false,\n trailing: true,\n}\n\n/**\n * A hook that returns a throttled callback function.\n *\n * @param fn The function to throttle\n * @param wait The time in ms to wait before calling the function\n * @param dependencies The dependencies to watch for changes\n * @param options The throttle options\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useThrottledCallback<T extends (...args: any[]) => any>(\n fn: T,\n wait = 250,\n dependencies: React.DependencyList = [],\n options: ThrottleSettings = defaultOptions\n): {\n (this: ThisParameterType<T>, ...args: Parameters<T>): ReturnType<T>\n cancel: () => void\n flush: () => void\n} {\n const handler = useMemo(\n () => throttle<T>(fn, wait, options),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n dependencies\n )\n\n useUnmount(() => {\n handler.cancel()\n })\n\n return handler\n}\n\nexport default useThrottledCallback\n","import { useRef, useEffect } from \"react\"\n\n/**\n * Hook that executes a callback when the component unmounts.\n *\n * @param callback Function to be called on component unmount\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const useUnmount = (callback: (...args: Array<any>) => any) => {\n const ref = useRef(callback)\n ref.current = callback\n\n useEffect(\n () => () => {\n ref.current()\n },\n []\n )\n}\n\nexport default useUnmount\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { useThrottledCallback } from \"@/hooks/use-throttled-callback\"\n\nexport type RectState = Omit<DOMRect, \"toJSON\">\n\nexport interface ElementRectOptions {\n /**\n * The element to track. Can be an Element, ref, or selector string.\n * Defaults to document.body if not provided.\n */\n element?: Element | React.RefObject<Element> | string | null\n /**\n * Whether to enable rect tracking\n */\n enabled?: boolean\n /**\n * Throttle delay in milliseconds for rect updates\n */\n throttleMs?: number\n /**\n * Whether to use ResizeObserver for more accurate tracking\n */\n useResizeObserver?: boolean\n}\n\nconst initialRect: RectState = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n}\n\nconst isSSR = typeof window === \"undefined\"\nconst hasResizeObserver = !isSSR && typeof ResizeObserver !== \"undefined\"\n\n/**\n * Helper function to check if code is running on client side\n */\nconst isClientSide = (): boolean => !isSSR\n\n/**\n * Custom hook that tracks an element's bounding rectangle and updates on resize, scroll, etc.\n *\n * @param options Configuration options for element rect tracking\n * @returns The current bounding rectangle of the element\n */\nexport function useElementRect({\n element,\n enabled = true,\n throttleMs = 100,\n useResizeObserver = true,\n}: ElementRectOptions = {}): RectState {\n const [rect, setRect] = useState<RectState>(initialRect)\n\n const getTargetElement = useCallback((): Element | null => {\n if (!enabled || !isClientSide()) return null\n\n if (!element) {\n return document.body\n }\n\n if (typeof element === \"string\") {\n return document.querySelector(element)\n }\n\n if (\"current\" in element) {\n return element.current\n }\n\n return element\n }, [element, enabled])\n\n const updateRect = useThrottledCallback(\n () => {\n if (!enabled || !isClientSide()) return\n\n const targetElement = getTargetElement()\n if (!targetElement) {\n setRect(initialRect)\n return\n }\n\n const newRect = targetElement.getBoundingClientRect()\n setRect({\n x: newRect.x,\n y: newRect.y,\n width: newRect.width,\n height: newRect.height,\n top: newRect.top,\n right: newRect.right,\n bottom: newRect.bottom,\n left: newRect.left,\n })\n },\n throttleMs,\n [enabled, getTargetElement],\n { leading: true, trailing: true }\n )\n\n useEffect(() => {\n if (!enabled || !isClientSide()) {\n setRect(initialRect)\n return\n }\n\n const targetElement = getTargetElement()\n if (!targetElement) return\n\n updateRect()\n\n const cleanup: (() => void)[] = []\n\n if (useResizeObserver && hasResizeObserver) {\n const resizeObserver = new ResizeObserver(() => {\n window.requestAnimationFrame(updateRect)\n })\n resizeObserver.observe(targetElement)\n cleanup.push(() => resizeObserver.disconnect())\n }\n\n const handleUpdate = () => updateRect()\n\n window.addEventListener(\"scroll\", handleUpdate, true)\n window.addEventListener(\"resize\", handleUpdate, true)\n\n cleanup.push(() => {\n window.removeEventListener(\"scroll\", handleUpdate)\n window.removeEventListener(\"resize\", handleUpdate)\n })\n\n return () => {\n cleanup.forEach((fn) => fn())\n setRect(initialRect)\n }\n }, [enabled, getTargetElement, updateRect, useResizeObserver])\n\n return rect\n}\n\n/**\n * Convenience hook for tracking document.body rect\n */\nexport function useBodyRect(\n options: Omit<ElementRectOptions, \"element\"> = {}\n): RectState {\n return useElementRect({\n ...options,\n element: isClientSide() ? document.body : null,\n })\n}\n\n/**\n * Convenience hook for tracking a ref element's rect\n */\nexport function useRefRect<T extends Element>(\n ref: React.RefObject<T>,\n options: Omit<ElementRectOptions, \"element\"> = {}\n): RectState {\n return useElementRect({ ...options, element: ref })\n}\n","\"use client\"\n\nimport type { Editor } from \"@tiptap/react\"\nimport { useWindowSize } from \"@/hooks/use-window-size\"\nimport { useBodyRect } from \"@/hooks/use-element-rect\"\nimport { useEffect } from \"react\"\n\nexport interface CursorVisibilityOptions {\n /**\n * The Tiptap editor instance\n */\n editor?: Editor | null\n /**\n * Reference to the toolbar element that may obscure the cursor\n */\n overlayHeight?: number\n}\n\n/**\n * Custom hook that ensures the cursor remains visible when typing in a Tiptap editor.\n * Automatically scrolls the window when the cursor would be hidden by the toolbar.\n *\n * @param options.editor The Tiptap editor instance\n * @param options.overlayHeight Toolbar height to account for\n * @returns The bounding rect of the body\n */\nexport function useCursorVisibility({\n editor,\n overlayHeight = 0,\n}: CursorVisibilityOptions) {\n const { height: windowHeight } = useWindowSize()\n const rect = useBodyRect({\n enabled: true,\n throttleMs: 100,\n useResizeObserver: true,\n })\n\n useEffect(() => {\n const ensureCursorVisibility = () => {\n if (!editor) return\n\n const { state, view } = editor\n if (!view.hasFocus()) return\n\n // Get current cursor position coordinates\n const { from } = state.selection\n const cursorCoords = view.coordsAtPos(from)\n\n if (windowHeight < rect.height && cursorCoords) {\n const availableSpace = windowHeight - cursorCoords.top\n\n // If the cursor is hidden behind the overlay or offscreen, scroll it into view\n if (availableSpace < overlayHeight) {\n const targetCursorY = Math.max(windowHeight / 2, overlayHeight)\n const currentScrollY = window.scrollY\n const cursorAbsoluteY = cursorCoords.top + currentScrollY\n const newScrollY = cursorAbsoluteY - targetCursorY\n\n window.scrollTo({\n top: Math.max(0, newScrollY),\n behavior: \"smooth\",\n })\n }\n }\n }\n\n ensureCursorVisibility()\n }, [editor, overlayHeight, windowHeight, rect.height])\n\n return rect\n}\n","\"use client\"\r\n\r\nimport type { EditorChangePayload } from \"../../types/editor-payload\"\r\nimport { EditorShell } from \"../editor-shell/EditorShell\"\r\nimport { EditorLayout } from \"../editorLayout/editorLayout\"\r\nimport { SimpleEditor } from \"../tiptap-templates/simple/simple-editor\"\r\n\r\ninterface EditorProps {\r\n onChange?: (payload: EditorChangePayload) => void\r\n className?: string\r\n style?: React.CSSProperties\r\n}\r\n\r\nexport function Editor({ onChange, className, style }: EditorProps) {\r\n return (\r\n <div className={className} style={style}>\r\n <EditorShell>\r\n <EditorLayout onChange={onChange}>\r\n <SimpleEditor />\r\n </EditorLayout>\r\n </EditorShell>\r\n </div>\r\n )\r\n}\r\n","import type { RefObject } from \"react\"\nimport { useEffect, useState } from \"react\"\n\ntype ScrollTarget = RefObject<HTMLElement> | Window | null | undefined\ntype EventTargetWithScroll = Window | HTMLElement | Document\n\ninterface UseScrollingOptions {\n debounce?: number\n fallbackToDocument?: boolean\n}\n\nexport function useScrolling(\n target?: ScrollTarget,\n options: UseScrollingOptions = {}\n): boolean {\n const { debounce = 150, fallbackToDocument = true } = options\n const [isScrolling, setIsScrolling] = useState(false)\n\n useEffect(() => {\n // Resolve element or window\n const element: EventTargetWithScroll =\n target && typeof Window !== \"undefined\" && target instanceof Window\n ? target\n : ((target as RefObject<HTMLElement>)?.current ?? window)\n\n // Mobile: fallback to document when using window\n const eventTarget: EventTargetWithScroll =\n fallbackToDocument &&\n element === window &&\n typeof document !== \"undefined\"\n ? document\n : element\n\n const on = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.addEventListener(event, handler, true)\n\n const off = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.removeEventListener(event, handler)\n\n let timeout: ReturnType<typeof setTimeout>\n const supportsScrollEnd = element === window && \"onscrollend\" in window\n\n const handleScroll: EventListener = () => {\n if (!isScrolling) setIsScrolling(true)\n\n if (!supportsScrollEnd) {\n clearTimeout(timeout)\n timeout = setTimeout(() => setIsScrolling(false), debounce)\n }\n }\n\n const handleScrollEnd: EventListener = () => setIsScrolling(false)\n\n on(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n on(eventTarget, \"scrollend\", handleScrollEnd)\n }\n\n return () => {\n off(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n off(eventTarget, \"scrollend\", handleScrollEnd)\n }\n clearTimeout(timeout)\n }\n }, [target, debounce, fallbackToDocument, isScrolling])\n\n return isScrolling\n}\n","// lib/local-image.ts\r\nexport function fileToBase64(file: File): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader()\r\n reader.readAsDataURL(file)\r\n reader.onload = () => resolve(reader.result as string)\r\n reader.onerror = (error) => reject(error)\r\n })\r\n }\r\n \r\n export function saveImageBase64(key: string, base64: string) {\r\n localStorage.setItem(key, base64)\r\n }\r\n \r\n export function loadImageBase64(key: string): string | null {\r\n return localStorage.getItem(key)\r\n }\r\n "],"mappings":"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","names":["React","import_react_slot","import_class_variance_authority","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","open","import_jsx_runtime","import_react","import_lucide_react","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_core","index_default","import_core","index_default","import_extension_text_style","import_extensions","import_core","import_react","import_react","import_jsx_runtime","Tooltip","TooltipTrigger","TooltipContent","import_core","cn","isMac","import_jsx_runtime","Button","cn","Tooltip","TooltipTrigger","TooltipContent","import_jsx_runtime","import_react","import_react","import_jsx_runtime","Separator","cn","import_react","import_react","import_jsx_runtime","cn","Separator","import_react","import_lucide_react","import_jsx_runtime","editor","import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","Button","ImageUploadNode","import_react","TiptapHorizontalRule","import_react","import_react","import_jsx_runtime","import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","canToggle","Button","import_react","import_state","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","DropdownMenuPrimitive","import_jsx_runtime","DropdownMenu","DropdownMenuTrigger","DropdownMenuItem","cn","DropdownMenuContent","import_react","import_jsx_runtime","cn","import_jsx_runtime","canToggle","DropdownMenu","DropdownMenuTrigger","Button","DropdownMenuContent","DropdownMenuItem","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","Button","import_react","import_react","import_react","import_jsx_runtime","shouldShowButton","import_react","import_react","import_jsx_runtime","canToggle","Button","import_react","import_state","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","canToggle","import_react","import_jsx_runtime","canToggle","DropdownMenu","DropdownMenuTrigger","Button","DropdownMenuContent","DropdownMenuItem","import_react","import_jsx_runtime","canToggle","Button","import_react","import_state","import_react","import_jsx_runtime","shouldShowButton","canToggle","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","cn","import_react","import_jsx_runtime","canColorHighlight","Button","import_react","import_react_hotkeys_hook","shouldShowButton","import_jsx_runtime","Button","Separator","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","Input","cn","import_jsx_runtime","Button","Input","Separator","import_react","import_react","import_jsx_runtime","canToggle","Button","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","canToggle","import_react","import_jsx_runtime","Button","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","import_react","import_jsx_runtime","Button","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","import_react","import_lucide_react","import_lucide_react","import_jsx_runtime","CommandPrimitive","CommandPrimitive","CommandPrimitive","PopoverPrimitive","import_jsx_runtime","Popover","PopoverTrigger","PopoverContent","import_jsx_runtime","Popover","PopoverTrigger","PopoverContent","import_react","import_jsx_runtime","Label","import_react","import_jsx_runtime","React","Popover","PopoverTrigger","PopoverContent","Label","import_react","import_jsx_runtime","Popover","PopoverTrigger","PopoverContent","import_react","import_jsx_runtime","import_react","import_lodash","import_react","import_react","throttle","import_react","import_react","import_jsx_runtime","Button","index_default","Color","Image","ImageUploadNode","editor","import_jsx_runtime","import_react","debounce"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/ui/sidebar.tsx","../src/hooks/use-mobile.ts","../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/input.tsx","../src/components/ui/separator.tsx","../src/components/ui/sheet.tsx","../src/components/ui/tooltip.tsx","../src/components/editor-shell/EditorShell.tsx","../src/components/editorLayout/editorLayout.tsx","../src/components/sidebar/EditorSidebar.tsx","../src/components/ui/dropdown-menu.tsx","../src/contexts/EditorBridge.tsx","../src/components/tiptap-templates/simple/simple-editor.tsx","../node_modules/@tiptap/extension-document/src/document.ts","../node_modules/@tiptap/extension-document/src/index.ts","../node_modules/@tiptap/extension-paragraph/src/paragraph.ts","../node_modules/@tiptap/extension-paragraph/src/index.ts","../node_modules/@tiptap/extension-text/src/text.ts","../node_modules/@tiptap/extension-text/src/index.ts","../src/components/extensions/font-size-stepper.ts","../src/components/tiptap-ui-primitive/button/button.tsx","../src/components/tiptap-ui-primitive/tooltip/tooltip.tsx","../src/lib/tiptap-utils.ts","../src/components/tiptap-ui-primitive/spacer/spacer.tsx","../src/components/tiptap-ui-primitive/toolbar/toolbar.tsx","../src/components/tiptap-ui-primitive/separator/separator.tsx","../src/hooks/use-menu-navigation.ts","../src/hooks/use-composed-ref.ts","../src/components/tiptap-ui-primitive/bubble-menu/bubble-menu.tsx","../src/components/tiptap-node/image-upload-node/image-upload-node-extension.ts","../src/components/tiptap-node/image-upload-node/image-upload-node.tsx","../src/components/tiptap-icons/close-icon.tsx","../src/components/tiptap-node/horizontal-rule-node/horizontal-rule-node-extension.ts","../src/components/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.tsx","../src/components/tiptap-icons/chevron-down-icon.tsx","../src/hooks/use-tiptap-editor.ts","../src/components/tiptap-ui/heading-button/heading-button.tsx","../src/components/tiptap-ui-primitive/badge/badge.tsx","../src/components/tiptap-ui/heading-button/use-heading.ts","../src/components/tiptap-icons/heading-one-icon.tsx","../src/components/tiptap-icons/heading-two-icon.tsx","../src/components/tiptap-icons/heading-three-icon.tsx","../src/components/tiptap-icons/heading-four-icon.tsx","../src/components/tiptap-icons/heading-five-icon.tsx","../src/components/tiptap-icons/heading-six-icon.tsx","../src/components/tiptap-ui-primitive/dropdown-menu/dropdown-menu.tsx","../src/components/tiptap-ui-primitive/card/card.tsx","../src/components/tiptap-ui/heading-dropdown-menu/use-heading-dropdown-menu.ts","../src/components/tiptap-icons/heading-icon.tsx","../src/components/tiptap-ui/image-upload-button/image-upload-button.tsx","../src/components/tiptap-ui/image-upload-button/use-image-upload.ts","../src/hooks/use-is-breakpoint.ts","../src/components/tiptap-icons/image-plus-icon.tsx","../src/components/tiptap-ui/list-dropdown-menu/list-dropdown-menu.tsx","../src/components/tiptap-ui/list-button/list-button.tsx","../src/components/tiptap-ui/list-button/use-list.ts","../src/components/tiptap-icons/list-icon.tsx","../src/components/tiptap-icons/list-ordered-icon.tsx","../src/components/tiptap-icons/list-todo-icon.tsx","../src/components/tiptap-ui/list-dropdown-menu/use-list-dropdown-menu.ts","../src/components/tiptap-ui/blockquote-button/blockquote-button.tsx","../src/components/tiptap-ui/blockquote-button/use-blockquote.ts","../src/components/tiptap-icons/blockquote-icon.tsx","../src/components/tiptap-ui/color-highlight-popover/color-highlight-popover.tsx","../src/components/tiptap-icons/ban-icon.tsx","../src/components/tiptap-icons/highlighter-icon.tsx","../src/components/tiptap-ui-primitive/popover/popover.tsx","../src/components/tiptap-ui/color-highlight-button/color-highlight-button.tsx","../src/components/tiptap-ui/color-highlight-button/use-color-highlight.ts","../src/components/tiptap-ui/link-popover/link-popover.tsx","../src/components/tiptap-icons/corner-down-left-icon.tsx","../src/components/tiptap-icons/external-link-icon.tsx","../src/components/tiptap-icons/link-icon.tsx","../src/components/tiptap-icons/trash-icon.tsx","../src/components/tiptap-ui-primitive/input/input.tsx","../src/components/tiptap-ui/link-popover/use-link-popover.ts","../src/components/tiptap-ui/mark-button/mark-button.tsx","../src/components/tiptap-ui/mark-button/use-mark.ts","../src/components/tiptap-icons/bold-icon.tsx","../src/components/tiptap-icons/code2-icon.tsx","../src/components/tiptap-icons/italic-icon.tsx","../src/components/tiptap-icons/strike-icon.tsx","../src/components/tiptap-icons/subscript-icon.tsx","../src/components/tiptap-icons/superscript-icon.tsx","../src/components/tiptap-icons/underline-icon.tsx","../src/components/tiptap-ui/text-align-button/text-align-button.tsx","../src/components/tiptap-ui/text-align-button/use-text-align.ts","../src/components/tiptap-icons/align-center-icon.tsx","../src/components/tiptap-icons/align-justify-icon.tsx","../src/components/tiptap-icons/align-left-icon.tsx","../src/components/tiptap-icons/align-right-icon.tsx","../src/components/tiptap-ui/undo-redo-button/undo-redo-button.tsx","../src/components/tiptap-ui/undo-redo-button/use-undo-redo.ts","../src/components/tiptap-icons/redo2-icon.tsx","../src/components/tiptap-icons/undo2-icon.tsx","../src/components/tiptap-ui/font-family-dropdown/font-family-dropdown.tsx","../src/lib/font.ts","../src/components/ui/command.tsx","../src/components/ui/popover.tsx","../src/components/tiptap-ui/color-picker/color-picker.tsx","../src/lib/colors.ts","../src/components/ui/label.tsx","../src/components/tiptap-ui/table-dropdown-menu/table-dropdown-menu.tsx","../src/components/tiptap-icons/arrow-left-icon.tsx","../src/hooks/use-window-size.ts","../src/hooks/use-throttled-callback.ts","../src/hooks/use-unmount.ts","../src/hooks/use-element-rect.ts","../src/hooks/use-cursor-visibility.ts","../src/components/editor/editor.tsx","../src/hooks/use-scrolling.ts","../src/lib/editorStorage.ts","../src/lib/local-image.ts"],"sourcesContent":["// Export components\r\nexport { Editor } from \"../src/components/editor/editor\"\r\n\r\n// types are OK to export\r\nexport type {\r\n EditorChangePayload,\r\n EditorChangeSource,\r\n} from \"./types/editor-payload\"\r\n\r\n// Export hooks / context\r\nexport * from './hooks'\r\nexport * from './contexts'\r\nexport * from './lib'\r\nexport * from \"./types/editor-payload\"\r\nimport './styles/index.scss'\r\nimport './styles/_variables.scss'\r\n// Import global CSS\r\nimport './styles/globals.css';\r\nexport * from './components/editor/editor'","\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { PanelLeftIcon } from \"lucide-react\"\n\nimport { useIsMobile } from \"../../hooks/use-mobile\"\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"../../components/ui/button\"\nimport { Input } from \"../../components/ui/input\"\nimport { Separator } from \"../../components/ui/separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"../../components/ui/sheet\"\nimport { Skeleton } from \"../../components/ui/skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../../components/ui/tooltip\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n // React.useEffect(() => {\n // const handleKeyDown = (event: KeyboardEvent) => {\n // if (\n // event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n // (event.metaKey || event.ctrlKey)\n // ) {\n // event.preventDefault()\n // toggleSidebar()\n // }\n // }\n\n // window.addEventListener(\"keydown\", handleKeyDown)\n // return () => window.removeEventListener(\"keydown\", handleKeyDown)\n // }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer text-sidebar-foreground hidden md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"size-7\", className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"bg-background relative flex w-full flex-1 flex-col\",\n \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"bg-background h-8 w-full shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"bg-sidebar-border mx-2 w-auto\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"div\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n \"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot : \"button\"\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n showOnHover &&\n \"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none\",\n \"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n }, [])\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean\n size?: \"sm\" | \"md\"\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n \"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground\",\n size === \"sm\" && \"text-xs\",\n size === \"md\" && \"text-sm\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n","import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outlineFontFamily:\n \"border rounded-sm text-left bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-transparent dark:border-[#a3a3a8] dark:hover:bg-input/50\",\n outline:\n \"border bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-transparent dark:border-input dark:hover:bg-input/50\",\n tableButton:\n \"bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-transparent dark:border-input dark:hover:bg-input/50\",\n secondary: \n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-7 px-4 py-2 has-[>svg]:px-3\",\n colorbuttonsize: \" px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n side === \"right\" &&\n \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n side === \"left\" &&\n \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n side === \"top\" &&\n \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b\",\n side === \"bottom\" &&\n \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t\",\n className\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none\">\n <XIcon className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n )\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","\"use client\"\r\n\r\nimport type { ReactNode } from \"react\"\r\nimport { SidebarProvider } from \"../../components/ui/sidebar\"\r\n\r\ninterface EditorShellProps {\r\n children: ReactNode\r\n}\r\n\r\nexport function EditorShell({ children }: EditorShellProps) {\r\n return (\r\n <div\r\n className=\"\r\n relative\r\n w-full\r\n h-full\r\n overflow-hidden\r\n border\r\n rounded-md\r\n bg-background\r\n \"\r\n data-easyflow-editor\r\n >\r\n <SidebarProvider>\r\n {children}\r\n </SidebarProvider>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\n\r\nimport { useState, useEffect, useRef, useCallback } from \"react\"\r\nimport type { ReactNode } from \"react\"\r\nimport type { Editor } from \"@tiptap/core\"\r\n\r\nimport {\r\n SidebarProvider,\r\n SidebarTrigger,\r\n SidebarInset,\r\n} from \"../../components/ui/sidebar\"\r\n\r\nimport { AppSidebar } from \"../sidebar/EditorSidebar\"\r\nimport { EditorBridgeProvider } from \"../../contexts/EditorBridge\"\r\n// import { loadTabs, saveTabs } from \"../../lib/editorStorage\"\r\n\r\nimport type { EditorTab } from \"../../components/types/editor-tabs\"\r\nimport type { EditorChangePayload, EditorChangeSource } from \"../../types/editor-payload\"\r\n\r\n\r\ninterface EditorLayoutProps {\r\n children: ReactNode\r\n initialTabs?:EditorTab[]\r\n onChange?: (payload: EditorChangePayload) => void\r\n onTabsChange?: (tabs: EditorTab[]) => void\r\n}\r\n\r\nexport function EditorLayout({ children, onChange, initialTabs, onTabsChange }: EditorLayoutProps) {\r\n const [editor, setEditor] = useState<Editor | null>(null)\r\n const [tabs, setTabs] = useState<EditorTab[]>([])\r\n const [activeTabId, setActiveTabId] = useState(\"\")\r\n const [activeSubTabId, setActiveSubTabId] = useState<string | null>(null)\r\n\r\n const debouncedSaveRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n const lastRestoredRef = useRef<{ tabId: string; subTabId: string | null } | null>(null)\r\n const isRestoringRef = useRef(false)\r\n const onChangeDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n\r\n\r\n // Debounced onChange to prevent duplicate calls\r\n const emitChangeDebounced = useCallback(\r\n (payload: EditorChangePayload) => {\r\n if (!onChange) return\r\n\r\n // Clear any pending onChange calls\r\n if (onChangeDebounceRef.current) {\r\n clearTimeout(onChangeDebounceRef.current)\r\n }\r\n\r\n // Debounce onChange calls to avoid duplicates\r\n onChangeDebounceRef.current = setTimeout(() => {\r\n onChange(payload)\r\n }, 100)\r\n },\r\n [onChange]\r\n )\r\n\r\n\r\n const emitChange = useCallback(\r\n (source: EditorChangeSource) => {\r\n if (!onChange) return\r\n\r\n emitChangeDebounced({\r\n tabs,\r\n activeTabId,\r\n activeSubTabId,\r\n source,\r\n })\r\n },\r\n [emitChangeDebounced, tabs, activeTabId, activeSubTabId]\r\n )\r\n /* ---------------- LOAD ---------------- */\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n useEffect(() => {\r\n if (initialTabs?.length === 0) {\r\n setTabs([{ id: \"1\", title: \"Tab 1\", content: null, subtabs: [] }])\r\n setActiveTabId(\"1\")\r\n } else {\r\n setTabs(initialTabs ?? [])\r\n setActiveTabId(initialTabs?.[0]?.id ?? \"\")\r\n }\r\n }, [initialTabs])\r\n\r\n \r\n\r\n\r\n\r\n\r\n /* ---------------- SAVE TO LOCALSTORAGE ---------------- */\r\n\r\n\r\n useEffect(() => {\r\n onTabsChange?.(tabs)\r\n }, [tabs, onTabsChange])\r\n \r\n\r\n \r\n\r\n\r\n /* ---------------- HELPERS ---------------- */\r\n \r\n \r\n // Synchronous save that returns updated tabs\r\n const saveCurrentContent = useCallback(() => {\r\n if (!editor) return tabs\r\n\r\n const json = editor.getJSON()\r\n\r\n const updatedTabs = tabs.map(tab => {\r\n if (tab.id !== activeTabId) return tab\r\n\r\n if (activeSubTabId) {\r\n return {\r\n ...tab,\r\n subtabs: tab.subtabs.map(st =>\r\n st.id === activeSubTabId ? { ...st, content: json } : st\r\n ),\r\n }\r\n }\r\n\r\n return { ...tab, content: json }\r\n })\r\n\r\n return updatedTabs\r\n }, [editor, tabs, activeTabId, activeSubTabId])\r\n\r\n \r\n const saveFromEditor = useCallback(\r\n (editorInstance: Editor, source: EditorChangeSource = \"editor\") => {\r\n const json = editorInstance.getJSON()\r\n \r\n setTabs(prev => {\r\n const updatedTabs = prev.map(tab => {\r\n if (tab.id !== activeTabId) return tab\r\n \r\n if (activeSubTabId) {\r\n return {\r\n ...tab,\r\n subtabs: tab.subtabs.map(st =>\r\n st.id === activeSubTabId\r\n ? { ...st, content: json }\r\n : st\r\n ),\r\n }\r\n }\r\n \r\n return { ...tab, content: json }\r\n })\r\n \r\n // Only emit for editor changes (user typing)\r\n if (source === \"editor\") {\r\n emitChangeDebounced({\r\n tabs: updatedTabs,\r\n activeTabId,\r\n activeSubTabId,\r\n source,\r\n })\r\n }\r\n \r\n return updatedTabs\r\n })\r\n },\r\n [activeTabId, activeSubTabId, emitChangeDebounced]\r\n )\r\n \r\n // Debounced save to avoid excessive writes\r\n \r\n const debouncedSave = useCallback(\r\n (editorInstance: Editor) => {\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n }\r\n \r\n debouncedSaveRef.current = setTimeout(() => {\r\n saveFromEditor(editorInstance, \"editor\")\r\n }, 800)\r\n },\r\n [saveFromEditor]\r\n )\r\n \r\n const addTab = () => {\r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // ✅ Get updated tabs with current content saved\r\n const updatedTabs = saveCurrentContent()\r\n \r\n const id = Date.now().toString()\r\n const newTabs = [\r\n ...updatedTabs,\r\n { id, title: `Tab ${updatedTabs.length + 1}`, content: null, subtabs: [] },\r\n ]\r\n \r\n // Update everything together\r\n setTabs(newTabs)\r\n setActiveTabId(id)\r\n setActiveSubTabId(null)\r\n \r\n // Clear editor after state update\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n\r\n // Single debounced onChange call\r\n emitChangeDebounced({\r\n tabs: newTabs,\r\n activeTabId: id,\r\n activeSubTabId: null,\r\n source: \"add-tab\",\r\n })\r\n }\r\n \r\n const addSubTab = (tabId: string) => {\r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // ✅ Get updated tabs with current content saved\r\n const updatedTabs = saveCurrentContent()\r\n \r\n const subId = Date.now().toString()\r\n \r\n const newTabs = updatedTabs.map(tab =>\r\n tab.id === tabId\r\n ? {\r\n ...tab,\r\n subtabs: [\r\n ...tab.subtabs,\r\n { id: subId, title: \"New Subtab\", content: null },\r\n ],\r\n }\r\n : tab\r\n )\r\n \r\n setTabs(newTabs)\r\n setActiveTabId(tabId)\r\n setActiveSubTabId(subId)\r\n \r\n // Clear editor after state update\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n\r\n emitChangeDebounced({\r\n tabs: newTabs,\r\n activeTabId: tabId,\r\n activeSubTabId: subId,\r\n source: \"add-subtab\",\r\n })\r\n }\r\n \r\n const selectNode = (tabId: string, subId?: string) => {\r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // ✅ Save current content before switching\r\n const updatedTabs = saveCurrentContent()\r\n \r\n setTabs(updatedTabs)\r\n setActiveTabId(tabId)\r\n setActiveSubTabId(subId ?? null)\r\n\r\n emitChangeDebounced({\r\n tabs: updatedTabs,\r\n activeTabId: tabId,\r\n activeSubTabId: subId ?? null,\r\n source: \"tab-switch\",\r\n })\r\n }\r\n \r\n\r\n const renameTab = (id: string, title: string) => {\r\n setTabs((prev) => prev.map((t) => (t.id === id ? { ...t, title } : t)))\r\n }\r\n\r\n const deleteSubTab = (tabId: string, subTabId: string) => {\r\n console.log(\"🗑️ Deleting subtab:\", subTabId)\r\n setTabs((prev) =>\r\n prev.map((tab) => {\r\n if (tab.id !== tabId) return tab\r\n\r\n const remainingSubTabs = tab.subtabs.filter((st) => st.id !== subTabId)\r\n\r\n if (subTabId === activeSubTabId) {\r\n setActiveSubTabId(null)\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n }\r\n \r\n return {\r\n ...tab,\r\n subtabs: remainingSubTabs,\r\n }\r\n })\r\n )\r\n emitChange(\"delete-subtab\")\r\n }\r\n\r\n const renameSubTab = (tabId: string, subTabId: string, title: string) => {\r\n setTabs((prev) =>\r\n prev.map((tab) =>\r\n tab.id === tabId\r\n ? {\r\n ...tab,\r\n subtabs: tab.subtabs.map((st) =>\r\n st.id === subTabId ? { ...st, title } : st\r\n ),\r\n }\r\n : tab\r\n )\r\n )\r\n }\r\n\r\n const deleteTab = (id: string) => {\r\n console.log(\"🗑️ Deleting tab:\", id)\r\n \r\n // Clear any pending debounced saves\r\n if (debouncedSaveRef.current) {\r\n clearTimeout(debouncedSaveRef.current)\r\n debouncedSaveRef.current = null\r\n }\r\n\r\n // Save current content if we're deleting a different tab\r\n const updatedTabs = id === activeTabId ? tabs : saveCurrentContent()\r\n \r\n setTabs((prev) => {\r\n const remaining = (id === activeTabId ? prev : updatedTabs).filter((t) => t.id !== id)\r\n\r\n if (id === activeTabId) {\r\n const next = remaining[0]\r\n setActiveTabId(next?.id ?? \"\")\r\n setActiveSubTabId(null)\r\n if (!next) {\r\n setTimeout(() => {\r\n editor?.commands.clearContent()\r\n }, 0)\r\n }\r\n }\r\n\r\n return remaining\r\n })\r\n \r\n emitChange(\"delete-tab\")\r\n }\r\n\r\n /* ---------------- RESTORE CONTENT ---------------- */\r\n useEffect(() => {\r\n if (!editor) return\r\n\r\n const key = { tabId: activeTabId, subTabId: activeSubTabId }\r\n\r\n if (\r\n lastRestoredRef.current &&\r\n lastRestoredRef.current.tabId === key.tabId &&\r\n lastRestoredRef.current.subTabId === key.subTabId\r\n ) {\r\n return\r\n }\r\n\r\n // Prevent restore during save operations\r\n if (isRestoringRef.current) return\r\n isRestoringRef.current = true\r\n\r\n const tab = tabs.find(t => t.id === activeTabId)\r\n const node = activeSubTabId\r\n ? tab?.subtabs.find(st => st.id === activeSubTabId)\r\n : tab\r\n\r\n if (node?.content) {\r\n editor.commands.setContent(node.content)\r\n } else {\r\n editor.commands.clearContent()\r\n }\r\n\r\n lastRestoredRef.current = key\r\n isRestoringRef.current = false\r\n }, [editor, tabs, activeTabId, activeSubTabId])\r\n\r\n\r\n\r\n return (\r\n <EditorBridgeProvider value={{ \r\n editorContent: editor, \r\n setEditorContent: setEditor,\r\n debouncedSave \r\n }}>\r\n <SidebarProvider>\r\n <div className=\"flex h-screen w-full min-h-0\">\r\n <AppSidebar\r\n tabs={tabs}\r\n activeTabId={activeTabId}\r\n activeSubTabId={activeSubTabId}\r\n canDeleteTab={tabs.length > 1}\r\n onAddTab={addTab}\r\n onAddSubTab={addSubTab}\r\n onSelect={selectNode}\r\n onRename={renameTab}\r\n onDelete={deleteTab}\r\n onRenameSubTab={renameSubTab}\r\n onDeleteSubTab={deleteSubTab}\r\n />\r\n\r\n <SidebarInset className=\"flex flex-col flex-1 min-h-0\">\r\n <header className=\"h-12 flex-shrink-0 border-b\">\r\n <SidebarTrigger />\r\n </header>\r\n\r\n {children}\r\n </SidebarInset>\r\n </div>\r\n </SidebarProvider>\r\n </EditorBridgeProvider>\r\n )\r\n}","\"use client\";\r\n\r\nimport { useState } from \"react\";\r\nimport { MoreHorizontal, Plus, FileText } from \"lucide-react\";\r\nimport { motion, AnimatePresence, Variant } from \"framer-motion\"; // ✨ ADD THIS\r\n\r\nimport {\r\n Sidebar,\r\n SidebarContent,\r\n SidebarGroup,\r\n SidebarGroupLabel,\r\n SidebarMenu,\r\n SidebarMenuItem,\r\n} from \"../../components/ui/sidebar\";\r\n\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n} from \"../../components/ui/dropdown-menu\";\r\n\r\nimport { ChevronRight } from \"lucide-react\";\r\n\r\nimport { Input } from \"../../components/ui/input\";\r\nimport { EditorTab } from \"../../components/types/editor-tabs\";\r\n\r\ninterface EditorSidebarProps {\r\n tabs: EditorTab[];\r\n activeTabId: string;\r\n activeSubTabId: string | null;\r\n canDeleteTab: boolean;\r\n onAddTab: () => void;\r\n onAddSubTab: (tabId: string) => void;\r\n onSelect: (tabId: string, subId?: string) => void;\r\n onRename: (id: string, title: string) => void;\r\n onDelete: (id: string) => void;\r\n onRenameSubTab: (tabId: string, subTabId: string, title: string) => void;\r\n onDeleteSubTab: (tabId: string, subTabId: string) => void;\r\n}\r\n\r\n// ✨ Animation variants\r\nconst tabVariants : any = {\r\n initial: { opacity: 0, x: -20, height: 0 },\r\n animate: { \r\n opacity: 1, \r\n x: 0, \r\n height: \"auto\",\r\n transition: {\r\n duration: 0.3,\r\n ease: \"easeOut\"\r\n }\r\n },\r\n exit: { \r\n opacity: 0, \r\n x: -20, \r\n height: 0,\r\n transition: {\r\n duration: 0.2,\r\n ease: \"easeIn\"\r\n }\r\n }\r\n};\r\n\r\nconst subtabVariants : any = {\r\n initial: { opacity: 0, x: -10, height: 0 },\r\n animate: { \r\n opacity: 1, \r\n x: 0, \r\n height: \"auto\",\r\n transition: {\r\n duration: 0.25,\r\n ease: \"easeOut\"\r\n }\r\n },\r\n exit: { \r\n opacity: 0, \r\n x: -10, \r\n height: 0,\r\n transition: {\r\n duration: 0.15,\r\n ease: \"easeIn\"\r\n }\r\n }\r\n};\r\n\r\nexport function AppSidebar({\r\n tabs,\r\n activeTabId,\r\n activeSubTabId,\r\n canDeleteTab,\r\n onAddTab,\r\n onAddSubTab,\r\n onSelect,\r\n onRename,\r\n onDelete,\r\n onRenameSubTab,\r\n onDeleteSubTab,\r\n}: EditorSidebarProps) {\r\n const [editingId, setEditingId] = useState<string | null>(null);\r\n const [editingSubId, setEditingSubId] = useState<string | null>(null);\r\n const [tempTitle, setTempTitle] = useState(\"\");\r\n const [openTabs, setOpenTabs] = useState<Record<string, boolean>>({});\r\n\r\n /* ---------- Rename helpers ---------- */\r\n\r\n const startRenameTab = (id: string, title: string) => {\r\n setEditingId(id);\r\n setEditingSubId(null);\r\n setTempTitle(title);\r\n };\r\n\r\n const startRenameSubTab = (id: string, title: string) => {\r\n setEditingSubId(id);\r\n setEditingId(null);\r\n setTempTitle(title);\r\n };\r\n\r\n const commitRenameTab = () => {\r\n if (!editingId) return;\r\n onRename(editingId, tempTitle.trim() || \"Untitled\");\r\n setEditingId(null);\r\n };\r\n\r\n const commitRenameSubTab = (tabId: string) => {\r\n if (!editingSubId || !onRenameSubTab) return;\r\n onRenameSubTab(tabId, editingSubId, tempTitle.trim() || \"Untitled\");\r\n setEditingSubId(null);\r\n };\r\n\r\n const toggleTabOpen = (tabId: string) => {\r\n setOpenTabs((prev) => ({\r\n ...prev,\r\n [tabId]: !prev[tabId],\r\n }));\r\n };\r\n\r\n return (\r\n <Sidebar>\r\n <SidebarContent>\r\n <SidebarGroup>\r\n <SidebarGroupLabel className=\"flex items-center justify-between\">\r\n Documents\r\n <button\r\n onClick={onAddTab}\r\n className=\"rounded p-1 transition-all duration-200 hover:bg-accent hover:scale-110\"\r\n aria-label=\"Add new document\"\r\n >\r\n <Plus size={16} />\r\n </button>\r\n </SidebarGroupLabel>\r\n\r\n <SidebarMenu>\r\n {/* ✨ Wrap with AnimatePresence for exit animations */}\r\n <AnimatePresence mode=\"popLayout\">\r\n {tabs.map((tab) => {\r\n const isOpen = openTabs[tab.id];\r\n const hasSubtabs = tab.subtabs.length > 0;\r\n const isActiveTab = tab.id === activeTabId && !activeSubTabId;\r\n\r\n return (\r\n <motion.div\r\n key={tab.id}\r\n variants={tabVariants}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n layout // ✨ Smooth layout shifts\r\n >\r\n <SidebarMenuItem className=\"list-none\">\r\n {/* ---------- TAB ROW ---------- */}\r\n <div\r\n className={`\r\n group flex items-center gap-2 rounded-md px-2 py-1.5\r\n transition-all duration-200 ease-in-out\r\n ${isActiveTab ? \"bg-accent\" : \"hover:bg-accent/50\"}\r\n `}\r\n >\r\n {/* DROPDOWN CHEVRON */}\r\n {hasSubtabs && (\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n toggleTabOpen(tab.id);\r\n }}\r\n className=\"flex h-5 w-5 items-center justify-center rounded transition-all duration-200 hover:bg-accent/80\"\r\n aria-label={\r\n isOpen ? \"Collapse subtabs\" : \"Expand subtabs\"\r\n }\r\n >\r\n <ChevronRight\r\n size={14}\r\n className={`transition-transform duration-300 ease-in-out ${\r\n isOpen ? \"rotate-90\" : \"\"\r\n }`}\r\n />\r\n </button>\r\n )}\r\n\r\n {/* DOC ICON */}\r\n <FileText\r\n size={16}\r\n className={`flex-shrink-0 transition-all duration-200 ${\r\n hasSubtabs ? \"\" : \"ml-5\"\r\n } ${\r\n isActiveTab\r\n ? \"opacity-100\"\r\n : \"opacity-60 group-hover:opacity-100\"\r\n }`}\r\n />\r\n\r\n {/* TAB TITLE / RENAME */}\r\n <div className=\"flex-1 min-w-0\">\r\n {editingId === tab.id ? (\r\n <Input\r\n value={tempTitle}\r\n autoFocus\r\n onChange={(e) => setTempTitle(e.target.value)}\r\n onBlur={commitRenameTab}\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\") commitRenameTab();\r\n if (e.key === \"Escape\") setEditingId(null);\r\n }}\r\n className=\"h-7 transition-all duration-200\"\r\n />\r\n ) : (\r\n <button\r\n className=\"w-full truncate text-left text-sm transition-colors duration-200\"\r\n onClick={() => onSelect(tab.id)}\r\n onDoubleClick={() =>\r\n startRenameTab(tab.id, tab.title)\r\n }\r\n >\r\n {tab.title}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* TAB MENU */}\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <button\r\n className=\"opacity-0 group-hover:opacity-100 rounded p-1 transition-all duration-200 hover:bg-accent/80\"\r\n aria-label=\"Tab options\"\r\n >\r\n <MoreHorizontal size={14} />\r\n </button>\r\n </DropdownMenuTrigger>\r\n\r\n <DropdownMenuContent align=\"end\" className=\"w-40\">\r\n <DropdownMenuItem\r\n onClick={() => {\r\n onAddSubTab(tab.id);\r\n setOpenTabs((prev) => ({\r\n ...prev,\r\n [tab.id]: true,\r\n }));\r\n }}\r\n className=\"cursor-pointer transition-colors duration-150\"\r\n >\r\n Add subtab\r\n </DropdownMenuItem>\r\n\r\n {canDeleteTab && (\r\n <DropdownMenuItem\r\n className=\"text-red-500 cursor-pointer transition-colors duration-150 focus:text-red-600\"\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n onDelete(tab.id);\r\n }}\r\n >\r\n Delete\r\n </DropdownMenuItem>\r\n )}\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n </div>\r\n\r\n {/* ---------- SUBTABS ---------- */}\r\n {hasSubtabs && (\r\n <div\r\n className={`\r\n grid transition-all duration-300 ease-in-out\r\n ${\r\n isOpen\r\n ? \"grid-rows-[1fr] opacity-100\"\r\n : \"grid-rows-[0fr] opacity-0\"\r\n }\r\n `}\r\n >\r\n <div className=\"overflow-hidden\">\r\n <div className=\"pt-1 space-y-1\">\r\n {/* ✨ AnimatePresence for subtabs */}\r\n <AnimatePresence mode=\"popLayout\">\r\n {tab.subtabs.map((st) => {\r\n const isActiveSubTab = st.id === activeSubTabId;\r\n\r\n return (\r\n <motion.div\r\n key={st.id}\r\n variants={subtabVariants}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n layout\r\n className={`\r\n group ml-9 flex items-center gap-2 rounded-md px-2 py-1.5 text-sm\r\n transition-all duration-200 ease-in-out\r\n ${\r\n isActiveSubTab\r\n ? \"bg-accent\"\r\n : \"hover:bg-accent/50\"\r\n }\r\n `}\r\n >\r\n {/* SUBDOC ICON */}\r\n <FileText\r\n size={14}\r\n className={`flex-shrink-0 transition-all duration-200 ${\r\n isActiveSubTab\r\n ? \"opacity-100\"\r\n : \"opacity-50 group-hover:opacity-100\"\r\n }`}\r\n />\r\n\r\n {/* SUBTAB TITLE / RENAME */}\r\n <div className=\"flex-1 min-w-0\">\r\n {editingSubId === st.id ? (\r\n <Input\r\n value={tempTitle}\r\n autoFocus\r\n onChange={(e) =>\r\n setTempTitle(e.target.value)\r\n }\r\n onBlur={() => commitRenameSubTab(tab.id)}\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\")\r\n commitRenameSubTab(tab.id);\r\n if (e.key === \"Escape\")\r\n setEditingSubId(null);\r\n }}\r\n className=\"h-6 transition-all duration-200\"\r\n />\r\n ) : (\r\n <button\r\n className=\"w-full truncate text-left transition-colors duration-200\"\r\n onClick={() => onSelect(tab.id, st.id)}\r\n onDoubleClick={() =>\r\n startRenameSubTab(st.id, st.title)\r\n }\r\n >\r\n {st.title}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* SUBTAB MENU */}\r\n {onDeleteSubTab && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <button\r\n className=\"opacity-0 group-hover:opacity-100 rounded p-1 transition-all duration-200 hover:bg-accent/80\"\r\n aria-label=\"Subtab options\"\r\n >\r\n <MoreHorizontal size={14} />\r\n </button>\r\n </DropdownMenuTrigger>\r\n\r\n <DropdownMenuContent\r\n align=\"end\"\r\n className=\"w-40\"\r\n >\r\n <DropdownMenuItem\r\n className=\"text-red-500 cursor-pointer transition-colors duration-150 focus:text-red-600\"\r\n onClick={() =>\r\n onDeleteSubTab(tab.id, st.id)\r\n }\r\n >\r\n Delete\r\n </DropdownMenuItem>\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </motion.div>\r\n );\r\n })}\r\n </AnimatePresence>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </SidebarMenuItem>\r\n </motion.div>\r\n );\r\n })}\r\n </AnimatePresence>\r\n </SidebarMenu>\r\n </SidebarGroup>\r\n </SidebarContent>\r\n </Sidebar>\r\n );\r\n}\r\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n )\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","\"use client\";\r\n\r\nimport React, { createContext, useContext } from \"react\";\r\nimport type { Editor } from \"@tiptap/core\";\r\n\r\nexport type EditorBridgeValue = {\r\n editorContent: Editor | null;\r\n setEditorContent: (editor: Editor | null) => void;\r\n debouncedSave: (editor: Editor) => void;\r\n};\r\n\r\nconst EditorBridgeContext = createContext<EditorBridgeValue | undefined>(\r\n undefined\r\n);\r\n\r\nexport function EditorBridgeProvider({\r\n children,\r\n value,\r\n}: {\r\n children: React.ReactNode;\r\n value: EditorBridgeValue;\r\n}) {\r\n return (\r\n <EditorBridgeContext.Provider value={value}>\r\n {children}\r\n </EditorBridgeContext.Provider>\r\n );\r\n}\r\n\r\nexport function useEditorBridge() {\r\n const ctx = useContext(EditorBridgeContext);\r\n if (!ctx) {\r\n throw new Error(\"useEditorBridge must be used within EditorBridgeProvider\");\r\n }\r\n return ctx;\r\n}\r\n","\"use client\";\r\n\r\nimport { useEffect, useRef, useState } from \"react\";\r\nimport { EditorContent, EditorContext, useEditor } from \"@tiptap/react\";\r\nimport { useEditorBridge } from \"../../../contexts/EditorBridge\";\r\n\r\n// --- Tiptap Core Extensions ---\r\nimport { StarterKit } from \"@tiptap/starter-kit\";\r\nimport ImageResize from \"tiptap-extension-resize-image\";\r\nimport Image from \"@tiptap/extension-image\";\r\nimport { TaskItem, TaskList } from \"@tiptap/extension-list\";\r\nimport { TextAlign } from \"@tiptap/extension-text-align\";\r\nimport { Typography } from \"@tiptap/extension-typography\";\r\nimport { Highlight } from \"@tiptap/extension-highlight\";\r\nimport { Subscript } from \"@tiptap/extension-subscript\";\r\nimport { Superscript } from \"@tiptap/extension-superscript\";\r\nimport { Gapcursor, Selection } from \"@tiptap/extensions\";\r\nimport { TextStyleKit } from \"@tiptap/extension-text-style\";\r\nimport Document from \"@tiptap/extension-document\";\r\nimport Paragraph from \"@tiptap/extension-paragraph\";\r\nimport Text from \"@tiptap/extension-text\";\r\nimport { FontFamily, TextStyle } from \"@tiptap/extension-text-style\";\r\nimport Color from \"@tiptap/extension-color\";\r\nimport { TableKit } from \"@tiptap/extension-table\";\r\nimport { Dropcursor } from \"@tiptap/extensions\";\r\nimport { FontSizeStepper } from \"../../extensions/font-size-stepper\";\r\n\r\n// --- UI Primitives ---\r\nimport { Button } from \"../../tiptap-ui-primitive/button/button\";\r\nimport { Spacer } from \"../../tiptap-ui-primitive/spacer/spacer\";\r\nimport {\r\n Toolbar,\r\n ToolbarGroup,\r\n ToolbarSeparator,\r\n} from \"../../tiptap-ui-primitive/toolbar/toolbar\";\r\nimport { BubbleMenuInline } from \"../../tiptap-ui-primitive/bubble-menu/bubble-menu\";\r\n\r\n// --- Tiptap Node ---\r\nimport { ImageUploadNode } from \"../../tiptap-node/image-upload-node/image-upload-node-extension\";\r\nimport { HorizontalRule } from \"../../tiptap-node/horizontal-rule-node/horizontal-rule-node-extension\";\r\nimport \"../../tiptap-node/blockquote-node/blockquote-node.scss\";\r\nimport \"../../tiptap-node/code-block-node/code-block-node.scss\";\r\nimport \"../../tiptap-node/horizontal-rule-node/horizontal-rule-node.scss\";\r\nimport \"../../tiptap-node/list-node/list-node.scss\";\r\nimport \"../../tiptap-node/image-node/image-node.scss\";\r\nimport \"../../tiptap-node/heading-node/heading-node.scss\";\r\n\r\n// --- Tiptap UI ---\r\nimport { HeadingDropdownMenu } from \"../../tiptap-ui/heading-dropdown-menu\";\r\nimport { ImageUploadButton } from \"../../tiptap-ui/image-upload-button\";\r\nimport { ListDropdownMenu } from \"../../tiptap-ui/list-dropdown-menu\";\r\nimport { BlockquoteButton } from \"../../tiptap-ui/blockquote-button\";\r\nimport { CodeBlockButton } from \"../../tiptap-ui/code-block-button\";\r\nimport {\r\n ColorHighlightPopover,\r\n ColorHighlightPopoverContent,\r\n ColorHighlightPopoverButton,\r\n} from \"../../tiptap-ui/color-highlight-popover\";\r\nimport {\r\n LinkPopover,\r\n LinkContent,\r\n LinkButton,\r\n} from \"../../tiptap-ui/link-popover\";\r\nimport { MarkButton } from \"../../tiptap-ui/mark-button\";\r\nimport { TextAlignButton } from \"../../tiptap-ui/text-align-button\";\r\nimport { UndoRedoButton } from \"../../tiptap-ui/undo-redo-button\";\r\nimport { FontFamilyDropdown } from \"../../tiptap-ui/font-family-dropdown/font-family-dropdown\";\r\nimport { ColorPicker } from \"../../tiptap-ui/color-picker/color-picker\";\r\nimport { TableDropdownMenu } from \"../../tiptap-ui/table-dropdown-menu/table-dropdown-menu\";\r\n// --- Icons ---\r\nimport { ArrowLeftIcon } from \"../../tiptap-icons/arrow-left-icon\";\r\nimport { HighlighterIcon } from \"../../tiptap-icons/highlighter-icon\";\r\nimport { LinkIcon } from \"../../tiptap-icons/link-icon\";\r\n\r\n// --- Hooks ---\r\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\";\r\nimport { useWindowSize } from \"../../../hooks/use-window-size\";\r\nimport { useCursorVisibility } from \"../../../hooks/use-cursor-visibility\";\r\n\r\n// --- Components ---\r\nimport { ThemeToggle } from \"../../tiptap-templates/simple/theme-toggle\";\r\n\r\n// --- Lib ---\r\nimport { handleImageUpload, MAX_FILE_SIZE } from \"../../../lib/tiptap-utils\";\r\n\r\n// --- Styles ---\r\nimport \"../simple/simple-editor.scss\";\r\n\r\n\r\n\r\nconst MainToolbarContent = ({\r\n onHighlighterClick,\r\n onLinkClick,\r\n isMobile,\r\n}: {\r\n onHighlighterClick: () => void;\r\n onLinkClick: () => void;\r\n isMobile: boolean;\r\n}) => {\r\n return (\r\n <>\r\n <Spacer />\r\n <FontFamilyDropdown />\r\n <ColorPicker type=\"text\" />\r\n <ToolbarGroup>\r\n <MarkButton type=\"bold\" />\r\n <MarkButton type=\"italic\" />\r\n <MarkButton type=\"strike\" />\r\n <MarkButton type=\"code\" />\r\n <MarkButton type=\"underline\" />\r\n <UndoRedoButton action=\"undo\" />\r\n <UndoRedoButton action=\"redo\" />\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n <ToolbarGroup>\r\n <TextAlignButton align=\"left\" />\r\n <TextAlignButton align=\"center\" />\r\n <TextAlignButton align=\"right\" />\r\n <TextAlignButton align=\"justify\" />\r\n {/* <HeadingDropdownMenu levels={[1, 2, 3, 4]} portal={isMobile} />\r\n <ListDropdownMenu\r\n types={[\"bulletList\", \"orderedList\", \"taskList\"]}\r\n portal={isMobile}\r\n />\r\n <BlockquoteButton />\r\n <CodeBlockButton /> */}\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n <ToolbarGroup>\r\n <HeadingDropdownMenu levels={[1, 2, 3, 4]} portal={isMobile} />\r\n <ListDropdownMenu\r\n types={[\"bulletList\", \"orderedList\", \"taskList\"]}\r\n portal={isMobile}\r\n />\r\n <BlockquoteButton />\r\n {/* <ColorPicker type=\"background\" /> */}\r\n </ToolbarGroup>\r\n <ToolbarGroup>\r\n <TableDropdownMenu />\r\n {/* {!isMobile ? (\r\n <ColorHighlightPopover />\r\n ) : (\r\n <ColorHighlightPopoverButton onClick={onHighlighterClick} />\r\n )}\r\n {!isMobile ? <LinkPopover /> : <LinkButton onClick={onLinkClick} />} */}\r\n {/* <MarkButton type=\"superscript\" />\r\n <MarkButton type=\"subscript\" /> */}\r\n </ToolbarGroup>\r\n\r\n <ToolbarGroup>\r\n {/* <TextAlignButton align=\"left\" />\r\n <TextAlignButton align=\"center\" />\r\n <TextAlignButton align=\"right\" />\r\n <TextAlignButton align=\"justify\" /> */}\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n <ToolbarGroup>\r\n <ImageUploadButton text=\"Add\" />\r\n </ToolbarGroup>\r\n\r\n <Spacer />\r\n\r\n {isMobile && <ToolbarSeparator />}\r\n\r\n {/* <ToolbarGroup>\r\n <ThemeToggle />\r\n </ToolbarGroup> */}\r\n </>\r\n );\r\n};\r\n\r\nconst MobileToolbarContent = ({\r\n type,\r\n onBack,\r\n}: {\r\n type: \"highlighter\" | \"link\";\r\n onBack: () => void;\r\n}) => (\r\n <>\r\n <ToolbarGroup>\r\n <Button data-style=\"ghost\" onClick={onBack}>\r\n <ArrowLeftIcon className=\"tiptap-button-icon\" />\r\n {type === \"highlighter\" ? (\r\n <HighlighterIcon className=\"tiptap-button-icon\" />\r\n ) : (\r\n <LinkIcon className=\"tiptap-button-icon\" />\r\n )}\r\n </Button>\r\n </ToolbarGroup>\r\n\r\n <ToolbarSeparator />\r\n\r\n {type === \"highlighter\" ? (\r\n <ColorHighlightPopoverContent />\r\n ) : (\r\n <LinkContent />\r\n )}\r\n </>\r\n);\r\n\r\nexport function SimpleEditor() {\r\n const { setEditorContent, debouncedSave} = useEditorBridge();\r\n const isMobile = useIsBreakpoint();\r\n const { height } = useWindowSize();\r\n const [mobileView, setMobileView] = useState<\"main\" | \"highlighter\" | \"link\">(\r\n \"main\"\r\n );\r\n const toolbarRef = useRef<HTMLDivElement>(null);\r\n\r\n\r\n const editor = useEditor({\r\n immediatelyRender: false,\r\n editorProps: {\r\n attributes: {\r\n autocomplete: \"off\",\r\n autocorrect: \"off\",\r\n autocapitalize: \"off\",\r\n \"aria-label\": \"Main content area, start typing to enter text.\",\r\n class: \"simple-editor\",\r\n },\r\n },\r\n extensions: [\r\n StarterKit.configure({\r\n horizontalRule: false,\r\n link: {\r\n openOnClick: false,\r\n enableClickSelection: true,\r\n },\r\n }),\r\n HorizontalRule,\r\n Document,\r\n Paragraph,\r\n Text,\r\n Gapcursor,\r\n TextStyle,\r\n FontSizeStepper.configure({ step: 2, min: 8, defaultSize: 16 }),\r\n FontFamily.configure({\r\n types: [\"textStyle\"],\r\n }),\r\n Color.configure({ types: [\"textStyle\"] }),\r\n Highlight.configure({ multicolor: true }),\r\n TableKit.configure({\r\n table: { resizable: true },\r\n }),\r\n TextStyleKit,\r\n TextAlign.configure({ types: [\"heading\", \"paragraph\"] }),\r\n TaskList,\r\n TaskItem.configure({ nested: true }),\r\n Highlight.configure({ multicolor: true }),\r\n Image,\r\n Dropcursor,\r\n Typography,\r\n Superscript,\r\n Subscript,\r\n Selection,\r\n ImageUploadNode.configure({\r\n accept: \"image/*\",\r\n maxSize: MAX_FILE_SIZE,\r\n limit: 3,\r\n upload: handleImageUpload,\r\n onError: (error) => console.error(\"Upload failed:\", error),\r\n }),\r\n ],\r\n content: \"\",\r\n onCreate: ({ editor }) => {\r\n console.log(\"🟢 Editor created\");\r\n setEditorContent(editor);\r\n },\r\n onUpdate: ({ editor }) => {\r\n console.log(\"✏️ Editor updated - triggering debounced save\");\r\n debouncedSave(editor);\r\n },\r\n });\r\n\r\n\r\n useEffect(() => {\r\n if (editor) {\r\n console.log(\"🔧 Setting editor content in context\");\r\n setEditorContent(editor);\r\n }\r\n }, [editor, setEditorContent]);\r\n\r\n\r\n \r\n const rect = useCursorVisibility({\r\n editor,\r\n overlayHeight: toolbarRef.current?.getBoundingClientRect().height ?? 0,\r\n });\r\n\r\n \r\n \r\n\r\n useEffect(() => {\r\n if (!isMobile && mobileView !== \"main\") {\r\n setMobileView(\"main\");\r\n }\r\n }, [isMobile, mobileView]);\r\n useEffect(() => {\r\n if (editor) {\r\n editor.commands.focus(\"start\"); // or \"end\"\r\n }\r\n }, [editor]);\r\n\r\n useEffect(() => {\r\n if (!window?.visualViewport) return;\r\n\r\n const toolbar = document.querySelector(\r\n \".tiptap-toolbar[data-variant='fixed']\"\r\n ) as HTMLElement | null;\r\n\r\n if (!toolbar) return;\r\n\r\n const updatePosition = () => {\r\n toolbar.style.top = `${window.visualViewport?.offsetTop}px`;\r\n };\r\n\r\n window.visualViewport.addEventListener(\"resize\", updatePosition);\r\n window.visualViewport.addEventListener(\"scroll\", updatePosition);\r\n\r\n updatePosition();\r\n\r\n return () => {\r\n window.visualViewport?.removeEventListener(\"resize\", updatePosition);\r\n window.visualViewport?.removeEventListener(\"scroll\", updatePosition);\r\n };\r\n }, []);\r\n\r\n return (\r\n <div className=\"simple-editor-wrapper\">\r\n <EditorContext.Provider value={{ editor }}>\r\n <Toolbar\r\n ref={toolbarRef}\r\n style={{\r\n ...(isMobile\r\n ? {\r\n bottom: `calc(100% - ${height - rect.y}px)`,\r\n }\r\n : {}),\r\n }}\r\n >\r\n {mobileView === \"main\" ? (\r\n <MainToolbarContent\r\n onHighlighterClick={() => setMobileView(\"highlighter\")}\r\n onLinkClick={() => setMobileView(\"link\")}\r\n isMobile={isMobile}\r\n />\r\n ) : (\r\n <MobileToolbarContent\r\n type={mobileView === \"highlighter\" ? \"highlighter\" : \"link\"}\r\n onBack={() => setMobileView(\"main\")}\r\n />\r\n )}\r\n </Toolbar>\r\n\r\n <EditorContent\r\n editor={editor}\r\n role=\"presentation\"\r\n autoFocus\r\n className=\"simple-editor-content\"\r\n >\r\n {editor && <BubbleMenuInline />}\r\n </EditorContent>\r\n </EditorContext.Provider>\r\n </div>\r\n );\r\n}\r\n","import { Node } from '@tiptap/core'\n\n/**\n * The default document node which represents the top level node of the editor.\n * @see https://tiptap.dev/api/nodes/document\n */\nexport const Document = Node.create({\n name: 'doc',\n topNode: true,\n content: 'block+',\n\n renderMarkdown: (node, h) => {\n if (!node.content) {\n return ''\n }\n\n return h.renderChildren(node.content, '\\n\\n')\n },\n})\n","import { Document } from './document.js'\n\nexport * from './document.js'\n\nexport default Document\n","import { mergeAttributes, Node } from '@tiptap/core'\n\nexport interface ParagraphOptions {\n /**\n * The HTML attributes for a paragraph node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n paragraph: {\n /**\n * Toggle a paragraph\n * @example editor.commands.toggleParagraph()\n */\n setParagraph: () => ReturnType\n }\n }\n}\n\n/**\n * This extension allows you to create paragraphs.\n * @see https://www.tiptap.dev/api/nodes/paragraph\n */\nexport const Paragraph = Node.create<ParagraphOptions>({\n name: 'paragraph',\n\n priority: 1000,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n group: 'block',\n\n content: 'inline*',\n\n parseHTML() {\n return [{ tag: 'p' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['p', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n parseMarkdown: (token, helpers) => {\n const tokens = token.tokens || []\n\n // Special case: if paragraph contains only a single image token,\n // unwrap it to avoid nesting block elements incorrectly\n if (tokens.length === 1 && tokens[0].type === 'image') {\n // Parse the image token directly as a block element\n return helpers.parseChildren([tokens[0]])\n }\n\n // Convert 'paragraph' token to paragraph node\n return helpers.createNode(\n 'paragraph',\n undefined, // no attributes for paragraph\n helpers.parseInline(tokens),\n )\n },\n\n renderMarkdown: (node, h) => {\n if (!node || !Array.isArray(node.content)) {\n return ''\n }\n\n return h.renderChildren(node.content)\n },\n\n addCommands() {\n return {\n setParagraph:\n () =>\n ({ commands }) => {\n return commands.setNode(this.name)\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Alt-0': () => this.editor.commands.setParagraph(),\n }\n },\n})\n","import { Paragraph } from './paragraph.js'\n\nexport * from './paragraph.js'\n\nexport default Paragraph\n","import { Node } from '@tiptap/core'\n\n/**\n * This extension allows you to create text nodes.\n * @see https://www.tiptap.dev/api/nodes/text\n */\nexport const Text = Node.create({\n name: 'text',\n group: 'inline',\n\n parseMarkdown: token => {\n // Convert 'text' token to text node - text nodes are special as they store text directly\n return {\n type: 'text',\n text: token.text || '',\n }\n },\n\n renderMarkdown: node => node.text || '',\n})\n","import { Text } from './text.js'\n\nexport * from './text.js'\n\nexport default Text\n","// extensions/font-size-stepper.ts\r\nimport { Extension } from \"@tiptap/core\";\r\n\r\nfunction parsePx(value?: string | null): number | null {\r\n if (!value) return null;\r\n const m = /(-?\\d+\\.?\\d*)px/.exec(String(value));\r\n if (!m) return null;\r\n const n = parseFloat(m[1]);\r\n return Number.isFinite(n) ? Math.round(n) : null;\r\n}\r\n\r\nfunction getFontSizeFromResolvedPos(editor: any): number | null {\r\n const { $from } = editor.state.selection;\r\n // Check marks at the resolved position\r\n const marks = $from.marks();\r\n for (const m of marks) {\r\n if (m.type && m.type.name === \"textStyle\" && m.attrs && m.attrs.fontSize) {\r\n const parsed = parsePx(m.attrs.fontSize);\r\n if (parsed !== null) return parsed;\r\n }\r\n }\r\n\r\n // As a last resort, check node attrs (rare)\r\n const node = editor.state.doc.nodeAt($from.pos);\r\n if (node && node.attrs && node.attrs.style) {\r\n const style = node.attrs.style;\r\n const m = /font-size\\s*:\\s*([^;]+)/i.exec(style);\r\n if (m && m[1]) {\r\n const parsed = parsePx(m[1].trim());\r\n if (parsed !== null) return parsed;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport const FontSizeStepper = Extension.create({\r\n name: \"fontSizeStepper\",\r\n\r\n // configuration option to control step & min size\r\n addOptions() {\r\n return {\r\n step: 2,\r\n min: 8,\r\n defaultSize: 16,\r\n };\r\n },\r\n\r\n addCommands() {\r\n return {\r\n increaseFontSize:\r\n () =>\r\n ({ commands, editor }) => {\r\n if (!editor) return false;\r\n\r\n // 1) prefer active textStyle attribute\r\n const attrs = editor.getAttributes(\"textStyle\") || {};\r\n let currentPx = parsePx(attrs.fontSize ?? null);\r\n\r\n // 2) fallback to marks/node at selection\r\n if (currentPx === null) {\r\n currentPx = getFontSizeFromResolvedPos(editor);\r\n }\r\n\r\n // 3) final fallback to sensible default (not tiny 8px)\r\n if (currentPx === null) {\r\n currentPx = this.options.defaultSize;\r\n }\r\n\r\n const newSize = currentPx + this.options.step;\r\n return commands.setFontSize(`${newSize}px`);\r\n },\r\n\r\n decreaseFontSize:\r\n () =>\r\n ({ commands, editor }) => {\r\n if (!editor) return false;\r\n\r\n const attrs = editor.getAttributes(\"textStyle\") || {};\r\n let currentPx = parsePx(attrs.fontSize ?? null);\r\n\r\n if (currentPx === null) {\r\n currentPx = getFontSizeFromResolvedPos(editor);\r\n }\r\n\r\n \r\n if (currentPx === null) {\r\n currentPx = this.options.defaultSize;\r\n }\r\n\r\n const newSize = Math.max(this.options.min, currentPx! - this.options.step);\r\n return commands.setFontSize(`${newSize}px`);\r\n \r\n },\r\n };\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n // Increase: Mod + Shift + . => '>' (Shift + .) — Mod maps to Ctrl/Cmd\r\n \"Mod-Shift-.\": () => this.editor.commands.increaseFontSize(),\r\n // Decrease: Mod + Shift + , => '<' (Shift + ,)\r\n \"Mod-Shift-,\": () => this.editor.commands.decreaseFontSize(),\r\n // Optional extra bindings for explicit Ctrl (if you want):\r\n // \"Ctrl-Shift-.\": () => this.editor.commands.increaseFontSize(),\r\n // \"Ctrl-Shift-,\": () => this.editor.commands.decreaseFontSize(),\r\n };\r\n },\r\n});\r\n","\"use client\"\n\nimport { forwardRef, Fragment, useMemo } from \"react\"\n\n// --- Tiptap UI Primitive ---\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../../../components/tiptap-ui-primitive/tooltip\"\n\n// --- Lib ---\nimport { cn, parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\nimport \"../../../components/tiptap-ui-primitive/button/button-colors.scss\"\nimport \"../../../components/tiptap-ui-primitive/button/button-group.scss\"\nimport \"../../../components/tiptap-ui-primitive/button/button.scss\"\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string\n showTooltip?: boolean\n tooltip?: React.ReactNode\n shortcutKeys?: string\n}\n\nexport const ShortcutDisplay: React.FC<{ shortcuts: string[] }> = ({\n shortcuts,\n}) => {\n if (shortcuts.length === 0) return null\n\n return (\n <div>\n {shortcuts.map((key, index) => (\n <Fragment key={index}>\n {index > 0 && <kbd>+</kbd>}\n <kbd>{key}</kbd>\n </Fragment>\n ))}\n </div>\n )\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n children,\n tooltip,\n showTooltip = true,\n shortcutKeys,\n \"aria-label\": ariaLabel,\n ...props\n },\n ref\n ) => {\n const shortcuts = useMemo<string[]>(\n () => parseShortcutKeys({ shortcutKeys }),\n [shortcutKeys]\n )\n\n if (!tooltip || !showTooltip) {\n return (\n <button\n className={cn(\"tiptap-button\", className)}\n ref={ref}\n aria-label={ariaLabel}\n {...props}\n >\n {children}\n </button>\n )\n }\n\n return (\n <Tooltip delay={200}>\n <TooltipTrigger\n className={cn(\"tiptap-button\", className)}\n ref={ref}\n aria-label={ariaLabel}\n {...props}\n >\n {children}\n </TooltipTrigger>\n <TooltipContent>\n {tooltip}\n <ShortcutDisplay shortcuts={shortcuts} />\n </TooltipContent>\n </Tooltip>\n )\n }\n)\n\nButton.displayName = \"Button\"\n\nexport const ButtonGroup = forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> & {\n orientation?: \"horizontal\" | \"vertical\"\n }\n>(({ className, children, orientation = \"vertical\", ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-button-group\", className)}\n data-orientation={orientation}\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n )\n})\nButtonGroup.displayName = \"ButtonGroup\"\n\nexport default Button\n","\"use client\"\n\nimport {\n cloneElement,\n createContext,\n forwardRef,\n isValidElement,\n useContext,\n useMemo,\n useState,\n version,\n} from \"react\"\nimport {\n useFloating,\n autoUpdate,\n offset,\n flip,\n shift,\n useHover,\n useFocus,\n useDismiss,\n useRole,\n useInteractions,\n useMergeRefs,\n FloatingPortal,\n type Placement,\n type UseFloatingReturn,\n type ReferenceType,\n FloatingDelayGroup,\n} from \"@floating-ui/react\"\nimport \"../../../components/tiptap-ui-primitive/tooltip/tooltip.scss\"\n\ninterface TooltipProviderProps {\n children: React.ReactNode\n initialOpen?: boolean\n placement?: Placement\n open?: boolean\n onOpenChange?: (open: boolean) => void\n delay?: number\n closeDelay?: number\n timeout?: number\n useDelayGroup?: boolean\n}\n\ninterface TooltipTriggerProps\n extends Omit<React.HTMLProps<HTMLElement>, \"ref\"> {\n asChild?: boolean\n children: React.ReactNode\n}\n\ninterface TooltipContentProps\n extends Omit<React.HTMLProps<HTMLDivElement>, \"ref\"> {\n children?: React.ReactNode\n portal?: boolean\n portalProps?: Omit<React.ComponentProps<typeof FloatingPortal>, \"children\">\n}\n\ninterface TooltipContextValue extends UseFloatingReturn<ReferenceType> {\n open: boolean\n setOpen: (open: boolean) => void\n getReferenceProps: (\n userProps?: React.HTMLProps<HTMLElement>\n ) => Record<string, unknown>\n getFloatingProps: (\n userProps?: React.HTMLProps<HTMLDivElement>\n ) => Record<string, unknown>\n}\n\nfunction useTooltip({\n initialOpen = false,\n placement = \"top\",\n open: controlledOpen,\n onOpenChange: setControlledOpen,\n delay = 600,\n closeDelay = 0,\n}: Omit<TooltipProviderProps, \"children\"> = {}) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState<boolean>(initialOpen)\n\n const open = controlledOpen ?? uncontrolledOpen\n const setOpen = setControlledOpen ?? setUncontrolledOpen\n\n const data = useFloating({\n placement,\n open,\n onOpenChange: setOpen,\n whileElementsMounted: autoUpdate,\n middleware: [\n offset(4),\n flip({\n crossAxis: placement.includes(\"-\"),\n fallbackAxisSideDirection: \"start\",\n padding: 4,\n }),\n shift({ padding: 4 }),\n ],\n })\n\n const context = data.context\n\n const hover = useHover(context, {\n mouseOnly: true,\n move: false,\n restMs: delay,\n enabled: controlledOpen == null,\n delay: {\n close: closeDelay,\n },\n })\n const focus = useFocus(context, {\n enabled: controlledOpen == null,\n })\n const dismiss = useDismiss(context)\n const role = useRole(context, { role: \"tooltip\" })\n\n const interactions = useInteractions([hover, focus, dismiss, role])\n\n return useMemo(\n () => ({\n open,\n setOpen,\n ...interactions,\n ...data,\n }),\n [open, setOpen, interactions, data]\n )\n}\n\nconst TooltipContext = createContext<TooltipContextValue | null>(null)\n\nfunction useTooltipContext() {\n const context = useContext(TooltipContext)\n\n if (context == null) {\n throw new Error(\"Tooltip components must be wrapped in <TooltipProvider />\")\n }\n\n return context\n}\n\nexport function Tooltip({ children, ...props }: TooltipProviderProps) {\n const tooltip = useTooltip(props)\n\n if (!props.useDelayGroup) {\n return (\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n )\n }\n\n return (\n <FloatingDelayGroup\n delay={{ open: props.delay ?? 0, close: props.closeDelay ?? 0 }}\n timeoutMs={props.timeout}\n >\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n </FloatingDelayGroup>\n )\n}\n\nexport const TooltipTrigger = forwardRef<HTMLElement, TooltipTriggerProps>(\n function TooltipTrigger({ children, asChild = false, ...props }, propRef) {\n const context = useTooltipContext()\n const childrenRef = isValidElement(children)\n ? parseInt(version, 10) >= 19\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (children as { props: { ref?: React.Ref<any> } }).props.ref\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (children as any).ref\n : undefined\n const ref = useMergeRefs([context.refs.setReference, propRef, childrenRef])\n\n if (asChild && isValidElement(children)) {\n const dataAttributes = {\n \"data-tooltip-state\": context.open ? \"open\" : \"closed\",\n }\n\n return cloneElement(\n children,\n context.getReferenceProps({\n ref,\n ...props,\n ...(typeof children.props === \"object\" ? children.props : {}),\n ...dataAttributes,\n })\n )\n }\n\n return (\n <button\n ref={ref}\n data-tooltip-state={context.open ? \"open\" : \"closed\"}\n {...context.getReferenceProps(props)}\n >\n {children}\n </button>\n )\n }\n)\n\nexport const TooltipContent = forwardRef<HTMLDivElement, TooltipContentProps>(\n function TooltipContent(\n { style, children, portal = true, portalProps = {}, ...props },\n propRef\n ) {\n const context = useTooltipContext()\n const ref = useMergeRefs([context.refs.setFloating, propRef])\n\n if (!context.open) return null\n\n const content = (\n <div\n ref={ref}\n style={{\n ...context.floatingStyles,\n ...style,\n }}\n {...context.getFloatingProps(props)}\n className=\"tiptap-tooltip\"\n >\n {children}\n </div>\n )\n\n if (portal) {\n return <FloatingPortal {...portalProps}>{content}</FloatingPortal>\n }\n\n return content\n }\n)\n\nTooltip.displayName = \"Tooltip\"\nTooltipTrigger.displayName = \"TooltipTrigger\"\nTooltipContent.displayName = \"TooltipContent\"\n","import type { Node as TiptapNode } from \"@tiptap/pm/model\"\nimport type { Transaction } from \"@tiptap/pm/state\"\nimport {\n AllSelection,\n NodeSelection,\n Selection,\n TextSelection,\n} from \"@tiptap/pm/state\"\nimport type { Editor, NodeWithPos } from \"@tiptap/react\"\nimport { Extension } from \"@tiptap/core\"\n\nexport const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB\n\nexport const MAC_SYMBOLS: Record<string, string> = {\n mod: \"⌘\",\n command: \"⌘\",\n meta: \"⌘\",\n ctrl: \"⌃\",\n control: \"⌃\",\n alt: \"⌥\",\n option: \"⌥\",\n shift: \"⇧\",\n backspace: \"Del\",\n delete: \"⌦\",\n enter: \"⏎\",\n escape: \"⎋\",\n capslock: \"⇪\",\n} as const\n\nexport const SR_ONLY = {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n borderWidth: 0,\n} as const\n\nexport function cn(\n ...classes: (string | boolean | undefined | null)[]\n): string {\n return classes.filter(Boolean).join(\" \")\n}\n\n/**\n * Determines if the current platform is macOS\n * @returns boolean indicating if the current platform is Mac\n */\nexport function isMac(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.platform.toLowerCase().includes(\"mac\")\n )\n}\n\n/**\n * Formats a shortcut key based on the platform (Mac or non-Mac)\n * @param key - The key to format (e.g., \"ctrl\", \"alt\", \"shift\")\n * @param isMac - Boolean indicating if the platform is Mac\n * @param capitalize - Whether to capitalize the key (default: true)\n * @returns Formatted shortcut key symbol\n */\nexport const formatShortcutKey = (\n key: string,\n isMac: boolean,\n capitalize: boolean = true\n) => {\n if (isMac) {\n const lowerKey = key.toLowerCase()\n return MAC_SYMBOLS[lowerKey] || (capitalize ? key.toUpperCase() : key)\n }\n\n return capitalize ? key.charAt(0).toUpperCase() + key.slice(1) : key\n}\n\n/**\n * Parses a shortcut key string into an array of formatted key symbols\n * @param shortcutKeys - The string of shortcut keys (e.g., \"ctrl-alt-shift\")\n * @param delimiter - The delimiter used to split the keys (default: \"-\")\n * @param capitalize - Whether to capitalize the keys (default: true)\n * @returns Array of formatted shortcut key symbols\n */\nexport const parseShortcutKeys = (props: {\n shortcutKeys: string | undefined\n delimiter?: string\n capitalize?: boolean\n}) => {\n const { shortcutKeys, delimiter = \"+\", capitalize = true } = props\n\n if (!shortcutKeys) return []\n\n return shortcutKeys\n .split(delimiter)\n .map((key) => key.trim())\n .map((key) => formatShortcutKey(key, isMac(), capitalize))\n}\n\n/**\n * Checks if a mark exists in the editor schema\n * @param markName - The name of the mark to check\n * @param editor - The editor instance\n * @returns boolean indicating if the mark exists in the schema\n */\nexport const isMarkInSchema = (\n markName: string,\n editor: Editor | null\n): boolean => {\n if (!editor?.schema) return false\n return editor.schema.spec.marks.get(markName) !== undefined\n}\n\n/**\n * Checks if a node exists in the editor schema\n * @param nodeName - The name of the node to check\n * @param editor - The editor instance\n * @returns boolean indicating if the node exists in the schema\n */\nexport const isNodeInSchema = (\n nodeName: string,\n editor: Editor | null\n): boolean => {\n if (!editor?.schema) return false\n return editor.schema.spec.nodes.get(nodeName) !== undefined\n}\n\n/**\n * Moves the focus to the next node in the editor\n * @param editor - The editor instance\n * @returns boolean indicating if the focus was moved\n */\nexport function focusNextNode(editor: Editor) {\n const { state, view } = editor\n const { doc, selection } = state\n\n const nextSel = Selection.findFrom(selection.$to, 1, true)\n if (nextSel) {\n view.dispatch(state.tr.setSelection(nextSel).scrollIntoView())\n return true\n }\n\n const paragraphType = state.schema.nodes.paragraph\n if (!paragraphType) {\n console.warn(\"No paragraph node type found in schema.\")\n return false\n }\n\n const end = doc.content.size\n const para = paragraphType.create()\n let tr = state.tr.insert(end, para)\n\n // Place the selection inside the new paragraph\n const $inside = tr.doc.resolve(end + 1)\n tr = tr.setSelection(TextSelection.near($inside)).scrollIntoView()\n view.dispatch(tr)\n return true\n}\n\n/**\n * Checks if a value is a valid number (not null, undefined, or NaN)\n * @param value - The value to check\n * @returns boolean indicating if the value is a valid number\n */\nexport function isValidPosition(pos: number | null | undefined): pos is number {\n return typeof pos === \"number\" && pos >= 0\n}\n\n/**\n * Checks if one or more extensions are registered in the Tiptap editor.\n * @param editor - The Tiptap editor instance\n * @param extensionNames - A single extension name or an array of names to check\n * @returns True if at least one of the extensions is available, false otherwise\n */\nexport function isExtensionAvailable(\n editor: Editor | null,\n extensionNames: string | string[]\n): boolean {\n if (!editor) return false\n\n const names = Array.isArray(extensionNames)\n ? extensionNames\n : [extensionNames]\n\n const found = names.some((name) =>\n editor.extensionManager.extensions.some((ext) => ext.name === name)\n )\n\n if (!found) {\n console.warn(\n `None of the extensions [${names.join(\", \")}] were found in the editor schema. Ensure they are included in the editor configuration.`\n )\n }\n\n return found\n}\n\n/**\n * Finds a node at the specified position with error handling\n * @param editor The Tiptap editor instance\n * @param position The position in the document to find the node\n * @returns The node at the specified position, or null if not found\n */\nexport function findNodeAtPosition(editor: Editor, position: number) {\n try {\n const node = editor.state.doc.nodeAt(position)\n if (!node) {\n console.warn(`No node found at position ${position}`)\n return null\n }\n return node\n } catch (error) {\n console.error(`Error getting node at position ${position}:`, error)\n return null\n }\n}\n\n/**\n * Finds the position and instance of a node in the document\n * @param props Object containing editor, node (optional), and nodePos (optional)\n * @param props.editor The Tiptap editor instance\n * @param props.node The node to find (optional if nodePos is provided)\n * @param props.nodePos The position of the node to find (optional if node is provided)\n * @returns An object with the position and node, or null if not found\n */\nexport function findNodePosition(props: {\n editor: Editor | null\n node?: TiptapNode | null\n nodePos?: number | null\n}): { pos: number; node: TiptapNode } | null {\n const { editor, node, nodePos } = props\n\n if (!editor || !editor.state?.doc) return null\n\n // Zero is valid position\n const hasValidNode = node !== undefined && node !== null\n const hasValidPos = isValidPosition(nodePos)\n\n if (!hasValidNode && !hasValidPos) {\n return null\n }\n\n // First search for the node in the document if we have a node\n if (hasValidNode) {\n let foundPos = -1\n let foundNode: TiptapNode | null = null\n\n editor.state.doc.descendants((currentNode, pos) => {\n // TODO: Needed?\n // if (currentNode.type && currentNode.type.name === node!.type.name) {\n if (currentNode === node) {\n foundPos = pos\n foundNode = currentNode\n return false\n }\n return true\n })\n\n if (foundPos !== -1 && foundNode !== null) {\n return { pos: foundPos, node: foundNode }\n }\n }\n\n // If we have a valid position, use findNodeAtPosition\n if (hasValidPos) {\n const nodeAtPos = findNodeAtPosition(editor, nodePos!)\n if (nodeAtPos) {\n return { pos: nodePos!, node: nodeAtPos }\n }\n }\n\n return null\n}\n\n/**\n * Determines whether the current selection contains a node whose type matches\n * any of the provided node type names.\n * @param editor Tiptap editor instance\n * @param nodeTypeNames List of node type names to match against\n * @param checkAncestorNodes Whether to check ancestor node types up the depth chain\n */\nexport function isNodeTypeSelected(\n editor: Editor | null,\n nodeTypeNames: string[] = [],\n checkAncestorNodes: boolean = false\n): boolean {\n if (!editor || !editor.state.selection) return false\n\n const { selection } = editor.state\n if (selection.empty) return false\n\n // Direct node selection check\n if (selection instanceof NodeSelection) {\n const selectedNode = selection.node\n return selectedNode ? nodeTypeNames.includes(selectedNode.type.name) : false\n }\n\n // Depth-based ancestor node check\n if (checkAncestorNodes) {\n const { $from } = selection\n for (let depth = $from.depth; depth > 0; depth--) {\n const ancestorNode = $from.node(depth)\n if (nodeTypeNames.includes(ancestorNode.type.name)) {\n return true\n }\n }\n }\n\n return false\n}\n\n/**\n * Check whether the current selection is fully within nodes\n * whose type names are in the provided `types` list.\n *\n * - NodeSelection → checks the selected node.\n * - Text/AllSelection → ensures all textblocks within [from, to) are allowed.\n */\nexport function selectionWithinConvertibleTypes(\n editor: Editor,\n types: string[] = []\n): boolean {\n if (!editor || types.length === 0) return false\n\n const { state } = editor\n const { selection } = state\n const allowed = new Set(types)\n\n if (selection instanceof NodeSelection) {\n const nodeType = selection.node?.type?.name\n return !!nodeType && allowed.has(nodeType)\n }\n\n if (selection instanceof TextSelection || selection instanceof AllSelection) {\n let valid = true\n state.doc.nodesBetween(selection.from, selection.to, (node) => {\n if (node.isTextblock && !allowed.has(node.type.name)) {\n valid = false\n return false // stop early\n }\n return valid\n })\n return valid\n }\n\n return false\n}\n\n/**\n * Handles image upload with progress tracking and abort capability\n * @param file The file to upload\n * @param onProgress Optional callback for tracking upload progress\n * @param abortSignal Optional AbortSignal for cancelling the upload\n * @returns Promise resolving to the URL of the uploaded image\n */\nexport const handleImageUpload = async (\n file: File,\n onProgress?: (event: { progress: number }) => void,\n abortSignal?: AbortSignal\n): Promise<string> => {\n // Validate file\n if (!file) {\n throw new Error(\"No file provided\")\n }\n\n if (file.size > MAX_FILE_SIZE) {\n throw new Error(\n `File size exceeds maximum allowed (${MAX_FILE_SIZE / (1024 * 1024)}MB)`\n )\n }\n\n // For demo/testing: Simulate upload progress. In production, replace the following code\n // with your own upload implementation.\n for (let progress = 0; progress <= 100; progress += 10) {\n if (abortSignal?.aborted) {\n throw new Error(\"Upload cancelled\")\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n onProgress?.({ progress })\n }\n\n return \"/images/tiptap-ui-placeholder-image.jpg\"\n}\n\ntype ProtocolOptions = {\n /**\n * The protocol scheme to be registered.\n * @default '''\n * @example 'ftp'\n * @example 'git'\n */\n scheme: string\n\n /**\n * If enabled, it allows optional slashes after the protocol.\n * @default false\n * @example true\n */\n optionalSlashes?: boolean\n}\n\ntype ProtocolConfig = Array<ProtocolOptions | string>\n\nconst ATTR_WHITESPACE =\n // eslint-disable-next-line no-control-regex\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g\n\nexport function isAllowedUri(\n uri: string | undefined,\n protocols?: ProtocolConfig\n) {\n const allowedProtocols: string[] = [\n \"http\",\n \"https\",\n \"ftp\",\n \"ftps\",\n \"mailto\",\n \"tel\",\n \"callto\",\n \"sms\",\n \"cid\",\n \"xmpp\",\n ]\n\n if (protocols) {\n protocols.forEach((protocol) => {\n const nextProtocol =\n typeof protocol === \"string\" ? protocol : protocol.scheme\n\n if (nextProtocol) {\n allowedProtocols.push(nextProtocol)\n }\n })\n }\n\n return (\n !uri ||\n uri.replace(ATTR_WHITESPACE, \"\").match(\n new RegExp(\n // eslint-disable-next-line no-useless-escape\n `^(?:(?:${allowedProtocols.join(\"|\")}):|[^a-z]|[a-z0-9+.\\-]+(?:[^a-z+.\\-:]|$))`,\n \"i\"\n )\n )\n )\n}\n\nexport function sanitizeUrl(\n inputUrl: string,\n baseUrl: string,\n protocols?: ProtocolConfig\n): string {\n try {\n const url = new URL(inputUrl, baseUrl)\n\n if (isAllowedUri(url.href, protocols)) {\n return url.href\n }\n } catch {\n // If URL creation fails, it's considered invalid\n }\n return \"#\"\n}\n\n/**\n * Update a single attribute on multiple nodes.\n *\n * @param tr - The transaction to mutate\n * @param targets - Array of { node, pos }\n * @param attrName - Attribute key to update\n * @param next - New value OR updater function receiving previous value\n * Pass `undefined` to remove the attribute.\n * @returns true if at least one node was updated, false otherwise\n */\nexport function updateNodesAttr<A extends string = string, V = unknown>(\n tr: Transaction,\n targets: readonly NodeWithPos[],\n attrName: A,\n next: V | ((prev: V | undefined) => V | undefined)\n): boolean {\n if (!targets.length) return false\n\n let changed = false\n\n for (const { pos } of targets) {\n // Always re-read from the transaction's current doc\n const currentNode = tr.doc.nodeAt(pos)\n if (!currentNode) continue\n\n const prevValue = (currentNode.attrs as Record<string, unknown>)[\n attrName\n ] as V | undefined\n const resolvedNext =\n typeof next === \"function\"\n ? (next as (p: V | undefined) => V | undefined)(prevValue)\n : next\n\n if (prevValue === resolvedNext) continue\n\n const nextAttrs: Record<string, unknown> = { ...currentNode.attrs }\n if (resolvedNext === undefined) {\n // Remove the key entirely instead of setting null\n delete nextAttrs[attrName]\n } else {\n nextAttrs[attrName] = resolvedNext\n }\n\n tr.setNodeMarkup(pos, undefined, nextAttrs)\n changed = true\n }\n\n return changed\n}\n\n/**\n * Selects the entire content of the current block node if the selection is empty.\n * If the selection is not empty, it does nothing.\n * @param editor The Tiptap editor instance\n */\nexport function selectCurrentBlockContent(editor: Editor) {\n const { selection, doc } = editor.state\n\n if (!selection.empty) return\n\n const $pos = selection.$from\n let blockNode = null\n let blockPos = -1\n\n for (let depth = $pos.depth; depth >= 0; depth--) {\n const node = $pos.node(depth)\n const pos = $pos.start(depth)\n\n if (node.isBlock && node.textContent.trim()) {\n blockNode = node\n blockPos = pos\n break\n }\n }\n\n if (blockNode && blockPos >= 0) {\n const from = blockPos\n const to = blockPos + blockNode.nodeSize - 2 // -2 to exclude the closing tag\n\n if (from < to) {\n const $from = doc.resolve(from)\n const $to = doc.resolve(to)\n const newSelection = TextSelection.between($from, $to, 1)\n\n if (newSelection && !selection.eq(newSelection)) {\n editor.view.dispatch(editor.state.tr.setSelection(newSelection))\n }\n }\n }\n}\n\nexport const FONT_SIZES = [\n \"8px\",\n \"10px\",\n \"12px\",\n \"14px\",\n \"16px\",\n \"18px\",\n \"20px\",\n \"24px\",\n \"28px\",\n \"32px\",\n \"36px\",\n \"40px\",\n \"48px\",\n \"56px\",\n \"64px\",\n]\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType\n increaseFontSize: () => ReturnType\n decreaseFontSize: () => ReturnType\n }\n }\n}\n\nexport const FontSizeExtension = Extension.create({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n }\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize || element.getAttribute(\"data-font-size\"),\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {}\n }\n\n return {\n style: `font-size: ${attributes.fontSize}`,\n }\n },\n },\n },\n },\n ]\n },\n\n addCommands() {\n return {\n setFontSize:\n (fontSize: string) =>\n ({ commands }) => {\n return commands.setMark(\"textStyle\", { fontSize })\n },\n\n increaseFontSize:\n () =>\n ({ editor }) => {\n const currentSize = editor.getAttributes(\"textStyle\").fontSize\n const currentIndex = FONT_SIZES.indexOf(currentSize || \"16px\")\n const nextIndex = Math.min(currentIndex + 1, FONT_SIZES.length - 1)\n const nextSize = FONT_SIZES[nextIndex]\n\n return editor.chain().focus().setFontSize(nextSize).run()\n },\n\n decreaseFontSize:\n () =>\n ({ editor }) => {\n const currentSize = editor.getAttributes(\"textStyle\").fontSize\n const currentIndex = FONT_SIZES.indexOf(currentSize || \"16px\")\n const nextIndex = Math.max(currentIndex - 1, 0)\n const nextSize = FONT_SIZES[nextIndex]\n\n return editor.chain().focus().setFontSize(nextSize).run()\n },\n }\n },\n\n addKeyboardShortcuts() {\n return {\n \"mod+shift+>\": () => this.editor.commands.increaseFontSize(),\n \"mod+shift+<\": () => this.editor.commands.decreaseFontSize(),\n }\n },\n})\n","\"use client\"\n\nexport type SpacerOrientation = \"horizontal\" | \"vertical\"\n\nexport interface SpacerProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: SpacerOrientation\n size?: string | number\n}\n\nexport function Spacer({\n orientation = \"horizontal\",\n size,\n style = {},\n ...props\n}: SpacerProps) {\n const computedStyle = {\n ...style,\n ...(orientation === \"horizontal\" && !size && { flex: 1 }),\n ...(size && {\n width: orientation === \"vertical\" ? \"1px\" : size,\n height: orientation === \"horizontal\" ? \"1px\" : size,\n }),\n }\n\n return <div {...props} style={computedStyle} />\n}\n","\"use client\"\n\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\"\nimport { Separator } from \"../../../components/tiptap-ui-primitive/separator\"\nimport \"../../../components/tiptap-ui-primitive/toolbar/toolbar.scss\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation\"\nimport { useComposedRef } from \"../../../hooks/use-composed-ref\"\n\ntype BaseProps = React.HTMLAttributes<HTMLDivElement>\n\ninterface ToolbarProps extends BaseProps {\n variant?: \"floating\" | \"fixed\"\n}\n\nconst useToolbarNavigation = (\n toolbarRef: React.RefObject<HTMLDivElement | null>\n) => {\n const [items, setItems] = useState<HTMLElement[]>([])\n\n const collectItems = useCallback(() => {\n if (!toolbarRef.current) return []\n return Array.from(\n toolbarRef.current.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [role=\"button\"]:not([disabled]), [tabindex=\"0\"]:not([disabled])'\n )\n )\n }, [toolbarRef])\n\n useEffect(() => {\n const toolbar = toolbarRef.current\n if (!toolbar) return\n\n const updateItems = () => setItems(collectItems())\n\n updateItems()\n const observer = new MutationObserver(updateItems)\n observer.observe(toolbar, { childList: true, subtree: true })\n\n return () => observer.disconnect()\n }, [collectItems, toolbarRef])\n\n const { selectedIndex } = useMenuNavigation<HTMLElement>({\n containerRef: toolbarRef,\n items,\n orientation: \"horizontal\",\n onSelect: (el) => el.click(),\n autoSelectFirstItem: false,\n })\n\n useEffect(() => {\n const toolbar = toolbarRef.current\n if (!toolbar) return\n\n const handleFocus = (e: FocusEvent) => {\n const target = e.target as HTMLElement\n if (toolbar.contains(target))\n target.setAttribute(\"data-focus-visible\", \"true\")\n }\n\n const handleBlur = (e: FocusEvent) => {\n const target = e.target as HTMLElement\n if (toolbar.contains(target)) target.removeAttribute(\"data-focus-visible\")\n }\n\n toolbar.addEventListener(\"focus\", handleFocus, true)\n toolbar.addEventListener(\"blur\", handleBlur, true)\n\n return () => {\n toolbar.removeEventListener(\"focus\", handleFocus, true)\n toolbar.removeEventListener(\"blur\", handleBlur, true)\n }\n }, [toolbarRef])\n\n useEffect(() => {\n if (selectedIndex !== undefined && items[selectedIndex]) {\n items[selectedIndex].focus()\n }\n }, [selectedIndex, items])\n}\n\nexport const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(\n ({ children, className, variant = \"fixed\", ...props }, ref) => {\n const toolbarRef = useRef<HTMLDivElement>(null)\n const composedRef = useComposedRef(toolbarRef, ref)\n useToolbarNavigation(toolbarRef)\n\n return (\n <div\n ref={composedRef}\n role=\"toolbar\"\n aria-label=\"toolbar\"\n data-variant={variant}\n className={cn(\"tiptap-toolbar\", className)}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nToolbar.displayName = \"Toolbar\"\n\nexport const ToolbarGroup = forwardRef<HTMLDivElement, BaseProps>(\n ({ children, className, ...props }, ref) => (\n <div\n ref={ref}\n role=\"group\"\n className={cn(\"tiptap-toolbar-group\", className)}\n {...props}\n >\n {children}\n </div>\n )\n)\nToolbarGroup.displayName = \"ToolbarGroup\"\n\nexport const ToolbarSeparator = forwardRef<HTMLDivElement, BaseProps>(\n ({ ...props }, ref) => (\n <Separator ref={ref} orientation=\"vertical\" decorative {...props} />\n )\n)\nToolbarSeparator.displayName = \"ToolbarSeparator\"\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport \"../../../components/tiptap-ui-primitive/separator/separator.scss\"\nimport { cn } from \"../../../lib/tiptap-utils\"\n\nexport type Orientation = \"horizontal\" | \"vertical\"\n\nexport interface SeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: Orientation\n decorative?: boolean\n}\n\nexport const Separator = forwardRef<HTMLDivElement, SeparatorProps>(\n ({ decorative, orientation = \"vertical\", className, ...divProps }, ref) => {\n const ariaOrientation = orientation === \"vertical\" ? orientation : undefined\n const semanticProps = decorative\n ? { role: \"none\" }\n : { \"aria-orientation\": ariaOrientation, role: \"separator\" }\n\n return (\n <div\n className={cn(\"tiptap-separator\", className)}\n data-orientation={orientation}\n {...semanticProps}\n {...divProps}\n ref={ref}\n />\n )\n }\n)\n\nSeparator.displayName = \"Separator\"\n","\"use client\"\n\nimport type { Editor } from \"@tiptap/react\"\nimport { useEffect, useState } from \"react\"\n\ntype Orientation = \"horizontal\" | \"vertical\" | \"both\"\n\ninterface MenuNavigationOptions<T> {\n /**\n * The Tiptap editor instance, if using with a Tiptap editor.\n */\n editor?: Editor | null\n /**\n * Reference to the container element for handling keyboard events.\n */\n containerRef?: React.RefObject<HTMLElement | null>\n /**\n * Search query that affects the selected item.\n */\n query?: string\n /**\n * Array of items to navigate through.\n */\n items: T[]\n /**\n * Callback fired when an item is selected.\n */\n onSelect?: (item: T) => void\n /**\n * Callback fired when the menu should close.\n */\n onClose?: () => void\n /**\n * The navigation orientation of the menu.\n * @default \"vertical\"\n */\n orientation?: Orientation\n /**\n * Whether to automatically select the first item when the menu opens.\n * @default true\n */\n autoSelectFirstItem?: boolean\n}\n\n/**\n * Hook that implements keyboard navigation for dropdown menus and command palettes.\n *\n * Handles arrow keys, tab, home/end, enter for selection, and escape to close.\n * Works with both Tiptap editors and regular DOM elements.\n *\n * @param options - Configuration options for the menu navigation\n * @returns Object containing the selected index and a setter function\n */\nexport function useMenuNavigation<T>({\n editor,\n containerRef,\n query,\n items,\n onSelect,\n onClose,\n orientation = \"vertical\",\n autoSelectFirstItem = true,\n}: MenuNavigationOptions<T>) {\n const [selectedIndex, setSelectedIndex] = useState<number>(\n autoSelectFirstItem ? 0 : -1\n )\n\n useEffect(() => {\n const handleKeyboardNavigation = (event: KeyboardEvent) => {\n if (!items.length) return false\n\n const moveNext = () =>\n setSelectedIndex((currentIndex) => {\n if (currentIndex === -1) return 0\n return (currentIndex + 1) % items.length\n })\n\n const movePrev = () =>\n setSelectedIndex((currentIndex) => {\n if (currentIndex === -1) return items.length - 1\n return (currentIndex - 1 + items.length) % items.length\n })\n\n switch (event.key) {\n case \"ArrowUp\": {\n if (orientation === \"horizontal\") return false\n event.preventDefault()\n movePrev()\n return true\n }\n\n case \"ArrowDown\": {\n if (orientation === \"horizontal\") return false\n event.preventDefault()\n moveNext()\n return true\n }\n\n case \"ArrowLeft\": {\n if (orientation === \"vertical\") return false\n event.preventDefault()\n movePrev()\n return true\n }\n\n case \"ArrowRight\": {\n if (orientation === \"vertical\") return false\n event.preventDefault()\n moveNext()\n return true\n }\n\n case \"Tab\": {\n event.preventDefault()\n if (event.shiftKey) {\n movePrev()\n } else {\n moveNext()\n }\n return true\n }\n\n case \"Home\": {\n event.preventDefault()\n setSelectedIndex(0)\n return true\n }\n\n case \"End\": {\n event.preventDefault()\n setSelectedIndex(items.length - 1)\n return true\n }\n\n case \"Enter\": {\n if (event.isComposing) return false\n event.preventDefault()\n if (selectedIndex !== -1 && items[selectedIndex]) {\n onSelect?.(items[selectedIndex])\n }\n return true\n }\n\n case \"Escape\": {\n event.preventDefault()\n onClose?.()\n return true\n }\n\n default:\n return false\n }\n }\n\n let targetElement: HTMLElement | null = null\n\n if (editor) {\n targetElement = editor.view.dom\n } else if (containerRef?.current) {\n targetElement = containerRef.current\n }\n\n if (targetElement) {\n targetElement.addEventListener(\"keydown\", handleKeyboardNavigation, true)\n\n return () => {\n targetElement?.removeEventListener(\n \"keydown\",\n handleKeyboardNavigation,\n true\n )\n }\n }\n\n return undefined\n }, [\n editor,\n containerRef,\n items,\n selectedIndex,\n onSelect,\n onClose,\n orientation,\n ])\n\n useEffect(() => {\n if (query) {\n setSelectedIndex(autoSelectFirstItem ? 0 : -1)\n }\n }, [query, autoSelectFirstItem])\n\n return {\n selectedIndex: items.length ? selectedIndex : undefined,\n setSelectedIndex,\n }\n}\n","\"use client\"\n\nimport { useCallback, useRef } from \"react\"\n\n// basically Exclude<React.ClassAttributes<T>[\"ref\"], string>\ntype UserRef<T> =\n | ((instance: T | null) => void)\n | React.RefObject<T | null>\n | null\n | undefined\n\nconst updateRef = <T>(ref: NonNullable<UserRef<T>>, value: T | null) => {\n if (typeof ref === \"function\") {\n ref(value)\n } else if (ref && typeof ref === \"object\" && \"current\" in ref) {\n // Safe assignment without MutableRefObject\n ;(ref as { current: T | null }).current = value\n }\n}\n\nexport const useComposedRef = <T extends HTMLElement>(\n libRef: React.RefObject<T | null>,\n userRef: UserRef<T>\n) => {\n const prevUserRef = useRef<UserRef<T>>(null)\n\n return useCallback(\n (instance: T | null) => {\n if (libRef && \"current\" in libRef) {\n ;(libRef as { current: T | null }).current = instance\n }\n\n if (prevUserRef.current) {\n updateRef(prevUserRef.current, null)\n }\n\n prevUserRef.current = userRef\n\n if (userRef) {\n updateRef(userRef, instance)\n }\n },\n [libRef, userRef]\n )\n}\n\nexport default useComposedRef\n","\"use client\";\r\n\r\nimport { BubbleMenu } from '@tiptap/react/menus';\r\nimport { useCurrentEditor } from \"@tiptap/react\";\r\nimport { Button } from \"../../../components/ui/button\";\r\nimport { Separator } from \"../../../components/ui/separator\";\r\nimport { \r\n List, \r\n ListOrdered, \r\n CheckSquare, \r\n Heading1, \r\n Heading2, \r\n Heading3, \r\n Quote, \r\n Code \r\n} from \"lucide-react\";\r\n\r\nexport function BubbleMenuInline() {\r\n const { editor } = useCurrentEditor();\r\n\r\n if (!editor) return null;\r\n\r\n return (\r\n <BubbleMenu\r\n editor={editor}\r\n updateDelay={100}\r\n shouldShow={({ editor, state }) => {\r\n const { from, to, empty } = state.selection;\r\n \r\n // Don't show if no selection\r\n if (empty) return false;\r\n \r\n // Don't show if editor is not editable\r\n if (!editor.isEditable) return false;\r\n \r\n // ✨ Check if any image node exists in the selection\r\n let hasImage = false;\r\n state.doc.nodesBetween(from, to, (node) => {\r\n if (node.type.name === 'image' || node.type.name === 'Image') {\r\n hasImage = true;\r\n return false; // stop traversing\r\n }\r\n });\r\n \r\n if (hasImage) return false;\r\n \r\n return true;\r\n }}\r\n >\r\n <div \r\n className=\"relative flex items-center gap-1 rounded-md border bg-popover p-1 shadow-md z-[15]\r\n animate-in fade-in slide-in-from-top-2 duration-200\"\r\n >\r\n {/* Headings */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}\r\n className={editor.isActive(\"heading\", { level: 1 }) ? \"bg-accent\" : \"\"}\r\n >\r\n <Heading1 size={15} />\r\n </Button>\r\n \r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}\r\n className={editor.isActive(\"heading\", { level: 2 }) ? \"bg-accent\" : \"\"}\r\n >\r\n <Heading2 size={15} />\r\n </Button>\r\n \r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}\r\n className={editor.isActive(\"heading\", { level: 3 }) ? \"bg-accent\" : \"\"}\r\n >\r\n <Heading3 size={15} />\r\n </Button>\r\n\r\n <Separator orientation=\"vertical\" className=\"mx-1\" />\r\n\r\n {/* Bullet List */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleBulletList().run()}\r\n className={editor.isActive(\"bulletList\") ? \"bg-accent\" : \"\"}\r\n >\r\n <List size={15} />\r\n </Button>\r\n\r\n {/* Ordered List */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\r\n className={editor.isActive(\"orderedList\") ? \"bg-accent\" : \"\"}\r\n >\r\n <ListOrdered size={15} />\r\n </Button>\r\n\r\n {/* Task List */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleTaskList().run()}\r\n className={editor.isActive(\"taskList\") ? \"bg-accent\" : \"\"}\r\n >\r\n <CheckSquare size={15} />\r\n </Button>\r\n\r\n <Separator orientation=\"vertical\" className=\"mx-1\" />\r\n\r\n {/* Code Block */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => editor.chain().focus().toggleCodeBlock().run()}\r\n className={editor.isActive(\"codeBlock\") ? \"bg-accent\" : \"\"}\r\n >\r\n <Code size={15} />\r\n </Button>\r\n </div>\r\n </BubbleMenu>\r\n );\r\n}\r\n","import { mergeAttributes, Node } from \"@tiptap/react\"\nimport { ReactNodeViewRenderer } from \"@tiptap/react\"\nimport { ImageUploadNode as ImageUploadNodeComponent } from \"./image-upload-node\"\nimport type { NodeType } from \"@tiptap/pm/model\"\n\nexport type UploadFunction = (\n file: File,\n onProgress?: (event: { progress: number }) => void,\n abortSignal?: AbortSignal\n) => Promise<string>\n\nexport interface ImageUploadNodeOptions {\n /**\n * The type of the node.\n * @default 'image'\n */\n type?: string | NodeType | undefined\n /**\n * Acceptable file types for upload.\n * @default 'image/*'\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded.\n * @default 1\n */\n limit?: number\n /**\n * Maximum file size in bytes (0 for unlimited).\n * @default 0\n */\n maxSize?: number\n /**\n * Function to handle the upload process.\n */\n upload?: UploadFunction\n /**\n * Callback for upload errors.\n */\n onError?: (error: Error) => void\n /**\n * Callback for successful uploads.\n */\n onSuccess?: (url: string) => void\n /**\n * HTML attributes to add to the image element.\n * @default {}\n * @example { class: 'foo' }\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n HTMLAttributes: Record<string, any>\n}\n\ndeclare module \"@tiptap/react\" {\n interface Commands<ReturnType> {\n imageUpload: {\n setImageUploadNode: (options?: ImageUploadNodeOptions) => ReturnType\n }\n }\n}\n\n/**\n * A Tiptap node extension that creates an image upload component.\n * @see registry/tiptap-node/image-upload-node/image-upload-node\n */\nexport const ImageUploadNode = Node.create<ImageUploadNodeOptions>({\n name: \"imageUpload\",\n\n group: \"block\",\n\n draggable: true,\n\n selectable: true,\n\n atom: true,\n\n addOptions() {\n return {\n type: \"image\",\n accept: \"image/*\",\n limit: 1,\n maxSize: 0,\n upload: undefined,\n onError: undefined,\n onSuccess: undefined,\n HTMLAttributes: {},\n }\n },\n\n addAttributes() {\n return {\n accept: {\n default: this.options.accept,\n },\n limit: {\n default: this.options.limit,\n },\n maxSize: {\n default: this.options.maxSize,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"image-upload\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"div\",\n mergeAttributes({ \"data-type\": \"image-upload\" }, HTMLAttributes),\n ]\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(ImageUploadNodeComponent)\n },\n\n addCommands() {\n return {\n setImageUploadNode:\n (options) =>\n ({ commands }) => {\n return commands.insertContent({\n type: this.name,\n attrs: options,\n })\n },\n }\n },\n\n /**\n * Adds Enter key handler to trigger the upload component when it's selected.\n */\n addKeyboardShortcuts() {\n return {\n Enter: ({ editor }) => {\n const { selection } = editor.state\n const { nodeAfter } = selection.$from\n\n if (\n nodeAfter &&\n nodeAfter.type.name === \"imageUpload\" &&\n editor.isActive(\"imageUpload\")\n ) {\n const nodeEl = editor.view.nodeDOM(selection.$from.pos)\n if (nodeEl && nodeEl instanceof HTMLElement) {\n // Since NodeViewWrapper is wrapped with a div, we need to click the first child\n const firstChild = nodeEl.firstChild\n if (firstChild && firstChild instanceof HTMLElement) {\n firstChild.click()\n return true\n }\n }\n }\n return false\n },\n }\n },\n})\n\nexport default ImageUploadNode\n","\"use client\"\n\nimport { useRef, useState } from \"react\"\nimport type { NodeViewProps } from \"@tiptap/react\"\nimport { NodeViewWrapper } from \"@tiptap/react\"\nimport { Button } from \"../../tiptap-ui-primitive/button/button\"\nimport { CloseIcon } from \"../../tiptap-icons/close-icon\"\nimport \"./image-upload-node.scss\"\nimport { focusNextNode, isValidPosition } from \"../../../lib/tiptap-utils\"\n\nexport interface FileItem {\n /**\n * Unique identifier for the file item\n */\n id: string\n /**\n * The actual File object being uploaded\n */\n file: File\n /**\n * Current upload progress as a percentage (0-100)\n */\n progress: number\n /**\n * Current status of the file upload process\n * @default \"uploading\"\n */\n status: \"uploading\" | \"success\" | \"error\"\n\n /**\n * URL to the uploaded file, available after successful upload\n * @optional\n */\n url?: string\n /**\n * Controller that can be used to abort the upload process\n * @optional\n */\n abortController?: AbortController\n}\n\nexport interface UploadOptions {\n /**\n * Maximum allowed file size in bytes\n */\n maxSize: number\n /**\n * Maximum number of files that can be uploaded\n */\n limit: number\n /**\n * String specifying acceptable file types (MIME types or extensions)\n * @example \".jpg,.png,image/jpeg\" or \"image/*\"\n */\n accept: string\n /**\n * Function that handles the actual file upload process\n * @param {File} file - The file to be uploaded\n * @param {Function} onProgress - Callback function to report upload progress\n * @param {AbortSignal} signal - Signal that can be used to abort the upload\n * @returns {Promise<string>} Promise resolving to the URL of the uploaded file\n */\n upload: (\n file: File,\n onProgress: (event: { progress: number }) => void,\n signal: AbortSignal\n ) => Promise<string>\n /**\n * Callback triggered when a file is uploaded successfully\n * @param {string} url - URL of the successfully uploaded file\n * @optional\n */\n onSuccess?: (url: string) => void\n /**\n * Callback triggered when an error occurs during upload\n * @param {Error} error - The error that occurred\n * @optional\n */\n onError?: (error: Error) => void\n}\n\n/**\n * Custom hook for managing multiple file uploads with progress tracking and cancellation\n */\nfunction useFileUpload(options: UploadOptions) {\n const [fileItems, setFileItems] = useState<FileItem[]>([])\n\n const uploadFile = async (file: File): Promise<string | null> => {\n if (file.size > options.maxSize) {\n const error = new Error(\n `File size exceeds maximum allowed (${options.maxSize / 1024 / 1024}MB)`\n )\n options.onError?.(error)\n return null\n }\n\n const abortController = new AbortController()\n const fileId = crypto.randomUUID()\n\n const newFileItem: FileItem = {\n id: fileId,\n file,\n progress: 0,\n status: \"uploading\",\n abortController,\n }\n\n setFileItems((prev) => [...prev, newFileItem])\n\n try {\n if (!options.upload) {\n throw new Error(\"Upload function is not defined\")\n }\n\n const url = await options.upload(\n file,\n (event: { progress: number }) => {\n setFileItems((prev) =>\n prev.map((item) =>\n item.id === fileId ? { ...item, progress: event.progress } : item\n )\n )\n },\n abortController.signal\n )\n\n if (!url) throw new Error(\"Upload failed: No URL returned\")\n\n if (!abortController.signal.aborted) {\n setFileItems((prev) =>\n prev.map((item) =>\n item.id === fileId\n ? { ...item, status: \"success\", url, progress: 100 }\n : item\n )\n )\n options.onSuccess?.(url)\n return url\n }\n\n return null\n } catch (error) {\n if (!abortController.signal.aborted) {\n setFileItems((prev) =>\n prev.map((item) =>\n item.id === fileId\n ? { ...item, status: \"error\", progress: 0 }\n : item\n )\n )\n options.onError?.(\n error instanceof Error ? error : new Error(\"Upload failed\")\n )\n }\n return null\n }\n }\n\n const uploadFiles = async (files: File[]): Promise<string[]> => {\n if (!files || files.length === 0) {\n options.onError?.(new Error(\"No files to upload\"))\n return []\n }\n\n if (options.limit && files.length > options.limit) {\n options.onError?.(\n new Error(\n `Maximum ${options.limit} file${options.limit === 1 ? \"\" : \"s\"} allowed`\n )\n )\n return []\n }\n\n // Upload all files concurrently\n const uploadPromises = files.map((file) => uploadFile(file))\n const results = await Promise.all(uploadPromises)\n\n // Filter out null results (failed uploads)\n return results.filter((url): url is string => url !== null)\n }\n\n const removeFileItem = (fileId: string) => {\n setFileItems((prev) => {\n const fileToRemove = prev.find((item) => item.id === fileId)\n if (fileToRemove?.abortController) {\n fileToRemove.abortController.abort()\n }\n if (fileToRemove?.url) {\n URL.revokeObjectURL(fileToRemove.url)\n }\n return prev.filter((item) => item.id !== fileId)\n })\n }\n\n const clearAllFiles = () => {\n fileItems.forEach((item) => {\n if (item.abortController) {\n item.abortController.abort()\n }\n if (item.url) {\n URL.revokeObjectURL(item.url)\n }\n })\n setFileItems([])\n }\n\n return {\n fileItems,\n uploadFiles,\n removeFileItem,\n clearAllFiles,\n }\n}\n\nconst CloudUploadIcon: React.FC = () => (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n className=\"tiptap-image-upload-icon\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M11.1953 4.41771C10.3478 4.08499 9.43578 3.94949 8.5282 4.02147C7.62062 4.09345 6.74133 4.37102 5.95691 4.83316C5.1725 5.2953 4.50354 5.92989 4.00071 6.68886C3.49788 7.44783 3.17436 8.31128 3.05465 9.2138C2.93495 10.1163 3.0222 11.0343 3.3098 11.8981C3.5974 12.7619 4.07781 13.5489 4.71463 14.1995C5.10094 14.5942 5.09414 15.2274 4.69945 15.6137C4.30476 16 3.67163 15.9932 3.28532 15.5985C2.43622 14.731 1.79568 13.6816 1.41221 12.5299C1.02875 11.3781 0.91241 10.1542 1.07201 8.95084C1.23162 7.74748 1.66298 6.59621 2.33343 5.58425C3.00387 4.57229 3.89581 3.72617 4.9417 3.10998C5.98758 2.4938 7.15998 2.1237 8.37008 2.02773C9.58018 1.93176 10.7963 2.11243 11.9262 2.55605C13.0561 2.99968 14.0703 3.69462 14.8919 4.58825C15.5423 5.29573 16.0585 6.11304 16.4177 7.00002H17.4999C18.6799 6.99991 19.8288 7.37933 20.7766 8.08222C21.7245 8.78515 22.4212 9.7743 22.7637 10.9036C23.1062 12.0328 23.0765 13.2423 22.6788 14.3534C22.2812 15.4644 21.5367 16.4181 20.5554 17.0736C20.0962 17.3803 19.4752 17.2567 19.1684 16.7975C18.8617 16.3382 18.9853 15.7172 19.4445 15.4105C20.069 14.9934 20.5427 14.3865 20.7958 13.6794C21.0488 12.9724 21.0678 12.2027 20.8498 11.4841C20.6318 10.7655 20.1885 10.136 19.5853 9.6887C18.9821 9.24138 18.251 8.99993 17.5001 9.00002H15.71C15.2679 9.00002 14.8783 8.70973 14.7518 8.28611C14.4913 7.41374 14.0357 6.61208 13.4195 5.94186C12.8034 5.27164 12.0427 4.75043 11.1953 4.41771Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M11 14.4142V21C11 21.5523 11.4477 22 12 22C12.5523 22 13 21.5523 13 21V14.4142L15.2929 16.7071C15.6834 17.0976 16.3166 17.0976 16.7071 16.7071C17.0976 16.3166 17.0976 15.6834 16.7071 15.2929L12.7078 11.2936C12.7054 11.2912 12.703 11.2888 12.7005 11.2864C12.5208 11.1099 12.2746 11.0008 12.003 11L12 11L11.997 11C11.8625 11.0004 11.7343 11.0273 11.6172 11.0759C11.502 11.1236 11.3938 11.1937 11.2995 11.2864C11.297 11.2888 11.2946 11.2912 11.2922 11.2936L7.29289 15.2929C6.90237 15.6834 6.90237 16.3166 7.29289 16.7071C7.68342 17.0976 8.31658 17.0976 8.70711 16.7071L11 14.4142Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\nconst FileIcon: React.FC = () => (\n <svg\n width=\"43\"\n height=\"57\"\n viewBox=\"0 0 43 57\"\n fill=\"currentColor\"\n className=\"tiptap-image-upload-dropzone-rect-primary\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0.75 10.75C0.75 5.64137 4.89137 1.5 10 1.5H32.3431C33.2051 1.5 34.0317 1.84241 34.6412 2.4519L40.2981 8.10876C40.9076 8.71825 41.25 9.5449 41.25 10.4069V46.75C41.25 51.8586 37.1086 56 32 56H10C4.89137 56 0.75 51.8586 0.75 46.75V10.75Z\"\n fill=\"currentColor\"\n fillOpacity=\"0.11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n </svg>\n)\n\nconst FileCornerIcon: React.FC = () => (\n <svg\n width=\"10\"\n height=\"10\"\n className=\"tiptap-image-upload-dropzone-rect-secondary\"\n viewBox=\"0 0 10 10\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0.75H0.343146C1.40401 0.75 2.42143 1.17143 3.17157 1.92157L8.82843 7.57843C9.57857 8.32857 10 9.34599 10 10.4069V10.75H4C1.79086 10.75 0 8.95914 0 6.75V0.75Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\ninterface ImageUploadDragAreaProps {\n /**\n * Callback function triggered when files are dropped or selected\n * @param {File[]} files - Array of File objects that were dropped or selected\n */\n onFile: (files: File[]) => void\n /**\n * Optional child elements to render inside the drag area\n * @optional\n * @default undefined\n */\n children?: React.ReactNode\n}\n\n/**\n * A component that creates a drag-and-drop area for image uploads\n */\nconst ImageUploadDragArea: React.FC<ImageUploadDragAreaProps> = ({\n onFile,\n children,\n}) => {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isDragActive, setIsDragActive] = useState(false)\n\n const handleDragEnter = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(true)\n }\n\n const handleDragLeave = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!e.currentTarget.contains(e.relatedTarget as Node)) {\n setIsDragActive(false)\n setIsDragOver(false)\n }\n }\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(true)\n }\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(false)\n setIsDragOver(false)\n\n const files = Array.from(e.dataTransfer.files)\n if (files.length > 0) {\n onFile(files)\n }\n }\n\n return (\n <div\n className={`tiptap-image-upload-drag-area ${isDragActive ? \"drag-active\" : \"\"} ${isDragOver ? \"drag-over\" : \"\"}`}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {children}\n </div>\n )\n}\n\ninterface ImageUploadPreviewProps {\n /**\n * The file item to preview\n */\n fileItem: FileItem\n /**\n * Callback to remove this file from upload queue\n */\n onRemove: () => void\n}\n\n/**\n * Component that displays a preview of an uploading file with progress\n */\nconst ImageUploadPreview: React.FC<ImageUploadPreviewProps> = ({\n fileItem,\n onRemove,\n}) => {\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return \"0 Bytes\"\n const k = 1024\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"]\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`\n }\n\n return (\n <div className=\"tiptap-image-upload-preview\">\n {fileItem.status === \"uploading\" && (\n <div\n className=\"tiptap-image-upload-progress\"\n style={{ width: `${fileItem.progress}%` }}\n />\n )}\n\n <div className=\"tiptap-image-upload-preview-content\">\n <div className=\"tiptap-image-upload-file-info\">\n <div className=\"tiptap-image-upload-file-icon\">\n <CloudUploadIcon />\n </div>\n <div className=\"tiptap-image-upload-details\">\n <span className=\"tiptap-image-upload-text\">\n {fileItem.file.name}\n </span>\n <span className=\"tiptap-image-upload-subtext\">\n {formatFileSize(fileItem.file.size)}\n </span>\n </div>\n </div>\n <div className=\"tiptap-image-upload-actions\">\n {fileItem.status === \"uploading\" && (\n <span className=\"tiptap-image-upload-progress-text\">\n {fileItem.progress}%\n </span>\n )}\n <Button\n type=\"button\"\n data-style=\"ghost\"\n onClick={(e) => {\n e.stopPropagation()\n onRemove()\n }}\n >\n <CloseIcon className=\"tiptap-button-icon\" />\n </Button>\n </div>\n </div>\n </div>\n )\n}\n\nconst DropZoneContent: React.FC<{ maxSize: number; limit: number }> = ({\n maxSize,\n limit,\n}) => (\n <>\n <div className=\"tiptap-image-upload-dropzone\">\n <FileIcon />\n <FileCornerIcon />\n <div className=\"tiptap-image-upload-icon-container\">\n <CloudUploadIcon />\n </div>\n </div>\n\n <div className=\"tiptap-image-upload-content\">\n <span className=\"tiptap-image-upload-text\">\n <em>Click to upload</em> or drag and drop\n </span>\n <span className=\"tiptap-image-upload-subtext\">\n Maximum {limit} file{limit === 1 ? \"\" : \"s\"}, {maxSize / 1024 / 1024}MB\n each.\n </span>\n </div>\n </>\n)\n\nexport const ImageUploadNode: React.FC<NodeViewProps> = (props) => {\n const { accept, limit, maxSize } = props.node.attrs\n const inputRef = useRef<HTMLInputElement>(null)\n const extension = props.extension\n\n const uploadOptions: UploadOptions = {\n maxSize,\n limit,\n accept,\n upload: extension.options.upload,\n onSuccess: extension.options.onSuccess,\n onError: extension.options.onError,\n }\n\n const { fileItems, uploadFiles, removeFileItem, clearAllFiles } =\n useFileUpload(uploadOptions)\n\n const handleUpload = async (files: File[]) => {\n const urls = await uploadFiles(files)\n\n if (urls.length > 0) {\n const pos = props.getPos()\n\n if (isValidPosition(pos)) {\n const imageNodes = urls.map((url, index) => {\n const filename =\n files[index]?.name.replace(/\\.[^/.]+$/, \"\") || \"unknown\"\n return {\n type: extension.options.type,\n attrs: {\n ...extension.options,\n src: url,\n alt: filename,\n title: filename,\n },\n }\n })\n\n props.editor\n .chain()\n .focus()\n .deleteRange({ from: pos, to: pos + props.node.nodeSize })\n .insertContentAt(pos, imageNodes)\n .run()\n\n focusNextNode(props.editor)\n }\n }\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files\n if (!files || files.length === 0) {\n extension.options.onError?.(new Error(\"No file selected\"))\n return\n }\n handleUpload(Array.from(files))\n }\n\n const handleClick = () => {\n if (inputRef.current && fileItems.length === 0) {\n inputRef.current.value = \"\"\n inputRef.current.click()\n }\n }\n\n const hasFiles = fileItems.length > 0\n\n return (\n <NodeViewWrapper\n className=\"tiptap-image-upload\"\n tabIndex={0}\n onClick={handleClick}\n >\n {!hasFiles && (\n <ImageUploadDragArea onFile={handleUpload}>\n <DropZoneContent maxSize={maxSize} limit={limit} />\n </ImageUploadDragArea>\n )}\n\n {hasFiles && (\n <div className=\"tiptap-image-upload-previews\">\n {fileItems.length > 1 && (\n <div className=\"tiptap-image-upload-header\">\n <span>Uploading {fileItems.length} files</span>\n <Button\n type=\"button\"\n data-style=\"ghost\"\n onClick={(e) => {\n e.stopPropagation()\n clearAllFiles()\n }}\n >\n Clear All\n </Button>\n </div>\n )}\n {fileItems.map((fileItem) => (\n <ImageUploadPreview\n key={fileItem.id}\n fileItem={fileItem}\n onRemove={() => removeFileItem(fileItem.id)}\n />\n ))}\n </div>\n )}\n\n <input\n ref={inputRef}\n name=\"file\"\n accept={accept}\n type=\"file\"\n multiple={limit > 1}\n onChange={handleChange}\n onClick={(e: React.MouseEvent<HTMLInputElement>) => e.stopPropagation()}\n />\n </NodeViewWrapper>\n )\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const CloseIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M18.7071 6.70711C19.0976 6.31658 19.0976 5.68342 18.7071 5.29289C18.3166 4.90237 17.6834 4.90237 17.2929 5.29289L12 10.5858L6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L10.5858 12L5.29289 17.2929C4.90237 17.6834 4.90237 18.3166 5.29289 18.7071C5.68342 19.0976 6.31658 19.0976 6.70711 18.7071L12 13.4142L17.2929 18.7071C17.6834 19.0976 18.3166 19.0976 18.7071 18.7071C19.0976 18.3166 19.0976 17.6834 18.7071 17.2929L13.4142 12L18.7071 6.70711Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nCloseIcon.displayName = \"CloseIcon\"\n","import { mergeAttributes } from \"@tiptap/react\"\nimport TiptapHorizontalRule from \"@tiptap/extension-horizontal-rule\"\n\nexport const HorizontalRule = TiptapHorizontalRule.extend({\n renderHTML() {\n return [\n \"div\",\n mergeAttributes(this.options.HTMLAttributes, { \"data-type\": this.name }),\n [\"hr\"],\n ]\n },\n})\n\nexport default HorizontalRule\n","\"use client\"\n\nimport { forwardRef, useCallback, useState } from \"react\"\n\n// --- Icons ---\nimport { ChevronDownIcon } from \"../../../components/tiptap-icons/chevron-down-icon\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport { HeadingButton } from \"../../../components/tiptap-ui/heading-button\"\nimport type { UseHeadingDropdownMenuConfig } from \"../../../components/tiptap-ui/heading-dropdown-menu\"\nimport { useHeadingDropdownMenu } from \"../../../components/tiptap-ui/heading-dropdown-menu\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n} from \"../../../components/tiptap-ui-primitive/dropdown-menu\"\nimport { Card, CardBody } from \"../../../components/tiptap-ui-primitive/card\"\n\nexport interface HeadingDropdownMenuProps\n extends Omit<ButtonProps, \"type\">,\n UseHeadingDropdownMenuConfig {\n /**\n * Whether to render the dropdown menu in a portal\n * @default false\n */\n portal?: boolean\n /**\n * Callback for when the dropdown opens or closes\n */\n onOpenChange?: (isOpen: boolean) => void\n}\n\n/**\n * Dropdown menu component for selecting heading levels in a Tiptap editor.\n *\n * For custom dropdown implementations, use the `useHeadingDropdownMenu` hook instead.\n */\nexport const HeadingDropdownMenu = forwardRef<\n HTMLButtonElement,\n HeadingDropdownMenuProps\n>(\n (\n {\n editor: providedEditor,\n levels = [1, 2, 3, 4, 5, 6],\n hideWhenUnavailable = false,\n portal = false,\n onOpenChange,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState<boolean>(false)\n const { isVisible, isActive, canToggle, Icon } = useHeadingDropdownMenu({\n editor,\n levels,\n hideWhenUnavailable,\n })\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!editor || !canToggle) return\n setIsOpen(open)\n onOpenChange?.(open)\n },\n [canToggle, editor, onOpenChange]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <DropdownMenu modal open={isOpen} onOpenChange={handleOpenChange}>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label=\"Format text as heading\"\n aria-pressed={isActive}\n tooltip=\"Heading\"\n {...buttonProps}\n ref={ref}\n >\n <Icon className=\"tiptap-button-icon\" />\n <ChevronDownIcon className=\"tiptap-button-dropdown-small\" />\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"start\" portal={portal}>\n <Card>\n <CardBody>\n <ButtonGroup>\n {levels.map((level) => (\n <DropdownMenuItem key={`heading-${level}`} asChild>\n <HeadingButton\n editor={editor}\n level={level}\n text={`Heading ${level}`}\n showTooltip={false}\n />\n </DropdownMenuItem>\n ))}\n </ButtonGroup>\n </CardBody>\n </Card>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n)\n\nHeadingDropdownMenu.displayName = \"HeadingDropdownMenu\"\n\nexport default HeadingDropdownMenu\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ChevronDownIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.29289 8.29289C5.68342 7.90237 6.31658 7.90237 6.70711 8.29289L12 13.5858L17.2929 8.29289C17.6834 7.90237 18.3166 7.90237 18.7071 8.29289C19.0976 8.68342 19.0976 9.31658 18.7071 9.70711L12.7071 15.7071C12.3166 16.0976 11.6834 16.0976 11.2929 15.7071L5.29289 9.70711C4.90237 9.31658 4.90237 8.68342 5.29289 8.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nChevronDownIcon.displayName = \"ChevronDownIcon\"\n","\"use client\"\n\nimport type { Editor } from \"@tiptap/react\"\nimport { useCurrentEditor, useEditorState } from \"@tiptap/react\"\nimport { useMemo } from \"react\"\n\n/**\n * Hook that provides access to a Tiptap editor instance.\n *\n * Accepts an optional editor instance directly, or falls back to retrieving\n * the editor from the Tiptap context if available. This allows components\n * to work both when given an editor directly and when used within a Tiptap\n * editor context.\n *\n * @param providedEditor - Optional editor instance to use instead of the context editor\n * @returns The provided editor or the editor from context, whichever is available\n */\nexport function useTiptapEditor(providedEditor?: Editor | null): {\n editor: Editor | null\n editorState?: Editor[\"state\"]\n canCommand?: Editor[\"can\"]\n} {\n const { editor: coreEditor } = useCurrentEditor()\n const mainEditor = useMemo(\n () => providedEditor || coreEditor,\n [providedEditor, coreEditor]\n )\n\n const editorState = useEditorState({\n editor: mainEditor,\n selector(context) {\n if (!context.editor) {\n return {\n editor: null,\n editorState: undefined,\n canCommand: undefined,\n }\n }\n\n return {\n editor: context.editor,\n editorState: context.editor.state,\n canCommand: context.editor.can,\n }\n },\n })\n\n return editorState || { editor: null }\n}\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Tiptap UI ---\nimport type {\n Level,\n UseHeadingConfig,\n} from \"../../../components/tiptap-ui/heading-button\"\nimport {\n HEADING_SHORTCUT_KEYS,\n useHeading,\n} from \"../../../components/tiptap-ui/heading-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\nexport interface HeadingButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseHeadingConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function HeadingShortcutBadge({\n level,\n shortcutKeys = HEADING_SHORTCUT_KEYS[level],\n}: {\n level: Level\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for toggling heading in a Tiptap editor.\n *\n * For custom button implementations, use the `useHeading` hook instead.\n */\nexport const HeadingButton = forwardRef<HTMLButtonElement, HeadingButtonProps>(\n (\n {\n editor: providedEditor,\n level,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = true,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canToggle,\n isActive,\n handleToggle,\n label,\n Icon,\n shortcutKeys,\n } = useHeading({\n editor,\n level,\n hideWhenUnavailable,\n onToggled,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <HeadingShortcutBadge level={level} shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nHeadingButton.displayName = \"HeadingButton\"\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport \"../../../components/tiptap-ui-primitive/badge/badge-colors.scss\"\nimport \"../../../components/tiptap-ui-primitive/badge/badge-group.scss\"\nimport \"../../../components/tiptap-ui-primitive/badge/badge.scss\"\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"ghost\" | \"white\" | \"gray\" | \"green\" | \"default\"\n size?: \"default\" | \"small\"\n appearance?: \"default\" | \"subdued\" | \"emphasized\"\n trimText?: boolean\n}\n\nexport const Badge = forwardRef<HTMLDivElement, BadgeProps>(\n (\n {\n variant,\n size = \"default\",\n appearance = \"default\",\n trimText = false,\n className,\n children,\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={`tiptap-badge ${className || \"\"}`}\n data-style={variant}\n data-size={size}\n data-appearance={appearance}\n data-text-trim={trimText ? \"on\" : \"off\"}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\n\nBadge.displayName = \"Badge\"\n\nexport default Badge\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\nimport { NodeSelection, TextSelection } from \"@tiptap/pm/state\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport {\n findNodePosition,\n isNodeInSchema,\n isNodeTypeSelected,\n isValidPosition,\n selectionWithinConvertibleTypes,\n} from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { HeadingOneIcon } from \"../../../components/tiptap-icons/heading-one-icon\"\nimport { HeadingTwoIcon } from \"../../../components/tiptap-icons/heading-two-icon\"\nimport { HeadingThreeIcon } from \"../../../components/tiptap-icons/heading-three-icon\"\nimport { HeadingFourIcon } from \"../../../components/tiptap-icons/heading-four-icon\"\nimport { HeadingFiveIcon } from \"../../../components/tiptap-icons/heading-five-icon\"\nimport { HeadingSixIcon } from \"../../../components/tiptap-icons/heading-six-icon\"\n\nexport type Level = 1 | 2 | 3 | 4 | 5 | 6\n\n/**\n * Configuration for the heading functionality\n */\nexport interface UseHeadingConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The heading level.\n */\n level: Level\n /**\n * Whether the button should hide when heading is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful heading toggle.\n */\n onToggled?: () => void\n}\n\nexport const headingIcons = {\n 1: HeadingOneIcon,\n 2: HeadingTwoIcon,\n 3: HeadingThreeIcon,\n 4: HeadingFourIcon,\n 5: HeadingFiveIcon,\n 6: HeadingSixIcon,\n}\n\nexport const HEADING_SHORTCUT_KEYS: Record<Level, string> = {\n 1: \"ctrl+alt+1\",\n 2: \"ctrl+alt+2\",\n 3: \"ctrl+alt+3\",\n 4: \"ctrl+alt+4\",\n 5: \"ctrl+alt+5\",\n 6: \"ctrl+alt+6\",\n}\n\n/**\n * Checks if heading can be toggled in the current editor state\n */\nexport function canToggle(\n editor: Editor | null,\n level?: Level,\n turnInto: boolean = true\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (\n !isNodeInSchema(\"heading\", editor) ||\n isNodeTypeSelected(editor, [\"image\"])\n )\n return false\n\n if (!turnInto) {\n return level\n ? editor.can().setNode(\"heading\", { level })\n : editor.can().setNode(\"heading\")\n }\n\n // Ensure selection is in nodes we're allowed to convert\n if (\n !selectionWithinConvertibleTypes(editor, [\n \"paragraph\",\n \"heading\",\n \"bulletList\",\n \"orderedList\",\n \"taskList\",\n \"blockquote\",\n \"codeBlock\",\n ])\n )\n return false\n\n // Either we can set heading directly on the selection,\n // or we can clear formatting/nodes to arrive at a heading.\n return level\n ? editor.can().setNode(\"heading\", { level }) || editor.can().clearNodes()\n : editor.can().setNode(\"heading\") || editor.can().clearNodes()\n}\n\n/**\n * Checks if heading is currently active\n */\nexport function isHeadingActive(\n editor: Editor | null,\n level?: Level | Level[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n if (Array.isArray(level)) {\n return level.some((l) => editor.isActive(\"heading\", { level: l }))\n }\n\n return level\n ? editor.isActive(\"heading\", { level })\n : editor.isActive(\"heading\")\n}\n\n/**\n * Toggles heading in the editor\n */\nexport function toggleHeading(\n editor: Editor | null,\n level: Level | Level[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n const levels = Array.isArray(level) ? level : [level]\n const toggleLevel = levels.find((l) => canToggle(editor, l))\n\n if (!toggleLevel) return false\n\n try {\n const view = editor.view\n let state = view.state\n let tr = state.tr\n\n // No selection, find the cursor position\n if (state.selection.empty || state.selection instanceof TextSelection) {\n const pos = findNodePosition({\n editor,\n node: state.selection.$anchor.node(1),\n })?.pos\n if (!isValidPosition(pos)) return false\n\n tr = tr.setSelection(NodeSelection.create(state.doc, pos))\n view.dispatch(tr)\n state = view.state\n }\n\n const selection = state.selection\n let chain = editor.chain().focus()\n\n // Handle NodeSelection\n if (selection instanceof NodeSelection) {\n const firstChild = selection.node.firstChild?.firstChild\n const lastChild = selection.node.lastChild?.lastChild\n\n const from = firstChild\n ? selection.from + firstChild.nodeSize\n : selection.from + 1\n\n const to = lastChild\n ? selection.to - lastChild.nodeSize\n : selection.to - 1\n\n const resolvedFrom = state.doc.resolve(from)\n const resolvedTo = state.doc.resolve(to)\n\n chain = chain\n .setTextSelection(TextSelection.between(resolvedFrom, resolvedTo))\n .clearNodes()\n }\n\n const isActive = levels.some((l) =>\n editor.isActive(\"heading\", { level: l })\n )\n\n const toggle = isActive\n ? chain.setNode(\"paragraph\")\n : chain.setNode(\"heading\", { level: toggleLevel })\n\n toggle.run()\n\n editor.chain().focus().selectTextblockEnd().run()\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Determines if the heading button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n level?: Level | Level[]\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, level, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(\"heading\", editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n if (Array.isArray(level)) {\n return level.some((l) => canToggle(editor, l))\n }\n return canToggle(editor, level)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides heading functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleHeadingButton() {\n * const { isVisible, isActive, handleToggle, Icon } = useHeading({ level: 1 })\n *\n * if (!isVisible) return null\n *\n * return (\n * <button\n * onClick={handleToggle}\n * aria-pressed={isActive}\n * >\n * <Icon />\n * Heading 1\n * </button>\n * )\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedHeadingButton() {\n * const { isVisible, isActive, handleToggle, label, Icon } = useHeading({\n * level: 2,\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onToggled: (isActive) => console.log('Heading toggled:', isActive)\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleToggle}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * <Icon />\n * Toggle Heading 2\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useHeading(config: UseHeadingConfig) {\n const {\n editor: providedEditor,\n level,\n hideWhenUnavailable = false,\n onToggled,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggleState = canToggle(editor, level)\n const isActive = isHeadingActive(editor, level)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, level, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, level, hideWhenUnavailable])\n\n const handleToggle = useCallback(() => {\n if (!editor) return false\n\n const success = toggleHeading(editor, level)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, level, onToggled])\n\n return {\n isVisible,\n isActive,\n handleToggle,\n canToggle: canToggleState,\n label: `Heading ${level}`,\n shortcutKeys: HEADING_SHORTCUT_KEYS[level],\n Icon: headingIcons[level],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingOneIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M21.0001 10C21.0001 9.63121 20.7971 9.29235 20.472 9.11833C20.1468 8.94431 19.7523 8.96338 19.4454 9.16795L16.4454 11.168C15.9859 11.4743 15.8617 12.0952 16.1681 12.5547C16.4744 13.0142 17.0953 13.1384 17.5548 12.8321L19.0001 11.8685V18C19.0001 18.5523 19.4478 19 20.0001 19C20.5524 19 21.0001 18.5523 21.0001 18V10Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingOneIcon.displayName = \"HeadingOneIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingTwoIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M22.0001 12C22.0001 10.7611 21.1663 9.79297 20.0663 9.42632C18.9547 9.05578 17.6171 9.28724 16.4001 10.2C15.9582 10.5314 15.8687 11.1582 16.2001 11.6C16.5314 12.0418 17.1582 12.1314 17.6001 11.8C18.383 11.2128 19.0455 11.1942 19.4338 11.3237C19.8339 11.457 20.0001 11.7389 20.0001 12C20.0001 12.4839 19.8554 12.7379 19.6537 12.9481C19.4275 13.1837 19.1378 13.363 18.7055 13.6307C18.6313 13.6767 18.553 13.7252 18.4701 13.777C17.9572 14.0975 17.3128 14.5261 16.8163 15.2087C16.3007 15.9177 16.0001 16.8183 16.0001 18C16.0001 18.5523 16.4478 19 17.0001 19H21.0001C21.5523 19 22.0001 18.5523 22.0001 18C22.0001 17.4477 21.5523 17 21.0001 17H18.131C18.21 16.742 18.3176 16.5448 18.4338 16.385C18.6873 16.0364 19.0429 15.7775 19.5301 15.473C19.5898 15.4357 19.6536 15.3966 19.7205 15.3556C20.139 15.0992 20.6783 14.7687 21.0964 14.3332C21.6447 13.7621 22.0001 13.0161 22.0001 12Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingTwoIcon.displayName = \"HeadingTwoIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingThreeIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M4 5C4.55228 5 5 5.44772 5 6V11H11V6C11 5.44772 11.4477 5 12 5C12.5523 5 13 5.44772 13 6V18C13 18.5523 12.5523 19 12 19C11.4477 19 11 18.5523 11 18V13H5V18C5 18.5523 4.55228 19 4 19C3.44772 19 3 18.5523 3 18V6C3 5.44772 3.44772 5 4 5Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M19.4608 11.2169C19.1135 11.0531 18.5876 11.0204 18.0069 11.3619C17.5309 11.642 16.918 11.4831 16.638 11.007C16.358 10.531 16.5169 9.91809 16.9929 9.63807C18.1123 8.97962 19.3364 8.94691 20.314 9.40808C21.2839 9.86558 21.9999 10.818 21.9999 12C21.9999 12.7957 21.6838 13.5587 21.1212 14.1213C20.5586 14.6839 19.7956 15 18.9999 15C18.4476 15 17.9999 14.5523 17.9999 14C17.9999 13.4477 18.4476 13 18.9999 13C19.2651 13 19.5195 12.8947 19.707 12.7071C19.8946 12.5196 19.9999 12.2652 19.9999 12C19.9999 11.6821 19.8159 11.3844 19.4608 11.2169Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M18.0001 14C18.0001 13.4477 18.4478 13 19.0001 13C19.7957 13 20.5588 13.3161 21.1214 13.8787C21.684 14.4413 22.0001 15.2043 22.0001 16C22.0001 17.2853 21.2767 18.3971 20.1604 18.8994C19.0257 19.41 17.642 19.2315 16.4001 18.3C15.9582 17.9686 15.8687 17.3418 16.2001 16.9C16.5314 16.4582 17.1582 16.3686 17.6001 16.7C18.3581 17.2685 18.9744 17.24 19.3397 17.0756C19.7234 16.9029 20.0001 16.5147 20.0001 16C20.0001 15.7348 19.8947 15.4804 19.7072 15.2929C19.5196 15.1054 19.2653 15 19.0001 15C18.4478 15 18.0001 14.5523 18.0001 14Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingThreeIcon.displayName = \"HeadingThreeIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingFourIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M4 5C4.55228 5 5 5.44772 5 6V11H11V6C11 5.44772 11.4477 5 12 5C12.5523 5 13 5.44772 13 6V18C13 18.5523 12.5523 19 12 19C11.4477 19 11 18.5523 11 18V13H5V18C5 18.5523 4.55228 19 4 19C3.44772 19 3 18.5523 3 18V6C3 5.44772 3.44772 5 4 5Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M17 9C17.5523 9 18 9.44772 18 10V13H20V10C20 9.44772 20.4477 9 21 9C21.5523 9 22 9.44772 22 10V18C22 18.5523 21.5523 19 21 19C20.4477 19 20 18.5523 20 18V15H17C16.4477 15 16 14.5523 16 14V10C16 9.44772 16.4477 9 17 9Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingFourIcon.displayName = \"HeadingFourIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingFiveIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M16 10C16 9.44772 16.4477 9 17 9H21C21.5523 9 22 9.44772 22 10C22 10.5523 21.5523 11 21 11H18V12H18.3C20.2754 12 22 13.4739 22 15.5C22 17.5261 20.2754 19 18.3 19C17.6457 19 17.0925 18.8643 16.5528 18.5944C16.0588 18.3474 15.8586 17.7468 16.1055 17.2528C16.3525 16.7588 16.9532 16.5586 17.4472 16.8056C17.7074 16.9357 17.9542 17 18.3 17C19.3246 17 20 16.2739 20 15.5C20 14.7261 19.3246 14 18.3 14H17C16.4477 14 16 13.5523 16 13L16 12.9928V10Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingFiveIcon.displayName = \"HeadingFiveIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingSixIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M5 6C5 5.44772 4.55228 5 4 5C3.44772 5 3 5.44772 3 6V18C3 18.5523 3.44772 19 4 19C4.55228 19 5 18.5523 5 18V13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6V11H5V6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M20.7071 9.29289C21.0976 9.68342 21.0976 10.3166 20.7071 10.7071C19.8392 11.575 19.2179 12.2949 18.7889 13.0073C18.8587 13.0025 18.929 13 19 13C20.6569 13 22 14.3431 22 16C22 17.6569 20.6569 19 19 19C17.3431 19 16 17.6569 16 16C16 14.6007 16.2837 13.4368 16.8676 12.3419C17.4384 11.2717 18.2728 10.3129 19.2929 9.29289C19.6834 8.90237 20.3166 8.90237 20.7071 9.29289ZM19 17C18.4477 17 18 16.5523 18 16C18 15.4477 18.4477 15 19 15C19.5523 15 20 15.4477 20 16C20 16.5523 19.5523 17 19 17Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingSixIcon.displayName = \"HeadingSixIcon\"\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/dropdown-menu/dropdown-menu.scss\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root modal={false} {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return <DropdownMenuPrimitive.Portal {...props} />\n}\n\nconst DropdownMenuTrigger = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>\n>(({ ...props }, ref) => <DropdownMenuPrimitive.Trigger ref={ref} {...props} />)\nDropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownMenuItem = DropdownMenuPrimitive.Item\n\nconst DropdownMenuSubTrigger = DropdownMenuPrimitive.SubTrigger\n\nconst DropdownMenuSubContent = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent> & {\n portal?: boolean | React.ComponentProps<typeof DropdownMenuPortal>\n }\n>(({ className, portal = true, ...props }, ref) => {\n const content = (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\"tiptap-dropdown-menu\", className)}\n {...props}\n />\n )\n\n return portal ? (\n <DropdownMenuPortal {...(typeof portal === \"object\" ? portal : {})}>\n {content}\n </DropdownMenuPortal>\n ) : (\n content\n )\n})\nDropdownMenuSubContent.displayName =\n DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownMenuContent = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> & {\n portal?: boolean\n }\n>(({ className, sideOffset = 4, portal = false, ...props }, ref) => {\n const content = (\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n onCloseAutoFocus={(e) => e.preventDefault()}\n className={cn(\"tiptap-dropdown-menu\", className)}\n {...props}\n />\n )\n\n return portal ? (\n <DropdownMenuPortal {...(typeof portal === \"object\" ? portal : {})}>\n {content}\n </DropdownMenuPortal>\n ) : (\n content\n )\n})\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuGroup,\n DropdownMenuSub,\n DropdownMenuPortal,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n}\n","\"use client\"\n\nimport { forwardRef } from \"react\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/card/card.scss\"\n\nconst Card = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return <div ref={ref} className={cn(\"tiptap-card\", className)} {...props} />\n }\n)\nCard.displayName = \"Card\"\n\nconst CardHeader = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-header\", className)}\n {...props}\n />\n )\n }\n)\nCardHeader.displayName = \"CardHeader\"\n\nconst CardBody = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"tiptap-card-body\", className)} {...props} />\n )\n }\n)\nCardBody.displayName = \"CardBody\"\n\nconst CardItemGroup = forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> & {\n orientation?: \"horizontal\" | \"vertical\"\n }\n>(({ className, orientation = \"vertical\", ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-orientation={orientation}\n className={cn(\"tiptap-card-item-group\", className)}\n {...props}\n />\n )\n})\nCardItemGroup.displayName = \"CardItemGroup\"\n\nconst CardGroupLabel = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-group-label\", className)}\n {...props}\n />\n )\n }\n)\nCardGroupLabel.displayName = \"CardGroupLabel\"\n\nconst CardFooter = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-footer\", className)}\n {...props}\n />\n )\n }\n)\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardBody, CardItemGroup, CardGroupLabel }\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { HeadingIcon } from \"../../../components/tiptap-icons/heading-icon\"\n\n// --- Tiptap UI ---\nimport {\n headingIcons,\n type Level,\n isHeadingActive,\n canToggle,\n shouldShowButton,\n} from \"../../../components/tiptap-ui/heading-button\"\n\n/**\n * Configuration for the heading dropdown menu functionality\n */\nexport interface UseHeadingDropdownMenuConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Available heading levels to show in the dropdown\n * @default [1, 2, 3, 4, 5, 6]\n */\n levels?: Level[]\n /**\n * Whether the dropdown should hide when headings are not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n}\n\n/**\n * Gets the currently active heading level from the available levels\n */\nexport function getActiveHeadingLevel(\n editor: Editor | null,\n levels: Level[] = [1, 2, 3, 4, 5, 6]\n): Level | undefined {\n if (!editor || !editor.isEditable) return undefined\n return levels.find((level) => isHeadingActive(editor, level))\n}\n\n/**\n * Custom hook that provides heading dropdown menu functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MyHeadingDropdown() {\n * const {\n * isVisible,\n * activeLevel,\n * isAnyHeadingActive,\n * canToggle,\n * levels,\n * } = useHeadingDropdownMenu()\n *\n * if (!isVisible) return null\n *\n * return (\n * <DropdownMenu>\n * // dropdown content\n * </DropdownMenu>\n * )\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedHeadingDropdown() {\n * const {\n * isVisible,\n * activeLevel,\n * } = useHeadingDropdownMenu({\n * editor: myEditor,\n * levels: [1, 2, 3],\n * hideWhenUnavailable: true,\n * })\n *\n * // component implementation\n * }\n * ```\n */\nexport function useHeadingDropdownMenu(config?: UseHeadingDropdownMenuConfig) {\n const {\n editor: providedEditor,\n levels = [1, 2, 3, 4, 5, 6],\n hideWhenUnavailable = false,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState(true)\n\n const activeLevel = getActiveHeadingLevel(editor, levels)\n const isActive = isHeadingActive(editor)\n const canToggleState = canToggle(editor)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(\n shouldShowButton({ editor, hideWhenUnavailable, level: levels })\n )\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable, levels])\n\n return {\n isVisible,\n activeLevel,\n isActive,\n canToggle: canToggleState,\n levels,\n label: \"Heading\",\n Icon: activeLevel ? headingIcons[activeLevel] : HeadingIcon,\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HeadingIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M6 3C6.55228 3 7 3.44772 7 4V11H17V4C17 3.44772 17.4477 3 18 3C18.5523 3 19 3.44772 19 4V20C19 20.5523 18.5523 21 18 21C17.4477 21 17 20.5523 17 20V13H7V20C7 20.5523 6.55228 21 6 21C5.44772 21 5 20.5523 5 20V4C5 3.44772 5.44772 3 6 3Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHeadingIcon.displayName = \"HeadingIcon\"\n"," \"use client\"\n\n import { forwardRef, useCallback } from \"react\"\n\n // --- Lib ---\n import { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n // --- Hooks ---\n import { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n // --- Tiptap UI ---\n import type { UseImageUploadConfig } from \"../../../components/tiptap-ui/image-upload-button\"\n import {\n IMAGE_UPLOAD_SHORTCUT_KEY,\n useImageUpload,\n } from \"../../../components/tiptap-ui/image-upload-button\"\n\n // --- UI Primitives ---\n import type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\n import { Button } from \"../../../components/tiptap-ui-primitive/button\"\n import { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\n type IconProps = React.SVGProps<SVGSVGElement>\n type IconComponent = ({ className, ...props }: IconProps) => React.ReactElement\n\n export interface ImageUploadButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseImageUploadConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default true\n */\n showShortcut?: boolean\n /**\n * Optional custom icon component to render instead of the default.\n */\n icon?: React.MemoExoticComponent<IconComponent> | React.FC<IconProps>\n }\n\n export function ImageShortcutBadge({\n shortcutKeys = IMAGE_UPLOAD_SHORTCUT_KEY,\n }: {\n shortcutKeys?: string\n }) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n }\n\n /**\n * Button component for uploading/inserting images in a Tiptap editor.\n *\n * For custom button implementations, use the `useImage` hook instead.\n */\n export const ImageUploadButton = forwardRef<\n HTMLButtonElement,\n ImageUploadButtonProps\n >(\n (\n {\n editor: providedEditor,\n text,\n hideWhenUnavailable = false,\n onInserted,\n showShortcut = false,\n onClick,\n icon: CustomIcon,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canInsert,\n handleImage,\n label,\n isActive,\n shortcutKeys,\n Icon,\n } = useImageUpload({\n editor,\n hideWhenUnavailable,\n onInserted,\n })\n\n const handleClick = useCallback(\n async (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n await handleImage() // 👈 important\n },\n [handleImage, onClick]\n )\n \n\n if (!isVisible) {\n return null\n }\n\n const RenderIcon = CustomIcon ?? Icon\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canInsert}\n data-disabled={!canInsert}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <RenderIcon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && <ImageShortcutBadge shortcutKeys={shortcutKeys} />}\n </>\n )}\n </Button>\n )\n }\n )\n\n ImageUploadButton.displayName = \"ImageUploadButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { useHotkeys } from \"react-hotkeys-hook\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\n\n// --- Lib ---\nimport { isExtensionAvailable } from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { ImagePlusIcon } from \"../../../components/tiptap-icons/image-plus-icon\"\n\nexport const IMAGE_UPLOAD_SHORTCUT_KEY = \"mod+shift+i\"\n\n/**\n * Configuration for the image upload functionality\n */\nexport interface UseImageUploadConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Whether the button should hide when insertion is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful image insertion.\n */\n onInserted?: () => void\n}\n\n/**\n * Checks if image can be inserted in the current editor state\n */\nexport function canInsertImage(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n if (!isExtensionAvailable(editor, \"imageUpload\")) return false\n\n return editor.can().insertContent({ type: \"imageUpload\" })\n}\n\n/**\n * Checks if image is currently active\n */\nexport function isImageActive(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive(\"imageUpload\")\n}\n\n/**\n * Inserts an image in the editor\n */\nexport async function insertImage(editor: Editor | null): Promise<boolean> {\n if (!editor || !editor.isEditable) return false\n if (!canInsertImage(editor)) return false\n\n try {\n // 1) pick file\n const input = document.createElement(\"input\")\n input.type = \"file\"\n input.accept = \"image/*\"\n\n return new Promise((resolve) => {\n input.onchange = async () => {\n const file = input.files?.[0]\n if (!file) return resolve(false)\n\n // 2) convert to base64\n const reader = new FileReader()\n reader.onload = () => {\n const base64 = reader.result as string\n\n // 3) store in localStorage\n const images = JSON.parse(localStorage.getItem(\"tiptap-images\") || \"[]\")\n images.push(base64)\n localStorage.setItem(\"tiptap-images\", JSON.stringify(images))\n\n // 4) insert into editor\n editor\n .chain()\n .focus()\n .insertContent({\n type: \"image\",\n attrs: { src: base64 },\n })\n .run()\n\n resolve(true)\n }\n reader.onerror = () => resolve(false)\n reader.readAsDataURL(file)\n }\n input.click()\n })\n } catch {\n return false\n }\n}\n\n\n/**\n * Determines if the image button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isExtensionAvailable(editor, \"imageUpload\")) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canInsertImage(editor)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides image functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage - no params needed\n * function MySimpleImageButton() {\n * const { isVisible, handleImage } = useImage()\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleImage}>Add Image</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedImageButton() {\n * const { isVisible, handleImage, label, isActive } = useImage({\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onInserted: () => console.log('Image inserted!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleImage}\n * aria-pressed={isActive}\n * aria-label={label}\n * >\n * Add Image\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useImageUpload(config?: UseImageUploadConfig) {\n const {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onInserted,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const isMobile = useIsBreakpoint()\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canInsert = canInsertImage(editor)\n const isActive = isImageActive(editor)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable])\n\n const handleImage = useCallback(async () => {\n if (!editor) return false\n\n const success = insertImage(editor)\n if (await success) {\n onInserted?.()\n }\n return success\n }, [editor, onInserted])\n\n useHotkeys(\n IMAGE_UPLOAD_SHORTCUT_KEY,\n (event) => {\n event.preventDefault()\n handleImage()\n },\n {\n enabled: isVisible && canInsert,\n enableOnContentEditable: !isMobile,\n enableOnFormTags: true,\n }\n )\n\n return {\n isVisible,\n isActive,\n handleImage,\n canInsert,\n label: \"Add image\",\n shortcutKeys: IMAGE_UPLOAD_SHORTCUT_KEY,\n Icon: ImagePlusIcon,\n }\n}\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\n\ntype BreakpointMode = \"min\" | \"max\"\n\n/**\n * Hook to detect whether the current viewport matches a given breakpoint rule.\n * Example:\n * useIsBreakpoint(\"max\", 768) // true when width < 768\n * useIsBreakpoint(\"min\", 1024) // true when width >= 1024\n */\nexport function useIsBreakpoint(\n mode: BreakpointMode = \"max\",\n breakpoint = 768\n) {\n const [matches, setMatches] = useState<boolean | undefined>(undefined)\n\n useEffect(() => {\n const query =\n mode === \"min\"\n ? `(min-width: ${breakpoint}px)`\n : `(max-width: ${breakpoint - 1}px)`\n\n const mql = window.matchMedia(query)\n const onChange = (e: MediaQueryListEvent) => setMatches(e.matches)\n\n // Set initial value\n setMatches(mql.matches)\n\n // Add listener\n mql.addEventListener(\"change\", onChange)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [mode, breakpoint])\n\n return !!matches\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ImagePlusIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M20 2C20 1.44772 19.5523 1 19 1C18.4477 1 18 1.44772 18 2V4H16C15.4477 4 15 4.44772 15 5C15 5.55228 15.4477 6 16 6H18V8C18 8.55228 18.4477 9 19 9C19.5523 9 20 8.55228 20 8V6H22C22.5523 6 23 5.55228 23 5C23 4.44772 22.5523 4 22 4H20V2ZM5 4C4.73478 4 4.48043 4.10536 4.29289 4.29289C4.10536 4.48043 4 4.73478 4 5V19C4 19.2652 4.10536 19.5196 4.29289 19.7071C4.48043 19.8946 4.73478 20 5 20H5.58579L14.379 11.2068C14.9416 10.6444 15.7045 10.3284 16.5 10.3284C17.2955 10.3284 18.0584 10.6444 18.621 11.2068L20 12.5858V12C20 11.4477 20.4477 11 21 11C21.5523 11 22 11.4477 22 12V14.998C22 14.9994 22 15.0007 22 15.002V19C22 19.7957 21.6839 20.5587 21.1213 21.1213C20.5587 21.6839 19.7957 22 19 22H6.00219C6.00073 22 5.99927 22 5.99781 22H5C4.20435 22 3.44129 21.6839 2.87868 21.1213C2.31607 20.5587 2 19.7957 2 19V5C2 4.20435 2.31607 3.44129 2.87868 2.87868C3.44129 2.31607 4.20435 2 5 2H12C12.5523 2 13 2.44772 13 3C13 3.55228 12.5523 4 12 4H5ZM8.41422 20H19C19.2652 20 19.5196 19.8946 19.7071 19.7071C19.8946 19.5196 20 19.2652 20 19V15.4142L17.207 12.6212C17.0195 12.4338 16.7651 12.3284 16.5 12.3284C16.2349 12.3284 15.9806 12.4337 15.7931 12.6211L8.41422 20ZM6.87868 6.87868C7.44129 6.31607 8.20435 6 9 6C9.79565 6 10.5587 6.31607 11.1213 6.87868C11.6839 7.44129 12 8.20435 12 9C12 9.79565 11.6839 10.5587 11.1213 11.1213C10.5587 11.6839 9.79565 12 9 12C8.20435 12 7.44129 11.6839 6.87868 11.1213C6.31607 10.5587 6 9.79565 6 9C6 8.20435 6.31607 7.44129 6.87868 6.87868ZM9 8C8.73478 8 8.48043 8.10536 8.29289 8.29289C8.10536 8.48043 8 8.73478 8 9C8 9.26522 8.10536 9.51957 8.29289 9.70711C8.48043 9.89464 8.73478 10 9 10C9.26522 10 9.51957 9.89464 9.70711 9.70711C9.89464 9.51957 10 9.26522 10 9C10 8.73478 9.89464 8.48043 9.70711 8.29289C9.51957 8.10536 9.26522 8 9 8Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nImagePlusIcon.displayName = \"ImagePlusIcon\"\n","\"use client\"\n\nimport { useCallback, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { ChevronDownIcon } from \"../../../components/tiptap-icons/chevron-down-icon\"\n\n// --- Tiptap UI ---\nimport { ListButton, type ListType } from \"../../../components/tiptap-ui/list-button\"\n\nimport { useListDropdownMenu } from \"../../../components/tiptap-ui/list-dropdown-menu/use-list-dropdown-menu\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n} from \"../../../components/tiptap-ui-primitive/dropdown-menu\"\nimport { Card, CardBody } from \"../../../components/tiptap-ui-primitive/card\"\n\nexport interface ListDropdownMenuProps extends Omit<ButtonProps, \"type\"> {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor\n /**\n * The list types to display in the dropdown.\n */\n types?: ListType[]\n /**\n * Whether the dropdown should be hidden when no list types are available\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback for when the dropdown opens or closes\n */\n onOpenChange?: (isOpen: boolean) => void\n /**\n * Whether to render the dropdown menu in a portal\n * @default false\n */\n portal?: boolean\n}\n\nexport function ListDropdownMenu({\n editor: providedEditor,\n types = [\"bulletList\", \"orderedList\", \"taskList\"],\n hideWhenUnavailable = false,\n onOpenChange,\n portal = false,\n ...props\n}: ListDropdownMenuProps) {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState(false)\n\n const { filteredLists, canToggle, isActive, isVisible, Icon } =\n useListDropdownMenu({\n editor,\n types,\n hideWhenUnavailable,\n })\n\n const handleOnOpenChange = useCallback(\n (open: boolean) => {\n setIsOpen(open)\n onOpenChange?.(open)\n },\n [onOpenChange]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <DropdownMenu open={isOpen} onOpenChange={handleOnOpenChange}>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label=\"List options\"\n tooltip=\"List\"\n {...props}\n >\n <Icon className=\"tiptap-button-icon\" />\n <ChevronDownIcon className=\"tiptap-button-dropdown-small\" />\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"start\" portal={portal}>\n <Card>\n <CardBody>\n <ButtonGroup>\n {filteredLists.map((option) => (\n <DropdownMenuItem key={option.type} asChild>\n <ListButton\n editor={editor}\n type={option.type}\n text={option.label}\n showTooltip={false}\n />\n </DropdownMenuItem>\n ))}\n </ButtonGroup>\n </CardBody>\n </Card>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nexport default ListDropdownMenu\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\n// --- Tiptap UI ---\nimport type { ListType, UseListConfig } from \"../../../components/tiptap-ui/list-button\"\nimport { LIST_SHORTCUT_KEYS, useList } from \"../../../components/tiptap-ui/list-button\"\n\nexport interface ListButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseListConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function ListShortcutBadge({\n type,\n shortcutKeys = LIST_SHORTCUT_KEYS[type],\n}: {\n type: ListType\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for toggling lists in a Tiptap editor.\n *\n * For custom button implementations, use the `useList` hook instead.\n */\nexport const ListButton = forwardRef<HTMLButtonElement, ListButtonProps>(\n (\n {\n editor: providedEditor,\n type,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = true ,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canToggle,\n isActive,\n handleToggle,\n label,\n shortcutKeys,\n Icon,\n } = useList({\n editor,\n type,\n hideWhenUnavailable,\n onToggled,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <ListShortcutBadge type={type} shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nListButton.displayName = \"ListButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\nimport { NodeSelection, TextSelection } from \"@tiptap/pm/state\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { ListIcon } from \"../../../components/tiptap-icons/list-icon\"\nimport { ListOrderedIcon } from \"../../../components/tiptap-icons/list-ordered-icon\"\nimport { ListTodoIcon } from \"../../../components/tiptap-icons/list-todo-icon\"\n\n// --- Lib ---\nimport {\n findNodePosition,\n isNodeInSchema,\n isNodeTypeSelected,\n isValidPosition,\n selectionWithinConvertibleTypes,\n} from \"../../../lib/tiptap-utils\"\n\nexport type ListType = \"bulletList\" | \"orderedList\" | \"taskList\"\n\n/**\n * Configuration for the list functionality\n */\nexport interface UseListConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The type of list to toggle.\n */\n type: ListType\n /**\n * Whether the button should hide when list is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful toggle.\n */\n onToggled?: () => void\n}\n\nexport const listIcons = {\n bulletList: ListIcon,\n orderedList: ListOrderedIcon,\n taskList: ListTodoIcon,\n}\n\nexport const listLabels: Record<ListType, string> = {\n bulletList: \"Bullet List\",\n orderedList: \"Ordered List\",\n taskList: \"Task List\",\n}\n\nexport const LIST_SHORTCUT_KEYS: Record<ListType, string> = {\n bulletList: \"mod+shift+8\",\n orderedList: \"mod+shift+7\",\n taskList: \"mod+shift+9\",\n}\n\n/**\n * Checks if a list can be toggled in the current editor state\n */\nexport function canToggleList(\n editor: Editor | null,\n type: ListType,\n turnInto: boolean = true\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(type, editor) || isNodeTypeSelected(editor, [\"image\"]))\n return false\n\n if (!turnInto) {\n switch (type) {\n case \"bulletList\":\n return editor.can().toggleBulletList()\n case \"orderedList\":\n return editor.can().toggleOrderedList()\n case \"taskList\":\n return editor.can().toggleList(\"taskList\", \"taskItem\")\n default:\n return false\n }\n }\n\n // Ensure selection is in nodes we're allowed to convert\n if (\n !selectionWithinConvertibleTypes(editor, [\n \"paragraph\",\n \"heading\",\n \"bulletList\",\n \"orderedList\",\n \"taskList\",\n \"blockquote\",\n \"codeBlock\",\n ])\n )\n return false\n\n // Either we can set list directly on the selection,\n // or we can clear formatting/nodes to arrive at a list.\n switch (type) {\n case \"bulletList\":\n return editor.can().toggleBulletList() || editor.can().clearNodes()\n case \"orderedList\":\n return editor.can().toggleOrderedList() || editor.can().clearNodes()\n case \"taskList\":\n return (\n editor.can().toggleList(\"taskList\", \"taskItem\") ||\n editor.can().clearNodes()\n )\n default:\n return false\n }\n}\n\n/**\n * Checks if list is currently active\n */\nexport function isListActive(editor: Editor | null, type: ListType): boolean {\n if (!editor || !editor.isEditable) return false\n\n switch (type) {\n case \"bulletList\":\n return editor.isActive(\"bulletList\")\n case \"orderedList\":\n return editor.isActive(\"orderedList\")\n case \"taskList\":\n return editor.isActive(\"taskList\")\n default:\n return false\n }\n}\n\n/**\n * Toggles list in the editor\n */\nexport function toggleList(editor: Editor | null, type: ListType): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canToggleList(editor, type)) return false\n\n try {\n const view = editor.view\n let state = view.state\n let tr = state.tr\n\n // No selection, find the the cursor position\n if (state.selection.empty || state.selection instanceof TextSelection) {\n const pos = findNodePosition({\n editor,\n node: state.selection.$anchor.node(1),\n })?.pos\n if (!isValidPosition(pos)) return false\n\n tr = tr.setSelection(NodeSelection.create(state.doc, pos))\n view.dispatch(tr)\n state = view.state\n }\n\n const selection = state.selection\n\n let chain = editor.chain().focus()\n\n // Handle NodeSelection\n if (selection instanceof NodeSelection) {\n const firstChild = selection.node.firstChild?.firstChild\n const lastChild = selection.node.lastChild?.lastChild\n\n const from = firstChild\n ? selection.from + firstChild.nodeSize\n : selection.from + 1\n\n const to = lastChild\n ? selection.to - lastChild.nodeSize\n : selection.to - 1\n\n const resolvedFrom = state.doc.resolve(from)\n const resolvedTo = state.doc.resolve(to)\n\n chain = chain\n .setTextSelection(TextSelection.between(resolvedFrom, resolvedTo))\n .clearNodes()\n }\n\n if (editor.isActive(type)) {\n // Unwrap list\n chain\n .liftListItem(\"listItem\")\n .lift(\"bulletList\")\n .lift(\"orderedList\")\n .lift(\"taskList\")\n .run()\n } else {\n // Wrap in specific list type\n const toggleMap: Record<ListType, () => typeof chain> = {\n bulletList: () => chain.toggleBulletList(),\n orderedList: () => chain.toggleOrderedList(),\n taskList: () => chain.toggleList(\"taskList\", \"taskItem\"),\n }\n\n const toggle = toggleMap[type]\n if (!toggle) return false\n\n toggle().run()\n }\n\n editor.chain().focus().selectTextblockEnd().run()\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Determines if the list button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n type: ListType\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, type, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(type, editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleList(editor, type)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides list functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleListButton() {\n * const { isVisible, handleToggle, isActive } = useList({ type: \"bulletList\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleToggle}>Bullet List</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedListButton() {\n * const { isVisible, handleToggle, label, isActive } = useList({\n * type: \"orderedList\",\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onToggled: () => console.log('List toggled!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleToggle}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * Toggle List\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useList(config: UseListConfig) {\n const {\n editor: providedEditor,\n type,\n hideWhenUnavailable = false,\n onToggled,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggle = canToggleList(editor, type)\n const isActive = isListActive(editor, type)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, type, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, type, hideWhenUnavailable])\n\n const handleToggle = useCallback(() => {\n if (!editor) return false\n\n const success = toggleList(editor, type)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, type, onToggled])\n\n return {\n isVisible,\n isActive,\n handleToggle,\n canToggle,\n label: listLabels[type],\n shortcutKeys: LIST_SHORTCUT_KEYS[type],\n Icon: listIcons[type],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ListIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 6C7 5.44772 7.44772 5 8 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H8C7.44772 7 7 6.55228 7 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 12C7 11.4477 7.44772 11 8 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H8C7.44772 13 7 12.5523 7 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 18C7 17.4477 7.44772 17 8 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H8C7.44772 19 7 18.5523 7 18Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H3.01C3.56228 5 4.01 5.44772 4.01 6C4.01 6.55228 3.56228 7 3.01 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 12C2 11.4477 2.44772 11 3 11H3.01C3.56228 11 4.01 11.4477 4.01 12C4.01 12.5523 3.56228 13 3.01 13H3C2.44772 13 2 12.5523 2 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 18C2 17.4477 2.44772 17 3 17H3.01C3.56228 17 4.01 17.4477 4.01 18C4.01 18.5523 3.56228 19 3.01 19H3C2.44772 19 2 18.5523 2 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nListIcon.displayName = \"ListIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ListOrderedIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9 6C9 5.44772 9.44772 5 10 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H10C9.44772 7 9 6.55228 9 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9 12C9 11.4477 9.44772 11 10 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H10C9.44772 13 9 12.5523 9 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9 18C9 17.4477 9.44772 17 10 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H10C9.44772 19 9 18.5523 9 18Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3 6C3 5.44772 3.44772 5 4 5H5C5.55228 5 6 5.44772 6 6V10C6 10.5523 5.55228 11 5 11C4.44772 11 4 10.5523 4 10V7C3.44772 7 3 6.55228 3 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3 10C3 9.44772 3.44772 9 4 9H6C6.55228 9 7 9.44772 7 10C7 10.5523 6.55228 11 6 11H4C3.44772 11 3 10.5523 3 10Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.82219 13.0431C6.54543 13.4047 6.99997 14.1319 6.99997 15C6.99997 15.5763 6.71806 16.0426 6.48747 16.35C6.31395 16.5814 6.1052 16.8044 5.91309 17H5.99997C6.55226 17 6.99997 17.4477 6.99997 18C6.99997 18.5523 6.55226 19 5.99997 19H3.99997C3.44769 19 2.99997 18.5523 2.99997 18C2.99997 17.4237 3.28189 16.9575 3.51247 16.65C3.74323 16.3424 4.03626 16.0494 4.26965 15.8161C4.27745 15.8083 4.2852 15.8006 4.29287 15.7929C4.55594 15.5298 4.75095 15.3321 4.88748 15.15C4.96287 15.0495 4.99021 14.9922 4.99911 14.9714C4.99535 14.9112 4.9803 14.882 4.9739 14.8715C4.96613 14.8588 4.95382 14.845 4.92776 14.8319C4.87723 14.8067 4.71156 14.7623 4.44719 14.8944C3.95321 15.1414 3.35254 14.9412 3.10555 14.4472C2.85856 13.9533 3.05878 13.3526 3.55276 13.1056C4.28839 12.7378 5.12272 12.6934 5.82219 13.0431Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nListOrderedIcon.displayName = \"ListOrderedIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ListTodoIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 4.89543 2.89543 4 4 4H8C9.10457 4 10 4.89543 10 6V10C10 11.1046 9.10457 12 8 12H4C2.89543 12 2 11.1046 2 10V6ZM8 6H4V10H8V6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.70711 14.2929C10.0976 14.6834 10.0976 15.3166 9.70711 15.7071L5.70711 19.7071C5.31658 20.0976 4.68342 20.0976 4.29289 19.7071L2.29289 17.7071C1.90237 17.3166 1.90237 16.6834 2.29289 16.2929C2.68342 15.9024 3.31658 15.9024 3.70711 16.2929L5 17.5858L8.29289 14.2929C8.68342 13.9024 9.31658 13.9024 9.70711 14.2929Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 6C12 5.44772 12.4477 5 13 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H13C12.4477 7 12 6.55228 12 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 12C12 11.4477 12.4477 11 13 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H13C12.4477 13 12 12.5523 12 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 18C12 17.4477 12.4477 17 13 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H13C12.4477 19 12 18.5523 12 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nListTodoIcon.displayName = \"ListTodoIcon\"\n","\"use client\"\n\nimport { useEffect, useMemo, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { ListIcon } from \"../../../components/tiptap-icons/list-icon\"\nimport { ListOrderedIcon } from \"../../../components/tiptap-icons/list-ordered-icon\"\nimport { ListTodoIcon } from \"../../../components/tiptap-icons/list-todo-icon\"\n\n// --- Lib ---\nimport { isNodeInSchema } from \"../../../lib/tiptap-utils\"\n\n// --- Tiptap UI ---\nimport {\n canToggleList,\n isListActive,\n listIcons,\n type ListType,\n} from \"../../../components/tiptap-ui/list-button\"\n\n/**\n * Configuration for the list dropdown menu functionality\n */\nexport interface UseListDropdownMenuConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The list types to display in the dropdown.\n * @default [\"bulletList\", \"orderedList\", \"taskList\"]\n */\n types?: ListType[]\n /**\n * Whether the dropdown should be hidden when no list types are available\n * @default false\n */\n hideWhenUnavailable?: boolean\n}\n\nexport interface ListOption {\n label: string\n type: ListType\n icon: React.ElementType\n}\n\nexport const listOptions: ListOption[] = [\n {\n label: \"Bullet List\",\n type: \"bulletList\",\n icon: ListIcon,\n },\n {\n label: \"Ordered List\",\n type: \"orderedList\",\n icon: ListOrderedIcon,\n },\n {\n label: \"Task List\",\n type: \"taskList\",\n icon: ListTodoIcon,\n },\n]\n\nexport function canToggleAnyList(\n editor: Editor | null,\n listTypes: ListType[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n return listTypes.some((type) => canToggleList(editor, type))\n}\n\nexport function isAnyListActive(\n editor: Editor | null,\n listTypes: ListType[]\n): boolean {\n if (!editor || !editor.isEditable) return false\n return listTypes.some((type) => isListActive(editor, type))\n}\n\nexport function getFilteredListOptions(\n availableTypes: ListType[]\n): typeof listOptions {\n return listOptions.filter(\n (option) => !option.type || availableTypes.includes(option.type)\n )\n}\n\nexport function shouldShowListDropdown(params: {\n editor: Editor | null\n listTypes: ListType[]\n hideWhenUnavailable: boolean\n listInSchema: boolean\n canToggleAny: boolean\n}): boolean {\n const { editor, hideWhenUnavailable, listInSchema, canToggleAny } = params\n\n if (!listInSchema || !editor) {\n return false\n }\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleAny\n }\n\n return true\n}\n\n/**\n * Gets the currently active list type from the available types\n */\nexport function getActiveListType(\n editor: Editor | null,\n availableTypes: ListType[]\n): ListType | undefined {\n if (!editor || !editor.isEditable) return undefined\n return availableTypes.find((type) => isListActive(editor, type))\n}\n\n/**\n * Custom hook that provides list dropdown menu functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MyListDropdown() {\n * const {\n * isVisible,\n * activeType,\n * isAnyActive,\n * canToggleAny,\n * filteredLists,\n * } = useListDropdownMenu()\n *\n * if (!isVisible) return null\n *\n * return (\n * <DropdownMenu>\n * // dropdown content\n * </DropdownMenu>\n * )\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedListDropdown() {\n * const {\n * isVisible,\n * activeType,\n * } = useListDropdownMenu({\n * editor: myEditor,\n * types: [\"bulletList\", \"orderedList\"],\n * hideWhenUnavailable: true,\n * })\n *\n * // component implementation\n * }\n * ```\n */\nexport function useListDropdownMenu(config?: UseListDropdownMenuConfig) {\n const {\n editor: providedEditor,\n types = [\"bulletList\", \"orderedList\", \"taskList\"],\n hideWhenUnavailable = false,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState(true)\n\n const listInSchema = types.some((type) => isNodeInSchema(type, editor))\n\n const filteredLists = useMemo(() => getFilteredListOptions(types), [types])\n\n const canToggleAny = canToggleAnyList(editor, types)\n const isAnyActive = isAnyListActive(editor, types)\n const activeType = getActiveListType(editor, types)\n const activeList = filteredLists.find((option) => option.type === activeType)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(\n shouldShowListDropdown({\n editor,\n listTypes: types,\n hideWhenUnavailable,\n listInSchema,\n canToggleAny,\n })\n )\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [canToggleAny, editor, hideWhenUnavailable, listInSchema, types])\n\n return {\n isVisible,\n activeType,\n isActive: isAnyActive,\n canToggle: canToggleAny,\n types,\n filteredLists,\n label: \"List\",\n Icon: activeList ? listIcons[activeList.type] : ListIcon,\n }\n}\n","\"use client\";\n\nimport { forwardRef, useCallback } from \"react\";\n\n// --- Tiptap UI ---\nimport type { UseBlockquoteConfig } from \"../blockquote-button\";\nimport {\n BLOCKQUOTE_SHORTCUT_KEY,\n useBlockquote,\n} from \"../blockquote-button\";\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\";\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\";\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../tiptap-ui-primitive/button\";\nimport { Button } from \"../../tiptap-ui-primitive/button\";\nimport { Badge } from \"../../tiptap-ui-primitive/badge\";\n\nexport interface BlockquoteButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseBlockquoteConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string;\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean;\n}\n\nexport function BlockquoteShortcutBadge({\n shortcutKeys = BLOCKQUOTE_SHORTCUT_KEY,\n}: {\n shortcutKeys?: string;\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>;\n}\n\n/**\n * Button component for toggling blockquote in a Tiptap editor.\n *\n * For custom button implementations, use the `useBlockquote` hook instead.\n */\nexport const BlockquoteButton = forwardRef<\n HTMLButtonElement,\n BlockquoteButtonProps\n>(\n (\n {\n editor: providedEditor,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = false,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor);\n const {\n isVisible,\n canToggle,\n isActive,\n handleToggle,\n label,\n shortcutKeys,\n Icon,\n } = useBlockquote({\n editor,\n hideWhenUnavailable,\n onToggled,\n });\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n handleToggle();\n },\n [handleToggle, onClick]\n );\n\n if (!isVisible) {\n return null;\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canToggle}\n data-disabled={!canToggle}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={`${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")})`\n : \"\"\n }`}\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <BlockquoteShortcutBadge shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n );\n }\n);\n\nBlockquoteButton.displayName = \"BlockquoteButton\";\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\nimport { NodeSelection, TextSelection } from \"@tiptap/pm/state\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { BlockquoteIcon } from \"../../tiptap-icons/blockquote-icon\"\n\n// --- UI Utils ---\nimport {\n findNodePosition,\n isNodeInSchema,\n isNodeTypeSelected,\n isValidPosition,\n selectionWithinConvertibleTypes,\n} from \"../../../lib/tiptap-utils\"\n\nexport const BLOCKQUOTE_SHORTCUT_KEY = \"mod+shift+b\"\n\n/**\n * Configuration for the blockquote functionality\n */\nexport interface UseBlockquoteConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Whether the button should hide when blockquote is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful toggle.\n */\n onToggled?: () => void\n}\n\n/**\n * Checks if blockquote can be toggled in the current editor state\n */\nexport function canToggleBlockquote(\n editor: Editor | null,\n turnInto: boolean = true\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (\n !isNodeInSchema(\"blockquote\", editor) ||\n isNodeTypeSelected(editor, [\"image\"])\n )\n return false\n\n if (!turnInto) {\n return editor.can().toggleWrap(\"blockquote\")\n }\n\n // Ensure selection is in nodes we're allowed to convert\n if (\n !selectionWithinConvertibleTypes(editor, [\n \"paragraph\",\n \"heading\",\n \"bulletList\",\n \"orderedList\",\n \"taskList\",\n \"blockquote\",\n \"codeBlock\",\n ])\n )\n return false\n\n // Either we can wrap in blockquote directly on the selection,\n // or we can clear formatting/nodes to arrive at a blockquote.\n return editor.can().toggleWrap(\"blockquote\") || editor.can().clearNodes()\n}\n\n/**\n * Toggles blockquote formatting for a specific node or the current selection\n */\nexport function toggleBlockquote(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canToggleBlockquote(editor)) return false\n\n try {\n const view = editor.view\n let state = view.state\n let tr = state.tr\n\n // No selection, find the the cursor position\n if (state.selection.empty || state.selection instanceof TextSelection) {\n const pos = findNodePosition({\n editor,\n node: state.selection.$anchor.node(1),\n })?.pos\n if (!isValidPosition(pos)) return false\n\n tr = tr.setSelection(NodeSelection.create(state.doc, pos))\n view.dispatch(tr)\n state = view.state\n }\n\n const selection = state.selection\n\n let chain = editor.chain().focus()\n\n // Handle NodeSelection\n if (selection instanceof NodeSelection) {\n const firstChild = selection.node.firstChild?.firstChild\n const lastChild = selection.node.lastChild?.lastChild\n\n const from = firstChild\n ? selection.from + firstChild.nodeSize\n : selection.from + 1\n\n const to = lastChild\n ? selection.to - lastChild.nodeSize\n : selection.to - 1\n\n const resolvedFrom = state.doc.resolve(from)\n const resolvedTo = state.doc.resolve(to)\n\n chain = chain\n .setTextSelection(TextSelection.between(resolvedFrom, resolvedTo))\n .clearNodes()\n }\n\n const toggle = editor.isActive(\"blockquote\")\n ? chain.lift(\"blockquote\")\n : chain.wrapIn(\"blockquote\")\n\n toggle.run()\n\n editor.chain().focus().selectTextblockEnd().run()\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Determines if the blockquote button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isNodeInSchema(\"blockquote\", editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleBlockquote(editor)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides blockquote functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage - no params needed\n * function MySimpleBlockquoteButton() {\n * const { isVisible, handleToggle, isActive } = useBlockquote()\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleToggle}>Blockquote</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedBlockquoteButton() {\n * const { isVisible, handleToggle, label, isActive } = useBlockquote({\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onToggled: () => console.log('Blockquote toggled!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleToggle}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * Toggle Blockquote\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useBlockquote(config?: UseBlockquoteConfig) {\n const {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onToggled,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggle = canToggleBlockquote(editor)\n const isActive = editor?.isActive(\"blockquote\") || false\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable])\n\n const handleToggle = useCallback(() => {\n if (!editor) return false\n\n const success = toggleBlockquote(editor)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, onToggled])\n\n return {\n isVisible,\n isActive,\n handleToggle,\n canToggle,\n label: \"Blockquote\",\n shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,\n Icon: BlockquoteIcon,\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const BlockquoteIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 6C8 5.44772 8.44772 5 9 5H16C16.5523 5 17 5.44772 17 6C17 6.55228 16.5523 7 16 7H9C8.44772 7 8 6.55228 8 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4 3C4.55228 3 5 3.44772 5 4L5 20C5 20.5523 4.55229 21 4 21C3.44772 21 3 20.5523 3 20L3 4C3 3.44772 3.44772 3 4 3Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 12C8 11.4477 8.44772 11 9 11H20C20.5523 11 21 11.4477 21 12C21 12.5523 20.5523 13 20 13H9C8.44772 13 8 12.5523 8 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 18C8 17.4477 8.44772 17 9 17H16C16.5523 17 17 17.4477 17 18C17 18.5523 16.5523 19 16 19H9C8.44772 19 8 18.5523 8 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nBlockquoteIcon.displayName = \"BlockquoteIcon\"\n","\"use client\"\n\nimport { forwardRef, useMemo, useRef, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation\"\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { BanIcon } from \"../../../components/tiptap-icons/ban-icon\"\nimport { HighlighterIcon } from \"../../../components/tiptap-icons/highlighter-icon\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n} from \"../../../components/tiptap-ui-primitive/popover\"\nimport { Separator } from \"../../../components/tiptap-ui-primitive/separator\"\nimport {\n Card,\n CardBody,\n CardItemGroup,\n} from \"../../../components/tiptap-ui-primitive/card\"\n\n// --- Tiptap UI ---\nimport type {\n HighlightColor,\n UseColorHighlightConfig,\n} from \"../../../components/tiptap-ui/color-highlight-button\"\nimport {\n ColorHighlightButton,\n pickHighlightColorsByValue,\n useColorHighlight,\n} from \"../../../components/tiptap-ui/color-highlight-button\"\n\nexport interface ColorHighlightPopoverContentProps {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Optional colors to use in the highlight popover.\n * If not provided, defaults to a predefined set of colors.\n */\n colors?: HighlightColor[]\n}\n\nexport interface ColorHighlightPopoverProps\n extends Omit<ButtonProps, \"type\">,\n Pick<\n UseColorHighlightConfig,\n \"editor\" | \"hideWhenUnavailable\" | \"onApplied\"\n > {\n /**\n * Optional colors to use in the highlight popover.\n * If not provided, defaults to a predefined set of colors.\n */\n colors?: HighlightColor[]\n}\n\nexport const ColorHighlightPopoverButton = forwardRef<\n HTMLButtonElement,\n ButtonProps\n>(({ className, children, ...props }, ref) => (\n <Button\n type=\"button\"\n className={className}\n data-style=\"ghost\"\n data-appearance=\"default\"\n role=\"button\"\n tabIndex={-1}\n aria-label=\"Highlight text\"\n tooltip=\"Highlight\"\n ref={ref}\n {...props}\n >\n {children ?? <HighlighterIcon className=\"tiptap-button-icon\" />}\n </Button>\n))\n\nColorHighlightPopoverButton.displayName = \"ColorHighlightPopoverButton\"\n\nexport function ColorHighlightPopoverContent({\n editor,\n colors = pickHighlightColorsByValue([\n \"var(--tt-color-highlight-green)\",\n \"var(--tt-color-highlight-blue)\",\n \"var(--tt-color-highlight-red)\",\n \"var(--tt-color-highlight-purple)\",\n \"var(--tt-color-highlight-yellow)\",\n ]),\n}: ColorHighlightPopoverContentProps) {\n const { handleRemoveHighlight } = useColorHighlight({ editor })\n const isMobile = useIsBreakpoint()\n const containerRef = useRef<HTMLDivElement>(null)\n\n const menuItems = useMemo(\n () => [...colors, { label: \"Remove highlight\", value: \"none\" }],\n [colors]\n )\n\n const { selectedIndex } = useMenuNavigation({\n containerRef,\n items: menuItems,\n orientation: \"both\",\n onSelect: (item) => {\n if (!containerRef.current) return false\n const highlightedElement = containerRef.current.querySelector(\n '[data-highlighted=\"true\"]'\n ) as HTMLElement\n if (highlightedElement) highlightedElement.click()\n if (item.value === \"none\") handleRemoveHighlight()\n return true\n },\n autoSelectFirstItem: false,\n })\n\n return (\n <Card\n ref={containerRef}\n tabIndex={0}\n style={isMobile ? { boxShadow: \"none\", border: 0 } : {}}\n >\n <CardBody style={isMobile ? { padding: 0 } : {}}>\n <CardItemGroup orientation=\"horizontal\">\n <ButtonGroup orientation=\"horizontal\">\n {colors.map((color, index) => (\n <ColorHighlightButton\n key={color.value}\n editor={editor}\n highlightColor={color.value}\n tooltip={color.label}\n aria-label={`${color.label} highlight color`}\n tabIndex={index === selectedIndex ? 0 : -1}\n data-highlighted={selectedIndex === index}\n />\n ))}\n </ButtonGroup>\n <Separator />\n <ButtonGroup orientation=\"horizontal\">\n <Button\n onClick={handleRemoveHighlight}\n aria-label=\"Remove highlight\"\n tooltip=\"Remove highlight\"\n tabIndex={selectedIndex === colors.length ? 0 : -1}\n type=\"button\"\n role=\"menuitem\"\n data-style=\"ghost\"\n data-highlighted={selectedIndex === colors.length}\n >\n <BanIcon className=\"tiptap-button-icon\" />\n </Button>\n </ButtonGroup>\n </CardItemGroup>\n </CardBody>\n </Card>\n )\n}\n\nexport function ColorHighlightPopover({\n editor: providedEditor,\n colors = pickHighlightColorsByValue([\n \"var(--tt-color-highlight-green)\",\n \"var(--tt-color-highlight-blue)\",\n \"var(--tt-color-highlight-red)\",\n \"var(--tt-color-highlight-purple)\",\n \"var(--tt-color-highlight-yellow)\",\n ]),\n hideWhenUnavailable = false,\n onApplied,\n ...props\n}: ColorHighlightPopoverProps) {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState(false)\n const { isVisible, canColorHighlight, isActive, label, Icon } =\n useColorHighlight({\n editor,\n hideWhenUnavailable,\n onApplied,\n })\n\n if (!isVisible) return null\n\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild>\n <ColorHighlightPopoverButton\n disabled={!canColorHighlight}\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canColorHighlight}\n aria-pressed={isActive}\n aria-label={label}\n tooltip={label}\n {...props}\n >\n <Icon className=\"tiptap-button-icon\" />\n </ColorHighlightPopoverButton>\n </PopoverTrigger>\n <PopoverContent aria-label=\"Highlight colors\">\n <ColorHighlightPopoverContent editor={editor} colors={colors} />\n </PopoverContent>\n </Popover>\n )\n}\n\nexport default ColorHighlightPopover\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const BanIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4.43471 4.01458C4.34773 4.06032 4.26607 4.11977 4.19292 4.19292C4.11977 4.26607 4.06032 4.34773 4.01458 4.43471C2.14611 6.40628 1 9.0693 1 12C1 18.0751 5.92487 23 12 23C14.9306 23 17.5936 21.854 19.5651 19.9856C19.6522 19.9398 19.7339 19.8803 19.8071 19.8071C19.8803 19.7339 19.9398 19.6522 19.9856 19.5651C21.854 17.5936 23 14.9306 23 12C23 5.92487 18.0751 1 12 1C9.0693 1 6.40628 2.14611 4.43471 4.01458ZM6.38231 4.9681C7.92199 3.73647 9.87499 3 12 3C16.9706 3 21 7.02944 21 12C21 14.125 20.2635 16.078 19.0319 17.6177L6.38231 4.9681ZM17.6177 19.0319C16.078 20.2635 14.125 21 12 21C7.02944 21 3 16.9706 3 12C3 9.87499 3.73647 7.92199 4.9681 6.38231L17.6177 19.0319Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nBanIcon.displayName = \"BanIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const HighlighterIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M14.7072 4.70711C15.0977 4.31658 15.0977 3.68342 14.7072 3.29289C14.3167 2.90237 13.6835 2.90237 13.293 3.29289L8.69294 7.89286L8.68594 7.9C8.13626 8.46079 7.82837 9.21474 7.82837 10C7.82837 10.2306 7.85491 10.4584 7.90631 10.6795L2.29289 16.2929C2.10536 16.4804 2 16.7348 2 17V20C2 20.5523 2.44772 21 3 21H12C12.2652 21 12.5196 20.8946 12.7071 20.7071L15.3205 18.0937C15.5416 18.1452 15.7695 18.1717 16.0001 18.1717C16.7853 18.1717 17.5393 17.8639 18.1001 17.3142L22.7072 12.7071C23.0977 12.3166 23.0977 11.6834 22.7072 11.2929C22.3167 10.9024 21.6835 10.9024 21.293 11.2929L16.6971 15.8887C16.5105 16.0702 16.2605 16.1717 16.0001 16.1717C15.7397 16.1717 15.4897 16.0702 15.303 15.8887L10.1113 10.697C9.92992 10.5104 9.82837 10.2604 9.82837 10C9.82837 9.73963 9.92992 9.48958 10.1113 9.30297L14.7072 4.70711ZM13.5858 17L9.00004 12.4142L4 17.4142V19H11.5858L13.5858 17Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nHighlighterIcon.displayName = \"HighlighterIcon\"\n","\"use client\"\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/popover/popover.scss\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n align={align}\n sideOffset={sideOffset}\n className={cn(\"tiptap-popover\", className)}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverTrigger, PopoverContent }\n","\"use client\"\n\nimport { forwardRef, useCallback, useMemo } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type { UseColorHighlightConfig } from \"../../../components/tiptap-ui/color-highlight-button\"\nimport {\n COLOR_HIGHLIGHT_SHORTCUT_KEY,\n useColorHighlight,\n} from \"../../../components/tiptap-ui/color-highlight-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\n// --- Styles ---\nimport \"../../../components/tiptap-ui/color-highlight-button/color-highlight-button.scss\"\n\nexport interface ColorHighlightButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseColorHighlightConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function ColorHighlightShortcutBadge({\n shortcutKeys = COLOR_HIGHLIGHT_SHORTCUT_KEY,\n}: {\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for applying color highlights in a Tiptap editor.\n *\n * Supports two highlighting modes:\n * - \"mark\": Uses the highlight mark extension (default)\n * - \"node\": Uses the node background extension\n *\n * For custom button implementations, use the `useColorHighlight` hook instead.\n *\n * @example\n * ```tsx\n * // Mark-based highlighting (default)\n * <ColorHighlightButton highlightColor=\"yellow\" />\n *\n * // Node-based background coloring\n * <ColorHighlightButton\n * highlightColor=\"var(--tt-color-highlight-blue)\"\n * mode=\"node\"\n * />\n *\n * // With custom callback\n * <ColorHighlightButton\n * highlightColor=\"red\"\n * mode=\"mark\"\n * onApplied={({ color, mode }) => console.log(`Applied ${color} in ${mode} mode`)}\n * />\n * ```\n */\nexport const ColorHighlightButton = forwardRef<\n HTMLButtonElement,\n ColorHighlightButtonProps\n>(\n (\n {\n editor: providedEditor,\n highlightColor,\n text,\n hideWhenUnavailable = false,\n mode = \"mark\",\n onApplied,\n showShortcut = false,\n onClick,\n children,\n style,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n canColorHighlight,\n isActive,\n handleColorHighlight,\n label,\n shortcutKeys,\n } = useColorHighlight({\n editor,\n highlightColor,\n label: text || `Toggle highlight (${highlightColor})`,\n hideWhenUnavailable,\n mode,\n onApplied,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleColorHighlight()\n },\n [handleColorHighlight, onClick]\n )\n\n const buttonStyle = useMemo(\n () =>\n ({\n ...style,\n \"--highlight-color\": highlightColor,\n }) as React.CSSProperties,\n [highlightColor, style]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n role=\"button\"\n tabIndex={-1}\n disabled={!canColorHighlight}\n data-disabled={!canColorHighlight}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={label}\n onClick={handleClick}\n style={buttonStyle}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <span\n className=\"tiptap-button-highlight\"\n style={\n { \"--highlight-color\": highlightColor } as React.CSSProperties\n }\n />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <ColorHighlightShortcutBadge shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nColorHighlightButton.displayName = \"ColorHighlightButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\nimport { useHotkeys } from \"react-hotkeys-hook\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\n\n// --- Lib ---\nimport {\n isMarkInSchema,\n isNodeTypeSelected,\n isExtensionAvailable,\n} from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { HighlighterIcon } from \"../../../components/tiptap-icons/highlighter-icon\"\n\nexport const COLOR_HIGHLIGHT_SHORTCUT_KEY = \"mod+shift+h\"\nexport const HIGHLIGHT_COLORS = [\n {\n label: \"Default background\",\n value: \"var(--tt-bg-color)\",\n border: \"var(--tt-bg-color-contrast)\",\n },\n {\n label: \"Gray background\",\n value: \"var(--tt-color-highlight-gray)\",\n border: \"var(--tt-color-highlight-gray-contrast)\",\n },\n {\n label: \"Brown background\",\n value: \"var(--tt-color-highlight-brown)\",\n border: \"var(--tt-color-highlight-brown-contrast)\",\n },\n {\n label: \"Orange background\",\n value: \"var(--tt-color-highlight-orange)\",\n border: \"var(--tt-color-highlight-orange-contrast)\",\n },\n {\n label: \"Yellow background\",\n value: \"var(--tt-color-highlight-yellow)\",\n border: \"var(--tt-color-highlight-yellow-contrast)\",\n },\n {\n label: \"Green background\",\n value: \"var(--tt-color-highlight-green)\",\n border: \"var(--tt-color-highlight-green-contrast)\",\n },\n {\n label: \"Blue background\",\n value: \"var(--tt-color-highlight-blue)\",\n border: \"var(--tt-color-highlight-blue-contrast)\",\n },\n {\n label: \"Purple background\",\n value: \"var(--tt-color-highlight-purple)\",\n border: \"var(--tt-color-highlight-purple-contrast)\",\n },\n {\n label: \"Pink background\",\n value: \"var(--tt-color-highlight-pink)\",\n border: \"var(--tt-color-highlight-pink-contrast)\",\n },\n {\n label: \"Red background\",\n value: \"var(--tt-color-highlight-red)\",\n border: \"var(--tt-color-highlight-red-contrast)\",\n },\n]\nexport type HighlightColor = (typeof HIGHLIGHT_COLORS)[number]\n\nexport type HighlightMode = \"mark\" | \"node\"\n\n/**\n * Configuration for the color highlight functionality\n */\nexport interface UseColorHighlightConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The color to apply when toggling the highlight.\n */\n highlightColor?: string\n /**\n * Optional label to display alongside the icon.\n */\n label?: string\n /**\n * Whether the button should hide when the mark is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * The highlighting mode to use.\n * - \"mark\": Uses the highlight mark extension (default)\n * - \"node\": Uses the node background extension\n * @default \"mark\"\n */\n mode?: HighlightMode\n /**\n * Called when the highlight is applied.\n */\n onApplied?: ({\n color,\n label,\n mode,\n }: {\n color: string\n label: string\n mode: HighlightMode\n }) => void\n}\n\nexport function pickHighlightColorsByValue(values: string[]) {\n const colorMap = new Map(\n HIGHLIGHT_COLORS.map((color) => [color.value, color])\n )\n return values\n .map((value) => colorMap.get(value))\n .filter((color): color is (typeof HIGHLIGHT_COLORS)[number] => !!color)\n}\n\n/**\n * Checks if highlight can be applied based on the mode and current editor state\n */\nexport function canColorHighlight(\n editor: Editor | null,\n mode: HighlightMode = \"mark\"\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n if (mode === \"mark\") {\n if (\n !isMarkInSchema(\"highlight\", editor) ||\n isNodeTypeSelected(editor, [\"image\"])\n )\n return false\n\n return editor.can().setMark(\"highlight\")\n } else {\n if (!isExtensionAvailable(editor, [\"nodeBackground\"])) return false\n\n try {\n return editor.can().setNode(\"nodeBackground\", { backgroundColor: \"test\" })\n } catch {\n return false\n }\n }\n}\n\n/**\n * Checks if highlight is currently active\n */\nexport function isColorHighlightActive(\n editor: Editor | null,\n highlightColor?: string,\n mode: HighlightMode = \"mark\"\n): boolean {\n if (!editor || !editor.isEditable) return false\n\n if (mode === \"mark\") {\n return highlightColor\n ? editor.isActive(\"highlight\", { color: highlightColor })\n : editor.isActive(\"highlight\")\n } else {\n if (!highlightColor) return false\n\n try {\n const { state } = editor\n const { selection } = state\n\n const $pos = selection.$anchor\n for (let depth = $pos.depth; depth >= 0; depth--) {\n const node = $pos.node(depth)\n if (node && node.attrs?.backgroundColor === highlightColor) {\n return true\n }\n }\n return false\n } catch {\n return false\n }\n }\n}\n\n/**\n * Removes highlight based on the mode\n */\nexport function removeHighlight(\n editor: Editor | null,\n mode: HighlightMode = \"mark\"\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canColorHighlight(editor, mode)) return false\n\n if (mode === \"mark\") {\n return editor.chain().focus().unsetMark(\"highlight\").run()\n } else {\n return editor.chain().focus().unsetBackgroundColor().run()\n }\n}\n\n/**\n * Determines if the highlight button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n mode: HighlightMode\n}): boolean {\n const { editor, hideWhenUnavailable, mode } = props\n\n if (!editor || !editor.isEditable) return false\n\n if (mode === \"mark\") {\n if (!isMarkInSchema(\"highlight\", editor)) return false\n } else {\n if (!isExtensionAvailable(editor, [\"nodeBackground\"])) return false\n }\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canColorHighlight(editor, mode)\n }\n\n return true\n}\n\nexport function useColorHighlight(config: UseColorHighlightConfig) {\n const {\n editor: providedEditor,\n label,\n highlightColor,\n hideWhenUnavailable = false,\n mode = \"mark\",\n onApplied,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const isMobile = useIsBreakpoint()\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canColorHighlightState = canColorHighlight(editor, mode)\n const isActive = isColorHighlightActive(editor, highlightColor, mode)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable, mode }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable, mode])\n\n const handleColorHighlight = useCallback(() => {\n if (!editor || !canColorHighlightState || !highlightColor || !label)\n return false\n\n if (mode === \"mark\") {\n if (editor.state.storedMarks) {\n const highlightMarkType = editor.schema.marks.highlight\n if (highlightMarkType) {\n editor.view.dispatch(\n editor.state.tr.removeStoredMark(highlightMarkType)\n )\n }\n }\n\n setTimeout(() => {\n const success = editor\n .chain()\n .focus()\n .toggleMark(\"highlight\", { color: highlightColor })\n .run()\n if (success) {\n onApplied?.({ color: highlightColor, label, mode })\n }\n return success\n }, 0)\n\n return true\n } else {\n const success = editor\n .chain()\n .focus()\n .setNode(\"nodeBackground\", { backgroundColor: highlightColor })\n .run()\n\n if (success) {\n onApplied?.({ color: highlightColor, label, mode })\n }\n return success\n }\n }, [canColorHighlightState, highlightColor, editor, label, onApplied, mode])\n\n const handleRemoveHighlight = useCallback(() => {\n const success = removeHighlight(editor, mode)\n if (success) {\n onApplied?.({ color: \"\", label: \"Remove highlight\", mode })\n }\n return success\n }, [editor, onApplied, mode])\n\n useHotkeys(\n COLOR_HIGHLIGHT_SHORTCUT_KEY,\n (event) => {\n event.preventDefault()\n handleColorHighlight()\n },\n {\n enabled: isVisible && canColorHighlightState,\n enableOnContentEditable: !isMobile,\n enableOnFormTags: true,\n }\n )\n\n return {\n isVisible,\n isActive,\n handleColorHighlight,\n handleRemoveHighlight,\n canColorHighlight: canColorHighlightState,\n label: label || `Highlight`,\n shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,\n Icon: HighlighterIcon,\n mode,\n }\n}\n","\"use client\"\n\nimport { forwardRef, useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useIsBreakpoint } from \"../../../hooks/use-is-breakpoint\"\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { CornerDownLeftIcon } from \"../../../components/tiptap-icons/corner-down-left-icon\"\nimport { ExternalLinkIcon } from \"../../../components/tiptap-icons/external-link-icon\"\nimport { LinkIcon } from \"../../../components/tiptap-icons/link-icon\"\nimport { TrashIcon } from \"../../../components/tiptap-icons/trash-icon\"\n\n// --- Tiptap UI ---\nimport type { UseLinkPopoverConfig } from \"../../../components/tiptap-ui/link-popover\"\nimport { useLinkPopover } from \"../../../components/tiptap-ui/link-popover\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button, ButtonGroup } from \"../../../components/tiptap-ui-primitive/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../components/tiptap-ui-primitive/popover\"\nimport { Separator } from \"../../../components/tiptap-ui-primitive/separator\"\nimport {\n Card,\n CardBody,\n CardItemGroup,\n} from \"../../../components/tiptap-ui-primitive/card\"\nimport { Input, InputGroup } from \"../../../components/tiptap-ui-primitive/input\"\n\nexport interface LinkMainProps {\n /**\n * The URL to set for the link.\n */\n url: string\n /**\n * Function to update the URL state.\n */\n setUrl: React.Dispatch<React.SetStateAction<string | null>>\n /**\n * Function to set the link in the editor.\n */\n setLink: () => void\n /**\n * Function to remove the link from the editor.\n */\n removeLink: () => void\n /**\n * Function to open the link.\n */\n openLink: () => void\n /**\n * Whether the link is currently active in the editor.\n */\n isActive: boolean\n}\n\nexport interface LinkPopoverProps\n extends Omit<ButtonProps, \"type\">,\n UseLinkPopoverConfig {\n /**\n * Callback for when the popover opens or closes.\n */\n onOpenChange?: (isOpen: boolean) => void\n /**\n * Whether to automatically open the popover when a link is active.\n * @default true\n */\n autoOpenOnLinkActive?: boolean\n}\n\n/**\n * Link button component for triggering the link popover\n */\nexport const LinkButton = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <Button\n type=\"button\"\n className={className}\n data-style=\"ghost\"\n role=\"button\"\n tabIndex={-1}\n aria-label=\"Link\"\n tooltip=\"Link\"\n ref={ref}\n {...props}\n >\n {children || <LinkIcon className=\"tiptap-button-icon\" />}\n </Button>\n )\n }\n)\n\nLinkButton.displayName = \"LinkButton\"\n\n/**\n * Main content component for the link popover\n */\nconst LinkMain: React.FC<LinkMainProps> = ({\n url,\n setUrl,\n setLink,\n removeLink,\n openLink,\n isActive,\n}) => {\n const isMobile = useIsBreakpoint()\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Enter\") {\n event.preventDefault()\n setLink()\n }\n }\n\n return (\n <Card\n style={{\n ...(isMobile ? { boxShadow: \"none\", border: 0 } : {}),\n }}\n >\n <CardBody\n style={{\n ...(isMobile ? { padding: 0 } : {}),\n }}\n >\n <CardItemGroup orientation=\"horizontal\">\n <InputGroup>\n <Input\n type=\"url\"\n placeholder=\"Paste a link...\"\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n onKeyDown={handleKeyDown}\n autoFocus\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n />\n </InputGroup>\n\n <ButtonGroup orientation=\"horizontal\">\n <Button\n type=\"button\"\n onClick={setLink}\n title=\"Apply link\"\n disabled={!url && !isActive}\n data-style=\"ghost\"\n >\n <CornerDownLeftIcon className=\"tiptap-button-icon\" />\n </Button>\n </ButtonGroup>\n\n <Separator />\n\n <ButtonGroup orientation=\"horizontal\">\n <Button\n type=\"button\"\n onClick={openLink}\n title=\"Open in new window\"\n disabled={!url && !isActive}\n data-style=\"ghost\"\n >\n <ExternalLinkIcon className=\"tiptap-button-icon\" />\n </Button>\n\n <Button\n type=\"button\"\n onClick={removeLink}\n title=\"Remove link\"\n disabled={!url && !isActive}\n data-style=\"ghost\"\n >\n <TrashIcon className=\"tiptap-button-icon\" />\n </Button>\n </ButtonGroup>\n </CardItemGroup>\n </CardBody>\n </Card>\n )\n}\n\n/**\n * Link content component for standalone use\n */\nexport const LinkContent: React.FC<{\n editor?: Editor | null\n}> = ({ editor }) => {\n const linkPopover = useLinkPopover({\n editor,\n })\n\n return <LinkMain {...linkPopover} />\n}\n\n/**\n * Link popover component for Tiptap editors.\n *\n * For custom popover implementations, use the `useLinkPopover` hook instead.\n */\nexport const LinkPopover = forwardRef<HTMLButtonElement, LinkPopoverProps>(\n (\n {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onSetLink,\n onOpenChange,\n autoOpenOnLinkActive = true,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const [isOpen, setIsOpen] = useState(false)\n\n const {\n isVisible,\n canSet,\n isActive,\n url,\n setUrl,\n setLink,\n removeLink,\n openLink,\n label,\n Icon,\n } = useLinkPopover({\n editor,\n hideWhenUnavailable,\n onSetLink,\n })\n\n const handleOnOpenChange = useCallback(\n (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen)\n onOpenChange?.(nextIsOpen)\n },\n [onOpenChange]\n )\n\n const handleSetLink = useCallback(() => {\n setLink()\n setIsOpen(false)\n }, [setLink])\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n setIsOpen(!isOpen)\n },\n [onClick, isOpen]\n )\n\n useEffect(() => {\n if (autoOpenOnLinkActive && isActive) {\n setIsOpen(true)\n }\n }, [autoOpenOnLinkActive, isActive])\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Popover open={isOpen} onOpenChange={handleOnOpenChange}>\n <PopoverTrigger asChild>\n <LinkButton\n disabled={!canSet}\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canSet}\n aria-label={label}\n aria-pressed={isActive}\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? <Icon className=\"tiptap-button-icon\" />}\n </LinkButton>\n </PopoverTrigger>\n\n <PopoverContent>\n <LinkMain\n url={url}\n setUrl={setUrl}\n setLink={handleSetLink}\n removeLink={removeLink}\n openLink={openLink}\n isActive={isActive}\n />\n </PopoverContent>\n </Popover>\n )\n }\n)\n\nLinkPopover.displayName = \"LinkPopover\"\n\nexport default LinkPopover\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const CornerDownLeftIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M21 4C21 3.44772 20.5523 3 20 3C19.4477 3 19 3.44772 19 4V11C19 11.7956 18.6839 12.5587 18.1213 13.1213C17.5587 13.6839 16.7956 14 16 14H6.41421L9.70711 10.7071C10.0976 10.3166 10.0976 9.68342 9.70711 9.29289C9.31658 8.90237 8.68342 8.90237 8.29289 9.29289L3.29289 14.2929C2.90237 14.6834 2.90237 15.3166 3.29289 15.7071L8.29289 20.7071C8.68342 21.0976 9.31658 21.0976 9.70711 20.7071C10.0976 20.3166 10.0976 19.6834 9.70711 19.2929L6.41421 16H16C17.3261 16 18.5979 15.4732 19.5355 14.5355C20.4732 13.5979 21 12.3261 21 11V4Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nCornerDownLeftIcon.displayName = \"CornerDownLeftIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ExternalLinkIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M14 3C14 2.44772 14.4477 2 15 2H21C21.5523 2 22 2.44772 22 3V9C22 9.55228 21.5523 10 21 10C20.4477 10 20 9.55228 20 9V5.41421L10.7071 14.7071C10.3166 15.0976 9.68342 15.0976 9.29289 14.7071C8.90237 14.3166 8.90237 13.6834 9.29289 13.2929L18.5858 4H15C14.4477 4 14 3.55228 14 3Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M4.29289 7.29289C4.48043 7.10536 4.73478 7 5 7H11C11.5523 7 12 6.55228 12 6C12 5.44772 11.5523 5 11 5H5C4.20435 5 3.44129 5.31607 2.87868 5.87868C2.31607 6.44129 2 7.20435 2 8V19C2 19.7957 2.31607 20.5587 2.87868 21.1213C3.44129 21.6839 4.20435 22 5 22H16C16.7957 22 17.5587 21.6839 18.1213 21.1213C18.6839 20.5587 19 19.7957 19 19V13C19 12.4477 18.5523 12 18 12C17.4477 12 17 12.4477 17 13V19C17 19.2652 16.8946 19.5196 16.7071 19.7071C16.5196 19.8946 16.2652 20 16 20H5C4.73478 20 4.48043 19.8946 4.29289 19.7071C4.10536 19.5196 4 19.2652 4 19V8C4 7.73478 4.10536 7.48043 4.29289 7.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nExternalLinkIcon.displayName = \"ExternalLinkIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const LinkIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M16.9958 1.06669C15.4226 1.05302 13.907 1.65779 12.7753 2.75074L12.765 2.76086L11.045 4.47086C10.6534 4.86024 10.6515 5.49341 11.0409 5.88507C11.4303 6.27673 12.0634 6.27858 12.4551 5.88919L14.1697 4.18456C14.9236 3.45893 15.9319 3.05752 16.9784 3.06662C18.0272 3.07573 19.0304 3.49641 19.772 4.23804C20.5137 4.97967 20.9344 5.98292 20.9435 7.03171C20.9526 8.07776 20.5515 9.08563 19.8265 9.83941L16.833 12.8329C16.4274 13.2386 15.9393 13.5524 15.4019 13.7529C14.8645 13.9533 14.2903 14.0359 13.7181 13.9949C13.146 13.9539 12.5894 13.7904 12.0861 13.5154C11.5827 13.2404 11.1444 12.8604 10.8008 12.401C10.47 11.9588 9.84333 11.8685 9.40108 12.1993C8.95883 12.5301 8.86849 13.1568 9.1993 13.599C9.71464 14.288 10.3721 14.858 11.1272 15.2705C11.8822 15.683 12.7171 15.9283 13.5753 15.9898C14.4334 16.0513 15.2948 15.9274 16.1009 15.6267C16.907 15.326 17.639 14.8555 18.2473 14.247L21.2472 11.2471L21.2593 11.2347C22.3523 10.1031 22.9571 8.58751 22.9434 7.01433C22.9297 5.44115 22.2987 3.93628 21.1863 2.82383C20.0738 1.71138 18.5689 1.08036 16.9958 1.06669Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M10.4247 8.0102C9.56657 7.94874 8.70522 8.07256 7.89911 8.37326C7.09305 8.67395 6.36096 9.14458 5.75272 9.753L2.75285 12.7529L2.74067 12.7653C1.64772 13.8969 1.04295 15.4125 1.05662 16.9857C1.07029 18.5589 1.70131 20.0637 2.81376 21.1762C3.9262 22.2886 5.43108 22.9196 7.00426 22.9333C8.57744 22.947 10.0931 22.3422 11.2247 21.2493L11.2371 21.2371L12.9471 19.5271C13.3376 19.1366 13.3376 18.5034 12.9471 18.1129C12.5565 17.7223 11.9234 17.7223 11.5328 18.1129L9.82932 19.8164C9.07555 20.5414 8.06768 20.9425 7.02164 20.9334C5.97285 20.9243 4.9696 20.5036 4.22797 19.762C3.48634 19.0203 3.06566 18.0171 3.05655 16.9683C3.04746 15.9222 3.44851 14.9144 4.17355 14.1606L7.16719 11.167C7.5727 10.7613 8.06071 10.4476 8.59811 10.2471C9.13552 10.0467 9.70976 9.96412 10.2819 10.0051C10.854 10.0461 11.4106 10.2096 11.9139 10.4846C12.4173 10.7596 12.8556 11.1397 13.1992 11.599C13.53 12.0412 14.1567 12.1316 14.5989 11.8007C15.0412 11.4699 15.1315 10.8433 14.8007 10.401C14.2854 9.71205 13.6279 9.14198 12.8729 8.72948C12.1178 8.31697 11.2829 8.07166 10.4247 8.0102Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nLinkIcon.displayName = \"LinkIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const TrashIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 5V4C7 3.17477 7.40255 2.43324 7.91789 1.91789C8.43324 1.40255 9.17477 1 10 1H14C14.8252 1 15.5668 1.40255 16.0821 1.91789C16.5975 2.43324 17 3.17477 17 4V5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H20V20C20 20.8252 19.5975 21.5668 19.0821 22.0821C18.5668 22.5975 17.8252 23 17 23H7C6.17477 23 5.43324 22.5975 4.91789 22.0821C4.40255 21.5668 4 20.8252 4 20V7H3C2.44772 7 2 6.55228 2 6C2 5.44772 2.44772 5 3 5H7ZM9 4C9 3.82523 9.09745 3.56676 9.33211 3.33211C9.56676 3.09745 9.82523 3 10 3H14C14.1748 3 14.4332 3.09745 14.6679 3.33211C14.9025 3.56676 15 3.82523 15 4V5H9V4ZM6 7V20C6 20.1748 6.09745 20.4332 6.33211 20.6679C6.56676 20.9025 6.82523 21 7 21H17C17.1748 21 17.4332 20.9025 17.6679 20.6679C17.9025 20.4332 18 20.1748 18 20V7H6Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nTrashIcon.displayName = \"TrashIcon\"\n","\"use client\"\n\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"../../../components/tiptap-ui-primitive/input/input.scss\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input type={type} className={cn(\"tiptap-input\", className)} {...props} />\n )\n}\n\nfunction InputGroup({\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div className={cn(\"tiptap-input-group\", className)} {...props}>\n {children}\n </div>\n )\n}\n\nexport { Input, InputGroup }\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Icons ---\nimport { LinkIcon } from \"../../../components/tiptap-icons/link-icon\"\n\n// --- Lib ---\nimport {\n isMarkInSchema,\n isNodeTypeSelected,\n sanitizeUrl,\n} from \"../../../lib/tiptap-utils\"\n\n/**\n * Configuration for the link popover functionality\n */\nexport interface UseLinkPopoverConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * Whether to hide the link popover when not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called when the link is set.\n */\n onSetLink?: () => void\n}\n\n/**\n * Configuration for the link handler functionality\n */\nexport interface LinkHandlerProps {\n /**\n * The Tiptap editor instance.\n */\n editor: Editor | null\n /**\n * Callback function called when the link is set.\n */\n onSetLink?: () => void\n}\n\n/**\n * Checks if a link can be set in the current editor state\n */\nexport function canSetLink(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n\n // The third argument 'true' checks whether the current selection is inside an image caption, and prevents setting a link there\n // If the selection is inside an image caption, we can't set a link\n if (isNodeTypeSelected(editor, [\"image\"], true)) return false\n return editor.can().setMark(\"link\")\n}\n\n/**\n * Checks if a link is currently active in the editor\n */\nexport function isLinkActive(editor: Editor | null): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive(\"link\")\n}\n\n/**\n * Determines if the link button should be shown\n */\nexport function shouldShowLinkButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, hideWhenUnavailable } = props\n\n const linkInSchema = isMarkInSchema(\"link\", editor)\n\n if (!linkInSchema || !editor) {\n return false\n }\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canSetLink(editor)\n }\n\n return true\n}\n\n/**\n * Custom hook for handling link operations in a Tiptap editor\n */\nexport function useLinkHandler(props: LinkHandlerProps) {\n const { editor, onSetLink } = props\n const [url, setUrl] = useState<string | null>(null)\n\n useEffect(() => {\n if (!editor) return\n\n // Get URL immediately on mount\n const { href } = editor.getAttributes(\"link\")\n\n if (isLinkActive(editor) && url === null) {\n setUrl(href || \"\")\n }\n }, [editor, url])\n\n useEffect(() => {\n if (!editor) return\n\n const updateLinkState = () => {\n const { href } = editor.getAttributes(\"link\")\n setUrl(href || \"\")\n }\n\n editor.on(\"selectionUpdate\", updateLinkState)\n return () => {\n editor.off(\"selectionUpdate\", updateLinkState)\n }\n }, [editor])\n\n const setLink = useCallback(() => {\n if (!url || !editor) return\n\n const { selection } = editor.state\n const isEmpty = selection.empty\n\n let chain = editor.chain().focus()\n\n chain = chain.extendMarkRange(\"link\").setLink({ href: url })\n\n if (isEmpty) {\n chain = chain.insertContent({ type: \"text\", text: url })\n }\n\n chain.run()\n\n setUrl(null)\n\n onSetLink?.()\n }, [editor, onSetLink, url])\n\n const removeLink = useCallback(() => {\n if (!editor) return\n editor\n .chain()\n .focus()\n .extendMarkRange(\"link\")\n .unsetLink()\n .setMeta(\"preventAutolink\", true)\n .run()\n setUrl(\"\")\n }, [editor])\n\n const openLink = useCallback(\n (target: string = \"_blank\", features: string = \"noopener,noreferrer\") => {\n if (!url) return\n\n const safeUrl = sanitizeUrl(url, window.location.href)\n if (safeUrl !== \"#\") {\n window.open(safeUrl, target, features)\n }\n },\n [url]\n )\n\n return {\n url: url || \"\",\n setUrl,\n setLink,\n removeLink,\n openLink,\n }\n}\n\n/**\n * Custom hook for link popover state management\n */\nexport function useLinkState(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n}) {\n const { editor, hideWhenUnavailable = false } = props\n\n const canSet = canSetLink(editor)\n const isActive = isLinkActive(editor)\n\n const [isVisible, setIsVisible] = useState(true)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(\n shouldShowLinkButton({\n editor,\n hideWhenUnavailable,\n })\n )\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable])\n\n return {\n isVisible,\n canSet,\n isActive,\n }\n}\n\n/**\n * Main hook that provides link popover functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MyLinkButton() {\n * const { isVisible, canSet, isActive, Icon, label } = useLinkPopover()\n *\n * if (!isVisible) return null\n *\n * return <button disabled={!canSet}>Link</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedLinkButton() {\n * const { isVisible, canSet, isActive, Icon, label } = useLinkPopover({\n * editor: myEditor,\n * hideWhenUnavailable: true,\n * onSetLink: () => console.log('Link set!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * disabled={!canSet}\n * aria-label={label}\n * aria-pressed={isActive}\n * >\n * <Icon />\n * {label}\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useLinkPopover(config?: UseLinkPopoverConfig) {\n const {\n editor: providedEditor,\n hideWhenUnavailable = false,\n onSetLink,\n } = config || {}\n\n const { editor } = useTiptapEditor(providedEditor)\n\n const { isVisible, canSet, isActive } = useLinkState({\n editor,\n hideWhenUnavailable,\n })\n\n const linkHandler = useLinkHandler({\n editor,\n onSetLink,\n })\n\n return {\n isVisible,\n canSet,\n isActive,\n label: \"Link\",\n Icon: LinkIcon,\n ...linkHandler,\n }\n}\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type { Mark, UseMarkConfig } from \"../../../components/tiptap-ui/mark-button\"\nimport { MARK_SHORTCUT_KEYS, useMark } from \"../../../components/tiptap-ui/mark-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\nexport interface MarkButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseMarkConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function MarkShortcutBadge({\n type,\n shortcutKeys = MARK_SHORTCUT_KEYS[type],\n}: {\n type: Mark\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for toggling marks in a Tiptap editor.\n *\n * For custom button implementations, use the `useMark` hook instead.\n */\nexport const MarkButton = forwardRef<HTMLButtonElement, MarkButtonProps>(\n (\n {\n editor: providedEditor,\n type,\n text,\n hideWhenUnavailable = false,\n onToggled,\n showShortcut = false,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n handleMark,\n label,\n canToggle,\n isActive,\n Icon,\n shortcutKeys,\n } = useMark({\n editor,\n type,\n hideWhenUnavailable,\n onToggled,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleMark()\n },\n [handleMark, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n disabled={!canToggle}\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canToggle}\n role=\"button\"\n tabIndex={-1}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <MarkShortcutBadge type={type} shortcutKeys={shortcutKeys} />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nMarkButton.displayName = \"MarkButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport { isMarkInSchema, isNodeTypeSelected } from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { BoldIcon } from \"../../../components/tiptap-icons/bold-icon\"\nimport { Code2Icon } from \"../../../components/tiptap-icons/code2-icon\"\nimport { ItalicIcon } from \"../../../components/tiptap-icons/italic-icon\"\nimport { StrikeIcon } from \"../../../components/tiptap-icons/strike-icon\"\nimport { SubscriptIcon } from \"../../../components/tiptap-icons/subscript-icon\"\nimport { SuperscriptIcon } from \"../../../components/tiptap-icons/superscript-icon\"\nimport { UnderlineIcon } from \"../../../components/tiptap-icons/underline-icon\"\n\nexport type Mark =\n | \"bold\"\n | \"italic\"\n | \"strike\"\n | \"code\"\n | \"underline\"\n | \"superscript\"\n | \"subscript\"\n\n/**\n * Configuration for the mark functionality\n */\nexport interface UseMarkConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The type of mark to toggle\n */\n type: Mark\n /**\n * Whether the button should hide when mark is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful mark toggle.\n */\n onToggled?: () => void\n}\n\nexport const markIcons = {\n bold: BoldIcon,\n italic: ItalicIcon,\n underline: UnderlineIcon,\n strike: StrikeIcon,\n code: Code2Icon,\n superscript: SuperscriptIcon,\n subscript: SubscriptIcon,\n}\n\nexport const MARK_SHORTCUT_KEYS: Record<Mark, string> = {\n bold: \"mod+b\",\n italic: \"mod+i\",\n underline: \"mod+u\",\n strike: \"mod+shift+s\",\n code: \"mod+e\",\n superscript: \"mod+.\",\n subscript: \"mod+,\",\n}\n\n/**\n * Checks if a mark can be toggled in the current editor state\n */\nexport function canToggleMark(editor: Editor | null, type: Mark): boolean {\n if (!editor || !editor.isEditable) return false\n if (!isMarkInSchema(type, editor) || isNodeTypeSelected(editor, [\"image\"]))\n return false\n\n return editor.can().toggleMark(type)\n}\n\n/**\n * Checks if a mark is currently active\n */\nexport function isMarkActive(editor: Editor | null, type: Mark): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive(type)\n}\n\n/**\n * Toggles a mark in the editor\n */\nexport function toggleMark(editor: Editor | null, type: Mark): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canToggleMark(editor, type)) return false\n\n return editor.chain().focus().toggleMark(type).run()\n}\n\n/**\n * Determines if the mark button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n type: Mark\n hideWhenUnavailable: boolean\n}): boolean {\n const { editor, type, hideWhenUnavailable } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isMarkInSchema(type, editor)) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canToggleMark(editor, type)\n }\n\n return true\n}\n\n/**\n * Gets the formatted mark name\n */\nexport function getFormattedMarkName(type: Mark): string {\n return type.charAt(0).toUpperCase() + type.slice(1)\n}\n\n/**\n * Custom hook that provides mark functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleBoldButton() {\n * const { isVisible, handleMark } = useMark({ type: \"bold\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleMark}>Bold</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedItalicButton() {\n * const { isVisible, handleMark, label, isActive } = useMark({\n * editor: myEditor,\n * type: \"italic\",\n * hideWhenUnavailable: true,\n * onToggled: () => console.log('Mark toggled!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleMark}\n * aria-pressed={isActive}\n * aria-label={label}\n * >\n * Italic\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useMark(config: UseMarkConfig) {\n const {\n editor: providedEditor,\n type,\n hideWhenUnavailable = false,\n onToggled,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canToggle = canToggleMark(editor, type)\n const isActive = isMarkActive(editor, type)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, type, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, type, hideWhenUnavailable])\n\n const handleMark = useCallback(() => {\n if (!editor) return false\n\n const success = toggleMark(editor, type)\n if (success) {\n onToggled?.()\n }\n return success\n }, [editor, type, onToggled])\n\n return {\n isVisible,\n isActive,\n handleMark,\n canToggle,\n label: getFormattedMarkName(type),\n shortcutKeys: MARK_SHORTCUT_KEYS[type],\n Icon: markIcons[type],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const BoldIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M6 2.5C5.17157 2.5 4.5 3.17157 4.5 4V20C4.5 20.8284 5.17157 21.5 6 21.5H15C16.4587 21.5 17.8576 20.9205 18.8891 19.8891C19.9205 18.8576 20.5 17.4587 20.5 16C20.5 14.5413 19.9205 13.1424 18.8891 12.1109C18.6781 11.9 18.4518 11.7079 18.2128 11.5359C19.041 10.5492 19.5 9.29829 19.5 8C19.5 6.54131 18.9205 5.14236 17.8891 4.11091C16.8576 3.07946 15.4587 2.5 14 2.5H6ZM14 10.5C14.663 10.5 15.2989 10.2366 15.7678 9.76777C16.2366 9.29893 16.5 8.66304 16.5 8C16.5 7.33696 16.2366 6.70107 15.7678 6.23223C15.2989 5.76339 14.663 5.5 14 5.5H7.5V10.5H14ZM7.5 18.5V13.5H15C15.663 13.5 16.2989 13.7634 16.7678 14.2322C17.2366 14.7011 17.5 15.337 17.5 16C17.5 16.663 17.2366 17.2989 16.7678 17.7678C16.2989 18.2366 15.663 18.5 15 18.5H7.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nBoldIcon.displayName = \"BoldIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const Code2Icon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M15.4545 4.2983C15.6192 3.77115 15.3254 3.21028 14.7983 3.04554C14.2712 2.88081 13.7103 3.1746 13.5455 3.70175L8.54554 19.7017C8.38081 20.2289 8.6746 20.7898 9.20175 20.9545C9.72889 21.1192 10.2898 20.8254 10.4545 20.2983L15.4545 4.2983Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M6.70711 7.29289C7.09763 7.68342 7.09763 8.31658 6.70711 8.70711L3.41421 12L6.70711 15.2929C7.09763 15.6834 7.09763 16.3166 6.70711 16.7071C6.31658 17.0976 5.68342 17.0976 5.29289 16.7071L1.29289 12.7071C0.902369 12.3166 0.902369 11.6834 1.29289 11.2929L5.29289 7.29289C5.68342 6.90237 6.31658 6.90237 6.70711 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M17.2929 7.29289C17.6834 6.90237 18.3166 6.90237 18.7071 7.29289L22.7071 11.2929C23.0976 11.6834 23.0976 12.3166 22.7071 12.7071L18.7071 16.7071C18.3166 17.0976 17.6834 17.0976 17.2929 16.7071C16.9024 16.3166 16.9024 15.6834 17.2929 15.2929L20.5858 12L17.2929 8.70711C16.9024 8.31658 16.9024 7.68342 17.2929 7.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nCode2Icon.displayName = \"Code2Icon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ItalicIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M15.0222 3H19C19.5523 3 20 3.44772 20 4C20 4.55228 19.5523 5 19 5H15.693L10.443 19H14C14.5523 19 15 19.4477 15 20C15 20.5523 14.5523 21 14 21H9.02418C9.00802 21.0004 8.99181 21.0004 8.97557 21H5C4.44772 21 4 20.5523 4 20C4 19.4477 4.44772 19 5 19H8.30704L13.557 5H10C9.44772 5 9 4.55228 9 4C9 3.44772 9.44772 3 10 3H14.9782C14.9928 2.99968 15.0075 2.99967 15.0222 3Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nItalicIcon.displayName = \"ItalicIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const StrikeIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M9.00039 3H16.0001C16.5524 3 17.0001 3.44772 17.0001 4C17.0001 4.55229 16.5524 5 16.0001 5H9.00011C8.68006 4.99983 8.36412 5.07648 8.07983 5.22349C7.79555 5.37051 7.55069 5.5836 7.36585 5.84487C7.181 6.10614 7.06155 6.40796 7.01754 6.72497C6.97352 7.04198 7.00623 7.36492 7.11292 7.66667C7.29701 8.18737 7.02414 8.75872 6.50344 8.94281C5.98274 9.1269 5.4114 8.85403 5.2273 8.33333C5.01393 7.72984 4.94851 7.08396 5.03654 6.44994C5.12456 5.81592 5.36346 5.21229 5.73316 4.68974C6.10285 4.1672 6.59256 3.74101 7.16113 3.44698C7.72955 3.15303 8.36047 2.99975 9.00039 3Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M18 13H20C20.5523 13 21 12.5523 21 12C21 11.4477 20.5523 11 20 11H4C3.44772 11 3 11.4477 3 12C3 12.5523 3.44772 13 4 13H14C14.7956 13 15.5587 13.3161 16.1213 13.8787C16.6839 14.4413 17 15.2044 17 16C17 16.7956 16.6839 17.5587 16.1213 18.1213C15.5587 18.6839 14.7956 19 14 19H6C5.44772 19 5 19.4477 5 20C5 20.5523 5.44772 21 6 21H14C15.3261 21 16.5979 20.4732 17.5355 19.5355C18.4732 18.5979 19 17.3261 19 16C19 14.9119 18.6453 13.8604 18 13Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nStrikeIcon.displayName = \"StrikeIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const SubscriptIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29289 7.29289C3.68342 6.90237 4.31658 6.90237 4.70711 7.29289L12.7071 15.2929C13.0976 15.6834 13.0976 16.3166 12.7071 16.7071C12.3166 17.0976 11.6834 17.0976 11.2929 16.7071L3.29289 8.70711C2.90237 8.31658 2.90237 7.68342 3.29289 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12.7071 7.29289C13.0976 7.68342 13.0976 8.31658 12.7071 8.70711L4.70711 16.7071C4.31658 17.0976 3.68342 17.0976 3.29289 16.7071C2.90237 16.3166 2.90237 15.6834 3.29289 15.2929L11.2929 7.29289C11.6834 6.90237 12.3166 6.90237 12.7071 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M17.4079 14.3995C18.0284 14.0487 18.7506 13.9217 19.4536 14.0397C20.1566 14.1578 20.7977 14.5138 21.2696 15.0481L21.2779 15.0574L21.2778 15.0575C21.7439 15.5988 22 16.2903 22 17C22 18.0823 21.3962 18.8401 20.7744 19.3404C20.194 19.8073 19.4858 20.141 18.9828 20.378C18.9638 20.387 18.9451 20.3958 18.9266 20.4045C18.4473 20.6306 18.2804 20.7817 18.1922 20.918C18.1773 20.9412 18.1619 20.9681 18.1467 21H21C21.5523 21 22 21.4477 22 22C22 22.5523 21.5523 23 21 23H17C16.4477 23 16 22.5523 16 22C16 21.1708 16.1176 20.4431 16.5128 19.832C16.9096 19.2184 17.4928 18.8695 18.0734 18.5956C18.6279 18.334 19.138 18.0901 19.5207 17.7821C19.8838 17.49 20 17.2477 20 17C20 16.7718 19.9176 16.5452 19.7663 16.3672C19.5983 16.1792 19.3712 16.0539 19.1224 16.0121C18.8722 15.9701 18.6152 16.015 18.3942 16.1394C18.1794 16.2628 18.0205 16.4549 17.9422 16.675C17.7572 17.1954 17.1854 17.4673 16.665 17.2822C16.1446 17.0972 15.8728 16.5254 16.0578 16.005C16.2993 15.3259 16.7797 14.7584 17.4039 14.4018L17.4079 14.3995L17.4079 14.3995Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nSubscriptIcon.displayName = \"SubscriptIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const SuperscriptIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12.7071 7.29289C13.0976 7.68342 13.0976 8.31658 12.7071 8.70711L4.70711 16.7071C4.31658 17.0976 3.68342 17.0976 3.29289 16.7071C2.90237 16.3166 2.90237 15.6834 3.29289 15.2929L11.2929 7.29289C11.6834 6.90237 12.3166 6.90237 12.7071 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29289 7.29289C3.68342 6.90237 4.31658 6.90237 4.70711 7.29289L12.7071 15.2929C13.0976 15.6834 13.0976 16.3166 12.7071 16.7071C12.3166 17.0976 11.6834 17.0976 11.2929 16.7071L3.29289 8.70711C2.90237 8.31658 2.90237 7.68342 3.29289 7.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M17.405 1.40657C18.0246 1.05456 18.7463 0.92634 19.4492 1.04344C20.1521 1.16054 20.7933 1.51583 21.2652 2.0497L21.2697 2.05469L21.2696 2.05471C21.7431 2.5975 22 3.28922 22 4.00203C22 5.08579 21.3952 5.84326 20.7727 6.34289C20.1966 6.80531 19.4941 7.13675 18.9941 7.37261C18.9714 7.38332 18.9491 7.39383 18.9273 7.40415C18.4487 7.63034 18.2814 7.78152 18.1927 7.91844C18.1778 7.94155 18.1625 7.96834 18.1473 8.00003H21C21.5523 8.00003 22 8.44774 22 9.00003C22 9.55231 21.5523 10 21 10H17C16.4477 10 16 9.55231 16 9.00003C16 8.17007 16.1183 7.44255 16.5138 6.83161C16.9107 6.21854 17.4934 5.86971 18.0728 5.59591C18.6281 5.33347 19.1376 5.09075 19.5208 4.78316C19.8838 4.49179 20 4.25026 20 4.00203C20 3.77192 19.9178 3.54865 19.7646 3.37182C19.5968 3.18324 19.3696 3.05774 19.1205 3.01625C18.8705 2.97459 18.6137 3.02017 18.3933 3.14533C18.1762 3.26898 18.0191 3.45826 17.9406 3.67557C17.7531 4.19504 17.18 4.46414 16.6605 4.27662C16.141 4.0891 15.8719 3.51596 16.0594 2.99649C16.303 2.3219 16.7817 1.76125 17.4045 1.40689L17.405 1.40657Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nSuperscriptIcon.displayName = \"SuperscriptIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const UnderlineIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7 4C7 3.44772 6.55228 3 6 3C5.44772 3 5 3.44772 5 4V10C5 11.8565 5.7375 13.637 7.05025 14.9497C8.36301 16.2625 10.1435 17 12 17C13.8565 17 15.637 16.2625 16.9497 14.9497C18.2625 13.637 19 11.8565 19 10V4C19 3.44772 18.5523 3 18 3C17.4477 3 17 3.44772 17 4V10C17 11.3261 16.4732 12.5979 15.5355 13.5355C14.5979 14.4732 13.3261 15 12 15C10.6739 15 9.40215 14.4732 8.46447 13.5355C7.52678 12.5979 7 11.3261 7 10V4ZM4 19C3.44772 19 3 19.4477 3 20C3 20.5523 3.44772 21 4 21H20C20.5523 21 21 20.5523 21 20C21 19.4477 20.5523 19 20 19H4Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nUnderlineIcon.displayName = \"UnderlineIcon\"\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type {\n TextAlign,\n UseTextAlignConfig,\n} from \"../../../components/tiptap-ui/text-align-button\"\nimport {\n TEXT_ALIGN_SHORTCUT_KEYS,\n useTextAlign,\n} from \"../../../components/tiptap-ui/text-align-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\ntype IconComponent = ({ className, ...props }: IconProps) => React.ReactElement\n\nexport interface TextAlignButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseTextAlignConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n /**\n * Optional custom icon component to render instead of the default.\n */\n icon?: React.MemoExoticComponent<IconComponent> | React.FC<IconProps>\n}\n\nexport function TextAlignShortcutBadge({\n align,\n shortcutKeys = TEXT_ALIGN_SHORTCUT_KEYS[align],\n}: {\n align: TextAlign\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for setting text alignment in a Tiptap editor.\n *\n * For custom button implementations, use the `useTextAlign` hook instead.\n */\nexport const TextAlignButton = forwardRef<\n HTMLButtonElement,\n TextAlignButtonProps\n>(\n (\n {\n editor: providedEditor,\n align,\n text,\n hideWhenUnavailable = false,\n onAligned,\n showShortcut = false,\n onClick,\n icon: CustomIcon,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const {\n isVisible,\n handleTextAlign,\n label,\n canAlign,\n isActive,\n Icon,\n shortcutKeys,\n } = useTextAlign({\n editor,\n align,\n hideWhenUnavailable,\n onAligned,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleTextAlign()\n },\n [handleTextAlign, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n const RenderIcon = CustomIcon ?? Icon\n\n return (\n <Button\n type=\"button\"\n disabled={!canAlign}\n data-style=\"ghost\"\n data-active-state={isActive ? \"on\" : \"off\"}\n data-disabled={!canAlign}\n role=\"button\"\n tabIndex={-1}\n aria-label={label}\n aria-pressed={isActive}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <RenderIcon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <TextAlignShortcutBadge\n align={align}\n shortcutKeys={shortcutKeys}\n />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nTextAlignButton.displayName = \"TextAlignButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport type { ChainedCommands } from \"@tiptap/react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport {\n isExtensionAvailable,\n isNodeTypeSelected,\n} from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { AlignCenterIcon } from \"../../../components/tiptap-icons/align-center-icon\"\nimport { AlignJustifyIcon } from \"../../../components/tiptap-icons/align-justify-icon\"\nimport { AlignLeftIcon } from \"../../../components/tiptap-icons/align-left-icon\"\nimport { AlignRightIcon } from \"../../../components/tiptap-icons/align-right-icon\"\n\nexport type TextAlign = \"left\" | \"center\" | \"right\" | \"justify\"\n\n/**\n * Configuration for the text align functionality\n */\nexport interface UseTextAlignConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The text alignment to apply.\n */\n align: TextAlign\n /**\n * Whether the button should hide when alignment is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful alignment change.\n */\n onAligned?: () => void\n}\n\nexport const TEXT_ALIGN_SHORTCUT_KEYS: Record<TextAlign, string> = {\n left: \"mod+shift+l\",\n center: \"mod+shift+e\",\n right: \"mod+shift+r\",\n justify: \"mod+shift+j\",\n}\n\nexport const textAlignIcons = {\n left: AlignLeftIcon,\n center: AlignCenterIcon,\n right: AlignRightIcon,\n justify: AlignJustifyIcon,\n}\n\nexport const textAlignLabels: Record<TextAlign, string> = {\n left: \"Align left\",\n center: \"Align center\",\n right: \"Align right\",\n justify: \"Align justify\",\n}\n\n/**\n * Checks if text alignment can be performed in the current editor state\n */\nexport function canSetTextAlign(\n editor: Editor | null,\n align: TextAlign\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (\n !isExtensionAvailable(editor, \"textAlign\") ||\n isNodeTypeSelected(editor, [\"image\", \"horizontalRule\"])\n )\n return false\n\n return editor.can().setTextAlign(align)\n}\n\nexport function hasSetTextAlign(\n commands: ChainedCommands\n): commands is ChainedCommands & {\n setTextAlign: (align: TextAlign) => ChainedCommands\n} {\n return \"setTextAlign\" in commands\n}\n\n/**\n * Checks if the text alignment is currently active\n */\nexport function isTextAlignActive(\n editor: Editor | null,\n align: TextAlign\n): boolean {\n if (!editor || !editor.isEditable) return false\n return editor.isActive({ textAlign: align })\n}\n\n/**\n * Sets text alignment in the editor\n */\nexport function setTextAlign(editor: Editor | null, align: TextAlign): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canSetTextAlign(editor, align)) return false\n\n const chain = editor.chain().focus()\n if (hasSetTextAlign(chain)) {\n return chain.setTextAlign(align).run()\n }\n\n return false\n}\n\n/**\n * Determines if the text align button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n align: TextAlign\n}): boolean {\n const { editor, hideWhenUnavailable, align } = props\n\n if (!editor || !editor.isEditable) return false\n if (!isExtensionAvailable(editor, \"textAlign\")) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canSetTextAlign(editor, align)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides text align functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleAlignButton() {\n * const { isVisible, handleTextAlign } = useTextAlign({ align: \"center\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleTextAlign}>Align Center</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedAlignButton() {\n * const { isVisible, handleTextAlign, label, isActive } = useTextAlign({\n * editor: myEditor,\n * align: \"right\",\n * hideWhenUnavailable: true,\n * onAligned: () => console.log('Text aligned!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleTextAlign}\n * aria-pressed={isActive}\n * aria-label={label}\n * >\n * Align Right\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useTextAlign(config: UseTextAlignConfig) {\n const {\n editor: providedEditor,\n align,\n hideWhenUnavailable = false,\n onAligned,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canAlign = canSetTextAlign(editor, align)\n const isActive = isTextAlignActive(editor, align)\n\n useEffect(() => {\n if (!editor) return\n\n const handleSelectionUpdate = () => {\n setIsVisible(shouldShowButton({ editor, align, hideWhenUnavailable }))\n }\n\n handleSelectionUpdate()\n\n editor.on(\"selectionUpdate\", handleSelectionUpdate)\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionUpdate)\n }\n }, [editor, hideWhenUnavailable, align])\n\n const handleTextAlign = useCallback(() => {\n if (!editor) return false\n\n const success = setTextAlign(editor, align)\n if (success) {\n onAligned?.()\n }\n return success\n }, [editor, align, onAligned])\n\n return {\n isVisible,\n isActive,\n handleTextAlign,\n canAlign,\n label: textAlignLabels[align],\n shortcutKeys: TEXT_ALIGN_SHORTCUT_KEYS[align],\n Icon: textAlignIcons[align],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignCenterIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M6 12C6 11.4477 6.44772 11 7 11H17C17.5523 11 18 11.4477 18 12C18 12.5523 17.5523 13 17 13H7C6.44772 13 6 12.5523 6 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4 18C4 17.4477 4.44772 17 5 17H19C19.5523 17 20 17.4477 20 18C20 18.5523 19.5523 19 19 19H5C4.44772 19 4 18.5523 4 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignCenterIcon.displayName = \"AlignCenterIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignJustifyIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 12C2 11.4477 2.44772 11 3 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H3C2.44772 13 2 12.5523 2 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 18C2 17.4477 2.44772 17 3 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H3C2.44772 19 2 18.5523 2 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignJustifyIcon.displayName = \"AlignJustifyIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignLeftIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 12C2 11.4477 2.44772 11 3 11H15C15.5523 11 16 11.4477 16 12C16 12.5523 15.5523 13 15 13H3C2.44772 13 2 12.5523 2 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 18C2 17.4477 2.44772 17 3 17H17C17.5523 17 18 17.4477 18 18C18 18.5523 17.5523 19 17 19H3C2.44772 19 2 18.5523 2 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignLeftIcon.displayName = \"AlignLeftIcon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const AlignRightIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M8 12C8 11.4477 8.44772 11 9 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H9C8.44772 13 8 12.5523 8 12Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M6 18C6 17.4477 6.44772 17 7 17H21C21.5523 17 22 17.4477 22 18C22 18.5523 21.5523 19 21 19H7C6.44772 19 6 18.5523 6 18Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nAlignRightIcon.displayName = \"AlignRightIcon\"\n","\"use client\"\n\nimport { forwardRef, useCallback } from \"react\"\n\n// --- Lib ---\nimport { parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Tiptap UI ---\nimport type {\n UndoRedoAction,\n UseUndoRedoConfig,\n} from \"../../../components/tiptap-ui/undo-redo-button\"\nimport {\n UNDO_REDO_SHORTCUT_KEYS,\n useUndoRedo,\n} from \"../../../components/tiptap-ui/undo-redo-button\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../../components/tiptap-ui-primitive/button\"\nimport { Badge } from \"../../../components/tiptap-ui-primitive/badge\"\n\nexport interface UndoRedoButtonProps\n extends Omit<ButtonProps, \"type\">,\n UseUndoRedoConfig {\n /**\n * Optional text to display alongside the icon.\n */\n text?: string\n /**\n * Optional show shortcut keys in the button.\n * @default false\n */\n showShortcut?: boolean\n}\n\nexport function HistoryShortcutBadge({\n action,\n shortcutKeys = UNDO_REDO_SHORTCUT_KEYS[action],\n}: {\n action: UndoRedoAction\n shortcutKeys?: string\n}) {\n return <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>\n}\n\n/**\n * Button component for triggering undo/redo actions in a Tiptap editor.\n *\n * For custom button implementations, use the `useHistory` hook instead.\n */\nexport const UndoRedoButton = forwardRef<\n HTMLButtonElement,\n UndoRedoButtonProps\n>(\n (\n {\n editor: providedEditor,\n action,\n text,\n hideWhenUnavailable = false,\n onExecuted,\n showShortcut = false,\n onClick,\n children,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const { isVisible, handleAction, label, canExecute, Icon, shortcutKeys } =\n useUndoRedo({\n editor,\n action,\n hideWhenUnavailable,\n onExecuted,\n })\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n handleAction()\n },\n [handleAction, onClick]\n )\n\n if (!isVisible) {\n return null\n }\n\n return (\n <Button\n type=\"button\"\n disabled={!canExecute}\n data-style=\"ghost\"\n data-disabled={!canExecute}\n role=\"button\"\n tabIndex={-1}\n aria-label={label}\n tooltip={\n `${label}${\n shortcutKeys\n ? ` (${String(parseShortcutKeys({ shortcutKeys }))\n .replace(/Mod/i, \"Ctrl\")\n .replace(/,/g, \" + \")\n })`\n : \"\"\n }`\n }\n onClick={handleClick}\n {...buttonProps}\n ref={ref}\n >\n {children ?? (\n <>\n <Icon className=\"tiptap-button-icon\" />\n {text && <span className=\"tiptap-button-text\">{text}</span>}\n {showShortcut && (\n <HistoryShortcutBadge\n action={action}\n shortcutKeys={shortcutKeys}\n />\n )}\n </>\n )}\n </Button>\n )\n }\n)\n\nUndoRedoButton.displayName = \"UndoRedoButton\"\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { type Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../../hooks/use-tiptap-editor\"\n\n// --- Lib ---\nimport { isNodeTypeSelected } from \"../../../lib/tiptap-utils\"\n\n// --- Icons ---\nimport { Redo2Icon } from \"../../../components/tiptap-icons/redo2-icon\"\nimport { Undo2Icon } from \"../../../components/tiptap-icons/undo2-icon\"\n\nexport type UndoRedoAction = \"undo\" | \"redo\"\n\n/**\n * Configuration for the history functionality\n */\nexport interface UseUndoRedoConfig {\n /**\n * The Tiptap editor instance.\n */\n editor?: Editor | null\n /**\n * The history action to perform (undo or redo).\n */\n action: UndoRedoAction\n /**\n * Whether the button should hide when action is not available.\n * @default false\n */\n hideWhenUnavailable?: boolean\n /**\n * Callback function called after a successful action execution.\n */\n onExecuted?: () => void\n}\n\nexport const UNDO_REDO_SHORTCUT_KEYS: Record<UndoRedoAction, string> = {\n undo: \"mod+z\",\n redo: \"mod+shift+z\",\n}\n\nexport const historyActionLabels: Record<UndoRedoAction, string> = {\n undo: \"Undo\",\n redo: \"Redo\",\n}\n\nexport const historyIcons = {\n undo: Undo2Icon,\n redo: Redo2Icon,\n}\n\n/**\n * Checks if a history action can be executed\n */\nexport function canExecuteUndoRedoAction(\n editor: Editor | null,\n action: UndoRedoAction\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (isNodeTypeSelected(editor, [\"image\"])) return false\n\n return action === \"undo\" ? editor.can().undo() : editor.can().redo()\n}\n\n/**\n * Executes a history action on the editor\n */\nexport function executeUndoRedoAction(\n editor: Editor | null,\n action: UndoRedoAction\n): boolean {\n if (!editor || !editor.isEditable) return false\n if (!canExecuteUndoRedoAction(editor, action)) return false\n\n const chain = editor.chain().focus()\n return action === \"undo\" ? chain.undo().run() : chain.redo().run()\n}\n\n/**\n * Determines if the history button should be shown\n */\nexport function shouldShowButton(props: {\n editor: Editor | null\n hideWhenUnavailable: boolean\n action: UndoRedoAction\n}): boolean {\n const { editor, hideWhenUnavailable, action } = props\n\n if (!editor || !editor.isEditable) return false\n\n if (hideWhenUnavailable && !editor.isActive(\"code\")) {\n return canExecuteUndoRedoAction(editor, action)\n }\n\n return true\n}\n\n/**\n * Custom hook that provides history functionality for Tiptap editor\n *\n * @example\n * ```tsx\n * // Simple usage\n * function MySimpleUndoButton() {\n * const { isVisible, handleAction } = useHistory({ action: \"undo\" })\n *\n * if (!isVisible) return null\n *\n * return <button onClick={handleAction}>Undo</button>\n * }\n *\n * // Advanced usage with configuration\n * function MyAdvancedRedoButton() {\n * const { isVisible, handleAction, label } = useHistory({\n * editor: myEditor,\n * action: \"redo\",\n * hideWhenUnavailable: true,\n * onExecuted: () => console.log('Action executed!')\n * })\n *\n * if (!isVisible) return null\n *\n * return (\n * <MyButton\n * onClick={handleAction}\n * aria-label={label}\n * >\n * Redo\n * </MyButton>\n * )\n * }\n * ```\n */\nexport function useUndoRedo(config: UseUndoRedoConfig) {\n const {\n editor: providedEditor,\n action,\n hideWhenUnavailable = false,\n onExecuted,\n } = config\n\n const { editor } = useTiptapEditor(providedEditor)\n const [isVisible, setIsVisible] = useState<boolean>(true)\n const canExecute = canExecuteUndoRedoAction(editor, action)\n\n useEffect(() => {\n if (!editor) return\n\n const handleUpdate = () => {\n setIsVisible(shouldShowButton({ editor, hideWhenUnavailable, action }))\n }\n\n handleUpdate()\n\n editor.on(\"transaction\", handleUpdate)\n\n return () => {\n editor.off(\"transaction\", handleUpdate)\n }\n }, [editor, hideWhenUnavailable, action])\n\n const handleAction = useCallback(() => {\n if (!editor) return false\n\n const success = executeUndoRedoAction(editor, action)\n if (success) {\n onExecuted?.()\n }\n return success\n }, [editor, action, onExecuted])\n\n return {\n isVisible,\n handleAction,\n canExecute,\n label: historyActionLabels[action],\n shortcutKeys: UNDO_REDO_SHORTCUT_KEYS[action],\n Icon: historyIcons[action],\n }\n}\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const Redo2Icon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M15.7071 2.29289C15.3166 1.90237 14.6834 1.90237 14.2929 2.29289C13.9024 2.68342 13.9024 3.31658 14.2929 3.70711L17.5858 7H9.5C7.77609 7 6.12279 7.68482 4.90381 8.90381C3.68482 10.1228 3 11.7761 3 13.5C3 14.3536 3.16813 15.1988 3.49478 15.9874C3.82144 16.7761 4.30023 17.4926 4.90381 18.0962C6.12279 19.3152 7.77609 20 9.5 20H13C13.5523 20 14 19.5523 14 19C14 18.4477 13.5523 18 13 18H9.5C8.30653 18 7.16193 17.5259 6.31802 16.682C5.90016 16.2641 5.56869 15.768 5.34254 15.2221C5.1164 14.6761 5 14.0909 5 13.5C5 12.3065 5.47411 11.1619 6.31802 10.318C7.16193 9.47411 8.30653 9 9.5 9H17.5858L14.2929 12.2929C13.9024 12.6834 13.9024 13.3166 14.2929 13.7071C14.6834 14.0976 15.3166 14.0976 15.7071 13.7071L20.7071 8.70711C21.0976 8.31658 21.0976 7.68342 20.7071 7.29289L15.7071 2.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nRedo2Icon.displayName = \"Redo2Icon\"\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const Undo2Icon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.70711 3.70711C10.0976 3.31658 10.0976 2.68342 9.70711 2.29289C9.31658 1.90237 8.68342 1.90237 8.29289 2.29289L3.29289 7.29289C2.90237 7.68342 2.90237 8.31658 3.29289 8.70711L8.29289 13.7071C8.68342 14.0976 9.31658 14.0976 9.70711 13.7071C10.0976 13.3166 10.0976 12.6834 9.70711 12.2929L6.41421 9H14.5C15.0909 9 15.6761 9.1164 16.2221 9.34254C16.768 9.56869 17.2641 9.90016 17.682 10.318C18.0998 10.7359 18.4313 11.232 18.6575 11.7779C18.8836 12.3239 19 12.9091 19 13.5C19 14.0909 18.8836 14.6761 18.6575 15.2221C18.4313 15.768 18.0998 16.2641 17.682 16.682C17.2641 17.0998 16.768 17.4313 16.2221 17.6575C15.6761 17.8836 15.0909 18 14.5 18H11C10.4477 18 10 18.4477 10 19C10 19.5523 10.4477 20 11 20H14.5C15.3536 20 16.1988 19.8319 16.9874 19.5052C17.7761 19.1786 18.4926 18.6998 19.0962 18.0962C19.6998 17.4926 20.1786 16.7761 20.5052 15.9874C20.8319 15.1988 21 14.3536 21 13.5C21 12.6464 20.8319 11.8012 20.5052 11.0126C20.1786 10.2239 19.6998 9.50739 19.0962 8.90381C18.4926 8.30022 17.7761 7.82144 16.9874 7.49478C16.1988 7.16813 15.3536 7 14.5 7H6.41421L9.70711 3.70711Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nUndo2Icon.displayName = \"Undo2Icon\"\n","\"use client\";\r\n\r\nimport { useCurrentEditor } from \"@tiptap/react\";\r\nimport { useState } from \"react\";\r\nimport { FONT_OPTIONS } from \"../../../lib/font\";\r\nimport { ChevronDown } from \"lucide-react\";\r\n\r\nimport { Button } from \"../../../components/ui/button\";\r\nimport {\r\n Command,\r\n CommandEmpty,\r\n CommandGroup,\r\n CommandInput,\r\n CommandItem,\r\n CommandList,\r\n} from \"../../../components/ui/command\";\r\nimport {\r\n Popover,\r\n PopoverContent,\r\n PopoverTrigger,\r\n} from \"../../../components/ui/popover\";\r\n\r\nexport function FontFamilyDropdown() {\r\n const { editor } = useCurrentEditor();\r\n const [open, setOpen] = useState(false);\r\n\r\n if (!editor) return null;\r\n\r\n // Always enabled — current applied or typing font\r\n const currentFont =\r\n editor.getAttributes(\"textStyle\").fontFamily || \"Font Family\";\r\n\r\n /**\r\n * APPLY FONT LOGIC:\r\n * - If no text selected → Tiptap applies mark, future typing uses same font\r\n * - If text selected → only that selection changes\r\n */\r\n const applyFont = (family: string) => {\r\n if (!editor) return;\r\n\r\n // Remove any stored textStyle marks to avoid conflicts\r\n if (editor.state.storedMarks) {\r\n const textStyleMark = editor.schema.marks.textStyle;\r\n if (textStyleMark) {\r\n editor.view.dispatch(editor.state.tr.removeStoredMark(textStyleMark));\r\n }\r\n }\r\n\r\n // Delay applying font to let Tiptap stabilize\r\n setTimeout(() => {\r\n const success = editor.chain().focus().setFontFamily(family).run();\r\n if (!success) {\r\n console.warn(\"Font not applied:\", family);\r\n }\r\n }, 0);\r\n };\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n variant=\"outlineFontFamily\"\r\n className=\"\r\n min-w-[90px] h-7 px-2 flex items-center justify-between rounded-sm\r\n border-[#a3a3a8] text-[#a3a3a8]\r\n hover:border-[#000] hover:text-[#fff] transition-colors\r\n \"\r\n >\r\n {currentFont}\r\n <ChevronDown className=\"w-4 h-4\" />\r\n </Button>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className=\"w-[300px] p-0\"\r\n align=\"start\"\r\n onInteractOutside={(e) => {\r\n const target = e.target as HTMLElement;\r\n if (target.closest(\".cmd-input-wrapper\")) {\r\n e.preventDefault(); // keep search input focus\r\n }\r\n }}\r\n >\r\n <Command>\r\n <div className=\"cmd-input-wrapper\">\r\n <CommandInput placeholder=\"Search font...\" />\r\n </div>\r\n\r\n <CommandList className=\"max-h-[220px]\">\r\n <CommandEmpty>No font found.</CommandEmpty>\r\n\r\n <CommandGroup>\r\n <CommandItem\r\n key=\"default\"\r\n onSelect={() => {\r\n if (!editor) return;\r\n\r\n if (editor.state.storedMarks) {\r\n const textStyleMark = editor.schema.marks.textStyle;\r\n if (textStyleMark) {\r\n editor.view.dispatch(\r\n editor.state.tr.removeStoredMark(textStyleMark)\r\n );\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n editor.chain().focus().unsetFontFamily().run();\r\n setOpen(false);\r\n }, 0);\r\n }}\r\n className=\"font-sans\"\r\n >\r\n Default\r\n </CommandItem>\r\n\r\n {FONT_OPTIONS.map(({ label, cssFontFamily }) => (\r\n <CommandItem\r\n key={label}\r\n onSelect={() => {\r\n applyFont(label);\r\n setOpen(false);\r\n }}\r\n style={{ fontFamily: cssFontFamily}}\r\n >\r\n {label}\r\n </CommandItem>\r\n ))}\r\n </CommandGroup>\r\n </CommandList>\r\n </Command>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n"," export type FontOption = {\r\n label: string\r\n cssFontFamily:string \r\n }\r\n // --- FINALLY, CREATE LIST ---\r\n export const FONT_OPTIONS: FontOption[] = [\r\n { label: \"Inter\", cssFontFamily: \"Inter\" },\r\n { label: \"Roboto\", cssFontFamily: \"Roboto\" },\r\n { label: \"Open Sans\", cssFontFamily: \"Opensans\" },\r\n { label: \"Poppins\", cssFontFamily: \"Poppins\" },\r\n { label: \"Montserrat\", cssFontFamily: \"Montserrat\" },\r\n { label: \"Lato\", cssFontFamily: \"Lato\" },\r\n { label: \"Oswald\", cssFontFamily: \"Oswald\" },\r\n { label: \"Raleway\", cssFontFamily: \"Raleway\" },\r\n { label: \"Merriweather\", cssFontFamily: \"Merriweather\" },\r\n { label: \"Playfair Display\", cssFontFamily: \"Playfair\" },\r\n { label: \"Ubuntu\", cssFontFamily: \"Ubuntu\" },\r\n { label: \"PT Sans\", cssFontFamily: \"Ptsans\" },\r\n { label: \"Barlow\", cssFontFamily: \"Barlow\" },\r\n { label: \"Fira Sans\", cssFontFamily: \"Fira\" },\r\n { label: \"Nunito\", cssFontFamily: \"Nunito\" },\r\n { label: \"Cabin\", cssFontFamily: \"Cabin\" },\r\n { label: \"Bebas Neue\", cssFontFamily: \"Bebas\" },\r\n { label: \"Source Serif Pro\", cssFontFamily: \"Sourceserif\" },\r\n { label: \"Libre Baskerville\", cssFontFamily: \"Librebask\" },\r\n { label: \"Rubik\", cssFontFamily: \"Rubik\" },\r\n { label: \"Inconsolata\", cssFontFamily: \"Inconsolata\" },\r\n { label: \"Work Sans\", cssFontFamily: \"Worksans\" },\r\n { label: \"Mulish\", cssFontFamily: \"Mulish\" },\r\n { label: \"Quicksand\", cssFontFamily: \"Quicksand\" },\r\n { label: \"Kanit\", cssFontFamily: \"Kanit\" },\r\n { label: \"Teko\", cssFontFamily: \"Teko\" },\r\n { label: \"Josefin Sans\", cssFontFamily: \"Josefin\" },\r\n { label: \"Philosopher\", cssFontFamily: \"Philosopher\" },\r\n { label: \"Dancing Script\", cssFontFamily: \"Dancing\" },\r\n { label: \"Noto Serif\", cssFontFamily: \"Notoserif\" },\r\n { label: \"Manrope\", cssFontFamily: \"Manrope\" },\r\n { label: \"Space Grotesk\", cssFontFamily: \"Spacegrotesk\" },\r\n ]\r\n ","\"use client\"\n\nimport * as React from \"react\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../../components/ui/dialog\"\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n className?: string\n showCloseButton?: boolean\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent\n className={cn(\"overflow-hidden p-0\", className)}\n showCloseButton={showCloseButton}\n >\n <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n data-slot=\"command-input-wrapper\"\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n </div>\n )\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm\"\n {...props}\n />\n )\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"bg-border -mx-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverAnchor({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }\n","\"use client\";\r\n\r\nimport { useState, useEffect } from \"react\";\r\nimport { useCurrentEditor } from \"@tiptap/react\";\r\nimport { HexColorPicker } from \"react-colorful\";\r\nimport { Button } from \"../../../components/ui/button\";\r\nimport { GRADIENT_ROWS_70 } from \"../../../lib/colors\";\r\nimport { debounce } from \"lodash\";\r\n\r\nimport {\r\n Popover,\r\n PopoverTrigger,\r\n PopoverContent,\r\n} from \"../../../components/ui/popover\";\r\nimport { Label } from \"../../../components/ui/label\";\r\nimport React from \"react\";\r\n\r\nexport function ColorPicker({ type = \"text\" }) {\r\n const { editor } = useCurrentEditor();\r\n\r\n const [open, setOpen] = useState(false);\r\n const [color, setColor] = useState(\"#000000\"); // committed color applied to editor\r\n const [showCustom, setShowCustom] = useState(false);\r\n\r\n // temp color inside the custom picker (only committed on OK)\r\n const [tempHex, setTempHex] = useState(\"#000000\");\r\n\r\n const [canApply, setCanApply] = useState(false);\r\n\r\n // ---- Sync editor color ----\r\n useEffect(() => {\r\n const current =\r\n type === \"text\"\r\n ? editor?.getAttributes(\"textStyle\").color || \"#000000\"\r\n : editor?.getAttributes(\"highlight\")?.color || \"#FFFF00\";\r\n\r\n setColor(current);\r\n setTempHex(current);\r\n }, [editor, type]);\r\n\r\n // ---- Selection validation ----\r\n useEffect(() => {\r\n const check = () => {\r\n try {\r\n setCanApply(!editor?.state.selection.empty);\r\n } catch {\r\n setCanApply(false);\r\n }\r\n };\r\n\r\n check();\r\n editor?.on(\"selectionUpdate\", check);\r\n editor?.on(\"transaction\", check);\r\n\r\n return () => {\r\n editor?.off(\"selectionUpdate\", check);\r\n editor?.off(\"transaction\", check);\r\n };\r\n }, [editor]);\r\n\r\n // ---- Apply color to Tiptap (committed) ----\r\n const applyColor = React.useCallback(\r\n (value: string) => {\r\n if (!editor) return;\r\n\r\n // try to remove any stored textStyle mark to avoid stale state (safety)\r\n if (editor.state.storedMarks) {\r\n const textStyleMark = editor.schema.marks.textStyle;\r\n if (textStyleMark) {\r\n editor.view.dispatch(editor.state.tr.removeStoredMark(textStyleMark));\r\n }\r\n }\r\n\r\n // apply color\r\n setTimeout(() => {\r\n editor.chain().focus().setColor(value).run();\r\n setColor(value);\r\n }, 0);\r\n },\r\n [editor]\r\n );\r\n\r\n // small debounce for input typing (doesn't apply to editor; only local use)\r\n const debouncedSetTemp = React.useMemo(\r\n () => debounce((v: string) => setTempHex(v), 50),\r\n []\r\n );\r\n\r\n if (!editor) return null;\r\n\r\n return (\r\n <Popover open={open} onOpenChange={(v) => setOpen(v)}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n variant=\"outlineFontFamily\"\r\n className=\"flex items-center h-7 rounded-sm px-2 border-[#a3a3a8] text-[#a3a3a8] hover:text-white\"\r\n >\r\n Color\r\n <span\r\n className=\"w-3 h-3 ml-2 rounded-sm border border-black/20\"\r\n style={{ backgroundColor: color }}\r\n />\r\n </Button>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className=\"w-[260px] p-3\"\r\n align=\"start\"\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <Label className=\"text-xs mb-2\">\r\n {type === \"text\" ? \"Text Color\" : \"Highlight Color\"}\r\n </Label>\r\n\r\n {/* ========== COLOR PALETTE ========== */}\r\n {!showCustom && (\r\n <div className=\"flex flex-col gap-3\">\r\n <div className=\"grid grid-cols-7 gap-1\">\r\n {GRADIENT_ROWS_70.map((c) => (\r\n <div\r\n key={c}\r\n onClick={() => {\r\n applyColor(c);\r\n setOpen(false); // keep previous behavior for presets\r\n }}\r\n className=\"w-5 h-5 rounded-lg cursor-pointer border border-black/10 hover:scale-105 transition\"\r\n style={{ backgroundColor: c }}\r\n />\r\n ))}\r\n </div>\r\n\r\n <Button\r\n size=\"sm\"\r\n variant=\"outline\"\r\n onClick={() => {\r\n // open custom picker; ensure tempHex reflects committed color\r\n setTempHex(color);\r\n setShowCustom(true);\r\n }}\r\n >\r\n Custom\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* ========== CUSTOM HEX PICKER ========== */}\r\n {showCustom && (\r\n // stop mouse/pointer events from bubbling so popover doesn't treat them as outside clicks\r\n <div\r\n className=\"flex flex-col gap-3\"\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onMouseUp={(e) => e.stopPropagation()}\r\n onPointerDown={(e) => e.stopPropagation()}\r\n onPointerUp={(e) => e.stopPropagation()}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {/* Only update tempHex on change — do NOT apply to editor yet */}\r\n <HexColorPicker\r\n color={tempHex}\r\n onChange={(v) => {\r\n // immediate local update (no editor apply)\r\n setTempHex(v);\r\n }}\r\n // ensure internal clicks don't bubble out\r\n onMouseDown={(e: any) => e.stopPropagation()}\r\n onMouseUp={(e: any) => e.stopPropagation()}\r\n />\r\n\r\n <div className=\"flex gap-2 items-center\">\r\n <input\r\n value={tempHex}\r\n onChange={(e) => {\r\n // accept typed hex locally; debounce assignment for UX\r\n debouncedSetTemp(e.target.value);\r\n setTempHex(e.target.value);\r\n }}\r\n className=\"w-full px-2 py-1 border rounded text-sm\"\r\n />\r\n\r\n <Button\r\n size=\"sm\"\r\n variant=\"outline\"\r\n onClick={() => {\r\n // discard changes and go back to palette (do not apply)\r\n setTempHex(color);\r\n setShowCustom(false);\r\n }}\r\n >\r\n Back\r\n </Button>\r\n </div>\r\n\r\n <div className=\"flex justify-end mt-2\">\r\n <Button\r\n size=\"sm\"\r\n onClick={() => {\r\n applyColor(tempHex);\r\n setShowCustom(false);\r\n setOpen(false);\r\n \r\n // 🔥 FIX: restore editor focus & selection after popover closes\r\n setTimeout(() => {\r\n editor?.commands.focus();\r\n }, 200);\r\n }}\r\n \r\n \r\n >\r\n OK\r\n </Button>\r\n </div>\r\n </div>\r\n )}\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n","export const GRADIENT_ROWS_70 = [\r\n // ROW 1 — GRAY (Neutral gradient)\r\n \"#ffffff\", \"#f2f2f2\", \"#e6e6e6\", \"#cccccc\", \"#b3b3b3\",\r\n \"#999999\", \"#808080\", \"#666666\", \"#4d4d4d\", \"#333333\",\r\n \r\n // ROW 2 — RED\r\n \"#ffe8e8\", \"#ffc4c4\", \"#ff9e9e\", \"#ff7878\", \"#ff5252\",\r\n \"#ff2d2d\", \"#ff0707\", \"#d30000\", \"#a80000\", \"#7d0000\",\r\n \r\n // ROW 3 — ORANGE\r\n \"#fff1e0\", \"#ffd9b3\", \"#ffc285\", \"#ffab57\", \"#ff9429\",\r\n \"#ff7d00\", \"#e66700\", \"#cc5500\", \"#b24400\", \"#803000\",\r\n \r\n // ROW 4 — YELLOW\r\n \"#fffbe0\", \"#fff4b3\", \"#ffec85\", \"#ffe457\", \"#ffdc29\",\r\n \"#ffd400\", \"#e6be00\", \"#cca900\", \"#b39400\", \"#806e00\",\r\n \r\n // ROW 5 — GREEN\r\n \"#e7ffe8\", \"#c4ffc7\", \"#9effa5\", \"#78ff83\", \"#52ff61\",\r\n \"#2dff3f\", \"#0afc22\", \"#00d51d\", \"#00ad18\", \"#008512\",\r\n \r\n // ROW 6 — BLUE\r\n \"#e4f2ff\", \"#bcdcff\", \"#94c5ff\", \"#6badff\", \"#4396ff\",\r\n \"#1b7eff\", \"#0065e6\", \"#0054bf\", \"#004499\", \"#003373\",\r\n \r\n // ROW 7 — PURPLE\r\n \"#f3e6ff\", \"#dfb5ff\", \"#cb85ff\", \"#b755ff\", \"#a326ff\",\r\n \"#8a0dff\", \"#7600e6\", \"#6300bf\", \"#4f0099\", \"#3c0073\",\r\n ];\r\n ","\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","\"use client\"\r\n\r\nimport { useState } from \"react\"\r\nimport { useCurrentEditor } from \"@tiptap/react\"\r\nimport { FiTable } from \"react-icons/fi\"\r\n\r\n// shadcn UI\r\nimport { Button } from \"../../../components/ui/button\"\r\nimport {\r\n Popover,\r\n PopoverTrigger,\r\n PopoverContent,\r\n} from \"../../../components/ui/popover\"\r\nimport {\r\n Command,\r\n CommandGroup,\r\n CommandItem,\r\n CommandInput,\r\n CommandList,\r\n} from \"../../../components/ui/command\"\r\n\r\nexport function TableDropdownMenu() {\r\n const { editor } = useCurrentEditor()\r\n const [open, setOpen] = useState(false)\r\n\r\n if (!editor) return null\r\n\r\n const handleAction = (action: string) => {\r\n switch (action) {\r\n case \"insert\":\r\n editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()\r\n break\r\n case \"addColBefore\":\r\n editor.chain().focus().addColumnBefore().run()\r\n break\r\n case \"addColAfter\":\r\n editor.chain().focus().addColumnAfter().run()\r\n break\r\n case \"delCol\":\r\n editor.chain().focus().deleteColumn().run()\r\n break\r\n case \"addRowBefore\":\r\n editor.chain().focus().addRowBefore().run()\r\n break\r\n case \"addRowAfter\":\r\n editor.chain().focus().addRowAfter().run()\r\n break\r\n case \"delRow\":\r\n editor.chain().focus().deleteRow().run()\r\n break\r\n case \"merge\":\r\n editor.chain().focus().mergeCells().run()\r\n break\r\n case \"split\":\r\n editor.chain().focus().splitCell().run()\r\n break\r\n case \"deleteTable\":\r\n editor.chain().focus().deleteTable().run()\r\n break\r\n default:\r\n break\r\n }\r\n\r\n setOpen(false) // close dropdown after click\r\n }\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger asChild>\r\n <Button variant=\"tableButton\" size=\"sm\">\r\n <FiTable size={16} color=\"#a3a3a8\" />\r\n </Button>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent className=\"w-[220px] p-0\" align=\"start\">\r\n <Command>\r\n <CommandInput placeholder=\"Search table actions...\" />\r\n <CommandList className=\"max-h-[260px]\">\r\n <CommandGroup>\r\n\r\n <CommandItem onSelect={() => handleAction(\"insert\")}>\r\n Insert Table\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"addColBefore\")}>\r\n Add Column Before\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"addColAfter\")}>\r\n Add Column After\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"delCol\")}>\r\n Delete Column\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"addRowBefore\")}>\r\n Add Row Before\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"addRowAfter\")}>\r\n Add Row After\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"delRow\")}>\r\n Delete Row\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"merge\")}>\r\n Merge Cells\r\n </CommandItem>\r\n <CommandItem onSelect={() => handleAction(\"split\")}>\r\n Split Cells\r\n </CommandItem>\r\n\r\n <CommandItem onSelect={() => handleAction(\"deleteTable\")}>\r\n Delete Table\r\n </CommandItem>\r\n\r\n </CommandGroup>\r\n </CommandList>\r\n </Command>\r\n </PopoverContent>\r\n </Popover>\r\n )\r\n}\r\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const ArrowLeftIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M12.7071 5.70711C13.0976 5.31658 13.0976 4.68342 12.7071 4.29289C12.3166 3.90237 11.6834 3.90237 11.2929 4.29289L4.29289 11.2929C3.90237 11.6834 3.90237 12.3166 4.29289 12.7071L11.2929 19.7071C11.6834 20.0976 12.3166 20.0976 12.7071 19.7071C13.0976 19.3166 13.0976 18.6834 12.7071 18.2929L7.41421 13L19 13C19.5523 13 20 12.5523 20 12C20 11.4477 19.5523 11 19 11L7.41421 11L12.7071 5.70711Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nArrowLeftIcon.displayName = \"ArrowLeftIcon\"\n","\"use client\"\n\nimport { useEffect, useState } from \"react\"\nimport { useThrottledCallback } from \"@/hooks/use-throttled-callback\"\n\nexport interface WindowSizeState {\n /**\n * The width of the window's visual viewport in pixels.\n */\n width: number\n /**\n * The height of the window's visual viewport in pixels.\n */\n height: number\n /**\n * The distance from the top of the visual viewport to the top of the layout viewport.\n * Particularly useful for handling mobile keyboard appearance.\n */\n offsetTop: number\n /**\n * The distance from the left of the visual viewport to the left of the layout viewport.\n */\n offsetLeft: number\n /**\n * The scale factor of the visual viewport.\n * This is useful for scaling elements based on the current zoom level.\n */\n scale: number\n}\n\n/**\n * Hook that tracks the window's visual viewport dimensions, position, and provides\n * a CSS transform for positioning elements.\n *\n * Uses the Visual Viewport API to get accurate measurements, especially important\n * for mobile devices where virtual keyboards can change the visible area.\n * Only updates state when values actually change to optimize performance.\n *\n * @returns An object containing viewport properties and a CSS transform string\n */\nexport function useWindowSize(): WindowSizeState {\n const [windowSize, setWindowSize] = useState<WindowSizeState>({\n width: 0,\n height: 0,\n offsetTop: 0,\n offsetLeft: 0,\n scale: 0,\n })\n\n const handleViewportChange = useThrottledCallback(() => {\n if (typeof window === \"undefined\") return\n\n const vp = window.visualViewport\n if (!vp) return\n\n const {\n width = 0,\n height = 0,\n offsetTop = 0,\n offsetLeft = 0,\n scale = 0,\n } = vp\n\n setWindowSize((prevState) => {\n if (\n width === prevState.width &&\n height === prevState.height &&\n offsetTop === prevState.offsetTop &&\n offsetLeft === prevState.offsetLeft &&\n scale === prevState.scale\n ) {\n return prevState\n }\n\n return { width, height, offsetTop, offsetLeft, scale }\n })\n }, 200)\n\n useEffect(() => {\n const visualViewport = window.visualViewport\n if (!visualViewport) return\n\n visualViewport.addEventListener(\"resize\", handleViewportChange)\n\n handleViewportChange()\n\n return () => {\n visualViewport.removeEventListener(\"resize\", handleViewportChange)\n }\n }, [handleViewportChange])\n\n return windowSize\n}\n","import throttle from \"lodash.throttle\"\n\nimport { useUnmount } from \"@/hooks/use-unmount\"\nimport { useMemo } from \"react\"\n\ninterface ThrottleSettings {\n leading?: boolean | undefined\n trailing?: boolean | undefined\n}\n\nconst defaultOptions: ThrottleSettings = {\n leading: false,\n trailing: true,\n}\n\n/**\n * A hook that returns a throttled callback function.\n *\n * @param fn The function to throttle\n * @param wait The time in ms to wait before calling the function\n * @param dependencies The dependencies to watch for changes\n * @param options The throttle options\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useThrottledCallback<T extends (...args: any[]) => any>(\n fn: T,\n wait = 250,\n dependencies: React.DependencyList = [],\n options: ThrottleSettings = defaultOptions\n): {\n (this: ThisParameterType<T>, ...args: Parameters<T>): ReturnType<T>\n cancel: () => void\n flush: () => void\n} {\n const handler = useMemo(\n () => throttle<T>(fn, wait, options),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n dependencies\n )\n\n useUnmount(() => {\n handler.cancel()\n })\n\n return handler\n}\n\nexport default useThrottledCallback\n","import { useRef, useEffect } from \"react\"\n\n/**\n * Hook that executes a callback when the component unmounts.\n *\n * @param callback Function to be called on component unmount\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const useUnmount = (callback: (...args: Array<any>) => any) => {\n const ref = useRef(callback)\n ref.current = callback\n\n useEffect(\n () => () => {\n ref.current()\n },\n []\n )\n}\n\nexport default useUnmount\n","\"use client\"\n\nimport { useCallback, useEffect, useState } from \"react\"\nimport { useThrottledCallback } from \"@/hooks/use-throttled-callback\"\n\nexport type RectState = Omit<DOMRect, \"toJSON\">\n\nexport interface ElementRectOptions {\n /**\n * The element to track. Can be an Element, ref, or selector string.\n * Defaults to document.body if not provided.\n */\n element?: Element | React.RefObject<Element> | string | null\n /**\n * Whether to enable rect tracking\n */\n enabled?: boolean\n /**\n * Throttle delay in milliseconds for rect updates\n */\n throttleMs?: number\n /**\n * Whether to use ResizeObserver for more accurate tracking\n */\n useResizeObserver?: boolean\n}\n\nconst initialRect: RectState = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n}\n\nconst isSSR = typeof window === \"undefined\"\nconst hasResizeObserver = !isSSR && typeof ResizeObserver !== \"undefined\"\n\n/**\n * Helper function to check if code is running on client side\n */\nconst isClientSide = (): boolean => !isSSR\n\n/**\n * Custom hook that tracks an element's bounding rectangle and updates on resize, scroll, etc.\n *\n * @param options Configuration options for element rect tracking\n * @returns The current bounding rectangle of the element\n */\nexport function useElementRect({\n element,\n enabled = true,\n throttleMs = 100,\n useResizeObserver = true,\n}: ElementRectOptions = {}): RectState {\n const [rect, setRect] = useState<RectState>(initialRect)\n\n const getTargetElement = useCallback((): Element | null => {\n if (!enabled || !isClientSide()) return null\n\n if (!element) {\n return document.body\n }\n\n if (typeof element === \"string\") {\n return document.querySelector(element)\n }\n\n if (\"current\" in element) {\n return element.current\n }\n\n return element\n }, [element, enabled])\n\n const updateRect = useThrottledCallback(\n () => {\n if (!enabled || !isClientSide()) return\n\n const targetElement = getTargetElement()\n if (!targetElement) {\n setRect(initialRect)\n return\n }\n\n const newRect = targetElement.getBoundingClientRect()\n setRect({\n x: newRect.x,\n y: newRect.y,\n width: newRect.width,\n height: newRect.height,\n top: newRect.top,\n right: newRect.right,\n bottom: newRect.bottom,\n left: newRect.left,\n })\n },\n throttleMs,\n [enabled, getTargetElement],\n { leading: true, trailing: true }\n )\n\n useEffect(() => {\n if (!enabled || !isClientSide()) {\n setRect(initialRect)\n return\n }\n\n const targetElement = getTargetElement()\n if (!targetElement) return\n\n updateRect()\n\n const cleanup: (() => void)[] = []\n\n if (useResizeObserver && hasResizeObserver) {\n const resizeObserver = new ResizeObserver(() => {\n window.requestAnimationFrame(updateRect)\n })\n resizeObserver.observe(targetElement)\n cleanup.push(() => resizeObserver.disconnect())\n }\n\n const handleUpdate = () => updateRect()\n\n window.addEventListener(\"scroll\", handleUpdate, true)\n window.addEventListener(\"resize\", handleUpdate, true)\n\n cleanup.push(() => {\n window.removeEventListener(\"scroll\", handleUpdate)\n window.removeEventListener(\"resize\", handleUpdate)\n })\n\n return () => {\n cleanup.forEach((fn) => fn())\n setRect(initialRect)\n }\n }, [enabled, getTargetElement, updateRect, useResizeObserver])\n\n return rect\n}\n\n/**\n * Convenience hook for tracking document.body rect\n */\nexport function useBodyRect(\n options: Omit<ElementRectOptions, \"element\"> = {}\n): RectState {\n return useElementRect({\n ...options,\n element: isClientSide() ? document.body : null,\n })\n}\n\n/**\n * Convenience hook for tracking a ref element's rect\n */\nexport function useRefRect<T extends Element>(\n ref: React.RefObject<T>,\n options: Omit<ElementRectOptions, \"element\"> = {}\n): RectState {\n return useElementRect({ ...options, element: ref })\n}\n","\"use client\"\n\nimport type { Editor } from \"@tiptap/react\"\nimport { useWindowSize } from \"@/hooks/use-window-size\"\nimport { useBodyRect } from \"@/hooks/use-element-rect\"\nimport { useEffect } from \"react\"\n\nexport interface CursorVisibilityOptions {\n /**\n * The Tiptap editor instance\n */\n editor?: Editor | null\n /**\n * Reference to the toolbar element that may obscure the cursor\n */\n overlayHeight?: number\n}\n\n/**\n * Custom hook that ensures the cursor remains visible when typing in a Tiptap editor.\n * Automatically scrolls the window when the cursor would be hidden by the toolbar.\n *\n * @param options.editor The Tiptap editor instance\n * @param options.overlayHeight Toolbar height to account for\n * @returns The bounding rect of the body\n */\nexport function useCursorVisibility({\n editor,\n overlayHeight = 0,\n}: CursorVisibilityOptions) {\n const { height: windowHeight } = useWindowSize()\n const rect = useBodyRect({\n enabled: true,\n throttleMs: 100,\n useResizeObserver: true,\n })\n\n useEffect(() => {\n const ensureCursorVisibility = () => {\n if (!editor) return\n\n const { state, view } = editor\n if (!view.hasFocus()) return\n\n // Get current cursor position coordinates\n const { from } = state.selection\n const cursorCoords = view.coordsAtPos(from)\n\n if (windowHeight < rect.height && cursorCoords) {\n const availableSpace = windowHeight - cursorCoords.top\n\n // If the cursor is hidden behind the overlay or offscreen, scroll it into view\n if (availableSpace < overlayHeight) {\n const targetCursorY = Math.max(windowHeight / 2, overlayHeight)\n const currentScrollY = window.scrollY\n const cursorAbsoluteY = cursorCoords.top + currentScrollY\n const newScrollY = cursorAbsoluteY - targetCursorY\n\n window.scrollTo({\n top: Math.max(0, newScrollY),\n behavior: \"smooth\",\n })\n }\n }\n }\n\n ensureCursorVisibility()\n }, [editor, overlayHeight, windowHeight, rect.height])\n\n return rect\n}\n","\r\nimport type { EditorChangePayload } from \"../../types/editor-payload\"\r\nimport { EditorShell } from \"../editor-shell/EditorShell\"\r\nimport { EditorLayout } from \"../editorLayout/editorLayout\"\r\nimport { SimpleEditor } from \"../tiptap-templates/simple/simple-editor\"\r\nimport type { EditorTab } from \"../../components/types/editor-tabs\"\r\n\r\ninterface EditorProps {\r\n onChange?: (payload: EditorChangePayload) => void\r\n initialTabs?:EditorTab[]\r\n onTabsChange?: (tabs: any[]) => void\r\n className?: string\r\n style?: React.CSSProperties\r\n}\r\n\r\nexport function Editor({ onChange, className, style, onTabsChange, initialTabs }: EditorProps) {\r\n return (\r\n <div className={className} style={style}>\r\n <EditorShell>\r\n <EditorLayout onChange={onChange} initialTabs={initialTabs} onTabsChange={onTabsChange}>\r\n <SimpleEditor />\r\n </EditorLayout>\r\n </EditorShell>\r\n </div>\r\n )\r\n}\r\n","import type { RefObject } from \"react\"\nimport { useEffect, useState } from \"react\"\n\ntype ScrollTarget = RefObject<HTMLElement> | Window | null | undefined\ntype EventTargetWithScroll = Window | HTMLElement | Document\n\ninterface UseScrollingOptions {\n debounce?: number\n fallbackToDocument?: boolean\n}\n\nexport function useScrolling(\n target?: ScrollTarget,\n options: UseScrollingOptions = {}\n): boolean {\n const { debounce = 150, fallbackToDocument = true } = options\n const [isScrolling, setIsScrolling] = useState(false)\n\n useEffect(() => {\n // Resolve element or window\n const element: EventTargetWithScroll =\n target && typeof Window !== \"undefined\" && target instanceof Window\n ? target\n : ((target as RefObject<HTMLElement>)?.current ?? window)\n\n // Mobile: fallback to document when using window\n const eventTarget: EventTargetWithScroll =\n fallbackToDocument &&\n element === window &&\n typeof document !== \"undefined\"\n ? document\n : element\n\n const on = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.addEventListener(event, handler, true)\n\n const off = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.removeEventListener(event, handler)\n\n let timeout: ReturnType<typeof setTimeout>\n const supportsScrollEnd = element === window && \"onscrollend\" in window\n\n const handleScroll: EventListener = () => {\n if (!isScrolling) setIsScrolling(true)\n\n if (!supportsScrollEnd) {\n clearTimeout(timeout)\n timeout = setTimeout(() => setIsScrolling(false), debounce)\n }\n }\n\n const handleScrollEnd: EventListener = () => setIsScrolling(false)\n\n on(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n on(eventTarget, \"scrollend\", handleScrollEnd)\n }\n\n return () => {\n off(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n off(eventTarget, \"scrollend\", handleScrollEnd)\n }\n clearTimeout(timeout)\n }\n }, [target, debounce, fallbackToDocument, isScrolling])\n\n return isScrolling\n}\n","// src/lib/editorStorage.ts\r\nimport { EditorTab } from \"../components/types/editor-tabs\";\r\nexport type TabContent = any;\r\n\r\n\r\n\r\nconst STORAGE_KEY = \"tiptap-tabs-v1\";\r\nconst ACTIVE_TAB_KEY = \"tiptap-active-tab\";\r\n\r\n\r\nexport function loadTabs(): EditorTab[] {\r\n if (typeof window === \"undefined\") return [];\r\n\r\n try {\r\n const raw = localStorage.getItem(\"tiptap-tabs-v1\");\r\n if (!raw) return [];\r\n\r\n const parsed = JSON.parse(raw);\r\n\r\n // runtime safety\r\n if (!Array.isArray(parsed)) return [];\r\n\r\n return parsed as EditorTab[];\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\nexport function saveTabs(tabs: EditorTab[]) {\r\n if (typeof window === \"undefined\") return;\r\n localStorage.setItem(STORAGE_KEY, JSON.stringify(tabs));\r\n}\r\n\r\nexport function loadActiveTab(): string {\r\n if (typeof window === \"undefined\") return \"1\";\r\n return localStorage.getItem(ACTIVE_TAB_KEY) ?? \"1\";\r\n}\r\n\r\nexport function saveActiveTab(id: string) {\r\n if (typeof window === \"undefined\") return;\r\n localStorage.setItem(ACTIVE_TAB_KEY, id);\r\n}\r\n\r\n","// lib/local-image.ts\r\nexport function fileToBase64(file: File): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader()\r\n reader.readAsDataURL(file)\r\n reader.onload = () => resolve(reader.result as string)\r\n reader.onerror = (error) => reject(error)\r\n })\r\n }\r\n \r\n export function saveImageBase64(key: string, base64: string) {\r\n localStorage.setItem(key, base64)\r\n }\r\n \r\n export function loadImageBase64(key: string): string | null {\r\n return localStorage.getItem(key)\r\n }\r\n "],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAAA,SAAuB;AACvB,IAAAC,qBAAqB;AACrB,IAAAC,mCAAuC;AACvC,IAAAC,uBAA8B;;;ACL9B,YAAuB;AAEvB,IAAM,oBAAoB;AAEnB,SAAS,cAAc;AAC5B,QAAM,CAAC,UAAU,WAAW,IAAU,eAA8B,MAAS;AAE7E,EAAM,gBAAU,MAAM;AACpB,UAAM,MAAM,OAAO,WAAW,eAAe,oBAAoB,CAAC,KAAK;AACvE,UAAM,WAAW,MAAM;AACrB,kBAAY,OAAO,aAAa,iBAAiB;AAAA,IACnD;AACA,QAAI,iBAAiB,UAAU,QAAQ;AACvC,gBAAY,OAAO,aAAa,iBAAiB;AACjD,WAAO,MAAM,IAAI,oBAAoB,UAAU,QAAQ;AAAA,EACzD,GAAG,CAAC,CAAC;AAEL,SAAO,CAAC,CAAC;AACX;;;AClBA,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ACJA,wBAAqB;AACrB,sCAAuC;AAsDnC;AAlDJ,IAAM,qBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,aACE;AAAA,QACF,mBACE;AAAA,QACA,SACA;AAAA,QACA,aACA;AAAA,QACF,WACE;AAAA,QACF,OACE;AAAA,QACF,MAAM;AAAA,MACR;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,iBAAiB;AAAA,QACjB,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,OAAO;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAGK;AACH,QAAM,OAAO,UAAU,yBAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,UAAU,CAAC,CAAC;AAAA,MACzD,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACxDI,IAAAC,sBAAA;AAFJ,SAAS,MAAM,EAAE,WAAW,MAAM,GAAG,MAAM,GAAkC;AAC3E,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACfA,yBAAoC;AAWhC,IAAAC,sBAAA;AAPJ,SAAS,UAAU;AAAA,EACjB;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AAAA,EACb,GAAG;AACL,GAAyD;AACvD,SACE;AAAA,IAAoB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACtBA,qBAAgC;AAChC,0BAAsB;AAKb,IAAAC,sBAAA;AADT,SAAS,MAAM,EAAE,GAAG,MAAM,GAAqD;AAC7E,SAAO,6CAAgB,qBAAf,EAAoB,aAAU,SAAS,GAAG,OAAO;AAC3D;AAcA,SAAS,YAAY;AAAA,EACnB,GAAG;AACL,GAAuD;AACrD,SAAO,6CAAgB,uBAAf,EAAsB,aAAU,gBAAgB,GAAG,OAAO;AACpE;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA,GAAG;AACL,GAAwD;AACtD,SACE;AAAA,IAAgB;AAAA,IAAf;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,GAEG;AACD,SACE,8CAAC,eACC;AAAA,iDAAC,gBAAa;AAAA,IACd;AAAA,MAAgB;AAAA,MAAf;AAAA,QACC,aAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA,SAAS,WACP;AAAA,UACF,SAAS,UACP;AAAA,UACF,SAAS,SACP;AAAA,UACF,SAAS,YACP;AAAA,UACF;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,UACD,8CAAgB,sBAAf,EAAqB,WAAU,8OAC9B;AAAA,yDAAC,6BAAM,WAAU,UAAS;AAAA,YAC1B,6CAAC,UAAK,WAAU,WAAU,mBAAK;AAAA,aACjC;AAAA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,MAAM,GAAgC;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,6BAA6B,SAAS;AAAA,MACnD,GAAG;AAAA;AAAA,EACN;AAEJ;AAYA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA,GAAG;AACL,GAAsD;AACpD,SACE;AAAA,IAAgB;AAAA,IAAf;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iCAAiC,SAAS;AAAA,MACvD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA,GAAG;AACL,GAA4D;AAC1D,SACE;AAAA,IAAgB;AAAA,IAAf;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iCAAiC,SAAS;AAAA,MACvD,GAAG;AAAA;AAAA,EACN;AAEJ;;;AC5HA,uBAAkC;AAS9B,IAAAC,sBAAA;AALJ,SAAS,gBAAgB;AAAA,EACvB,gBAAgB;AAAA,EAChB,GAAG;AACL,GAA2D;AACzD,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;APiHQ,IAAAC,sBAAA;AAxGR,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB,KAAK,KAAK,KAAK;AAC9C,IAAM,gBAAgB;AACtB,IAAM,uBAAuB;AAC7B,IAAM,qBAAqB;AAa3B,IAAM,iBAAuB,qBAA0C,IAAI;AAE3E,SAAS,aAAa;AACpB,QAAM,UAAgB,kBAAW,cAAc;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB;AAAA,EACvB,cAAc;AAAA,EACd,MAAM;AAAA,EACN,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAIG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,CAAC,YAAY,aAAa,IAAU,gBAAS,KAAK;AAIxD,QAAM,CAAC,OAAO,QAAQ,IAAU,gBAAS,WAAW;AACpD,QAAM,OAAO,YAAY;AACzB,QAAM,UAAgB;AAAA,IACpB,CAAC,UAAmD;AAClD,YAAM,YAAY,OAAO,UAAU,aAAa,MAAM,IAAI,IAAI;AAC9D,UAAI,aAAa;AACf,oBAAY,SAAS;AAAA,MACvB,OAAO;AACL,iBAAS,SAAS;AAAA,MACpB;AAGA,eAAS,SAAS,GAAG,mBAAmB,IAAI,SAAS,qBAAqB,sBAAsB;AAAA,IAClG;AAAA,IACA,CAAC,aAAa,IAAI;AAAA,EACpB;AAGA,QAAM,gBAAsB,mBAAY,MAAM;AAC5C,WAAO,WAAW,cAAc,CAACC,UAAS,CAACA,KAAI,IAAI,QAAQ,CAACA,UAAS,CAACA,KAAI;AAAA,EAC5E,GAAG,CAAC,UAAU,SAAS,aAAa,CAAC;AAoBrC,QAAM,QAAQ,OAAO,aAAa;AAElC,QAAM,eAAqB;AAAA,IACzB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,OAAO,MAAM,SAAS,UAAU,YAAY,eAAe,aAAa;AAAA,EAC3E;AAEA,SACE,6CAAC,eAAe,UAAf,EAAwB,OAAO,cAC9B,uDAAC,mBAAgB,eAAe,GAC9B;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,OACE;AAAA,QACE,mBAAmB;AAAA,QACnB,wBAAwB;AAAA,QACxB,GAAG;AAAA,MACL;AAAA,MAEF,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH,GACF,GACF;AAEJ;AAEA,SAAS,QAAQ;AAAA,EACf,OAAO;AAAA,EACP,UAAU;AAAA,EACV,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAIG;AACD,QAAM,EAAE,UAAU,OAAO,YAAY,cAAc,IAAI,WAAW;AAElE,MAAI,gBAAgB,QAAQ;AAC1B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,aAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,MAAI,UAAU;AACZ,WACE,6CAAC,SAAM,MAAM,YAAY,cAAc,eAAgB,GAAG,OACxD;AAAA,MAAC;AAAA;AAAA,QACC,gBAAa;AAAA,QACb,aAAU;AAAA,QACV,eAAY;AAAA,QACZ,WAAU;AAAA,QACV,OACE;AAAA,UACE,mBAAmB;AAAA,QACrB;AAAA,QAEF;AAAA,QAEA;AAAA,wDAAC,eAAY,WAAU,WACrB;AAAA,yDAAC,cAAW,qBAAO;AAAA,YACnB,6CAAC,oBAAiB,0CAA4B;AAAA,aAChD;AAAA,UACA,6CAAC,SAAI,WAAU,+BAA+B,UAAS;AAAA;AAAA;AAAA,IACzD,GACF;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,cAAY;AAAA,MACZ,oBAAkB,UAAU,cAAc,cAAc;AAAA,MACxD,gBAAc;AAAA,MACd,aAAW;AAAA,MACX,aAAU;AAAA,MAGV;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,aAAU;AAAA,YACV,WAAW;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA,YAAY,cAAc,YAAY,UAClC,qFACA;AAAA,YACN;AAAA;AAAA,QACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,aAAU;AAAA,YACV,WAAW;AAAA,cACT;AAAA,cACA,SAAS,SACL,mFACA;AAAA;AAAA,cAEJ,YAAY,cAAc,YAAY,UAClC,6FACA;AAAA,cACJ;AAAA,YACF;AAAA,YACC,GAAG;AAAA,YAEJ;AAAA,cAAC;AAAA;AAAA,gBACC,gBAAa;AAAA,gBACb,aAAU;AAAA,gBACV,WAAU;AAAA,gBAET;AAAA;AAAA,YACH;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAwC;AACtC,QAAM,EAAE,cAAc,IAAI,WAAW;AAErC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,gBAAa;AAAA,MACb,aAAU;AAAA,MACV,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAW,GAAG,UAAU,SAAS;AAAA,MACjC,SAAS,CAAC,UAAU;AAClB,kBAAU,KAAK;AACf,sBAAc;AAAA,MAChB;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,qDAAC,sCAAc;AAAA,QACf,6CAAC,UAAK,WAAU,WAAU,4BAAc;AAAA;AAAA;AAAA,EAC1C;AAEJ;AA2BA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAiC;AAC3E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAoDA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC5E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAa;AAAA,MACb,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAa;AAAA,MACb,WAAW,GAAG,6CAA6C,SAAS;AAAA,MACnE,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAwD;AACtD,QAAM,OAAO,UAAU,0BAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAa;AAAA,MACb,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAuCA,SAAS,YAAY,EAAE,WAAW,GAAG,MAAM,GAA+B;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAa;AAAA,MACb,WAAW,GAAG,sCAAsC,SAAS;AAAA,MAC5D,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC5E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAa;AAAA,MACb,WAAW,GAAG,4BAA4B,SAAS;AAAA,MAClD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAM,gCAA4B;AAAA,EAChC;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,SACE;AAAA,MACJ;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;AQxdM,IAAAC,sBAAA;AAdC,SAAS,YAAY,EAAE,SAAS,GAAqB;AAC1D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MASV,wBAAoB;AAAA,MAEpB,uDAAC,mBACE,UACH;AAAA;AAAA,EACF;AAEJ;;;AC1BA,IAAAC,gBAAyD;;;ACAzD,mBAAyB;AACzB,IAAAC,uBAA+C;AAC/C,2BAAiD;;;ACDjD,4BAAuC;AACvC,IAAAC,uBAAwD;AAO/C,IAAAC,sBAAA;AAHT,SAAS,aAAa;AAAA,EACpB,GAAG;AACL,GAA4D;AAC1D,SAAO,6CAAuB,4BAAtB,EAA2B,aAAU,iBAAiB,GAAG,OAAO;AAC1E;AAUA,SAAS,oBAAoB;AAAA,EAC3B,GAAG;AACL,GAA+D;AAC7D,SACE;AAAA,IAAuB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACT,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA,aAAa;AAAA,EACb,GAAG;AACL,GAA+D;AAC7D,SACE,6CAAuB,8BAAtB,EACC;AAAA,IAAuB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;AAUA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAGG;AACD,SACE;AAAA,IAAuB;AAAA,IAAtB;AAAA,MACC,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,gBAAc;AAAA,MACd,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;AD5DA,IAAAC,uBAA6B;AAuHnB,IAAAC,sBAAA;AAnGV,IAAM,cAAoB;AAAA,EACxB,SAAS,EAAE,SAAS,GAAG,GAAG,KAAK,QAAQ,EAAE;AAAA,EACzC,SAAS;AAAA,IACP,SAAS;AAAA,IACT,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,IAAM,iBAAuB;AAAA,EAC3B,SAAS,EAAE,SAAS,GAAG,GAAG,KAAK,QAAQ,EAAE;AAAA,EACzC,SAAS;AAAA,IACP,SAAS;AAAA,IACT,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAwB,IAAI;AAC9D,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAwB,IAAI;AACpE,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,EAAE;AAC7C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAkC,CAAC,CAAC;AAIpE,QAAM,iBAAiB,CAAC,IAAY,UAAkB;AACpD,iBAAa,EAAE;AACf,oBAAgB,IAAI;AACpB,iBAAa,KAAK;AAAA,EACpB;AAEA,QAAM,oBAAoB,CAAC,IAAY,UAAkB;AACvD,oBAAgB,EAAE;AAClB,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAAA,EACpB;AAEA,QAAM,kBAAkB,MAAM;AAC5B,QAAI,CAAC,UAAW;AAChB,aAAS,WAAW,UAAU,KAAK,KAAK,UAAU;AAClD,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,qBAAqB,CAAC,UAAkB;AAC5C,QAAI,CAAC,gBAAgB,CAAC,eAAgB;AACtC,mBAAe,OAAO,cAAc,UAAU,KAAK,KAAK,UAAU;AAClE,oBAAgB,IAAI;AAAA,EACtB;AAEA,QAAM,gBAAgB,CAAC,UAAkB;AACvC,gBAAY,CAAC,UAAU;AAAA,MACrB,GAAG;AAAA,MACH,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK;AAAA,IACtB,EAAE;AAAA,EACJ;AAEA,SACE,6CAAC,WACC,uDAAC,kBACC,wDAAC,gBACC;AAAA,kDAAC,qBAAkB,WAAU,qCAAoC;AAAA;AAAA,MAE/D;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT,WAAU;AAAA,UACV,cAAW;AAAA,UAEX,uDAAC,6BAAK,MAAM,IAAI;AAAA;AAAA,MAClB;AAAA,OACF;AAAA,IAEA,6CAAC,eAEC,uDAAC,wCAAgB,MAAK,aACnB,eAAK,IAAI,CAAC,QAAQ;AACjB,YAAM,SAAS,SAAS,IAAI,EAAE;AAC9B,YAAM,aAAa,IAAI,QAAQ,SAAS;AACxC,YAAM,cAAc,IAAI,OAAO,eAAe,CAAC;AAE/C,aACE;AAAA,QAAC,4BAAO;AAAA,QAAP;AAAA,UAEC,UAAU;AAAA,UACV,SAAQ;AAAA,UACR,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,QAAM;AAAA,UAEN,wDAAC,mBAAgB,WAAU,aAEzB;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA;AAAA;AAAA,4BAGP,cAAc,cAAc,oBAAoB;AAAA;AAAA,gBAInD;AAAA,gCACC;AAAA,oBAAC;AAAA;AAAA,sBACC,SAAS,CAAC,MAAM;AACd,0BAAE,gBAAgB;AAClB,sCAAc,IAAI,EAAE;AAAA,sBACtB;AAAA,sBACA,WAAU;AAAA,sBACV,cACE,SAAS,qBAAqB;AAAA,sBAGhC;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAM;AAAA,0BACN,WAAW,iDACT,SAAS,cAAc,EACzB;AAAA;AAAA,sBACF;AAAA;AAAA,kBACF;AAAA,kBAIF;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAM;AAAA,sBACN,WAAW,6CACT,aAAa,KAAK,MACpB,IACE,cACI,gBACA,oCACN;AAAA;AAAA,kBACF;AAAA,kBAGA,6CAAC,SAAI,WAAU,kBACZ,wBAAc,IAAI,KACjB;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,sBACP,WAAS;AAAA,sBACT,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,sBAC5C,QAAQ;AAAA,sBACR,WAAW,CAAC,MAAM;AAChB,4BAAI,EAAE,QAAQ,QAAS,iBAAgB;AACvC,4BAAI,EAAE,QAAQ,SAAU,cAAa,IAAI;AAAA,sBAC3C;AAAA,sBACA,WAAU;AAAA;AAAA,kBACZ,IAEA;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAU;AAAA,sBACV,SAAS,MAAM,SAAS,IAAI,EAAE;AAAA,sBAC9B,eAAe,MACb,eAAe,IAAI,IAAI,IAAI,KAAK;AAAA,sBAGjC,cAAI;AAAA;AAAA,kBACP,GAEJ;AAAA,kBAGA,8CAAC,gBACC;AAAA,iEAAC,uBAAoB,SAAO,MAC1B;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAU;AAAA,wBACV,cAAW;AAAA,wBAEX,uDAAC,uCAAe,MAAM,IAAI;AAAA;AAAA,oBAC5B,GACF;AAAA,oBAEA,8CAAC,uBAAoB,OAAM,OAAM,WAAU,QACzC;AAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,SAAS,MAAM;AACb,wCAAY,IAAI,EAAE;AAClB,wCAAY,CAAC,UAAU;AAAA,8BACrB,GAAG;AAAA,8BACH,CAAC,IAAI,EAAE,GAAG;AAAA,4BACZ,EAAE;AAAA,0BACJ;AAAA,0BACA,WAAU;AAAA,0BACX;AAAA;AAAA,sBAED;AAAA,sBAEC,gBACC;AAAA,wBAAC;AAAA;AAAA,0BACC,WAAU;AAAA,0BACV,SAAS,CAAC,MAAM;AACd,8BAAE,gBAAgB;AAClB,qCAAS,IAAI,EAAE;AAAA,0BACjB;AAAA,0BACD;AAAA;AAAA,sBAED;AAAA,uBAEJ;AAAA,qBACF;AAAA;AAAA;AAAA,YACF;AAAA,YAGC,cACC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA;AAAA,8BAGP,SACI,gCACA,2BACN;AAAA;AAAA,gBAGF,uDAAC,SAAI,WAAU,mBACb,uDAAC,SAAI,WAAU,kBAEb,uDAAC,wCAAgB,MAAK,aACnB,cAAI,QAAQ,IAAI,CAAC,OAAO;AACvB,wBAAM,iBAAiB,GAAG,OAAO;AAEjC,yBACE;AAAA,oBAAC,4BAAO;AAAA,oBAAP;AAAA,sBAEC,UAAU;AAAA,sBACV,SAAQ;AAAA,sBACR,SAAQ;AAAA,sBACR,MAAK;AAAA,sBACL,QAAM;AAAA,sBACN,WAAW;AAAA;AAAA;AAAA,0CAIP,iBACI,cACA,oBACN;AAAA;AAAA,sBAIF;AAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,MAAM;AAAA,4BACN,WAAW,6CACT,iBACI,gBACA,oCACN;AAAA;AAAA,wBACF;AAAA,wBAGA,6CAAC,SAAI,WAAU,kBACZ,2BAAiB,GAAG,KACnB;AAAA,0BAAC;AAAA;AAAA,4BACC,OAAO;AAAA,4BACP,WAAS;AAAA,4BACT,UAAU,CAAC,MACT,aAAa,EAAE,OAAO,KAAK;AAAA,4BAE7B,QAAQ,MAAM,mBAAmB,IAAI,EAAE;AAAA,4BACvC,WAAW,CAAC,MAAM;AAChB,kCAAI,EAAE,QAAQ;AACZ,mDAAmB,IAAI,EAAE;AAC3B,kCAAI,EAAE,QAAQ;AACZ,gDAAgB,IAAI;AAAA,4BACxB;AAAA,4BACA,WAAU;AAAA;AAAA,wBACZ,IAEA;AAAA,0BAAC;AAAA;AAAA,4BACC,WAAU;AAAA,4BACV,SAAS,MAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAAA,4BACrC,eAAe,MACb,kBAAkB,GAAG,IAAI,GAAG,KAAK;AAAA,4BAGlC,aAAG;AAAA;AAAA,wBACN,GAEJ;AAAA,wBAGC,kBACC,8CAAC,gBACC;AAAA,uEAAC,uBAAoB,SAAO,MAC1B;AAAA,4BAAC;AAAA;AAAA,8BACC,WAAU;AAAA,8BACV,cAAW;AAAA,8BAEX,uDAAC,uCAAe,MAAM,IAAI;AAAA;AAAA,0BAC5B,GACF;AAAA,0BAEA;AAAA,4BAAC;AAAA;AAAA,8BACC,OAAM;AAAA,8BACN,WAAU;AAAA,8BAEV;AAAA,gCAAC;AAAA;AAAA,kCACC,WAAU;AAAA,kCACV,SAAS,MACP,eAAe,IAAI,IAAI,GAAG,EAAE;AAAA,kCAE/B;AAAA;AAAA,8BAED;AAAA;AAAA,0BACF;AAAA,2BACF;AAAA;AAAA;AAAA,oBAlFG,GAAG;AAAA,kBAoFV;AAAA,gBAEJ,CAAC,GACH,GACF,GACF;AAAA;AAAA,YACF;AAAA,aAEJ;AAAA;AAAA,QArOK,IAAI;AAAA,MAsOX;AAAA,IAEJ,CAAC,GACH,GACF;AAAA,KACF,GACF,GACF;AAEJ;;;AE/YA,IAAAC,gBAAiD;AAqB7C,IAAAC,uBAAA;AAZJ,IAAM,0BAAsB;AAAA,EAC1B;AACF;AAEO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAGG;AACD,SACE,8CAAC,oBAAoB,UAApB,EAA6B,OAC3B,UACH;AAEJ;AAEO,SAAS,kBAAkB;AAChC,QAAM,UAAM,0BAAW,mBAAmB;AAC1C,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO;AACT;;;AHgXU,IAAAC,uBAAA;AAxXH,SAAS,aAAa,EAAE,UAAU,UAAU,aAAa,aAAa,GAAsB;AACjG,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAwB,IAAI;AACxD,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAsB,CAAC,CAAC;AAChD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,EAAE;AACjD,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAwB,IAAI;AAExE,QAAM,uBAAmB,sBAA6C,IAAI;AAC1E,QAAM,sBAAkB,sBAA0D,IAAI;AACtF,QAAM,qBAAiB,sBAAO,KAAK;AACnC,QAAM,0BAAsB,sBAA6C,IAAI;AAI7E,QAAM,0BAAsB;AAAA,IAC1B,CAAC,YAAiC;AAChC,UAAI,CAAC,SAAU;AAGf,UAAI,oBAAoB,SAAS;AAC/B,qBAAa,oBAAoB,OAAO;AAAA,MAC1C;AAGA,0BAAoB,UAAU,WAAW,MAAM;AAC7C,iBAAS,OAAO;AAAA,MAClB,GAAG,GAAG;AAAA,IACR;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAGA,QAAM,iBAAa;AAAA,IACjB,CAAC,WAA+B;AAC9B,UAAI,CAAC,SAAU;AAEf,0BAAoB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,qBAAqB,MAAM,aAAa,cAAc;AAAA,EACzD;AASC,+BAAU,MAAM;AACf,QAAI,aAAa,WAAW,GAAG;AAC7B,cAAQ,CAAC,EAAE,IAAI,KAAK,OAAO,SAAS,SAAS,MAAM,SAAS,CAAC,EAAE,CAAC,CAAC;AACjE,qBAAe,GAAG;AAAA,IACpB,OAAO;AACL,cAAQ,eAAe,CAAC,CAAC;AACzB,qBAAe,cAAc,CAAC,GAAG,MAAM,EAAE;AAAA,IAC3C;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAUhB,+BAAU,MAAM;AACd,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,MAAM,YAAY,CAAC;AAUvB,QAAM,yBAAqB,2BAAY,MAAM;AAC3C,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,OAAO,OAAO,QAAQ;AAE5B,UAAM,cAAc,KAAK,IAAI,SAAO;AAClC,UAAI,IAAI,OAAO,YAAa,QAAO;AAEnC,UAAI,gBAAgB;AAClB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,SAAS,IAAI,QAAQ;AAAA,YAAI,QACvB,GAAG,OAAO,iBAAiB,EAAE,GAAG,IAAI,SAAS,KAAK,IAAI;AAAA,UACxD;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,GAAG,KAAK,SAAS,KAAK;AAAA,IACjC,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,MAAM,aAAa,cAAc,CAAC;AAG9C,QAAM,qBAAiB;AAAA,IACrB,CAAC,gBAAwB,SAA6B,aAAa;AACjE,YAAM,OAAO,eAAe,QAAQ;AAEpC,cAAQ,UAAQ;AACd,cAAM,cAAc,KAAK,IAAI,SAAO;AAClC,cAAI,IAAI,OAAO,YAAa,QAAO;AAEnC,cAAI,gBAAgB;AAClB,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,SAAS,IAAI,QAAQ;AAAA,gBAAI,QACvB,GAAG,OAAO,iBACN,EAAE,GAAG,IAAI,SAAS,KAAK,IACvB;AAAA,cACN;AAAA,YACF;AAAA,UACF;AAEA,iBAAO,EAAE,GAAG,KAAK,SAAS,KAAK;AAAA,QACjC,CAAC;AAGD,YAAI,WAAW,UAAU;AACvB,8BAAoB;AAAA,YAClB,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa,gBAAgB,mBAAmB;AAAA,EACnD;AAIA,QAAM,oBAAgB;AAAA,IACpB,CAAC,mBAA2B;AAC1B,UAAI,iBAAiB,SAAS;AAC5B,qBAAa,iBAAiB,OAAO;AAAA,MACvC;AAEA,uBAAiB,UAAU,WAAW,MAAM;AAC1C,uBAAe,gBAAgB,QAAQ;AAAA,MACzC,GAAG,GAAG;AAAA,IACR;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,QAAM,SAAS,MAAM;AAEnB,QAAI,iBAAiB,SAAS;AAC5B,mBAAa,iBAAiB,OAAO;AACrC,uBAAiB,UAAU;AAAA,IAC7B;AAGA,UAAM,cAAc,mBAAmB;AAEvC,UAAM,KAAK,KAAK,IAAI,EAAE,SAAS;AAC/B,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,MACH,EAAE,IAAI,OAAO,OAAO,YAAY,SAAS,CAAC,IAAI,SAAS,MAAM,SAAS,CAAC,EAAE;AAAA,IAC3E;AAGA,YAAQ,OAAO;AACf,mBAAe,EAAE;AACjB,sBAAkB,IAAI;AAGtB,eAAW,MAAM;AACf,cAAQ,SAAS,aAAa;AAAA,IAChC,GAAG,CAAC;AAGJ,wBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,CAAC,UAAkB;AAEnC,QAAI,iBAAiB,SAAS;AAC5B,mBAAa,iBAAiB,OAAO;AACrC,uBAAiB,UAAU;AAAA,IAC7B;AAGA,UAAM,cAAc,mBAAmB;AAEvC,UAAM,QAAQ,KAAK,IAAI,EAAE,SAAS;AAElC,UAAM,UAAU,YAAY;AAAA,MAAI,SAC9B,IAAI,OAAO,QACP;AAAA,QACE,GAAG;AAAA,QACH,SAAS;AAAA,UACP,GAAG,IAAI;AAAA,UACP,EAAE,IAAI,OAAO,OAAO,cAAc,SAAS,KAAK;AAAA,QAClD;AAAA,MACF,IACA;AAAA,IACN;AAEA,YAAQ,OAAO;AACf,mBAAe,KAAK;AACpB,sBAAkB,KAAK;AAGvB,eAAW,MAAM;AACf,cAAQ,SAAS,aAAa;AAAA,IAChC,GAAG,CAAC;AAEJ,wBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,CAAC,OAAe,UAAmB;AAEpD,QAAI,iBAAiB,SAAS;AAC5B,mBAAa,iBAAiB,OAAO;AACrC,uBAAiB,UAAU;AAAA,IAC7B;AAGA,UAAM,cAAc,mBAAmB;AAEvC,YAAQ,WAAW;AACnB,mBAAe,KAAK;AACpB,sBAAkB,SAAS,IAAI;AAE/B,wBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,gBAAgB,SAAS;AAAA,MACzB,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,QAAM,YAAY,CAAC,IAAY,UAAkB;AAC/C,YAAQ,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,KAAK,EAAE,GAAG,GAAG,MAAM,IAAI,CAAE,CAAC;AAAA,EACxE;AAEA,QAAM,eAAe,CAAC,OAAe,aAAqB;AACxD,YAAQ,IAAI,oCAAwB,QAAQ;AAC5C;AAAA,MAAQ,CAAC,SACP,KAAK,IAAI,CAAC,QAAQ;AAChB,YAAI,IAAI,OAAO,MAAO,QAAO;AAE7B,cAAM,mBAAmB,IAAI,QAAQ,OAAO,CAAC,OAAO,GAAG,OAAO,QAAQ;AAEtE,YAAI,aAAa,gBAAgB;AAC/B,4BAAkB,IAAI;AACtB,qBAAW,MAAM;AACf,oBAAQ,SAAS,aAAa;AAAA,UAChC,GAAG,CAAC;AAAA,QACN;AAEA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AACA,eAAW,eAAe;AAAA,EAC5B;AAEA,QAAM,eAAe,CAAC,OAAe,UAAkB,UAAkB;AACvE;AAAA,MAAQ,CAAC,SACP,KAAK;AAAA,QAAI,CAAC,QACR,IAAI,OAAO,QACP;AAAA,UACE,GAAG;AAAA,UACH,SAAS,IAAI,QAAQ;AAAA,YAAI,CAAC,OACxB,GAAG,OAAO,WAAW,EAAE,GAAG,IAAI,MAAM,IAAI;AAAA,UAC1C;AAAA,QACF,IACA;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,OAAe;AAChC,YAAQ,IAAI,iCAAqB,EAAE;AAGnC,QAAI,iBAAiB,SAAS;AAC5B,mBAAa,iBAAiB,OAAO;AACrC,uBAAiB,UAAU;AAAA,IAC7B;AAGA,UAAM,cAAc,OAAO,cAAc,OAAO,mBAAmB;AAEnE,YAAQ,CAAC,SAAS;AAChB,YAAM,aAAa,OAAO,cAAc,OAAO,aAAa,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAErF,UAAI,OAAO,aAAa;AACtB,cAAM,OAAO,UAAU,CAAC;AACxB,uBAAe,MAAM,MAAM,EAAE;AAC7B,0BAAkB,IAAI;AACtB,YAAI,CAAC,MAAM;AACT,qBAAW,MAAM;AACf,oBAAQ,SAAS,aAAa;AAAA,UAChC,GAAG,CAAC;AAAA,QACN;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAED,eAAW,YAAY;AAAA,EACzB;AAGA,+BAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,MAAM,EAAE,OAAO,aAAa,UAAU,eAAe;AAE3D,QACE,gBAAgB,WAChB,gBAAgB,QAAQ,UAAU,IAAI,SACtC,gBAAgB,QAAQ,aAAa,IAAI,UACzC;AACA;AAAA,IACF;AAGA,QAAI,eAAe,QAAS;AAC5B,mBAAe,UAAU;AAEzB,UAAM,MAAM,KAAK,KAAK,OAAK,EAAE,OAAO,WAAW;AAC/C,UAAM,OAAO,iBACT,KAAK,QAAQ,KAAK,QAAM,GAAG,OAAO,cAAc,IAChD;AAEJ,QAAI,MAAM,SAAS;AACjB,aAAO,SAAS,WAAW,KAAK,OAAO;AAAA,IACzC,OAAO;AACL,aAAO,SAAS,aAAa;AAAA,IAC/B;AAEA,oBAAgB,UAAU;AAC1B,mBAAe,UAAU;AAAA,EAC3B,GAAG,CAAC,QAAQ,MAAM,aAAa,cAAc,CAAC;AAI9C,SACE,8CAAC,wBAAqB,OAAO;AAAA,IAC3B,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB;AAAA,EACF,GACE,wDAAC,mBACC,yDAAC,SAAI,WAAU,gCACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,KAAK,SAAS;AAAA,QAC5B,UAAU;AAAA,QACV,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,gBAAgB;AAAA;AAAA,IAClB;AAAA,IAEA,+CAAC,gBAAa,WAAU,gCACtB;AAAA,oDAAC,YAAO,WAAU,+BAChB,wDAAC,kBAAe,GAClB;AAAA,MAEC;AAAA,OACH;AAAA,KACF,GACF,GACF;AAEJ;;;AI1aA,IAAAC,iBAA4C;AAC5C,IAAAA,iBAAwD;AAIxD,yBAA2B;AAE3B,6BAAkB;AAClB,4BAAmC;AACnC,kCAA0B;AAC1B,kCAA2B;AAC3B,iCAA0B;AAC1B,iCAA0B;AAC1B,mCAA4B;AAC5B,wBAAqC;AACrC,kCAA6B;;;ACjB7B,kBAAqB;AAMd,IAAM,WAAW,iBAAK,OAAO;EAClC,MAAM;EACN,SAAS;EACT,SAAS;EAET,gBAAgB,CAAC,MAAM,MAAM;AAC3B,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;IACT;AAEA,WAAO,EAAE,eAAe,KAAK,SAAS,MAAM;EAC9C;AACF,CAAC;ACdD,IAAO,gBAAQ;;;ACJf,IAAAC,eAAsC;AA2B/B,IAAM,YAAY,kBAAK,OAAyB;EACrD,MAAM;EAEN,UAAU;EAEV,aAAa;AACX,WAAO;MACL,gBAAgB,CAAC;IACnB;EACF;EAEA,OAAO;EAEP,SAAS;EAET,YAAY;AACV,WAAO,CAAC,EAAE,KAAK,IAAI,CAAC;EACtB;EAEA,WAAW,EAAE,eAAe,GAAG;AAC7B,WAAO,CAAC,SAAK,8BAAgB,KAAK,QAAQ,gBAAgB,cAAc,GAAG,CAAC;EAC9E;EAEA,eAAe,CAAC,OAAO,YAAY;AACjC,UAAM,SAAS,MAAM,UAAU,CAAC;AAIhC,QAAI,OAAO,WAAW,KAAK,OAAO,CAAC,EAAE,SAAS,SAAS;AAErD,aAAO,QAAQ,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C;AAGA,WAAO,QAAQ;MACb;MACA;;MACA,QAAQ,YAAY,MAAM;IAC5B;EACF;EAEA,gBAAgB,CAAC,MAAM,MAAM;AAC3B,QAAI,CAAC,QAAQ,CAAC,MAAM,QAAQ,KAAK,OAAO,GAAG;AACzC,aAAO;IACT;AAEA,WAAO,EAAE,eAAe,KAAK,OAAO;EACtC;EAEA,cAAc;AACZ,WAAO;MACL,cACE,MACA,CAAC,EAAE,SAAS,MAAM;AAChB,eAAO,SAAS,QAAQ,KAAK,IAAI;MACnC;IACJ;EACF;EAEA,uBAAuB;AACrB,WAAO;MACL,aAAa,MAAM,KAAK,OAAO,SAAS,aAAa;IACvD;EACF;AACF,CAAC;ACvFD,IAAOC,iBAAQ;;;ACJf,IAAAC,eAAqB;AAMd,IAAM,OAAO,kBAAK,OAAO;EAC9B,MAAM;EACN,OAAO;EAEP,eAAe,CAAA,UAAS;AAEtB,WAAO;MACL,MAAM;MACN,MAAM,MAAM,QAAQ;IACtB;EACF;EAEA,gBAAgB,CAAA,SAAQ,KAAK,QAAQ;AACvC,CAAC;ACfD,IAAOC,iBAAQ;;;ANiBf,IAAAC,+BAAsC;AACtC,6BAAkB;AAClB,6BAAyB;AACzB,IAAAC,qBAA2B;;;AOvB3B,IAAAC,eAA0B;AAE1B,SAAS,QAAQ,OAAsC;AACrD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,IAAI,kBAAkB,KAAK,OAAO,KAAK,CAAC;AAC9C,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,IAAI,WAAW,EAAE,CAAC,CAAC;AACzB,SAAO,OAAO,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;AAC9C;AAEA,SAAS,2BAA2B,QAA4B;AAC9D,QAAM,EAAE,MAAM,IAAI,OAAO,MAAM;AAE/B,QAAM,QAAQ,MAAM,MAAM;AAC1B,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,QAAQ,EAAE,KAAK,SAAS,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU;AACxE,YAAM,SAAS,QAAQ,EAAE,MAAM,QAAQ;AACvC,UAAI,WAAW,KAAM,QAAO;AAAA,IAC9B;AAAA,EACF;AAGA,QAAM,OAAO,OAAO,MAAM,IAAI,OAAO,MAAM,GAAG;AAC9C,MAAI,QAAQ,KAAK,SAAS,KAAK,MAAM,OAAO;AAC1C,UAAM,QAAQ,KAAK,MAAM;AACzB,UAAM,IAAI,2BAA2B,KAAK,KAAK;AAC/C,QAAI,KAAK,EAAE,CAAC,GAAG;AACb,YAAM,SAAS,QAAQ,EAAE,CAAC,EAAE,KAAK,CAAC;AAClC,UAAI,WAAW,KAAM,QAAO;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,kBAAkB,uBAAU,OAAO;AAAA,EAC9C,MAAM;AAAA;AAAA,EAGN,aAAa;AACX,WAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK;AAAA,MACL,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL,kBACE,MACA,CAAC,EAAE,UAAU,OAAO,MAAM;AACxB,YAAI,CAAC,OAAQ,QAAO;AAGpB,cAAM,QAAQ,OAAO,cAAc,WAAW,KAAK,CAAC;AACpD,YAAI,YAAY,QAAQ,MAAM,YAAY,IAAI;AAG9C,YAAI,cAAc,MAAM;AACtB,sBAAY,2BAA2B,MAAM;AAAA,QAC/C;AAGA,YAAI,cAAc,MAAM;AACtB,sBAAY,KAAK,QAAQ;AAAA,QAC3B;AAEA,cAAM,UAAU,YAAY,KAAK,QAAQ;AACzC,eAAO,SAAS,YAAY,GAAG,OAAO,IAAI;AAAA,MAC5C;AAAA,MAEF,kBACE,MACA,CAAC,EAAE,UAAU,OAAO,MAAM;AACxB,YAAI,CAAC,OAAQ,QAAO;AAEpB,cAAM,QAAQ,OAAO,cAAc,WAAW,KAAK,CAAC;AACpD,YAAI,YAAY,QAAQ,MAAM,YAAY,IAAI;AAE9C,YAAI,cAAc,MAAM;AACtB,sBAAY,2BAA2B,MAAM;AAAA,QAC/C;AAGA,YAAI,cAAc,MAAM;AACtB,sBAAY,KAAK,QAAQ;AAAA,QAC3B;AAEA,cAAM,UAAU,KAAK,IAAI,KAAK,QAAQ,KAAK,YAAa,KAAK,QAAQ,IAAI;AACzE,eAAO,SAAS,YAAY,GAAG,OAAO,IAAI;AAAA,MAE5C;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,uBAAuB;AACrB,WAAO;AAAA;AAAA,MAEL,eAAe,MAAM,KAAK,OAAO,SAAS,iBAAiB;AAAA;AAAA,MAE3D,eAAe,MAAM,KAAK,OAAO,SAAS,iBAAiB;AAAA;AAAA;AAAA;AAAA,IAI7D;AAAA,EACF;AACF,CAAC;;;AC1GD,IAAAC,gBAA8C;;;ACA9C,IAAAC,gBASO;AACP,IAAAA,gBAiBO;AAmHD,IAAAC,uBAAA;AA5EN,SAAS,WAAW;AAAA,EAClB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,aAAa;AACf,IAA4C,CAAC,GAAG;AAC9C,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,wBAAkB,WAAW;AAE7E,QAAM,OAAO,kBAAkB;AAC/B,QAAM,UAAU,qBAAqB;AAErC,QAAM,WAAO,2BAAY;AAAA,IACvB;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,YAAY;AAAA,UACV,sBAAO,CAAC;AAAA,UACR,oBAAK;AAAA,QACH,WAAW,UAAU,SAAS,GAAG;AAAA,QACjC,2BAA2B;AAAA,QAC3B,SAAS;AAAA,MACX,CAAC;AAAA,UACD,qBAAM,EAAE,SAAS,EAAE,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAED,QAAM,UAAU,KAAK;AAErB,QAAM,YAAQ,wBAAS,SAAS;AAAA,IAC9B,WAAW;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS,kBAAkB;AAAA,IAC3B,OAAO;AAAA,MACL,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,QAAM,YAAQ,wBAAS,SAAS;AAAA,IAC9B,SAAS,kBAAkB;AAAA,EAC7B,CAAC;AACD,QAAM,cAAU,0BAAW,OAAO;AAClC,QAAM,WAAO,uBAAQ,SAAS,EAAE,MAAM,UAAU,CAAC;AAEjD,QAAM,mBAAe,+BAAgB,CAAC,OAAO,OAAO,SAAS,IAAI,CAAC;AAElE,aAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,CAAC,MAAM,SAAS,cAAc,IAAI;AAAA,EACpC;AACF;AAEA,IAAM,qBAAiB,6BAA0C,IAAI;AAErE,SAAS,oBAAoB;AAC3B,QAAM,cAAU,0BAAW,cAAc;AAEzC,MAAI,WAAW,MAAM;AACnB,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AAEA,SAAO;AACT;AAEO,SAASC,SAAQ,EAAE,UAAU,GAAG,MAAM,GAAyB;AACpE,QAAM,UAAU,WAAW,KAAK;AAEhC,MAAI,CAAC,MAAM,eAAe;AACxB,WACE,8CAAC,eAAe,UAAf,EAAwB,OAAO,SAC7B,UACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,MAAM,MAAM,SAAS,GAAG,OAAO,MAAM,cAAc,EAAE;AAAA,MAC9D,WAAW,MAAM;AAAA,MAEjB,wDAAC,eAAe,UAAf,EAAwB,OAAO,SAC7B,UACH;AAAA;AAAA,EACF;AAEJ;AAEO,IAAMC,sBAAiB;AAAA,EAC5B,SAASA,gBAAe,EAAE,UAAU,UAAU,OAAO,GAAG,MAAM,GAAG,SAAS;AACxE,UAAM,UAAU,kBAAkB;AAClC,UAAM,kBAAc,8BAAe,QAAQ,IACvC,SAAS,uBAAS,EAAE,KAAK;AAAA;AAAA,MAEtB,SAAiD,MAAM;AAAA;AAAA;AAAA,MAEvD,SAAiB;AAAA,QACpB;AACJ,UAAM,UAAM,4BAAa,CAAC,QAAQ,KAAK,cAAc,SAAS,WAAW,CAAC;AAE1E,QAAI,eAAW,8BAAe,QAAQ,GAAG;AACvC,YAAM,iBAAiB;AAAA,QACrB,sBAAsB,QAAQ,OAAO,SAAS;AAAA,MAChD;AAEA,iBAAO;AAAA,QACL;AAAA,QACA,QAAQ,kBAAkB;AAAA,UACxB;AAAA,UACA,GAAG;AAAA,UACH,GAAI,OAAO,SAAS,UAAU,WAAW,SAAS,QAAQ,CAAC;AAAA,UAC3D,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,sBAAoB,QAAQ,OAAO,SAAS;AAAA,QAC3C,GAAG,QAAQ,kBAAkB,KAAK;AAAA,QAElC;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEO,IAAMC,sBAAiB;AAAA,EAC5B,SAASA,gBACP,EAAE,OAAO,UAAU,SAAS,MAAM,cAAc,CAAC,GAAG,GAAG,MAAM,GAC7D,SACA;AACA,UAAM,UAAU,kBAAkB;AAClC,UAAM,UAAM,4BAAa,CAAC,QAAQ,KAAK,aAAa,OAAO,CAAC;AAE5D,QAAI,CAAC,QAAQ,KAAM,QAAO;AAE1B,UAAM,UACJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO;AAAA,UACL,GAAG,QAAQ;AAAA,UACX,GAAG;AAAA,QACL;AAAA,QACC,GAAG,QAAQ,iBAAiB,KAAK;AAAA,QAClC,WAAU;AAAA,QAET;AAAA;AAAA,IACH;AAGF,QAAI,QAAQ;AACV,aAAO,8CAAC,gCAAgB,GAAG,aAAc,mBAAQ;AAAA,IACnD;AAEA,WAAO;AAAA,EACT;AACF;AAEAF,SAAQ,cAAc;AACtBC,gBAAe,cAAc;AAC7BC,gBAAe,cAAc;;;AC1O7B,mBAKO;AAEP,IAAAC,eAA0B;AAEnB,IAAM,gBAAgB,IAAI,OAAO;AAEjC,IAAM,cAAsC;AAAA,EACjD,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AACZ;AAcO,SAASC,OACX,SACK;AACR,SAAO,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AACzC;AAMO,SAAS,QAAiB;AAC/B,SACE,OAAO,cAAc,eACrB,UAAU,SAAS,YAAY,EAAE,SAAS,KAAK;AAEnD;AASO,IAAM,oBAAoB,CAC/B,KACAC,QACA,aAAsB,SACnB;AACH,MAAIA,QAAO;AACT,UAAM,WAAW,IAAI,YAAY;AACjC,WAAO,YAAY,QAAQ,MAAM,aAAa,IAAI,YAAY,IAAI;AAAA,EACpE;AAEA,SAAO,aAAa,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC,IAAI;AACnE;AASO,IAAM,oBAAoB,CAAC,UAI5B;AACJ,QAAM,EAAE,cAAc,YAAY,KAAK,aAAa,KAAK,IAAI;AAE7D,MAAI,CAAC,aAAc,QAAO,CAAC;AAE3B,SAAO,aACJ,MAAM,SAAS,EACf,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,EACvB,IAAI,CAAC,QAAQ,kBAAkB,KAAK,MAAM,GAAG,UAAU,CAAC;AAC7D;AAQO,IAAM,iBAAiB,CAC5B,UACA,WACY;AACZ,MAAI,CAAC,QAAQ,OAAQ,QAAO;AAC5B,SAAO,OAAO,OAAO,KAAK,MAAM,IAAI,QAAQ,MAAM;AACpD;AAQO,IAAM,iBAAiB,CAC5B,UACA,WACY;AACZ,MAAI,CAAC,QAAQ,OAAQ,QAAO;AAC5B,SAAO,OAAO,OAAO,KAAK,MAAM,IAAI,QAAQ,MAAM;AACpD;AAOO,SAAS,cAAc,QAAgB;AAC5C,QAAM,EAAE,OAAO,KAAK,IAAI;AACxB,QAAM,EAAE,KAAK,UAAU,IAAI;AAE3B,QAAM,UAAU,uBAAU,SAAS,UAAU,KAAK,GAAG,IAAI;AACzD,MAAI,SAAS;AACX,SAAK,SAAS,MAAM,GAAG,aAAa,OAAO,EAAE,eAAe,CAAC;AAC7D,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,MAAM,OAAO,MAAM;AACzC,MAAI,CAAC,eAAe;AAClB,YAAQ,KAAK,yCAAyC;AACtD,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,IAAI,QAAQ;AACxB,QAAM,OAAO,cAAc,OAAO;AAClC,MAAI,KAAK,MAAM,GAAG,OAAO,KAAK,IAAI;AAGlC,QAAM,UAAU,GAAG,IAAI,QAAQ,MAAM,CAAC;AACtC,OAAK,GAAG,aAAa,2BAAc,KAAK,OAAO,CAAC,EAAE,eAAe;AACjE,OAAK,SAAS,EAAE;AAChB,SAAO;AACT;AAOO,SAAS,gBAAgB,KAA+C;AAC7E,SAAO,OAAO,QAAQ,YAAY,OAAO;AAC3C;AAQO,SAAS,qBACd,QACA,gBACS;AACT,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,QAAQ,MAAM,QAAQ,cAAc,IACtC,iBACA,CAAC,cAAc;AAEnB,QAAM,QAAQ,MAAM;AAAA,IAAK,CAAC,SACxB,OAAO,iBAAiB,WAAW,KAAK,CAAC,QAAQ,IAAI,SAAS,IAAI;AAAA,EACpE;AAEA,MAAI,CAAC,OAAO;AACV,YAAQ;AAAA,MACN,2BAA2B,MAAM,KAAK,IAAI,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AACT;AAQO,SAAS,mBAAmB,QAAgB,UAAkB;AACnE,MAAI;AACF,UAAM,OAAO,OAAO,MAAM,IAAI,OAAO,QAAQ;AAC7C,QAAI,CAAC,MAAM;AACT,cAAQ,KAAK,6BAA6B,QAAQ,EAAE;AACpD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,kCAAkC,QAAQ,KAAK,KAAK;AAClE,WAAO;AAAA,EACT;AACF;AAUO,SAAS,iBAAiB,OAIY;AAC3C,QAAM,EAAE,QAAQ,MAAM,QAAQ,IAAI;AAElC,MAAI,CAAC,UAAU,CAAC,OAAO,OAAO,IAAK,QAAO;AAG1C,QAAM,eAAe,SAAS,UAAa,SAAS;AACpD,QAAM,cAAc,gBAAgB,OAAO;AAE3C,MAAI,CAAC,gBAAgB,CAAC,aAAa;AACjC,WAAO;AAAA,EACT;AAGA,MAAI,cAAc;AAChB,QAAI,WAAW;AACf,QAAI,YAA+B;AAEnC,WAAO,MAAM,IAAI,YAAY,CAAC,aAAa,QAAQ;AAGjD,UAAI,gBAAgB,MAAM;AACxB,mBAAW;AACX,oBAAY;AACZ,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AAED,QAAI,aAAa,MAAM,cAAc,MAAM;AACzC,aAAO,EAAE,KAAK,UAAU,MAAM,UAAU;AAAA,IAC1C;AAAA,EACF;AAGA,MAAI,aAAa;AACf,UAAM,YAAY,mBAAmB,QAAQ,OAAQ;AACrD,QAAI,WAAW;AACb,aAAO,EAAE,KAAK,SAAU,MAAM,UAAU;AAAA,IAC1C;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,mBACd,QACA,gBAA0B,CAAC,GAC3B,qBAA8B,OACrB;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,MAAM,UAAW,QAAO;AAE/C,QAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,MAAI,UAAU,MAAO,QAAO;AAG5B,MAAI,qBAAqB,4BAAe;AACtC,UAAM,eAAe,UAAU;AAC/B,WAAO,eAAe,cAAc,SAAS,aAAa,KAAK,IAAI,IAAI;AAAA,EACzE;AAGA,MAAI,oBAAoB;AACtB,UAAM,EAAE,MAAM,IAAI;AAClB,aAAS,QAAQ,MAAM,OAAO,QAAQ,GAAG,SAAS;AAChD,YAAM,eAAe,MAAM,KAAK,KAAK;AACrC,UAAI,cAAc,SAAS,aAAa,KAAK,IAAI,GAAG;AAClD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,gCACd,QACA,QAAkB,CAAC,GACV;AACT,MAAI,CAAC,UAAU,MAAM,WAAW,EAAG,QAAO;AAE1C,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,EAAE,UAAU,IAAI;AACtB,QAAM,UAAU,IAAI,IAAI,KAAK;AAE7B,MAAI,qBAAqB,4BAAe;AACtC,UAAM,WAAW,UAAU,MAAM,MAAM;AACvC,WAAO,CAAC,CAAC,YAAY,QAAQ,IAAI,QAAQ;AAAA,EAC3C;AAEA,MAAI,qBAAqB,8BAAiB,qBAAqB,2BAAc;AAC3E,QAAI,QAAQ;AACZ,UAAM,IAAI,aAAa,UAAU,MAAM,UAAU,IAAI,CAAC,SAAS;AAC7D,UAAI,KAAK,eAAe,CAAC,QAAQ,IAAI,KAAK,KAAK,IAAI,GAAG;AACpD,gBAAQ;AACR,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AASO,IAAM,oBAAoB,OAC/B,MACA,YACA,gBACoB;AAEpB,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AAEA,MAAI,KAAK,OAAO,eAAe;AAC7B,UAAM,IAAI;AAAA,MACR,sCAAsC,iBAAiB,OAAO,KAAK;AAAA,IACrE;AAAA,EACF;AAIA,WAAS,WAAW,GAAG,YAAY,KAAK,YAAY,IAAI;AACtD,QAAI,aAAa,SAAS;AACxB,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACpC;AACA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,iBAAa,EAAE,SAAS,CAAC;AAAA,EAC3B;AAEA,SAAO;AACT;AAqBA,IAAM;AAAA;AAAA,EAEJ;AAAA;AAEK,SAAS,aACd,KACA,WACA;AACA,QAAM,mBAA6B;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,WAAW;AACb,cAAU,QAAQ,CAAC,aAAa;AAC9B,YAAM,eACJ,OAAO,aAAa,WAAW,WAAW,SAAS;AAErD,UAAI,cAAc;AAChB,yBAAiB,KAAK,YAAY;AAAA,MACpC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SACE,CAAC,OACD,IAAI,QAAQ,iBAAiB,EAAE,EAAE;AAAA,IAC/B,IAAI;AAAA;AAAA,MAEF,UAAU,iBAAiB,KAAK,GAAG,CAAC;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAEJ;AAEO,SAAS,YACd,UACA,SACA,WACQ;AACR,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,UAAU,OAAO;AAErC,QAAI,aAAa,IAAI,MAAM,SAAS,GAAG;AACrC,aAAO,IAAI;AAAA,IACb;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AA6FO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAYO,IAAM,oBAAoB,uBAAU,OAAO;AAAA,EAChD,MAAM;AAAA,EAEN,aAAa;AACX,WAAO;AAAA,MACL,OAAO,CAAC,WAAW;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,sBAAsB;AACpB,WAAO;AAAA,MACL;AAAA,QACE,OAAO,KAAK,QAAQ;AAAA,QACpB,YAAY;AAAA,UACV,UAAU;AAAA,YACR,SAAS;AAAA,YACT,WAAW,CAAC,YACV,QAAQ,MAAM,YAAY,QAAQ,aAAa,gBAAgB;AAAA,YACjE,YAAY,CAAC,eAAe;AAC1B,kBAAI,CAAC,WAAW,UAAU;AACxB,uBAAO,CAAC;AAAA,cACV;AAEA,qBAAO;AAAA,gBACL,OAAO,cAAc,WAAW,QAAQ;AAAA,cAC1C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL,aACE,CAAC,aACD,CAAC,EAAE,SAAS,MAAM;AAChB,eAAO,SAAS,QAAQ,aAAa,EAAE,SAAS,CAAC;AAAA,MACnD;AAAA,MAEF,kBACE,MACA,CAAC,EAAE,OAAO,MAAM;AACd,cAAM,cAAc,OAAO,cAAc,WAAW,EAAE;AACtD,cAAM,eAAe,WAAW,QAAQ,eAAe,MAAM;AAC7D,cAAM,YAAY,KAAK,IAAI,eAAe,GAAG,WAAW,SAAS,CAAC;AAClE,cAAM,WAAW,WAAW,SAAS;AAErC,eAAO,OAAO,MAAM,EAAE,MAAM,EAAE,YAAY,QAAQ,EAAE,IAAI;AAAA,MAC1D;AAAA,MAEF,kBACE,MACA,CAAC,EAAE,OAAO,MAAM;AACd,cAAM,cAAc,OAAO,cAAc,WAAW,EAAE;AACtD,cAAM,eAAe,WAAW,QAAQ,eAAe,MAAM;AAC7D,cAAM,YAAY,KAAK,IAAI,eAAe,GAAG,CAAC;AAC9C,cAAM,WAAW,WAAW,SAAS;AAErC,eAAO,OAAO,MAAM,EAAE,MAAM,EAAE,YAAY,QAAQ,EAAE,IAAI;AAAA,MAC1D;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,uBAAuB;AACrB,WAAO;AAAA,MACL,eAAe,MAAM,KAAK,OAAO,SAAS,iBAAiB;AAAA,MAC3D,eAAe,MAAM,KAAK,OAAO,SAAS,iBAAiB;AAAA,IAC7D;AAAA,EACF;AACF,CAAC;;;AF7mBO,IAAAC,uBAAA;AARD,IAAM,kBAAqD,CAAC;AAAA,EACjE;AACF,MAAM;AACJ,MAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,SACE,8CAAC,SACE,oBAAU,IAAI,CAAC,KAAK,UACnB,+CAAC,0BACE;AAAA,YAAQ,KAAK,8CAAC,SAAI,eAAC;AAAA,IACpB,8CAAC,SAAK,eAAI;AAAA,OAFG,KAGf,CACD,GACH;AAEJ;AAEO,IAAMC,cAAS;AAAA,EACpB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA,cAAc;AAAA,IACd,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,gBAAY;AAAA,MAChB,MAAM,kBAAkB,EAAE,aAAa,CAAC;AAAA,MACxC,CAAC,YAAY;AAAA,IACf;AAEA,QAAI,CAAC,WAAW,CAAC,aAAa;AAC5B,aACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAWC,IAAG,iBAAiB,SAAS;AAAA,UACxC;AAAA,UACA,cAAY;AAAA,UACX,GAAG;AAAA,UAEH;AAAA;AAAA,MACH;AAAA,IAEJ;AAEA,WACE,+CAACC,UAAA,EAAQ,OAAO,KACd;AAAA;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,WAAWF,IAAG,iBAAiB,SAAS;AAAA,UACxC;AAAA,UACA,cAAY;AAAA,UACX,GAAG;AAAA,UAEH;AAAA;AAAA,MACH;AAAA,MACA,+CAACG,iBAAA,EACE;AAAA;AAAA,QACD,8CAAC,mBAAgB,WAAsB;AAAA,SACzC;AAAA,OACF;AAAA,EAEJ;AACF;AAEAJ,QAAO,cAAc;AAEd,IAAM,kBAAc,0BAKzB,CAAC,EAAE,WAAW,UAAU,cAAc,YAAY,GAAG,MAAM,GAAG,QAAQ;AACtE,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAWC,IAAG,uBAAuB,SAAS;AAAA,MAC9C,oBAAkB;AAAA,MAClB,MAAK;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ,CAAC;AACD,YAAY,cAAc;;;AGzFjB,IAAAI,uBAAA;AAfF,SAAS,OAAO;AAAA,EACrB,cAAc;AAAA,EACd;AAAA,EACA,QAAQ,CAAC;AAAA,EACT,GAAG;AACL,GAAgB;AACd,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA,IACH,GAAI,gBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE;AAAA,IACvD,GAAI,QAAQ;AAAA,MACV,OAAO,gBAAgB,aAAa,QAAQ;AAAA,MAC5C,QAAQ,gBAAgB,eAAe,QAAQ;AAAA,IACjD;AAAA,EACF;AAEA,SAAO,8CAAC,SAAK,GAAG,OAAO,OAAO,eAAe;AAC/C;;;ACvBA,IAAAC,iBAAqE;;;ACArE,IAAAC,gBAA2B;AAmBrB,IAAAC,uBAAA;AARC,IAAMC,iBAAY;AAAA,EACvB,CAAC,EAAE,YAAY,cAAc,YAAY,WAAW,GAAG,SAAS,GAAG,QAAQ;AACzE,UAAM,kBAAkB,gBAAgB,aAAa,cAAc;AACnE,UAAM,gBAAgB,aAClB,EAAE,MAAM,OAAO,IACf,EAAE,oBAAoB,iBAAiB,MAAM,YAAY;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAWC,IAAG,oBAAoB,SAAS;AAAA,QAC3C,oBAAkB;AAAA,QACjB,GAAG;AAAA,QACH,GAAG;AAAA,QACJ;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEAD,WAAU,cAAc;;;AC7BxB,IAAAE,gBAAoC;AAkD7B,SAAS,kBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,sBAAsB;AACxB,GAA6B;AAC3B,QAAM,CAAC,eAAe,gBAAgB,QAAI;AAAA,IACxC,sBAAsB,IAAI;AAAA,EAC5B;AAEA,+BAAU,MAAM;AACd,UAAM,2BAA2B,CAAC,UAAyB;AACzD,UAAI,CAAC,MAAM,OAAQ,QAAO;AAE1B,YAAM,WAAW,MACf,iBAAiB,CAAC,iBAAiB;AACjC,YAAI,iBAAiB,GAAI,QAAO;AAChC,gBAAQ,eAAe,KAAK,MAAM;AAAA,MACpC,CAAC;AAEH,YAAM,WAAW,MACf,iBAAiB,CAAC,iBAAiB;AACjC,YAAI,iBAAiB,GAAI,QAAO,MAAM,SAAS;AAC/C,gBAAQ,eAAe,IAAI,MAAM,UAAU,MAAM;AAAA,MACnD,CAAC;AAEH,cAAQ,MAAM,KAAK;AAAA,QACjB,KAAK,WAAW;AACd,cAAI,gBAAgB,aAAc,QAAO;AACzC,gBAAM,eAAe;AACrB,mBAAS;AACT,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,aAAa;AAChB,cAAI,gBAAgB,aAAc,QAAO;AACzC,gBAAM,eAAe;AACrB,mBAAS;AACT,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,aAAa;AAChB,cAAI,gBAAgB,WAAY,QAAO;AACvC,gBAAM,eAAe;AACrB,mBAAS;AACT,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,cAAc;AACjB,cAAI,gBAAgB,WAAY,QAAO;AACvC,gBAAM,eAAe;AACrB,mBAAS;AACT,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,OAAO;AACV,gBAAM,eAAe;AACrB,cAAI,MAAM,UAAU;AAClB,qBAAS;AAAA,UACX,OAAO;AACL,qBAAS;AAAA,UACX;AACA,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,QAAQ;AACX,gBAAM,eAAe;AACrB,2BAAiB,CAAC;AAClB,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,OAAO;AACV,gBAAM,eAAe;AACrB,2BAAiB,MAAM,SAAS,CAAC;AACjC,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,SAAS;AACZ,cAAI,MAAM,YAAa,QAAO;AAC9B,gBAAM,eAAe;AACrB,cAAI,kBAAkB,MAAM,MAAM,aAAa,GAAG;AAChD,uBAAW,MAAM,aAAa,CAAC;AAAA,UACjC;AACA,iBAAO;AAAA,QACT;AAAA,QAEA,KAAK,UAAU;AACb,gBAAM,eAAe;AACrB,oBAAU;AACV,iBAAO;AAAA,QACT;AAAA,QAEA;AACE,iBAAO;AAAA,MACX;AAAA,IACF;AAEA,QAAI,gBAAoC;AAExC,QAAI,QAAQ;AACV,sBAAgB,OAAO,KAAK;AAAA,IAC9B,WAAW,cAAc,SAAS;AAChC,sBAAgB,aAAa;AAAA,IAC/B;AAEA,QAAI,eAAe;AACjB,oBAAc,iBAAiB,WAAW,0BAA0B,IAAI;AAExE,aAAO,MAAM;AACX,uBAAe;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,+BAAU,MAAM;AACd,QAAI,OAAO;AACT,uBAAiB,sBAAsB,IAAI,EAAE;AAAA,IAC/C;AAAA,EACF,GAAG,CAAC,OAAO,mBAAmB,CAAC;AAE/B,SAAO;AAAA,IACL,eAAe,MAAM,SAAS,gBAAgB;AAAA,IAC9C;AAAA,EACF;AACF;;;ACjMA,IAAAC,gBAAoC;AASpC,IAAM,YAAY,CAAI,KAA8B,UAAoB;AACtE,MAAI,OAAO,QAAQ,YAAY;AAC7B,QAAI,KAAK;AAAA,EACX,WAAW,OAAO,OAAO,QAAQ,YAAY,aAAa,KAAK;AAE7D;AAAC,IAAC,IAA8B,UAAU;AAAA,EAC5C;AACF;AAEO,IAAM,iBAAiB,CAC5B,QACA,YACG;AACH,QAAM,kBAAc,sBAAmB,IAAI;AAE3C,aAAO;AAAA,IACL,CAAC,aAAuB;AACtB,UAAI,UAAU,aAAa,QAAQ;AACjC;AAAC,QAAC,OAAiC,UAAU;AAAA,MAC/C;AAEA,UAAI,YAAY,SAAS;AACvB,kBAAU,YAAY,SAAS,IAAI;AAAA,MACrC;AAEA,kBAAY,UAAU;AAEtB,UAAI,SAAS;AACX,kBAAU,SAAS,QAAQ;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EAClB;AACF;;;AH4CM,IAAAC,uBAAA;AAzEN,IAAM,uBAAuB,CAC3B,eACG;AACH,QAAM,CAAC,OAAO,QAAQ,QAAI,yBAAwB,CAAC,CAAC;AAEpD,QAAM,mBAAe,4BAAY,MAAM;AACrC,QAAI,CAAC,WAAW,QAAS,QAAO,CAAC;AACjC,WAAO,MAAM;AAAA,MACX,WAAW,QAAQ;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,gCAAU,MAAM;AACd,UAAM,UAAU,WAAW;AAC3B,QAAI,CAAC,QAAS;AAEd,UAAM,cAAc,MAAM,SAAS,aAAa,CAAC;AAEjD,gBAAY;AACZ,UAAM,WAAW,IAAI,iBAAiB,WAAW;AACjD,aAAS,QAAQ,SAAS,EAAE,WAAW,MAAM,SAAS,KAAK,CAAC;AAE5D,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,cAAc,UAAU,CAAC;AAE7B,QAAM,EAAE,cAAc,IAAI,kBAA+B;AAAA,IACvD,cAAc;AAAA,IACd;AAAA,IACA,aAAa;AAAA,IACb,UAAU,CAAC,OAAO,GAAG,MAAM;AAAA,IAC3B,qBAAqB;AAAA,EACvB,CAAC;AAED,gCAAU,MAAM;AACd,UAAM,UAAU,WAAW;AAC3B,QAAI,CAAC,QAAS;AAEd,UAAM,cAAc,CAAC,MAAkB;AACrC,YAAM,SAAS,EAAE;AACjB,UAAI,QAAQ,SAAS,MAAM;AACzB,eAAO,aAAa,sBAAsB,MAAM;AAAA,IACpD;AAEA,UAAM,aAAa,CAAC,MAAkB;AACpC,YAAM,SAAS,EAAE;AACjB,UAAI,QAAQ,SAAS,MAAM,EAAG,QAAO,gBAAgB,oBAAoB;AAAA,IAC3E;AAEA,YAAQ,iBAAiB,SAAS,aAAa,IAAI;AACnD,YAAQ,iBAAiB,QAAQ,YAAY,IAAI;AAEjD,WAAO,MAAM;AACX,cAAQ,oBAAoB,SAAS,aAAa,IAAI;AACtD,cAAQ,oBAAoB,QAAQ,YAAY,IAAI;AAAA,IACtD;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,gCAAU,MAAM;AACd,QAAI,kBAAkB,UAAa,MAAM,aAAa,GAAG;AACvD,YAAM,aAAa,EAAE,MAAM;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,eAAe,KAAK,CAAC;AAC3B;AAEO,IAAM,cAAU;AAAA,EACrB,CAAC,EAAE,UAAU,WAAW,UAAU,SAAS,GAAG,MAAM,GAAG,QAAQ;AAC7D,UAAM,iBAAa,uBAAuB,IAAI;AAC9C,UAAM,cAAc,eAAe,YAAY,GAAG;AAClD,yBAAqB,UAAU;AAE/B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,cAAW;AAAA,QACX,gBAAc;AAAA,QACd,WAAWC,IAAG,kBAAkB,SAAS;AAAA,QACxC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,QAAQ,cAAc;AAEf,IAAM,mBAAe;AAAA,EAC1B,CAAC,EAAE,UAAU,WAAW,GAAG,MAAM,GAAG,QAClC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,WAAWA,IAAG,wBAAwB,SAAS;AAAA,MAC9C,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AACA,aAAa,cAAc;AAEpB,IAAM,uBAAmB;AAAA,EAC9B,CAAC,EAAE,GAAG,MAAM,GAAG,QACb,8CAACC,YAAA,EAAU,KAAU,aAAY,YAAW,YAAU,MAAE,GAAG,OAAO;AAEtE;AACA,iBAAiB,cAAc;;;AIxH/B,mBAA2B;AAC3B,IAAAC,iBAAiC;AAGjC,IAAAC,uBASO;AAkCD,IAAAC,uBAAA;AAhCC,SAAS,mBAAmB;AACjC,QAAM,EAAE,OAAO,QAAI,iCAAiB;AAEpC,MAAI,CAAC,OAAQ,QAAO;AAEpB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAa;AAAA,MACb,YAAY,CAAC,EAAE,QAAAC,SAAQ,MAAM,MAAM;AACjC,cAAM,EAAE,MAAM,IAAI,MAAM,IAAI,MAAM;AAGlC,YAAI,MAAO,QAAO;AAGlB,YAAI,CAACA,QAAO,WAAY,QAAO;AAG/B,YAAI,WAAW;AACf,cAAM,IAAI,aAAa,MAAM,IAAI,CAAC,SAAS;AACzC,cAAI,KAAK,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,SAAS;AAC5D,uBAAW;AACX,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AAED,YAAI,SAAU,QAAO;AAErB,eAAO;AAAA,MACT;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UAIV;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;AAAA,gBACtE,WAAW,OAAO,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC,IAAI,cAAc;AAAA,gBAEpE,wDAAC,iCAAS,MAAM,IAAI;AAAA;AAAA,YACtB;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;AAAA,gBACtE,WAAW,OAAO,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC,IAAI,cAAc;AAAA,gBAEpE,wDAAC,iCAAS,MAAM,IAAI;AAAA;AAAA,YACtB;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;AAAA,gBACtE,WAAW,OAAO,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC,IAAI,cAAc;AAAA,gBAEpE,wDAAC,iCAAS,MAAM,IAAI;AAAA;AAAA,YACtB;AAAA,YAEA,8CAAC,aAAU,aAAY,YAAW,WAAU,QAAO;AAAA,YAGnD;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI;AAAA,gBAC7D,WAAW,OAAO,SAAS,YAAY,IAAI,cAAc;AAAA,gBAEzD,wDAAC,6BAAK,MAAM,IAAI;AAAA;AAAA,YAClB;AAAA,YAGA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI;AAAA,gBAC9D,WAAW,OAAO,SAAS,aAAa,IAAI,cAAc;AAAA,gBAE1D,wDAAC,oCAAY,MAAM,IAAI;AAAA;AAAA,YACzB;AAAA,YAGA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI;AAAA,gBAC3D,WAAW,OAAO,SAAS,UAAU,IAAI,cAAc;AAAA,gBAEvD,wDAAC,oCAAY,MAAM,IAAI;AAAA;AAAA,YACzB;AAAA,YAEA,8CAAC,aAAU,aAAY,YAAW,WAAU,QAAO;AAAA,YAGnD;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI;AAAA,gBAC5D,WAAW,OAAO,SAAS,WAAW,IAAI,cAAc;AAAA,gBAExD,wDAAC,6BAAK,MAAM,IAAI;AAAA;AAAA,YAClB;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;;;AC/HA,IAAAC,iBAAsC;AACtC,IAAAA,iBAAsC;;;ACCtC,IAAAC,iBAAiC;AAEjC,IAAAA,iBAAgC;;;ACJhC,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,gBAAY,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,UAAU,cAAc;;;ADgMtB,IAAAC,uBAAA;AAnIF,SAAS,cAAc,SAAwB;AAC7C,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAqB,CAAC,CAAC;AAEzD,QAAM,aAAa,OAAO,SAAuC;AAC/D,QAAI,KAAK,OAAO,QAAQ,SAAS;AAC/B,YAAM,QAAQ,IAAI;AAAA,QAChB,sCAAsC,QAAQ,UAAU,OAAO,IAAI;AAAA,MACrE;AACA,cAAQ,UAAU,KAAK;AACvB,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,UAAM,SAAS,OAAO,WAAW;AAEjC,UAAM,cAAwB;AAAA,MAC5B,IAAI;AAAA,MACJ;AAAA,MACA,UAAU;AAAA,MACV,QAAQ;AAAA,MACR;AAAA,IACF;AAEA,iBAAa,CAAC,SAAS,CAAC,GAAG,MAAM,WAAW,CAAC;AAE7C,QAAI;AACF,UAAI,CAAC,QAAQ,QAAQ;AACnB,cAAM,IAAI,MAAM,gCAAgC;AAAA,MAClD;AAEA,YAAM,MAAM,MAAM,QAAQ;AAAA,QACxB;AAAA,QACA,CAAC,UAAgC;AAC/B;AAAA,YAAa,CAAC,SACZ,KAAK;AAAA,cAAI,CAAC,SACR,KAAK,OAAO,SAAS,EAAE,GAAG,MAAM,UAAU,MAAM,SAAS,IAAI;AAAA,YAC/D;AAAA,UACF;AAAA,QACF;AAAA,QACA,gBAAgB;AAAA,MAClB;AAEA,UAAI,CAAC,IAAK,OAAM,IAAI,MAAM,gCAAgC;AAE1D,UAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC;AAAA,UAAa,CAAC,SACZ,KAAK;AAAA,YAAI,CAAC,SACR,KAAK,OAAO,SACR,EAAE,GAAG,MAAM,QAAQ,WAAW,KAAK,UAAU,IAAI,IACjD;AAAA,UACN;AAAA,QACF;AACA,gBAAQ,YAAY,GAAG;AACvB,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC;AAAA,UAAa,CAAC,SACZ,KAAK;AAAA,YAAI,CAAC,SACR,KAAK,OAAO,SACR,EAAE,GAAG,MAAM,QAAQ,SAAS,UAAU,EAAE,IACxC;AAAA,UACN;AAAA,QACF;AACA,gBAAQ;AAAA,UACN,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,eAAe;AAAA,QAC5D;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,UAAqC;AAC9D,QAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,cAAQ,UAAU,IAAI,MAAM,oBAAoB,CAAC;AACjD,aAAO,CAAC;AAAA,IACV;AAEA,QAAI,QAAQ,SAAS,MAAM,SAAS,QAAQ,OAAO;AACjD,cAAQ;AAAA,QACN,IAAI;AAAA,UACF,WAAW,QAAQ,KAAK,QAAQ,QAAQ,UAAU,IAAI,KAAK,GAAG;AAAA,QAChE;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV;AAGA,UAAM,iBAAiB,MAAM,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC;AAC3D,UAAM,UAAU,MAAM,QAAQ,IAAI,cAAc;AAGhD,WAAO,QAAQ,OAAO,CAAC,QAAuB,QAAQ,IAAI;AAAA,EAC5D;AAEA,QAAM,iBAAiB,CAAC,WAAmB;AACzC,iBAAa,CAAC,SAAS;AACrB,YAAM,eAAe,KAAK,KAAK,CAAC,SAAS,KAAK,OAAO,MAAM;AAC3D,UAAI,cAAc,iBAAiB;AACjC,qBAAa,gBAAgB,MAAM;AAAA,MACrC;AACA,UAAI,cAAc,KAAK;AACrB,YAAI,gBAAgB,aAAa,GAAG;AAAA,MACtC;AACA,aAAO,KAAK,OAAO,CAAC,SAAS,KAAK,OAAO,MAAM;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB,MAAM;AAC1B,cAAU,QAAQ,CAAC,SAAS;AAC1B,UAAI,KAAK,iBAAiB;AACxB,aAAK,gBAAgB,MAAM;AAAA,MAC7B;AACA,UAAI,KAAK,KAAK;AACZ,YAAI,gBAAgB,KAAK,GAAG;AAAA,MAC9B;AAAA,IACF,CAAC;AACD,iBAAa,CAAC,CAAC;AAAA,EACjB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,kBAA4B,MAChC;AAAA,EAAC;AAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,WAAU;AAAA,IACV,MAAK;AAAA,IACL,OAAM;AAAA,IAEN;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA;AACF;AAGF,IAAM,WAAqB,MACzB;AAAA,EAAC;AAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,WAAU;AAAA,IACV,OAAM;AAAA,IAEN;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,MAAK;AAAA,QACL,aAAY;AAAA,QACZ,QAAO;AAAA,QACP,aAAY;AAAA;AAAA,IACd;AAAA;AACF;AAGF,IAAM,iBAA2B,MAC/B;AAAA,EAAC;AAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,WAAU;AAAA,IACV,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,MAAK;AAAA;AAAA,IACP;AAAA;AACF;AAoBF,IAAM,sBAA0D,CAAC;AAAA,EAC/D;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,YAAY,aAAa,QAAI,yBAAS,KAAK;AAClD,QAAM,CAAC,cAAc,eAAe,QAAI,yBAAS,KAAK;AAEtD,QAAM,kBAAkB,CAAC,MAAuB;AAC9C,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,oBAAgB,IAAI;AAAA,EACtB;AAEA,QAAM,kBAAkB,CAAC,MAAuB;AAC9C,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,QAAI,CAAC,EAAE,cAAc,SAAS,EAAE,aAAqB,GAAG;AACtD,sBAAgB,KAAK;AACrB,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,MAAuB;AAC7C,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,kBAAc,IAAI;AAAA,EACpB;AAEA,QAAM,aAAa,CAAC,MAAuB;AACzC,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,oBAAgB,KAAK;AACrB,kBAAc,KAAK;AAEnB,UAAM,QAAQ,MAAM,KAAK,EAAE,aAAa,KAAK;AAC7C,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iCAAiC,eAAe,gBAAgB,EAAE,IAAI,aAAa,cAAc,EAAE;AAAA,MAC9G,aAAa;AAAA,MACb,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,QAAQ;AAAA,MAEP;AAAA;AAAA,EACH;AAEJ;AAgBA,IAAM,qBAAwD,CAAC;AAAA,EAC7D;AAAA,EACA;AACF,MAAM;AACJ,QAAM,iBAAiB,CAAC,UAAkB;AACxC,QAAI,UAAU,EAAG,QAAO;AACxB,UAAM,IAAI;AACV,UAAM,QAAQ,CAAC,SAAS,MAAM,MAAM,IAAI;AACxC,UAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAClD,WAAO,GAAG,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AAAA,EACvE;AAEA,SACE,+CAAC,SAAI,WAAU,+BACZ;AAAA,aAAS,WAAW,eACnB;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,OAAO,GAAG,SAAS,QAAQ,IAAI;AAAA;AAAA,IAC1C;AAAA,IAGF,+CAAC,SAAI,WAAU,uCACb;AAAA,qDAAC,SAAI,WAAU,iCACb;AAAA,sDAAC,SAAI,WAAU,iCACb,wDAAC,mBAAgB,GACnB;AAAA,QACA,+CAAC,SAAI,WAAU,+BACb;AAAA,wDAAC,UAAK,WAAU,4BACb,mBAAS,KAAK,MACjB;AAAA,UACA,8CAAC,UAAK,WAAU,+BACb,yBAAe,SAAS,KAAK,IAAI,GACpC;AAAA,WACF;AAAA,SACF;AAAA,MACA,+CAAC,SAAI,WAAU,+BACZ;AAAA,iBAAS,WAAW,eACnB,+CAAC,UAAK,WAAU,qCACb;AAAA,mBAAS;AAAA,UAAS;AAAA,WACrB;AAAA,QAEF;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAW;AAAA,YACX,SAAS,CAAC,MAAM;AACd,gBAAE,gBAAgB;AAClB,uBAAS;AAAA,YACX;AAAA,YAEA,wDAAC,aAAU,WAAU,sBAAqB;AAAA;AAAA,QAC5C;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,IAAM,kBAAgE,CAAC;AAAA,EACrE;AAAA,EACA;AACF,MACE,gFACE;AAAA,iDAAC,SAAI,WAAU,gCACb;AAAA,kDAAC,YAAS;AAAA,IACV,8CAAC,kBAAe;AAAA,IAChB,8CAAC,SAAI,WAAU,sCACb,wDAAC,mBAAgB,GACnB;AAAA,KACF;AAAA,EAEA,+CAAC,SAAI,WAAU,+BACb;AAAA,mDAAC,UAAK,WAAU,4BACd;AAAA,oDAAC,QAAG,6BAAe;AAAA,MAAK;AAAA,OAC1B;AAAA,IACA,+CAAC,UAAK,WAAU,+BAA8B;AAAA;AAAA,MACnC;AAAA,MAAM;AAAA,MAAM,UAAU,IAAI,KAAK;AAAA,MAAI;AAAA,MAAG,UAAU,OAAO;AAAA,MAAK;AAAA,OAEvE;AAAA,KACF;AAAA,GACF;AAGK,IAAM,kBAA2C,CAAC,UAAU;AACjE,QAAM,EAAE,QAAQ,OAAO,QAAQ,IAAI,MAAM,KAAK;AAC9C,QAAM,eAAW,uBAAyB,IAAI;AAC9C,QAAM,YAAY,MAAM;AAExB,QAAM,gBAA+B;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,UAAU,QAAQ;AAAA,IAC1B,WAAW,UAAU,QAAQ;AAAA,IAC7B,SAAS,UAAU,QAAQ;AAAA,EAC7B;AAEA,QAAM,EAAE,WAAW,aAAa,gBAAgB,cAAc,IAC5D,cAAc,aAAa;AAE7B,QAAM,eAAe,OAAO,UAAkB;AAC5C,UAAM,OAAO,MAAM,YAAY,KAAK;AAEpC,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,MAAM,MAAM,OAAO;AAEzB,UAAI,gBAAgB,GAAG,GAAG;AACxB,cAAM,aAAa,KAAK,IAAI,CAAC,KAAK,UAAU;AAC1C,gBAAM,WACJ,MAAM,KAAK,GAAG,KAAK,QAAQ,aAAa,EAAE,KAAK;AACjD,iBAAO;AAAA,YACL,MAAM,UAAU,QAAQ;AAAA,YACxB,OAAO;AAAA,cACL,GAAG,UAAU;AAAA,cACb,KAAK;AAAA,cACL,KAAK;AAAA,cACL,OAAO;AAAA,YACT;AAAA,UACF;AAAA,QACF,CAAC;AAED,cAAM,OACH,MAAM,EACN,MAAM,EACN,YAAY,EAAE,MAAM,KAAK,IAAI,MAAM,MAAM,KAAK,SAAS,CAAC,EACxD,gBAAgB,KAAK,UAAU,EAC/B,IAAI;AAEP,sBAAc,MAAM,MAAM;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,MAA2C;AAC/D,UAAM,QAAQ,EAAE,OAAO;AACvB,QAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,gBAAU,QAAQ,UAAU,IAAI,MAAM,kBAAkB,CAAC;AACzD;AAAA,IACF;AACA,iBAAa,MAAM,KAAK,KAAK,CAAC;AAAA,EAChC;AAEA,QAAM,cAAc,MAAM;AACxB,QAAI,SAAS,WAAW,UAAU,WAAW,GAAG;AAC9C,eAAS,QAAQ,QAAQ;AACzB,eAAS,QAAQ,MAAM;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,WAAW,UAAU,SAAS;AAEpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,UAAU;AAAA,MACV,SAAS;AAAA,MAER;AAAA,SAAC,YACA,8CAAC,uBAAoB,QAAQ,cAC3B,wDAAC,mBAAgB,SAAkB,OAAc,GACnD;AAAA,QAGD,YACC,+CAAC,SAAI,WAAU,gCACZ;AAAA,oBAAU,SAAS,KAClB,+CAAC,SAAI,WAAU,8BACb;AAAA,2DAAC,UAAK;AAAA;AAAA,cAAW,UAAU;AAAA,cAAO;AAAA,eAAM;AAAA,YACxC;AAAA,cAACA;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,cAAW;AAAA,gBACX,SAAS,CAAC,MAAM;AACd,oBAAE,gBAAgB;AAClB,gCAAc;AAAA,gBAChB;AAAA,gBACD;AAAA;AAAA,YAED;AAAA,aACF;AAAA,UAED,UAAU,IAAI,CAAC,aACd;AAAA,YAAC;AAAA;AAAA,cAEC;AAAA,cACA,UAAU,MAAM,eAAe,SAAS,EAAE;AAAA;AAAA,YAFrC,SAAS;AAAA,UAGhB,CACD;AAAA,WACH;AAAA,QAGF;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,MAAK;AAAA,YACL;AAAA,YACA,MAAK;AAAA,YACL,UAAU,QAAQ;AAAA,YAClB,UAAU;AAAA,YACV,SAAS,CAAC,MAA0C,EAAE,gBAAgB;AAAA;AAAA,QACxE;AAAA;AAAA;AAAA,EACF;AAEJ;;;ADxeO,IAAMC,mBAAkB,oBAAK,OAA+B;AAAA,EACjE,MAAM;AAAA,EAEN,OAAO;AAAA,EAEP,WAAW;AAAA,EAEX,YAAY;AAAA,EAEZ,MAAM;AAAA,EAEN,aAAa;AACX,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,WAAW;AAAA,MACX,gBAAgB,CAAC;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,gBAAgB;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,SAAS,KAAK,QAAQ;AAAA,MACxB;AAAA,MACA,OAAO;AAAA,QACL,SAAS,KAAK,QAAQ;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,QACP,SAAS,KAAK,QAAQ;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY;AACV,WAAO,CAAC,EAAE,KAAK,gCAAgC,CAAC;AAAA,EAClD;AAAA,EAEA,WAAW,EAAE,eAAe,GAAG;AAC7B,WAAO;AAAA,MACL;AAAA,UACA,gCAAgB,EAAE,aAAa,eAAe,GAAG,cAAc;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,eAAO,sCAAsB,eAAwB;AAAA,EACvD;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL,oBACE,CAAC,YACD,CAAC,EAAE,SAAS,MAAM;AAChB,eAAO,SAAS,cAAc;AAAA,UAC5B,MAAM,KAAK;AAAA,UACX,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB;AACrB,WAAO;AAAA,MACL,OAAO,CAAC,EAAE,OAAO,MAAM;AACrB,cAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,cAAM,EAAE,UAAU,IAAI,UAAU;AAEhC,YACE,aACA,UAAU,KAAK,SAAS,iBACxB,OAAO,SAAS,aAAa,GAC7B;AACA,gBAAM,SAAS,OAAO,KAAK,QAAQ,UAAU,MAAM,GAAG;AACtD,cAAI,UAAU,kBAAkB,aAAa;AAE3C,kBAAM,aAAa,OAAO;AAC1B,gBAAI,cAAc,sBAAsB,aAAa;AACnD,yBAAW,MAAM;AACjB,qBAAO;AAAA,YACT;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF,CAAC;;;AG/JD,IAAAC,iBAAgC;AAChC,uCAAiC;AAE1B,IAAM,iBAAiB,iCAAAC,QAAqB,OAAO;AAAA,EACxD,aAAa;AACX,WAAO;AAAA,MACL;AAAA,UACA,gCAAgB,KAAK,QAAQ,gBAAgB,EAAE,aAAa,KAAK,KAAK,CAAC;AAAA,MACvE,CAAC,IAAI;AAAA,IACP;AAAA,EACF;AACF,CAAC;;;ACTD,IAAAC,iBAAkD;;;ACFlD,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,sBAAkB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,gBAAgB,cAAc;;;ACtB9B,IAAAC,iBAAiD;AACjD,IAAAA,iBAAwB;AAajB,SAAS,gBAAgB,gBAI9B;AACA,QAAM,EAAE,QAAQ,WAAW,QAAI,iCAAiB;AAChD,QAAM,iBAAa;AAAA,IACjB,MAAM,kBAAkB;AAAA,IACxB,CAAC,gBAAgB,UAAU;AAAA,EAC7B;AAEA,QAAM,kBAAc,+BAAe;AAAA,IACjC,QAAQ;AAAA,IACR,SAAS,SAAS;AAChB,UAAI,CAAC,QAAQ,QAAQ;AACnB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,YAAY;AAAA,QACd;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,QAAQ;AAAA,QAChB,aAAa,QAAQ,OAAO;AAAA,QAC5B,YAAY,QAAQ,OAAO;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,eAAe,EAAE,QAAQ,KAAK;AACvC;;;AC9CA,IAAAC,iBAAwC;;;ACAxC,IAAAC,iBAA2B;AA0BrB,IAAAC,uBAAA;AAdC,IAAM,YAAQ;AAAA,EACnB,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,gBAAgB,aAAa,EAAE;AAAA,QAC1C,cAAY;AAAA,QACZ,aAAW;AAAA,QACX,mBAAiB;AAAA,QACjB,kBAAgB,WAAW,OAAO;AAAA,QACjC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,MAAM,cAAc;;;ADCX,IAAAC,uBAAA;AAPF,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA,eAAe,sBAAsB,KAAK;AAC5C,GAGG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AAOO,IAAM,oBAAgB;AAAA,EAC3B,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM;AAAA,MACJ;AAAA,MACA,WAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,WAAW;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,qBAAa;AAAA,MACf;AAAA,MACA,CAAC,cAAc,OAAO;AAAA,IACxB;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,UAAU,CAACD;AAAA,QACX,iBAAe,CAACA;AAAA,QAChB,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,SACE,GAAG,KAAK,GACN,eACI,KAAK,OAAO,kBAAkB,EAAE,aAAa,CAAC,CAAC,EAC5C,QAAQ,QAAQ,MAAM,EACtB,QAAQ,MAAM,KAAK,CACtB,MACA,EACN;AAAA,QAEF,SAAS;AAAA,QACR,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA,wDAAC,QAAK,WAAU,sBAAqB;AAAA,UACpC,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBACC,8CAAC,wBAAqB,OAAc,cAA4B;AAAA,WAEpE;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,cAAc,cAAc;;;AErI5B,IAAAE,iBAAiD;AAEjD,IAAAC,gBAA6C;;;ACJ7C,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,qBAAiB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,eAAe,cAAc;;;AC3B7B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,qBAAiB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,eAAe,cAAc;;;AC3B7B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,uBAAmB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,iBAAiB,cAAc;;;ACnC/B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,sBAAkB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,gBAAgB,cAAc;;;AC3B9B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,sBAAkB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,gBAAgB,cAAc;;;AC3B9B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,qBAAiB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,eAAe,cAAc;;;ANsBtB,IAAM,eAAe;AAAA,EAC1B,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEO,IAAM,wBAA+C;AAAA,EAC1D,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAKO,SAAS,UACd,QACA,OACA,WAAoB,MACX;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MACE,CAAC,eAAe,WAAW,MAAM,KACjC,mBAAmB,QAAQ,CAAC,OAAO,CAAC;AAEpC,WAAO;AAET,MAAI,CAAC,UAAU;AACb,WAAO,QACH,OAAO,IAAI,EAAE,QAAQ,WAAW,EAAE,MAAM,CAAC,IACzC,OAAO,IAAI,EAAE,QAAQ,SAAS;AAAA,EACpC;AAGA,MACE,CAAC,gCAAgC,QAAQ;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,WAAO;AAIT,SAAO,QACH,OAAO,IAAI,EAAE,QAAQ,WAAW,EAAE,MAAM,CAAC,KAAK,OAAO,IAAI,EAAE,WAAW,IACtE,OAAO,IAAI,EAAE,QAAQ,SAAS,KAAK,OAAO,IAAI,EAAE,WAAW;AACjE;AAKO,SAAS,gBACd,QACA,OACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,KAAK,CAAC,MAAM,OAAO,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;AAAA,EACnE;AAEA,SAAO,QACH,OAAO,SAAS,WAAW,EAAE,MAAM,CAAC,IACpC,OAAO,SAAS,SAAS;AAC/B;AAKO,SAAS,cACd,QACA,OACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,QAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AACpD,QAAM,cAAc,OAAO,KAAK,CAAC,MAAM,UAAU,QAAQ,CAAC,CAAC;AAE3D,MAAI,CAAC,YAAa,QAAO;AAEzB,MAAI;AACF,UAAM,OAAO,OAAO;AACpB,QAAI,QAAQ,KAAK;AACjB,QAAI,KAAK,MAAM;AAGf,QAAI,MAAM,UAAU,SAAS,MAAM,qBAAqB,6BAAe;AACrE,YAAM,MAAM,iBAAiB;AAAA,QAC3B;AAAA,QACA,MAAM,MAAM,UAAU,QAAQ,KAAK,CAAC;AAAA,MACtC,CAAC,GAAG;AACJ,UAAI,CAAC,gBAAgB,GAAG,EAAG,QAAO;AAElC,WAAK,GAAG,aAAa,4BAAc,OAAO,MAAM,KAAK,GAAG,CAAC;AACzD,WAAK,SAAS,EAAE;AAChB,cAAQ,KAAK;AAAA,IACf;AAEA,UAAM,YAAY,MAAM;AACxB,QAAI,QAAQ,OAAO,MAAM,EAAE,MAAM;AAGjC,QAAI,qBAAqB,6BAAe;AACtC,YAAM,aAAa,UAAU,KAAK,YAAY;AAC9C,YAAM,YAAY,UAAU,KAAK,WAAW;AAE5C,YAAM,OAAO,aACT,UAAU,OAAO,WAAW,WAC5B,UAAU,OAAO;AAErB,YAAM,KAAK,YACP,UAAU,KAAK,UAAU,WACzB,UAAU,KAAK;AAEnB,YAAM,eAAe,MAAM,IAAI,QAAQ,IAAI;AAC3C,YAAM,aAAa,MAAM,IAAI,QAAQ,EAAE;AAEvC,cAAQ,MACL,iBAAiB,4BAAc,QAAQ,cAAc,UAAU,CAAC,EAChE,WAAW;AAAA,IAChB;AAEA,UAAM,WAAW,OAAO;AAAA,MAAK,CAAC,MAC5B,OAAO,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC;AAAA,IACzC;AAEA,UAAM,SAAS,WACX,MAAM,QAAQ,WAAW,IACzB,MAAM,QAAQ,WAAW,EAAE,OAAO,YAAY,CAAC;AAEnD,WAAO,IAAI;AAEX,WAAO,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI;AAEhD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,iBAAiB,OAIrB;AACV,QAAM,EAAE,QAAQ,OAAO,oBAAoB,IAAI;AAE/C,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,eAAe,WAAW,MAAM,EAAG,QAAO;AAE/C,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,MAAM,KAAK,CAAC,MAAM,UAAU,QAAQ,CAAC,CAAC;AAAA,IAC/C;AACA,WAAO,UAAU,QAAQ,KAAK;AAAA,EAChC;AAEA,SAAO;AACT;AAgDO,SAAS,WAAW,QAA0B;AACnD,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI;AAEJ,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAM,iBAAiB,UAAU,QAAQ,KAAK;AAC9C,QAAM,WAAW,gBAAgB,QAAQ,KAAK;AAE9C,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC,mBAAa,iBAAiB,EAAE,QAAQ,OAAO,oBAAoB,CAAC,CAAC;AAAA,IACvE;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,OAAO,mBAAmB,CAAC;AAEvC,QAAM,mBAAe,4BAAY,MAAM;AACrC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,cAAc,QAAQ,KAAK;AAC3C,QAAI,SAAS;AACX,kBAAY;AAAA,IACd;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,OAAO,SAAS,CAAC;AAE7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,OAAO,WAAW,KAAK;AAAA,IACvB,cAAc,sBAAsB,KAAK;AAAA,IACzC,MAAM,aAAa,KAAK;AAAA,EAC1B;AACF;;;AO9TA,IAAAC,iBAA2B;AAC3B,IAAAC,yBAAuC;AAO9B,IAAAC,uBAAA;AAHT,SAASC,cAAa;AAAA,EACpB,GAAG;AACL,GAA4D;AAC1D,SAAO,8CAAuB,6BAAtB,EAA2B,OAAO,OAAQ,GAAG,OAAO;AAC9D;AAEA,SAAS,mBAAmB;AAAA,EAC1B,GAAG;AACL,GAA8D;AAC5D,SAAO,8CAAuB,+BAAtB,EAA8B,GAAG,OAAO;AAClD;AAEA,IAAMC,2BAAsB,2BAG1B,CAAC,EAAE,GAAG,MAAM,GAAG,QAAQ,8CAAuB,gCAAtB,EAA8B,KAAW,GAAG,OAAO,CAAE;AAC/EA,qBAAoB,cAAoC,+BAAQ;AAQhE,IAAMC,oBAAyC;AAI/C,IAAM,6BAAyB,2BAK7B,CAAC,EAAE,WAAW,SAAS,MAAM,GAAG,MAAM,GAAG,QAAQ;AACjD,QAAM,UACJ;AAAA,IAAuB;AAAA,IAAtB;AAAA,MACC;AAAA,MACA,WAAWC,IAAG,wBAAwB,SAAS;AAAA,MAC9C,GAAG;AAAA;AAAA,EACN;AAGF,SAAO,SACL,8CAAC,sBAAoB,GAAI,OAAO,WAAW,WAAW,SAAS,CAAC,GAC7D,mBACH,IAEA;AAEJ,CAAC;AACD,uBAAuB,cACC,kCAAW;AAEnC,IAAMC,2BAAsB,2BAK1B,CAAC,EAAE,WAAW,aAAa,GAAG,SAAS,OAAO,GAAG,MAAM,GAAG,QAAQ;AAClE,QAAM,UACJ;AAAA,IAAuB;AAAA,IAAtB;AAAA,MACC;AAAA,MACA;AAAA,MACA,kBAAkB,CAAC,MAAM,EAAE,eAAe;AAAA,MAC1C,WAAWD,IAAG,wBAAwB,SAAS;AAAA,MAC9C,GAAG;AAAA;AAAA,EACN;AAGF,SAAO,SACL,8CAAC,sBAAoB,GAAI,OAAO,WAAW,WAAW,SAAS,CAAC,GAC7D,mBACH,IAEA;AAEJ,CAAC;AACDC,qBAAoB,cAAoC,+BAAQ;;;AClFhE,IAAAC,iBAA2B;AAMhB,IAAAC,uBAAA;AAFX,IAAM,WAAO;AAAA,EACX,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,WAAO,8CAAC,SAAI,KAAU,WAAWC,IAAG,eAAe,SAAS,GAAI,GAAG,OAAO;AAAA,EAC5E;AACF;AACA,KAAK,cAAc;AAEnB,IAAM,iBAAa;AAAA,EACjB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAWA,IAAG,sBAAsB,SAAS;AAAA,QAC5C,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;AAEzB,IAAM,eAAW;AAAA,EACf,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,WACE,8CAAC,SAAI,KAAU,WAAWA,IAAG,oBAAoB,SAAS,GAAI,GAAG,OAAO;AAAA,EAE5E;AACF;AACA,SAAS,cAAc;AAEvB,IAAM,oBAAgB,2BAKpB,CAAC,EAAE,WAAW,cAAc,YAAY,GAAG,MAAM,GAAG,QAAQ;AAC5D,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,oBAAkB;AAAA,MAClB,WAAWA,IAAG,0BAA0B,SAAS;AAAA,MAChD,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AACD,cAAc,cAAc;AAE5B,IAAM,qBAAiB;AAAA,EACrB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAWA,IAAG,2BAA2B,SAAS;AAAA,QACjD,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;AAE7B,IAAM,iBAAa;AAAA,EACjB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAWA,IAAG,sBAAsB,SAAS;AAAA,QAC5C,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;;;AbQf,IAAAC,uBAAA;AAvCH,IAAM,0BAAsB;AAAA,EAIjC,CACE;AAAA,IACE,QAAQ;AAAA,IACR,SAAS,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,IAC1B,sBAAsB;AAAA,IACtB,SAAS;AAAA,IACT;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM,CAAC,QAAQ,SAAS,QAAI,yBAAkB,KAAK;AACnD,UAAM,EAAE,WAAW,UAAU,WAAAC,YAAW,KAAK,IAAI,uBAAuB;AAAA,MACtE;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,uBAAmB;AAAA,MACvB,CAAC,SAAkB;AACjB,YAAI,CAAC,UAAU,CAACA,WAAW;AAC3B,kBAAU,IAAI;AACd,uBAAe,IAAI;AAAA,MACrB;AAAA,MACA,CAACA,YAAW,QAAQ,YAAY;AAAA,IAClC;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE,+CAACC,eAAA,EAAa,OAAK,MAAC,MAAM,QAAQ,cAAc,kBAC9C;AAAA,oDAACC,sBAAA,EAAoB,SAAO,MAC1B;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,cAAW;AAAA,UACX,qBAAmB,WAAW,OAAO;AAAA,UACrC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,UAAU,CAACH;AAAA,UACX,iBAAe,CAACA;AAAA,UAChB,cAAW;AAAA,UACX,gBAAc;AAAA,UACd,SAAQ;AAAA,UACP,GAAG;AAAA,UACJ;AAAA,UAEA;AAAA,0DAAC,QAAK,WAAU,sBAAqB;AAAA,YACrC,8CAAC,mBAAgB,WAAU,gCAA+B;AAAA;AAAA;AAAA,MAC5D,GACF;AAAA,MAEA,8CAACI,sBAAA,EAAoB,OAAM,SAAQ,QACjC,wDAAC,QACC,wDAAC,YACC,wDAAC,eACE,iBAAO,IAAI,CAAC,UACX,8CAACC,mBAAA,EAA0C,SAAO,MAChD;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,MAAM,WAAW,KAAK;AAAA,UACtB,aAAa;AAAA;AAAA,MACf,KANqB,WAAW,KAAK,EAOvC,CACD,GACH,GACF,GACF,GACF;AAAA,OACF;AAAA,EAEJ;AACF;AAEA,oBAAoB,cAAc;;;Ac5HlC,IAAAC,iBAAoC;;;ACFpC,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,kBAAc,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACrE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,YAAY,cAAc;;;ADoBnB,SAAS,sBACd,QACA,SAAkB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,GAChB;AACnB,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,OAAO,KAAK,CAAC,UAAU,gBAAgB,QAAQ,KAAK,CAAC;AAC9D;AAyCO,SAAS,uBAAuB,QAAuC;AAC5E,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,IAC1B,sBAAsB;AAAA,EACxB,IAAI,UAAU,CAAC;AAEf,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAS,IAAI;AAE/C,QAAM,cAAc,sBAAsB,QAAQ,MAAM;AACxD,QAAM,WAAW,gBAAgB,MAAM;AACvC,QAAM,iBAAiB,UAAU,MAAM;AAEvC,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC;AAAA,QACE,iBAAiB,EAAE,QAAQ,qBAAqB,OAAO,OAAO,CAAC;AAAA,MACjE;AAAA,IACF;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,qBAAqB,MAAM,CAAC;AAExC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,OAAO;AAAA,IACP,MAAM,cAAc,aAAa,WAAW,IAAI;AAAA,EAClD;AACF;;;AEjIE,IAAAC,iBAAwC;AA8C/B,IAAAC,uBAAA;AALF,SAAS,mBAAmB;AAAA,EACjC,eAAe;AACjB,GAEG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AAOO,IAAM,wBAAoB;AAAA,EAI/B,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,eAAe;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,kBAAc;AAAA,MAClB,OAAO,UAA+C;AACpD,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,cAAM,YAAY;AAAA,MACpB;AAAA,MACA,CAAC,aAAa,OAAO;AAAA,IACvB;AAGA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,cAAc;AAEjC,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,UAAU,CAAC;AAAA,QACX,iBAAe,CAAC;AAAA,QAChB,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,SACE,GAAG,KAAK,GACN,eACI,KAAK,OAAO,kBAAkB,EAAE,aAAa,CAAC,CAAC,EAC5C,QAAQ,QAAQ,MAAM,EACtB,QAAQ,MAAM,KAAK,CACtB,MACA,EACN;AAAA,QAEF,SAAS;AAAA,QACR,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA,wDAAC,cAAW,WAAU,sBAAqB;AAAA,UAC1C,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBAAgB,8CAAC,sBAAmB,cAA4B;AAAA,WACnE;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,kBAAkB,cAAc;;;AC5IlC,IAAAC,iBAAiD;AACjD,gCAA2B;;;ACD3B,IAAAC,iBAAoC;AAU7B,SAAS,gBACd,OAAuB,OACvB,aAAa,KACb;AACA,QAAM,CAAC,SAAS,UAAU,QAAI,yBAA8B,MAAS;AAErE,gCAAU,MAAM;AACd,UAAM,QACJ,SAAS,QACL,eAAe,UAAU,QACzB,eAAe,aAAa,CAAC;AAEnC,UAAM,MAAM,OAAO,WAAW,KAAK;AACnC,UAAM,WAAW,CAAC,MAA2B,WAAW,EAAE,OAAO;AAGjE,eAAW,IAAI,OAAO;AAGtB,QAAI,iBAAiB,UAAU,QAAQ;AACvC,WAAO,MAAM,IAAI,oBAAoB,UAAU,QAAQ;AAAA,EACzD,GAAG,CAAC,MAAM,UAAU,CAAC;AAErB,SAAO,CAAC,CAAC;AACX;;;ACpCA,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,oBAAgB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACvE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,cAAc,cAAc;;;AFTrB,IAAM,4BAA4B;AAwBlC,SAAS,eAAe,QAAgC;AAC7D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,qBAAqB,QAAQ,aAAa,EAAG,QAAO;AAEzD,SAAO,OAAO,IAAI,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3D;AAKO,SAAS,cAAc,QAAgC;AAC5D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,OAAO,SAAS,aAAa;AACtC;AAKA,eAAsB,YAAY,QAAyC;AACzE,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,eAAe,MAAM,EAAG,QAAO;AAEpC,MAAI;AAEF,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,OAAO;AACb,UAAM,SAAS;AAEf,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,WAAW,YAAY;AAC3B,cAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,YAAI,CAAC,KAAM,QAAO,QAAQ,KAAK;AAG/B,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,MAAM;AACpB,gBAAM,SAAS,OAAO;AAGtB,gBAAM,SAAS,KAAK,MAAM,aAAa,QAAQ,eAAe,KAAK,IAAI;AACvE,iBAAO,KAAK,MAAM;AAClB,uBAAa,QAAQ,iBAAiB,KAAK,UAAU,MAAM,CAAC;AAG5D,iBACG,MAAM,EACN,MAAM,EACN,cAAc;AAAA,YACb,MAAM;AAAA,YACN,OAAO,EAAE,KAAK,OAAO;AAAA,UACvB,CAAC,EACA,IAAI;AAEP,kBAAQ,IAAI;AAAA,QACd;AACA,eAAO,UAAU,MAAM,QAAQ,KAAK;AACpC,eAAO,cAAc,IAAI;AAAA,MAC3B;AACA,YAAM,MAAM;AAAA,IACd,CAAC;AAAA,EACH,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAASC,kBAAiB,OAGrB;AACV,QAAM,EAAE,QAAQ,oBAAoB,IAAI;AAExC,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,qBAAqB,QAAQ,aAAa,EAAG,QAAO;AAEzD,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,eAAe,MAAM;AAAA,EAC9B;AAEA,SAAO;AACT;AAsCO,SAAS,eAAe,QAA+B;AAC5D,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI,UAAU,CAAC;AAEf,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,WAAW,gBAAgB;AACjC,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAM,YAAY,eAAe,MAAM;AACvC,QAAM,WAAW,cAAc,MAAM;AAErC,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC,mBAAaA,kBAAiB,EAAE,QAAQ,oBAAoB,CAAC,CAAC;AAAA,IAChE;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,mBAAmB,CAAC;AAEhC,QAAM,kBAAc,4BAAY,YAAY;AAC1C,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,YAAY,MAAM;AAClC,QAAI,MAAM,SAAS;AACjB,mBAAa;AAAA,IACf;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,UAAU,CAAC;AAEvB;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AACT,YAAM,eAAe;AACrB,kBAAY;AAAA,IACd;AAAA,IACA;AAAA,MACE,SAAS,aAAa;AAAA,MACtB,yBAAyB,CAAC;AAAA,MAC1B,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,cAAc;AAAA,IACd,MAAM;AAAA,EACR;AACF;;;AG5NA,IAAAC,iBAAsC;;;ACAtC,IAAAC,iBAAwC;AAsC/B,IAAAC,uBAAA;AAPF,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,eAAe,mBAAmB,IAAI;AACxC,GAGG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AAOO,IAAM,iBAAa;AAAA,EACxB,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM;AAAA,MACJ;AAAA,MACA,WAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,qBAAa;AAAA,MACf;AAAA,MACA,CAAC,cAAc,OAAO;AAAA,IACxB;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,UAAU,CAACD;AAAA,QACX,iBAAe,CAACA;AAAA,QAChB,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,SACE,GAAG,KAAK,GACN,eACI,KAAK,OAAO,kBAAkB,EAAE,aAAa,CAAC,CAAC,EAC5C,QAAQ,QAAQ,MAAM,EACtB,QAAQ,MAAM,KAAK,CACtB,MACA,EACN;AAAA,QAEF,SAAS;AAAA,QACR,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA,wDAAC,QAAK,WAAU,sBAAqB;AAAA,UACpC,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBACC,8CAAC,qBAAkB,MAAY,cAA4B;AAAA,WAE/D;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;;;ACjIzB,IAAAE,iBAAiD;AAEjD,IAAAC,gBAA6C;;;ACJ7C,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,eAAW,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AAClE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,SAAS,cAAc;;;ACvDvB,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,sBAAkB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,gBAAgB,cAAc;;;ACvD9B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,mBAAe,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACtE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,aAAa,cAAc;;;AHDpB,IAAM,YAAY;AAAA,EACvB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AACZ;AAEO,IAAM,aAAuC;AAAA,EAClD,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AACZ;AAEO,IAAM,qBAA+C;AAAA,EAC1D,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AACZ;AAKO,SAAS,cACd,QACA,MACA,WAAoB,MACX;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,eAAe,MAAM,MAAM,KAAK,mBAAmB,QAAQ,CAAC,OAAO,CAAC;AACvE,WAAO;AAET,MAAI,CAAC,UAAU;AACb,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,OAAO,IAAI,EAAE,iBAAiB;AAAA,MACvC,KAAK;AACH,eAAO,OAAO,IAAI,EAAE,kBAAkB;AAAA,MACxC,KAAK;AACH,eAAO,OAAO,IAAI,EAAE,WAAW,YAAY,UAAU;AAAA,MACvD;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAGA,MACE,CAAC,gCAAgC,QAAQ;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,WAAO;AAIT,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,OAAO,IAAI,EAAE,iBAAiB,KAAK,OAAO,IAAI,EAAE,WAAW;AAAA,IACpE,KAAK;AACH,aAAO,OAAO,IAAI,EAAE,kBAAkB,KAAK,OAAO,IAAI,EAAE,WAAW;AAAA,IACrE,KAAK;AACH,aACE,OAAO,IAAI,EAAE,WAAW,YAAY,UAAU,KAC9C,OAAO,IAAI,EAAE,WAAW;AAAA,IAE5B;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,aAAa,QAAuB,MAAyB;AAC3E,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,OAAO,SAAS,YAAY;AAAA,IACrC,KAAK;AACH,aAAO,OAAO,SAAS,aAAa;AAAA,IACtC,KAAK;AACH,aAAO,OAAO,SAAS,UAAU;AAAA,IACnC;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,WAAW,QAAuB,MAAyB;AACzE,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,cAAc,QAAQ,IAAI,EAAG,QAAO;AAEzC,MAAI;AACF,UAAM,OAAO,OAAO;AACpB,QAAI,QAAQ,KAAK;AACjB,QAAI,KAAK,MAAM;AAGf,QAAI,MAAM,UAAU,SAAS,MAAM,qBAAqB,6BAAe;AACrE,YAAM,MAAM,iBAAiB;AAAA,QAC3B;AAAA,QACA,MAAM,MAAM,UAAU,QAAQ,KAAK,CAAC;AAAA,MACtC,CAAC,GAAG;AACJ,UAAI,CAAC,gBAAgB,GAAG,EAAG,QAAO;AAElC,WAAK,GAAG,aAAa,4BAAc,OAAO,MAAM,KAAK,GAAG,CAAC;AACzD,WAAK,SAAS,EAAE;AAChB,cAAQ,KAAK;AAAA,IACf;AAEA,UAAM,YAAY,MAAM;AAExB,QAAI,QAAQ,OAAO,MAAM,EAAE,MAAM;AAGjC,QAAI,qBAAqB,6BAAe;AACtC,YAAM,aAAa,UAAU,KAAK,YAAY;AAC9C,YAAM,YAAY,UAAU,KAAK,WAAW;AAE5C,YAAM,OAAO,aACT,UAAU,OAAO,WAAW,WAC5B,UAAU,OAAO;AAErB,YAAM,KAAK,YACP,UAAU,KAAK,UAAU,WACzB,UAAU,KAAK;AAEnB,YAAM,eAAe,MAAM,IAAI,QAAQ,IAAI;AAC3C,YAAM,aAAa,MAAM,IAAI,QAAQ,EAAE;AAEvC,cAAQ,MACL,iBAAiB,4BAAc,QAAQ,cAAc,UAAU,CAAC,EAChE,WAAW;AAAA,IAChB;AAEA,QAAI,OAAO,SAAS,IAAI,GAAG;AAEzB,YACG,aAAa,UAAU,EACvB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,IAAI;AAAA,IACT,OAAO;AAEL,YAAM,YAAkD;AAAA,QACtD,YAAY,MAAM,MAAM,iBAAiB;AAAA,QACzC,aAAa,MAAM,MAAM,kBAAkB;AAAA,QAC3C,UAAU,MAAM,MAAM,WAAW,YAAY,UAAU;AAAA,MACzD;AAEA,YAAM,SAAS,UAAU,IAAI;AAC7B,UAAI,CAAC,OAAQ,QAAO;AAEpB,aAAO,EAAE,IAAI;AAAA,IACf;AAEA,WAAO,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI;AAEhD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAASC,kBAAiB,OAIrB;AACV,QAAM,EAAE,QAAQ,MAAM,oBAAoB,IAAI;AAE9C,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,eAAe,MAAM,MAAM,EAAG,QAAO;AAE1C,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,cAAc,QAAQ,IAAI;AAAA,EACnC;AAEA,SAAO;AACT;AAuCO,SAAS,QAAQ,QAAuB;AAC7C,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI;AAEJ,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAMC,aAAY,cAAc,QAAQ,IAAI;AAC5C,QAAM,WAAW,aAAa,QAAQ,IAAI;AAE1C,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC,mBAAaD,kBAAiB,EAAE,QAAQ,MAAM,oBAAoB,CAAC,CAAC;AAAA,IACtE;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,mBAAmB,CAAC;AAEtC,QAAM,mBAAe,4BAAY,MAAM;AACrC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,WAAW,QAAQ,IAAI;AACvC,QAAI,SAAS;AACX,kBAAY;AAAA,IACd;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,MAAM,SAAS,CAAC;AAE5B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAAC;AAAA,IACA,OAAO,WAAW,IAAI;AAAA,IACtB,cAAc,mBAAmB,IAAI;AAAA,IACrC,MAAM,UAAU,IAAI;AAAA,EACtB;AACF;;;AInUA,IAAAC,iBAA6C;AAgDtC,IAAM,cAA4B;AAAA,EACvC;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACF;AAEO,SAAS,iBACd,QACA,WACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,UAAU,KAAK,CAAC,SAAS,cAAc,QAAQ,IAAI,CAAC;AAC7D;AAEO,SAAS,gBACd,QACA,WACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,UAAU,KAAK,CAAC,SAAS,aAAa,QAAQ,IAAI,CAAC;AAC5D;AAEO,SAAS,uBACd,gBACoB;AACpB,SAAO,YAAY;AAAA,IACjB,CAAC,WAAW,CAAC,OAAO,QAAQ,eAAe,SAAS,OAAO,IAAI;AAAA,EACjE;AACF;AAEO,SAAS,uBAAuB,QAM3B;AACV,QAAM,EAAE,QAAQ,qBAAqB,cAAc,aAAa,IAAI;AAEpE,MAAI,CAAC,gBAAgB,CAAC,QAAQ;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKO,SAAS,kBACd,QACA,gBACsB;AACtB,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,eAAe,KAAK,CAAC,SAAS,aAAa,QAAQ,IAAI,CAAC;AACjE;AAyCO,SAAS,oBAAoB,QAAoC;AACtE,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,QAAQ,CAAC,cAAc,eAAe,UAAU;AAAA,IAChD,sBAAsB;AAAA,EACxB,IAAI,UAAU,CAAC;AAEf,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAS,IAAI;AAE/C,QAAM,eAAe,MAAM,KAAK,CAAC,SAAS,eAAe,MAAM,MAAM,CAAC;AAEtE,QAAM,oBAAgB,wBAAQ,MAAM,uBAAuB,KAAK,GAAG,CAAC,KAAK,CAAC;AAE1E,QAAM,eAAe,iBAAiB,QAAQ,KAAK;AACnD,QAAM,cAAc,gBAAgB,QAAQ,KAAK;AACjD,QAAM,aAAa,kBAAkB,QAAQ,KAAK;AAClD,QAAM,aAAa,cAAc,KAAK,CAAC,WAAW,OAAO,SAAS,UAAU;AAE5E,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC;AAAA,QACE,uBAAuB;AAAA,UACrB;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,cAAc,QAAQ,qBAAqB,cAAc,KAAK,CAAC;AAEnE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,MAAM,aAAa,UAAU,WAAW,IAAI,IAAI;AAAA,EAClD;AACF;;;ANlIQ,IAAAC,uBAAA;AAjCD,SAAS,iBAAiB;AAAA,EAC/B,QAAQ;AAAA,EACR,QAAQ,CAAC,cAAc,eAAe,UAAU;AAAA,EAChD,sBAAsB;AAAA,EACtB;AAAA,EACA,SAAS;AAAA,EACT,GAAG;AACL,GAA0B;AACxB,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,QAAQ,SAAS,QAAI,yBAAS,KAAK;AAE1C,QAAM,EAAE,eAAe,WAAAC,YAAW,UAAU,WAAW,KAAK,IAC1D,oBAAoB;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAEH,QAAM,yBAAqB;AAAA,IACzB,CAAC,SAAkB;AACjB,gBAAU,IAAI;AACd,qBAAe,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SACE,+CAACC,eAAA,EAAa,MAAM,QAAQ,cAAc,oBACxC;AAAA,kDAACC,sBAAA,EAAoB,SAAO,MAC1B;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,UAAU,CAACH;AAAA,QACX,iBAAe,CAACA;AAAA,QAChB,cAAW;AAAA,QACX,SAAQ;AAAA,QACP,GAAG;AAAA,QAEJ;AAAA,wDAAC,QAAK,WAAU,sBAAqB;AAAA,UACrC,8CAAC,mBAAgB,WAAU,gCAA+B;AAAA;AAAA;AAAA,IAC5D,GACF;AAAA,IAEA,8CAACI,sBAAA,EAAoB,OAAM,SAAQ,QACjC,wDAAC,QACC,wDAAC,YACC,wDAAC,eACE,wBAAc,IAAI,CAAC,WAClB,8CAACC,mBAAA,EAAmC,SAAO,MACzC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,aAAa;AAAA;AAAA,IACf,KANqB,OAAO,IAO9B,CACD,GACH,GACF,GACF,GACF;AAAA,KACF;AAEJ;;;AOxHA,IAAAC,iBAAwC;AAuC/B,IAAAC,uBAAA;AALF,SAAS,wBAAwB;AAAA,EACtC,eAAe;AACjB,GAEG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AAOO,IAAM,uBAAmB;AAAA,EAI9B,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM;AAAA,MACJ;AAAA,MACA,WAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,cAAc;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,qBAAa;AAAA,MACf;AAAA,MACA,CAAC,cAAc,OAAO;AAAA,IACxB;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,UAAU,CAACD;AAAA,QACX,iBAAe,CAACA;AAAA,QAChB,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,SAAS,GAAG,KAAK,GACf,eACI,KAAK,OAAO,kBAAkB,EAAE,aAAa,CAAC,CAAC,EAC5C,QAAQ,QAAQ,MAAM,EACtB,QAAQ,MAAM,KAAK,CAAC,MACvB,EACN;AAAA,QACA,SAAS;AAAA,QACR,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA,wDAAC,QAAK,WAAU,sBAAqB;AAAA,UACpC,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBACC,8CAAC,2BAAwB,cAA4B;AAAA,WAEzD;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,iBAAiB,cAAc;;;AChI/B,IAAAE,iBAAiD;AAEjD,IAAAC,gBAA6C;;;ACJ7C,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,qBAAiB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,eAAe,cAAc;;;ADtBtB,IAAM,0BAA0B;AAwBhC,SAAS,oBACd,QACA,WAAoB,MACX;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MACE,CAAC,eAAe,cAAc,MAAM,KACpC,mBAAmB,QAAQ,CAAC,OAAO,CAAC;AAEpC,WAAO;AAET,MAAI,CAAC,UAAU;AACb,WAAO,OAAO,IAAI,EAAE,WAAW,YAAY;AAAA,EAC7C;AAGA,MACE,CAAC,gCAAgC,QAAQ;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,WAAO;AAIT,SAAO,OAAO,IAAI,EAAE,WAAW,YAAY,KAAK,OAAO,IAAI,EAAE,WAAW;AAC1E;AAKO,SAAS,iBAAiB,QAAgC;AAC/D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,oBAAoB,MAAM,EAAG,QAAO;AAEzC,MAAI;AACF,UAAM,OAAO,OAAO;AACpB,QAAI,QAAQ,KAAK;AACjB,QAAI,KAAK,MAAM;AAGf,QAAI,MAAM,UAAU,SAAS,MAAM,qBAAqB,6BAAe;AACrE,YAAM,MAAM,iBAAiB;AAAA,QAC3B;AAAA,QACA,MAAM,MAAM,UAAU,QAAQ,KAAK,CAAC;AAAA,MACtC,CAAC,GAAG;AACJ,UAAI,CAAC,gBAAgB,GAAG,EAAG,QAAO;AAElC,WAAK,GAAG,aAAa,4BAAc,OAAO,MAAM,KAAK,GAAG,CAAC;AACzD,WAAK,SAAS,EAAE;AAChB,cAAQ,KAAK;AAAA,IACf;AAEA,UAAM,YAAY,MAAM;AAExB,QAAI,QAAQ,OAAO,MAAM,EAAE,MAAM;AAGjC,QAAI,qBAAqB,6BAAe;AACtC,YAAM,aAAa,UAAU,KAAK,YAAY;AAC9C,YAAM,YAAY,UAAU,KAAK,WAAW;AAE5C,YAAM,OAAO,aACT,UAAU,OAAO,WAAW,WAC5B,UAAU,OAAO;AAErB,YAAM,KAAK,YACP,UAAU,KAAK,UAAU,WACzB,UAAU,KAAK;AAEnB,YAAM,eAAe,MAAM,IAAI,QAAQ,IAAI;AAC3C,YAAM,aAAa,MAAM,IAAI,QAAQ,EAAE;AAEvC,cAAQ,MACL,iBAAiB,4BAAc,QAAQ,cAAc,UAAU,CAAC,EAChE,WAAW;AAAA,IAChB;AAEA,UAAM,SAAS,OAAO,SAAS,YAAY,IACvC,MAAM,KAAK,YAAY,IACvB,MAAM,OAAO,YAAY;AAE7B,WAAO,IAAI;AAEX,WAAO,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI;AAEhD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAASC,kBAAiB,OAGrB;AACV,QAAM,EAAE,QAAQ,oBAAoB,IAAI;AAExC,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,eAAe,cAAc,MAAM,EAAG,QAAO;AAElD,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,oBAAoB,MAAM;AAAA,EACnC;AAEA,SAAO;AACT;AAsCO,SAAS,cAAc,QAA8B;AAC1D,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI,UAAU,CAAC;AAEf,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAMC,aAAY,oBAAoB,MAAM;AAC5C,QAAM,WAAW,QAAQ,SAAS,YAAY,KAAK;AAEnD,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC,mBAAaD,kBAAiB,EAAE,QAAQ,oBAAoB,CAAC,CAAC;AAAA,IAChE;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,mBAAmB,CAAC;AAEhC,QAAM,mBAAe,4BAAY,MAAM;AACrC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,iBAAiB,MAAM;AACvC,QAAI,SAAS;AACX,kBAAY;AAAA,IACd;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAAC;AAAA,IACA,OAAO;AAAA,IACP,cAAc;AAAA,IACd,MAAM;AAAA,EACR;AACF;;;AEnPA,IAAAC,iBAAsD;;;ACFtD,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,cAAU,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACjE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,QAAQ,cAAc;;;ACzBtB,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,sBAAkB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,gBAAgB,cAAc;;;ACvB9B,uBAAkC;AAOzB,IAAAC,uBAAA;AAHT,SAAS,QAAQ;AAAA,EACf,GAAG;AACL,GAAuD;AACrD,SAAO,8CAAkB,uBAAjB,EAAuB,GAAG,OAAO;AAC3C;AAEA,SAAS,eAAe;AAAA,EACtB,GAAG;AACL,GAA0D;AACxD,SAAO,8CAAkB,0BAAjB,EAA0B,GAAG,OAAO;AAC9C;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,GAAG;AACL,GAA0D;AACxD,SACE,8CAAkB,yBAAjB,EACC;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAWC,IAAG,kBAAkB,SAAS;AAAA,MACxC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;;;AChCA,IAAAC,iBAAiD;AA0CxC,IAAAC,uBAAA;AALF,SAAS,4BAA4B;AAAA,EAC1C,eAAe;AACjB,GAEG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AA8BO,IAAM,2BAAuB;AAAA,EAIlC,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,IACtB,OAAO;AAAA,IACP;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM;AAAA,MACJ;AAAA,MACA,mBAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,kBAAkB;AAAA,MACpB;AAAA,MACA;AAAA,MACA,OAAO,QAAQ,qBAAqB,cAAc;AAAA,MAClD;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,6BAAqB;AAAA,MACvB;AAAA,MACA,CAAC,sBAAsB,OAAO;AAAA,IAChC;AAEA,UAAM,kBAAc;AAAA,MAClB,OACG;AAAA,QACC,GAAG;AAAA,QACH,qBAAqB;AAAA,MACvB;AAAA,MACF,CAAC,gBAAgB,KAAK;AAAA,IACxB;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,MAAK;AAAA,QACL,UAAU;AAAA,QACV,UAAU,CAACD;AAAA,QACX,iBAAe,CAACA;AAAA,QAChB,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,SAAS;AAAA,QACT,SAAS;AAAA,QACT,OAAO;AAAA,QACN,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OACE,EAAE,qBAAqB,eAAe;AAAA;AAAA,UAE1C;AAAA,UACC,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBACC,8CAAC,+BAA4B,cAA4B;AAAA,WAE7D;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,qBAAqB,cAAc;;;ACxKnC,IAAAE,iBAAiD;AAEjD,IAAAC,6BAA2B;AAgBpB,IAAM,+BAA+B;AACrC,IAAM,mBAAmB;AAAA,EAC9B;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AA+CO,SAAS,2BAA2B,QAAkB;AAC3D,QAAM,WAAW,IAAI;AAAA,IACnB,iBAAiB,IAAI,CAAC,UAAU,CAAC,MAAM,OAAO,KAAK,CAAC;AAAA,EACtD;AACA,SAAO,OACJ,IAAI,CAAC,UAAU,SAAS,IAAI,KAAK,CAAC,EAClC,OAAO,CAAC,UAAsD,CAAC,CAAC,KAAK;AAC1E;AAKO,SAAS,kBACd,QACA,OAAsB,QACb;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,MAAI,SAAS,QAAQ;AACnB,QACE,CAAC,eAAe,aAAa,MAAM,KACnC,mBAAmB,QAAQ,CAAC,OAAO,CAAC;AAEpC,aAAO;AAET,WAAO,OAAO,IAAI,EAAE,QAAQ,WAAW;AAAA,EACzC,OAAO;AACL,QAAI,CAAC,qBAAqB,QAAQ,CAAC,gBAAgB,CAAC,EAAG,QAAO;AAE9D,QAAI;AACF,aAAO,OAAO,IAAI,EAAE,QAAQ,kBAAkB,EAAE,iBAAiB,OAAO,CAAC;AAAA,IAC3E,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,SAAS,uBACd,QACA,gBACA,OAAsB,QACb;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,MAAI,SAAS,QAAQ;AACnB,WAAO,iBACH,OAAO,SAAS,aAAa,EAAE,OAAO,eAAe,CAAC,IACtD,OAAO,SAAS,WAAW;AAAA,EACjC,OAAO;AACL,QAAI,CAAC,eAAgB,QAAO;AAE5B,QAAI;AACF,YAAM,EAAE,MAAM,IAAI;AAClB,YAAM,EAAE,UAAU,IAAI;AAEtB,YAAM,OAAO,UAAU;AACvB,eAAS,QAAQ,KAAK,OAAO,SAAS,GAAG,SAAS;AAChD,cAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,YAAI,QAAQ,KAAK,OAAO,oBAAoB,gBAAgB;AAC1D,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,SAAS,gBACd,QACA,OAAsB,QACb;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,kBAAkB,QAAQ,IAAI,EAAG,QAAO;AAE7C,MAAI,SAAS,QAAQ;AACnB,WAAO,OAAO,MAAM,EAAE,MAAM,EAAE,UAAU,WAAW,EAAE,IAAI;AAAA,EAC3D,OAAO;AACL,WAAO,OAAO,MAAM,EAAE,MAAM,EAAE,qBAAqB,EAAE,IAAI;AAAA,EAC3D;AACF;AAKO,SAASC,kBAAiB,OAIrB;AACV,QAAM,EAAE,QAAQ,qBAAqB,KAAK,IAAI;AAE9C,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,MAAI,SAAS,QAAQ;AACnB,QAAI,CAAC,eAAe,aAAa,MAAM,EAAG,QAAO;AAAA,EACnD,OAAO;AACL,QAAI,CAAC,qBAAqB,QAAQ,CAAC,gBAAgB,CAAC,EAAG,QAAO;AAAA,EAChE;AAEA,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,kBAAkB,QAAQ,IAAI;AAAA,EACvC;AAEA,SAAO;AACT;AAEO,SAAS,kBAAkB,QAAiC;AACjE,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,IACtB,OAAO;AAAA,IACP;AAAA,EACF,IAAI;AAEJ,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,WAAW,gBAAgB;AACjC,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAM,yBAAyB,kBAAkB,QAAQ,IAAI;AAC7D,QAAM,WAAW,uBAAuB,QAAQ,gBAAgB,IAAI;AAEpE,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC,mBAAaA,kBAAiB,EAAE,QAAQ,qBAAqB,KAAK,CAAC,CAAC;AAAA,IACtE;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,qBAAqB,IAAI,CAAC;AAEtC,QAAM,2BAAuB,4BAAY,MAAM;AAC7C,QAAI,CAAC,UAAU,CAAC,0BAA0B,CAAC,kBAAkB,CAAC;AAC5D,aAAO;AAET,QAAI,SAAS,QAAQ;AACnB,UAAI,OAAO,MAAM,aAAa;AAC5B,cAAM,oBAAoB,OAAO,OAAO,MAAM;AAC9C,YAAI,mBAAmB;AACrB,iBAAO,KAAK;AAAA,YACV,OAAO,MAAM,GAAG,iBAAiB,iBAAiB;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAEA,iBAAW,MAAM;AACf,cAAM,UAAU,OACb,MAAM,EACN,MAAM,EACN,WAAW,aAAa,EAAE,OAAO,eAAe,CAAC,EACjD,IAAI;AACP,YAAI,SAAS;AACX,sBAAY,EAAE,OAAO,gBAAgB,OAAO,KAAK,CAAC;AAAA,QACpD;AACA,eAAO;AAAA,MACT,GAAG,CAAC;AAEJ,aAAO;AAAA,IACT,OAAO;AACL,YAAM,UAAU,OACb,MAAM,EACN,MAAM,EACN,QAAQ,kBAAkB,EAAE,iBAAiB,eAAe,CAAC,EAC7D,IAAI;AAEP,UAAI,SAAS;AACX,oBAAY,EAAE,OAAO,gBAAgB,OAAO,KAAK,CAAC;AAAA,MACpD;AACA,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,wBAAwB,gBAAgB,QAAQ,OAAO,WAAW,IAAI,CAAC;AAE3E,QAAM,4BAAwB,4BAAY,MAAM;AAC9C,UAAM,UAAU,gBAAgB,QAAQ,IAAI;AAC5C,QAAI,SAAS;AACX,kBAAY,EAAE,OAAO,IAAI,OAAO,oBAAoB,KAAK,CAAC;AAAA,IAC5D;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,WAAW,IAAI,CAAC;AAE5B;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AACT,YAAM,eAAe;AACrB,2BAAqB;AAAA,IACvB;AAAA,IACA;AAAA,MACE,SAAS,aAAa;AAAA,MACtB,yBAAyB,CAAC;AAAA,MAC1B,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB,OAAO,SAAS;AAAA,IAChB,cAAc;AAAA,IACd,MAAM;AAAA,IACN;AAAA,EACF;AACF;;;ALjQiB,IAAAC,uBAAA;AAhBV,IAAM,kCAA8B,2BAGzC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,GAAG,QACpC;AAAA,EAACC;AAAA,EAAA;AAAA,IACC,MAAK;AAAA,IACL;AAAA,IACA,cAAW;AAAA,IACX,mBAAgB;AAAA,IAChB,MAAK;AAAA,IACL,UAAU;AAAA,IACV,cAAW;AAAA,IACX,SAAQ;AAAA,IACR;AAAA,IACC,GAAG;AAAA,IAEH,sBAAY,8CAAC,mBAAgB,WAAU,sBAAqB;AAAA;AAC/D,CACD;AAED,4BAA4B,cAAc;AAEnC,SAAS,6BAA6B;AAAA,EAC3C;AAAA,EACA,SAAS,2BAA2B;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH,GAAsC;AACpC,QAAM,EAAE,sBAAsB,IAAI,kBAAkB,EAAE,OAAO,CAAC;AAC9D,QAAM,WAAW,gBAAgB;AACjC,QAAM,mBAAe,uBAAuB,IAAI;AAEhD,QAAM,gBAAY;AAAA,IAChB,MAAM,CAAC,GAAG,QAAQ,EAAE,OAAO,oBAAoB,OAAO,OAAO,CAAC;AAAA,IAC9D,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,EAAE,cAAc,IAAI,kBAAkB;AAAA,IAC1C;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,UAAU,CAAC,SAAS;AAClB,UAAI,CAAC,aAAa,QAAS,QAAO;AAClC,YAAM,qBAAqB,aAAa,QAAQ;AAAA,QAC9C;AAAA,MACF;AACA,UAAI,mBAAoB,oBAAmB,MAAM;AACjD,UAAI,KAAK,UAAU,OAAQ,uBAAsB;AACjD,aAAO;AAAA,IACT;AAAA,IACA,qBAAqB;AAAA,EACvB,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,UAAU;AAAA,MACV,OAAO,WAAW,EAAE,WAAW,QAAQ,QAAQ,EAAE,IAAI,CAAC;AAAA,MAEtD,wDAAC,YAAS,OAAO,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,GAC5C,yDAAC,iBAAc,aAAY,cACzB;AAAA,sDAAC,eAAY,aAAY,cACtB,iBAAO,IAAI,CAAC,OAAO,UAClB;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA,gBAAgB,MAAM;AAAA,YACtB,SAAS,MAAM;AAAA,YACf,cAAY,GAAG,MAAM,KAAK;AAAA,YAC1B,UAAU,UAAU,gBAAgB,IAAI;AAAA,YACxC,oBAAkB,kBAAkB;AAAA;AAAA,UAN/B,MAAM;AAAA,QAOb,CACD,GACH;AAAA,QACA,8CAACC,YAAA,EAAU;AAAA,QACX,8CAAC,eAAY,aAAY,cACvB;AAAA,UAACD;AAAA,UAAA;AAAA,YACC,SAAS;AAAA,YACT,cAAW;AAAA,YACX,SAAQ;AAAA,YACR,UAAU,kBAAkB,OAAO,SAAS,IAAI;AAAA,YAChD,MAAK;AAAA,YACL,MAAK;AAAA,YACL,cAAW;AAAA,YACX,oBAAkB,kBAAkB,OAAO;AAAA,YAE3C,wDAAC,WAAQ,WAAU,sBAAqB;AAAA;AAAA,QAC1C,GACF;AAAA,SACF,GACF;AAAA;AAAA,EACF;AAEJ;;;AMhKA,IAAAE,iBAA6D;;;ACF7D,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,yBAAqB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AAC5E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,mBAAmB,cAAc;;;ACzBjC,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,uBAAmB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,iBAAiB,cAAc;;;AC3B/B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,eAAW,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AAClE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,SAAS,cAAc;;;AC3BvB,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,gBAAY,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,UAAU,cAAc;;;AClBpB,IAAAC,uBAAA;AAFJ,SAASC,OAAM,EAAE,WAAW,MAAM,GAAG,MAAM,GAAkC;AAC3E,SACE,8CAAC,WAAM,MAAY,WAAWC,IAAG,gBAAgB,SAAS,GAAI,GAAG,OAAO;AAE5E;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE,8CAAC,SAAI,WAAWA,IAAG,sBAAsB,SAAS,GAAI,GAAG,OACtD,UACH;AAEJ;;;ALwEqB,IAAAC,uBAAA;AAdd,IAAM,iBAAa;AAAA,EACxB,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,GAAG,QAAQ;AAC1C,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,cAAW;AAAA,QACX,MAAK;AAAA,QACL,UAAU;AAAA,QACV,cAAW;AAAA,QACX,SAAQ;AAAA,QACR;AAAA,QACC,GAAG;AAAA,QAEH,sBAAY,8CAAC,YAAS,WAAU,sBAAqB;AAAA;AAAA,IACxD;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;AAKzB,IAAM,WAAoC,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,WAAW,gBAAgB;AAEjC,QAAM,gBAAgB,CAAC,UAAiD;AACtE,QAAI,MAAM,QAAQ,SAAS;AACzB,YAAM,eAAe;AACrB,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAI,WAAW,EAAE,WAAW,QAAQ,QAAQ,EAAE,IAAI,CAAC;AAAA,MACrD;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,GAAI,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC;AAAA,UACnC;AAAA,UAEA,yDAAC,iBAAc,aAAY,cACzB;AAAA,0DAAC,cACC;AAAA,cAACC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,aAAY;AAAA,gBACZ,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,KAAK;AAAA,gBACtC,WAAW;AAAA,gBACX,WAAS;AAAA,gBACT,cAAa;AAAA,gBACb,aAAY;AAAA,gBACZ,gBAAe;AAAA;AAAA,YACjB,GACF;AAAA,YAEA,8CAAC,eAAY,aAAY,cACvB;AAAA,cAACD;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,OAAM;AAAA,gBACN,UAAU,CAAC,OAAO,CAAC;AAAA,gBACnB,cAAW;AAAA,gBAEX,wDAAC,sBAAmB,WAAU,sBAAqB;AAAA;AAAA,YACrD,GACF;AAAA,YAEA,8CAACE,YAAA,EAAU;AAAA,YAEX,+CAAC,eAAY,aAAY,cACvB;AAAA;AAAA,gBAACF;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS;AAAA,kBACT,OAAM;AAAA,kBACN,UAAU,CAAC,OAAO,CAAC;AAAA,kBACnB,cAAW;AAAA,kBAEX,wDAAC,oBAAiB,WAAU,sBAAqB;AAAA;AAAA,cACnD;AAAA,cAEA;AAAA,gBAACA;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS;AAAA,kBACT,OAAM;AAAA,kBACN,UAAU,CAAC,OAAO,CAAC;AAAA,kBACnB,cAAW;AAAA,kBAEX,wDAAC,aAAU,WAAU,sBAAqB;AAAA;AAAA,cAC5C;AAAA,eACF;AAAA,aACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAKO,IAAM,cAER,CAAC,EAAE,OAAO,MAAM;AACnB,QAAM,cAAc,eAAe;AAAA,IACjC;AAAA,EACF,CAAC;AAED,SAAO,8CAAC,YAAU,GAAG,aAAa;AACpC;AAOO,IAAM,kBAAc;AAAA,EACzB,CACE;AAAA,IACE,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,uBAAuB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM,CAAC,QAAQ,SAAS,QAAI,yBAAS,KAAK;AAE1C,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,eAAe;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,yBAAqB;AAAA,MACzB,CAAC,eAAwB;AACvB,kBAAU,UAAU;AACpB,uBAAe,UAAU;AAAA,MAC3B;AAAA,MACA,CAAC,YAAY;AAAA,IACf;AAEA,UAAM,oBAAgB,4BAAY,MAAM;AACtC,cAAQ;AACR,gBAAU,KAAK;AAAA,IACjB,GAAG,CAAC,OAAO,CAAC;AAEZ,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,kBAAU,CAAC,MAAM;AAAA,MACnB;AAAA,MACA,CAAC,SAAS,MAAM;AAAA,IAClB;AAEA,kCAAU,MAAM;AACd,UAAI,wBAAwB,UAAU;AACpC,kBAAU,IAAI;AAAA,MAChB;AAAA,IACF,GAAG,CAAC,sBAAsB,QAAQ,CAAC;AAEnC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE,+CAAC,WAAQ,MAAM,QAAQ,cAAc,oBACnC;AAAA,oDAAC,kBAAe,SAAO,MACrB;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,CAAC;AAAA,UACX,qBAAmB,WAAW,OAAO;AAAA,UACrC,iBAAe,CAAC;AAAA,UAChB,cAAY;AAAA,UACZ,gBAAc;AAAA,UACd,SAAS;AAAA,UACR,GAAG;AAAA,UACJ;AAAA,UAEC,sBAAY,8CAAC,QAAK,WAAU,sBAAqB;AAAA;AAAA,MACpD,GACF;AAAA,MAEA,8CAAC,kBACC;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF,GACF;AAAA,OACF;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;;;AM9S1B,IAAAG,iBAAiD;AAoD1C,SAAS,WAAW,QAAgC;AACzD,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAI1C,MAAI,mBAAmB,QAAQ,CAAC,OAAO,GAAG,IAAI,EAAG,QAAO;AACxD,SAAO,OAAO,IAAI,EAAE,QAAQ,MAAM;AACpC;AAKO,SAAS,aAAa,QAAgC;AAC3D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,OAAO,SAAS,MAAM;AAC/B;AAKO,SAAS,qBAAqB,OAGzB;AACV,QAAM,EAAE,QAAQ,oBAAoB,IAAI;AAExC,QAAM,eAAe,eAAe,QAAQ,MAAM;AAElD,MAAI,CAAC,gBAAgB,CAAC,QAAQ;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,WAAW,MAAM;AAAA,EAC1B;AAEA,SAAO;AACT;AAKO,SAAS,eAAe,OAAyB;AACtD,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,CAAC,KAAK,MAAM,QAAI,yBAAwB,IAAI;AAElD,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAGb,UAAM,EAAE,KAAK,IAAI,OAAO,cAAc,MAAM;AAE5C,QAAI,aAAa,MAAM,KAAK,QAAQ,MAAM;AACxC,aAAO,QAAQ,EAAE;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,GAAG,CAAC;AAEhB,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,kBAAkB,MAAM;AAC5B,YAAM,EAAE,KAAK,IAAI,OAAO,cAAc,MAAM;AAC5C,aAAO,QAAQ,EAAE;AAAA,IACnB;AAEA,WAAO,GAAG,mBAAmB,eAAe;AAC5C,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,eAAe;AAAA,IAC/C;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,cAAU,4BAAY,MAAM;AAChC,QAAI,CAAC,OAAO,CAAC,OAAQ;AAErB,UAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,UAAM,UAAU,UAAU;AAE1B,QAAI,QAAQ,OAAO,MAAM,EAAE,MAAM;AAEjC,YAAQ,MAAM,gBAAgB,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAE3D,QAAI,SAAS;AACX,cAAQ,MAAM,cAAc,EAAE,MAAM,QAAQ,MAAM,IAAI,CAAC;AAAA,IACzD;AAEA,UAAM,IAAI;AAEV,WAAO,IAAI;AAEX,gBAAY;AAAA,EACd,GAAG,CAAC,QAAQ,WAAW,GAAG,CAAC;AAE3B,QAAM,iBAAa,4BAAY,MAAM;AACnC,QAAI,CAAC,OAAQ;AACb,WACG,MAAM,EACN,MAAM,EACN,gBAAgB,MAAM,EACtB,UAAU,EACV,QAAQ,mBAAmB,IAAI,EAC/B,IAAI;AACP,WAAO,EAAE;AAAA,EACX,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAW;AAAA,IACf,CAAC,SAAiB,UAAU,WAAmB,0BAA0B;AACvE,UAAI,CAAC,IAAK;AAEV,YAAM,UAAU,YAAY,KAAK,OAAO,SAAS,IAAI;AACrD,UAAI,YAAY,KAAK;AACnB,eAAO,KAAK,SAAS,QAAQ,QAAQ;AAAA,MACvC;AAAA,IACF;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAEA,SAAO;AAAA,IACL,KAAK,OAAO;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,aAAa,OAG1B;AACD,QAAM,EAAE,QAAQ,sBAAsB,MAAM,IAAI;AAEhD,QAAM,SAAS,WAAW,MAAM;AAChC,QAAM,WAAW,aAAa,MAAM;AAEpC,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAS,IAAI;AAE/C,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC;AAAA,QACE,qBAAqB;AAAA,UACnB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,mBAAmB,CAAC;AAEhC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAuCO,SAAS,eAAe,QAA+B;AAC5D,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI,UAAU,CAAC;AAEf,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AAEjD,QAAM,EAAE,WAAW,QAAQ,SAAS,IAAI,aAAa;AAAA,IACnD;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,cAAc,eAAe;AAAA,IACjC;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;;;AC3RA,IAAAC,iBAAwC;AAsC/B,IAAAC,uBAAA;AAPF,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,eAAe,mBAAmB,IAAI;AACxC,GAGG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AAOO,IAAM,iBAAa;AAAA,EACxB,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,mBAAW;AAAA,MACb;AAAA,MACA,CAAC,YAAY,OAAO;AAAA,IACtB;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU,CAACD;AAAA,QACX,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,iBAAe,CAACA;AAAA,QAChB,MAAK;AAAA,QACL,UAAU;AAAA,QACV,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,SACE,GAAG,KAAK,GACN,eACI,KAAK,OAAO,kBAAkB,EAAE,aAAa,CAAC,CAAC,EAC5C,QAAQ,QAAQ,MAAM,EACtB,QAAQ,MAAM,KAAK,CACtB,MACA,EACN;AAAA,QAEF,SAAS;AAAA,QACR,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA,wDAAC,QAAK,WAAU,sBAAqB;AAAA,UACpC,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBACC,8CAAC,qBAAkB,MAAY,cAA4B;AAAA,WAE/D;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;;;ACjIzB,IAAAE,iBAAiD;;;ACFjD,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,eAAW,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AAClE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,SAAS,cAAc;;;ACzBvB,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,gBAAY,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,UAAU,cAAc;;;AC/BxB,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,iBAAa,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACpE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,WAAW,cAAc;;;ACvBzB,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,iBAAa,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACpE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,WAAW,cAAc;;;AC3BzB,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,oBAAgB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACvE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,cAAc,cAAc;;;ACrC5B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,sBAAkB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,gBAAgB,cAAc;;;ACrC9B,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,oBAAgB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACvE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,cAAc,cAAc;;;AP2BrB,IAAM,YAAY;AAAA,EACvB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AACb;AAEO,IAAM,qBAA2C;AAAA,EACtD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AACb;AAKO,SAAS,cAAc,QAAuB,MAAqB;AACxE,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,eAAe,MAAM,MAAM,KAAK,mBAAmB,QAAQ,CAAC,OAAO,CAAC;AACvE,WAAO;AAET,SAAO,OAAO,IAAI,EAAE,WAAW,IAAI;AACrC;AAKO,SAAS,aAAa,QAAuB,MAAqB;AACvE,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,OAAO,SAAS,IAAI;AAC7B;AAKO,SAAS,WAAW,QAAuB,MAAqB;AACrE,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,cAAc,QAAQ,IAAI,EAAG,QAAO;AAEzC,SAAO,OAAO,MAAM,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE,IAAI;AACrD;AAKO,SAASC,kBAAiB,OAIrB;AACV,QAAM,EAAE,QAAQ,MAAM,oBAAoB,IAAI;AAE9C,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,eAAe,MAAM,MAAM,EAAG,QAAO;AAE1C,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,cAAc,QAAQ,IAAI;AAAA,EACnC;AAEA,SAAO;AACT;AAKO,SAAS,qBAAqB,MAAoB;AACvD,SAAO,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AACpD;AAuCO,SAAS,QAAQ,QAAuB;AAC7C,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI;AAEJ,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAMC,aAAY,cAAc,QAAQ,IAAI;AAC5C,QAAM,WAAW,aAAa,QAAQ,IAAI;AAE1C,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC,mBAAaD,kBAAiB,EAAE,QAAQ,MAAM,oBAAoB,CAAC,CAAC;AAAA,IACtE;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,mBAAmB,CAAC;AAEtC,QAAM,iBAAa,4BAAY,MAAM;AACnC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,WAAW,QAAQ,IAAI;AACvC,QAAI,SAAS;AACX,kBAAY;AAAA,IACd;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,MAAM,SAAS,CAAC;AAE5B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAAC;AAAA,IACA,OAAO,qBAAqB,IAAI;AAAA,IAChC,cAAc,mBAAmB,IAAI;AAAA,IACrC,MAAM,UAAU,IAAI;AAAA,EACtB;AACF;;;AQnNA,IAAAC,iBAAwC;AAmD/B,IAAAC,uBAAA;AAPF,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA,eAAe,yBAAyB,KAAK;AAC/C,GAGG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AAOO,IAAM,sBAAkB;AAAA,EAI7B,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,aAAa;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,wBAAgB;AAAA,MAClB;AAAA,MACA,CAAC,iBAAiB,OAAO;AAAA,IAC3B;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,cAAc;AAEjC,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU,CAAC;AAAA,QACX,cAAW;AAAA,QACX,qBAAmB,WAAW,OAAO;AAAA,QACrC,iBAAe,CAAC;AAAA,QAChB,MAAK;AAAA,QACL,UAAU;AAAA,QACV,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,SACE,GAAG,KAAK,GACN,eACI,KAAK,OAAO,kBAAkB,EAAE,aAAa,CAAC,CAAC,EAC5C,QAAQ,QAAQ,MAAM,EACtB,QAAQ,MAAM,KAAK,CACtB,MACA,EACN;AAAA,QAEF,SAAS;AAAA,QACR,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA,wDAAC,cAAW,WAAU,sBAAqB;AAAA,UAC1C,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBACC;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA;AAAA,UACF;AAAA,WAEJ;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,gBAAgB,cAAc;;;ACvJ9B,IAAAC,iBAAiD;;;ACFjD,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,sBAAkB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,gBAAgB,cAAc;;;ACrC9B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,uBAAmB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,iBAAiB,cAAc;;;ACrC/B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,oBAAgB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACvE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,cAAc,cAAc;;;ACrC5B,IAAAC,iBAAqB;AAMjB,IAAAC,uBAAA;AAFG,IAAM,qBAAiB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAS;AAAA,YACT,UAAS;AAAA,YACT,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,eAAe,cAAc;;;AJStB,IAAM,2BAAsD;AAAA,EACjE,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEO,IAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEO,IAAM,kBAA6C;AAAA,EACxD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAKO,SAAS,gBACd,QACA,OACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MACE,CAAC,qBAAqB,QAAQ,WAAW,KACzC,mBAAmB,QAAQ,CAAC,SAAS,gBAAgB,CAAC;AAEtD,WAAO;AAET,SAAO,OAAO,IAAI,EAAE,aAAa,KAAK;AACxC;AAEO,SAAS,gBACd,UAGA;AACA,SAAO,kBAAkB;AAC3B;AAKO,SAAS,kBACd,QACA,OACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,SAAO,OAAO,SAAS,EAAE,WAAW,MAAM,CAAC;AAC7C;AAKO,SAAS,aAAa,QAAuB,OAA2B;AAC7E,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,gBAAgB,QAAQ,KAAK,EAAG,QAAO;AAE5C,QAAM,QAAQ,OAAO,MAAM,EAAE,MAAM;AACnC,MAAI,gBAAgB,KAAK,GAAG;AAC1B,WAAO,MAAM,aAAa,KAAK,EAAE,IAAI;AAAA,EACvC;AAEA,SAAO;AACT;AAKO,SAASC,kBAAiB,OAIrB;AACV,QAAM,EAAE,QAAQ,qBAAqB,MAAM,IAAI;AAE/C,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,qBAAqB,QAAQ,WAAW,EAAG,QAAO;AAEvD,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,gBAAgB,QAAQ,KAAK;AAAA,EACtC;AAEA,SAAO;AACT;AAuCO,SAAS,aAAa,QAA4B;AACvD,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI;AAEJ,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAM,WAAW,gBAAgB,QAAQ,KAAK;AAC9C,QAAM,WAAW,kBAAkB,QAAQ,KAAK;AAEhD,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,wBAAwB,MAAM;AAClC,mBAAaA,kBAAiB,EAAE,QAAQ,OAAO,oBAAoB,CAAC,CAAC;AAAA,IACvE;AAEA,0BAAsB;AAEtB,WAAO,GAAG,mBAAmB,qBAAqB;AAElD,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,qBAAqB;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,qBAAqB,KAAK,CAAC;AAEvC,QAAM,sBAAkB,4BAAY,MAAM;AACxC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,aAAa,QAAQ,KAAK;AAC1C,QAAI,SAAS;AACX,kBAAY;AAAA,IACd;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,OAAO,SAAS,CAAC;AAE7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,gBAAgB,KAAK;AAAA,IAC5B,cAAc,yBAAyB,KAAK;AAAA,IAC5C,MAAM,eAAe,KAAK;AAAA,EAC5B;AACF;;;AK7NA,IAAAC,iBAAwC;AA4C/B,IAAAC,uBAAA;AAPF,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA,eAAe,wBAAwB,MAAM;AAC/C,GAGG;AACD,SAAO,8CAAC,SAAO,4BAAkB,EAAE,aAAa,CAAC,GAAE;AACrD;AAOO,IAAM,qBAAiB;AAAA,EAI5B,CACE;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,UAAM,EAAE,WAAW,cAAc,OAAO,YAAY,MAAM,aAAa,IACrE,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAEH,UAAM,kBAAc;AAAA,MAClB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,MAAM,iBAAkB;AAC5B,qBAAa;AAAA,MACf;AAAA,MACA,CAAC,cAAc,OAAO;AAAA,IACxB;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,WACE;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU,CAAC;AAAA,QACX,cAAW;AAAA,QACX,iBAAe,CAAC;AAAA,QAChB,MAAK;AAAA,QACL,UAAU;AAAA,QACV,cAAY;AAAA,QACZ,SACE,GAAG,KAAK,GACN,eACI,KAAK,OAAO,kBAAkB,EAAE,aAAa,CAAC,CAAC,EAC5C,QAAQ,QAAQ,MAAM,EACtB,QAAQ,MAAM,KAAK,CACtB,MACA,EACN;AAAA,QAEF,SAAS;AAAA,QACR,GAAG;AAAA,QACJ;AAAA,QAEC,sBACC,gFACE;AAAA,wDAAC,QAAK,WAAU,sBAAqB;AAAA,UACpC,QAAQ,8CAAC,UAAK,WAAU,sBAAsB,gBAAK;AAAA,UACnD,gBACC;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA;AAAA,UACF;AAAA,WAEJ;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,eAAe,cAAc;;;ACpI7B,IAAAC,iBAAiD;;;ACFjD,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,gBAAY,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,UAAU,cAAc;;;ACzBxB,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,gBAAY,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,UAAS;AAAA,UACT,UAAS;AAAA,UACT,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,UAAU,cAAc;;;AFejB,IAAM,0BAA0D;AAAA,EACrE,MAAM;AAAA,EACN,MAAM;AACR;AAEO,IAAM,sBAAsD;AAAA,EACjE,MAAM;AAAA,EACN,MAAM;AACR;AAEO,IAAM,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,MAAM;AACR;AAKO,SAAS,yBACd,QACA,QACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,mBAAmB,QAAQ,CAAC,OAAO,CAAC,EAAG,QAAO;AAElD,SAAO,WAAW,SAAS,OAAO,IAAI,EAAE,KAAK,IAAI,OAAO,IAAI,EAAE,KAAK;AACrE;AAKO,SAAS,sBACd,QACA,QACS;AACT,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAC1C,MAAI,CAAC,yBAAyB,QAAQ,MAAM,EAAG,QAAO;AAEtD,QAAM,QAAQ,OAAO,MAAM,EAAE,MAAM;AACnC,SAAO,WAAW,SAAS,MAAM,KAAK,EAAE,IAAI,IAAI,MAAM,KAAK,EAAE,IAAI;AACnE;AAKO,SAASC,kBAAiB,OAIrB;AACV,QAAM,EAAE,QAAQ,qBAAqB,OAAO,IAAI;AAEhD,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,MAAI,uBAAuB,CAAC,OAAO,SAAS,MAAM,GAAG;AACnD,WAAO,yBAAyB,QAAQ,MAAM;AAAA,EAChD;AAEA,SAAO;AACT;AAsCO,SAAS,YAAY,QAA2B;AACrD,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA,sBAAsB;AAAA,IACtB;AAAA,EACF,IAAI;AAEJ,QAAM,EAAE,OAAO,IAAI,gBAAgB,cAAc;AACjD,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAkB,IAAI;AACxD,QAAM,aAAa,yBAAyB,QAAQ,MAAM;AAE1D,gCAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,eAAe,MAAM;AACzB,mBAAaA,kBAAiB,EAAE,QAAQ,qBAAqB,OAAO,CAAC,CAAC;AAAA,IACxE;AAEA,iBAAa;AAEb,WAAO,GAAG,eAAe,YAAY;AAErC,WAAO,MAAM;AACX,aAAO,IAAI,eAAe,YAAY;AAAA,IACxC;AAAA,EACF,GAAG,CAAC,QAAQ,qBAAqB,MAAM,CAAC;AAExC,QAAM,mBAAe,4BAAY,MAAM;AACrC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,UAAU,sBAAsB,QAAQ,MAAM;AACpD,QAAI,SAAS;AACX,mBAAa;AAAA,IACf;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,QAAQ,UAAU,CAAC;AAE/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,oBAAoB,MAAM;AAAA,IACjC,cAAc,wBAAwB,MAAM;AAAA,IAC5C,MAAM,aAAa,MAAM;AAAA,EAC3B;AACF;;;AGrLA,IAAAC,iBAAiC;AACjC,IAAAA,iBAAyB;;;ACEhB,IAAM,eAA6B;AAAA,EACxC,EAAE,OAAO,SAAS,eAAe,QAAQ;AAAA,EACzC,EAAE,OAAO,UAAU,eAAe,SAAS;AAAA,EAC3C,EAAE,OAAO,aAAa,eAAe,WAAW;AAAA,EAChD,EAAE,OAAO,WAAW,eAAe,UAAU;AAAA,EAC7C,EAAE,OAAO,cAAc,eAAe,aAAa;AAAA,EACnD,EAAE,OAAO,QAAQ,eAAe,OAAO;AAAA,EACvC,EAAE,OAAO,UAAU,eAAe,SAAS;AAAA,EAC3C,EAAE,OAAO,WAAW,eAAe,UAAU;AAAA,EAC7C,EAAE,OAAO,gBAAgB,eAAe,eAAe;AAAA,EACvD,EAAE,OAAO,oBAAoB,eAAe,WAAW;AAAA,EACvD,EAAE,OAAO,UAAU,eAAe,SAAS;AAAA,EAC3C,EAAE,OAAO,WAAW,eAAe,SAAS;AAAA,EAC5C,EAAE,OAAO,UAAU,eAAe,SAAS;AAAA,EAC3C,EAAE,OAAO,aAAa,eAAe,OAAO;AAAA,EAC5C,EAAE,OAAO,UAAU,eAAe,SAAS;AAAA,EAC3C,EAAE,OAAO,SAAS,eAAe,QAAQ;AAAA,EACzC,EAAE,OAAO,cAAc,eAAe,QAAQ;AAAA,EAC9C,EAAE,OAAO,oBAAoB,eAAe,cAAc;AAAA,EAC1D,EAAE,OAAO,qBAAqB,eAAe,YAAY;AAAA,EACzD,EAAE,OAAO,SAAS,eAAe,QAAQ;AAAA,EACzC,EAAE,OAAO,eAAe,eAAe,cAAc;AAAA,EACrD,EAAE,OAAO,aAAa,eAAe,WAAW;AAAA,EAChD,EAAE,OAAO,UAAU,eAAe,SAAS;AAAA,EAC3C,EAAE,OAAO,aAAa,eAAe,YAAY;AAAA,EACjD,EAAE,OAAO,SAAS,eAAe,QAAQ;AAAA,EACzC,EAAE,OAAO,QAAQ,eAAe,OAAO;AAAA,EACvC,EAAE,OAAO,gBAAgB,eAAe,UAAU;AAAA,EAClD,EAAE,OAAO,eAAe,eAAe,cAAc;AAAA,EACrD,EAAE,OAAO,kBAAkB,eAAe,UAAU;AAAA,EACpD,EAAE,OAAO,cAAc,eAAe,YAAY;AAAA,EAClD,EAAE,OAAO,WAAW,eAAe,UAAU;AAAA,EAC7C,EAAE,OAAO,iBAAiB,eAAe,eAAe;AAC1D;;;ADjCF,IAAAC,uBAA4B;;;AEF5B,kBAA4C;AAC5C,IAAAC,uBAA2B;AAgBvB,IAAAC,uBAAA;AALJ,SAAS,QAAQ;AAAA,EACf;AAAA,EACA,GAAG;AACL,GAAkD;AAChD,SACE;AAAA,IAAC,YAAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAiCA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA,GAAG;AACL,GAAwD;AACtD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAU;AAAA,MAEV;AAAA,sDAAC,mCAAW,WAAU,8BAA6B;AAAA,QACnD;AAAA,UAAC,YAAAC,QAAiB;AAAA,UAAjB;AAAA,YACC,aAAU;AAAA,YACV,WAAW;AAAA,cACT;AAAA,cACA;AAAA,YACF;AAAA,YACC,GAAG;AAAA;AAAA,QACN;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA,GAAG;AACL,GAAuD;AACrD,SACE;AAAA,IAAC,YAAAA,QAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB,GAAG;AACL,GAAwD;AACtD,SACE;AAAA,IAAC,YAAAA,QAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAU;AAAA,MACT,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA,GAAG;AACL,GAAwD;AACtD,SACE;AAAA,IAAC,YAAAA,QAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAeA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA,GAAG;AACL,GAAuD;AACrD,SACE;AAAA,IAAC,YAAAC,QAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACxJA,IAAAC,oBAAkC;AAOzB,IAAAC,uBAAA;AAHT,SAASC,SAAQ;AAAA,EACf,GAAG;AACL,GAAuD;AACrD,SAAO,8CAAkB,wBAAjB,EAAsB,aAAU,WAAW,GAAG,OAAO;AAC/D;AAEA,SAASC,gBAAe;AAAA,EACtB,GAAG;AACL,GAA0D;AACxD,SAAO,8CAAkB,2BAAjB,EAAyB,aAAU,mBAAmB,GAAG,OAAO;AAC1E;AAEA,SAASC,gBAAe;AAAA,EACtB;AAAA,EACA,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,GAAG;AACL,GAA0D;AACxD,SACE,8CAAkB,0BAAjB,EACC;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;;;AHqBQ,IAAAC,uBAAA;AAtCD,SAAS,qBAAqB;AACnC,QAAM,EAAE,OAAO,QAAI,iCAAiB;AACpC,QAAM,CAAC,MAAM,OAAO,QAAI,yBAAS,KAAK;AAEtC,MAAI,CAAC,OAAQ,QAAO;AAGpB,QAAM,cACJ,OAAO,cAAc,WAAW,EAAE,cAAc;AAOlD,QAAM,YAAY,CAAC,WAAmB;AACpC,QAAI,CAAC,OAAQ;AAGb,QAAI,OAAO,MAAM,aAAa;AAC5B,YAAM,gBAAgB,OAAO,OAAO,MAAM;AAC1C,UAAI,eAAe;AACjB,eAAO,KAAK,SAAS,OAAO,MAAM,GAAG,iBAAiB,aAAa,CAAC;AAAA,MACtE;AAAA,IACF;AAGA,eAAW,MAAM;AACf,YAAM,UAAU,OAAO,MAAM,EAAE,MAAM,EAAE,cAAc,MAAM,EAAE,IAAI;AACjE,UAAI,CAAC,SAAS;AACZ,gBAAQ,KAAK,qBAAqB,MAAM;AAAA,MAC1C;AAAA,IACF,GAAG,CAAC;AAAA,EACN;AAEA,SACE,+CAACC,UAAA,EAAQ,MAAY,cAAc,SACjC;AAAA,kDAACC,iBAAA,EAAe,SAAO,MACrB;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,WAAU;AAAA,QAMT;AAAA;AAAA,UACD,8CAAC,oCAAY,WAAU,WAAU;AAAA;AAAA;AAAA,IACnC,GACF;AAAA,IAEA;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAM;AAAA,QACN,mBAAmB,CAAC,MAAM;AACxB,gBAAM,SAAS,EAAE;AACjB,cAAI,OAAO,QAAQ,oBAAoB,GAAG;AACxC,cAAE,eAAe;AAAA,UACnB;AAAA,QACF;AAAA,QAEA,yDAAC,WACC;AAAA,wDAAC,SAAI,WAAU,qBACb,wDAAC,gBAAa,aAAY,kBAAiB,GAC7C;AAAA,UAEA,+CAAC,eAAY,WAAU,iBACrB;AAAA,0DAAC,gBAAa,4BAAc;AAAA,YAE5B,+CAAC,gBACC;AAAA;AAAA,gBAAC;AAAA;AAAA,kBAEC,UAAU,MAAM;AACd,wBAAI,CAAC,OAAQ;AAEb,wBAAI,OAAO,MAAM,aAAa;AAC5B,4BAAM,gBAAgB,OAAO,OAAO,MAAM;AAC1C,0BAAI,eAAe;AACjB,+BAAO,KAAK;AAAA,0BACV,OAAO,MAAM,GAAG,iBAAiB,aAAa;AAAA,wBAChD;AAAA,sBACF;AAAA,oBACF;AAEA,+BAAW,MAAM;AACf,6BAAO,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI;AAC7C,8BAAQ,KAAK;AAAA,oBACf,GAAG,CAAC;AAAA,kBACN;AAAA,kBACA,WAAU;AAAA,kBACX;AAAA;AAAA,gBAnBK;AAAA,cAqBN;AAAA,cAEC,aAAa,IAAI,CAAC,EAAE,OAAO,cAAc,MACxC;AAAA,gBAAC;AAAA;AAAA,kBAEC,UAAU,MAAM;AACd,8BAAU,KAAK;AACf,4BAAQ,KAAK;AAAA,kBACf;AAAA,kBACA,OAAO,EAAE,YAAY,cAAa;AAAA,kBAEjC;AAAA;AAAA,gBAPI;AAAA,cAQP,CACD;AAAA,eACH;AAAA,aACF;AAAA,WACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;;;AIpIA,IAAAC,iBAAoC;AACpC,IAAAA,iBAAiC;AACjC,4BAA+B;;;ACJxB,IAAM,mBAAmB;AAAA;AAAA,EAE5B;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAG5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAG5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAG5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAG5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAG5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAG5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAC9C;;;ADrBF,oBAAyB;;;AEJzB,qBAAgC;AAS5B,IAAAC,uBAAA;AALJ,SAASC,OAAM;AAAA,EACb;AAAA,EACA,GAAG;AACL,GAAqD;AACnD,SACE;AAAA,IAAgB;AAAA,IAAf;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;AFNA,IAAAC,iBAAkB;AA8EV,IAAAC,uBAAA;AA5ED,SAAS,YAAY,EAAE,OAAO,OAAO,GAAG;AAC7C,QAAM,EAAE,OAAO,QAAI,iCAAiB;AAEpC,QAAM,CAAC,MAAM,OAAO,QAAI,yBAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,QAAI,yBAAS,SAAS;AAC5C,QAAM,CAAC,YAAY,aAAa,QAAI,yBAAS,KAAK;AAGlD,QAAM,CAAC,SAAS,UAAU,QAAI,yBAAS,SAAS;AAEhD,QAAM,CAAC,UAAU,WAAW,QAAI,yBAAS,KAAK;AAG9C,gCAAU,MAAM;AACd,UAAM,UACJ,SAAS,SACL,QAAQ,cAAc,WAAW,EAAE,SAAS,YAC5C,QAAQ,cAAc,WAAW,GAAG,SAAS;AAEnD,aAAS,OAAO;AAChB,eAAW,OAAO;AAAA,EACpB,GAAG,CAAC,QAAQ,IAAI,CAAC;AAGjB,gCAAU,MAAM;AACd,UAAM,QAAQ,MAAM;AAClB,UAAI;AACF,oBAAY,CAAC,QAAQ,MAAM,UAAU,KAAK;AAAA,MAC5C,QAAQ;AACN,oBAAY,KAAK;AAAA,MACnB;AAAA,IACF;AAEA,UAAM;AACN,YAAQ,GAAG,mBAAmB,KAAK;AACnC,YAAQ,GAAG,eAAe,KAAK;AAE/B,WAAO,MAAM;AACX,cAAQ,IAAI,mBAAmB,KAAK;AACpC,cAAQ,IAAI,eAAe,KAAK;AAAA,IAClC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,aAAa,eAAAC,QAAM;AAAA,IACvB,CAAC,UAAkB;AACjB,UAAI,CAAC,OAAQ;AAGb,UAAI,OAAO,MAAM,aAAa;AAC5B,cAAM,gBAAgB,OAAO,OAAO,MAAM;AAC1C,YAAI,eAAe;AACjB,iBAAO,KAAK,SAAS,OAAO,MAAM,GAAG,iBAAiB,aAAa,CAAC;AAAA,QACtE;AAAA,MACF;AAGA,iBAAW,MAAM;AACf,eAAO,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,IAAI;AAC3C,iBAAS,KAAK;AAAA,MAChB,GAAG,CAAC;AAAA,IACN;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAGA,QAAM,mBAAmB,eAAAA,QAAM;AAAA,IAC7B,UAAM,wBAAS,CAAC,MAAc,WAAW,CAAC,GAAG,EAAE;AAAA,IAC/C,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,OAAQ,QAAO;AAEpB,SACE,+CAACC,UAAA,EAAQ,MAAY,cAAc,CAAC,MAAM,QAAQ,CAAC,GACjD;AAAA,kDAACC,iBAAA,EAAe,SAAO,MACrB;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,WAAU;AAAA,QACX;AAAA;AAAA,UAEC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,iBAAiB,MAAM;AAAA;AAAA,UAClC;AAAA;AAAA;AAAA,IACF,GACF;AAAA,IAEA;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAElC;AAAA,wDAACC,QAAA,EAAM,WAAU,gBACd,mBAAS,SAAS,eAAe,mBACpC;AAAA,UAGC,CAAC,cACA,+CAAC,SAAI,WAAU,uBACb;AAAA,0DAAC,SAAI,WAAU,0BACZ,2BAAiB,IAAI,CAAC,MACrB;AAAA,cAAC;AAAA;AAAA,gBAEC,SAAS,MAAM;AACb,6BAAW,CAAC;AACZ,0BAAQ,KAAK;AAAA,gBACf;AAAA,gBACA,WAAU;AAAA,gBACV,OAAO,EAAE,iBAAiB,EAAE;AAAA;AAAA,cANvB;AAAA,YAOP,CACD,GACH;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS,MAAM;AAEb,6BAAW,KAAK;AAChB,gCAAc,IAAI;AAAA,gBACpB;AAAA,gBACD;AAAA;AAAA,YAED;AAAA,aACF;AAAA,UAID;AAAA,UAEC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,aAAa,CAAC,MAAM,EAAE,gBAAgB;AAAA,cACtC,WAAW,CAAC,MAAM,EAAE,gBAAgB;AAAA,cACpC,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,cACxC,aAAa,CAAC,MAAM,EAAE,gBAAgB;AAAA,cACtC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,cAGlC;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,oBACP,UAAU,CAAC,MAAM;AAEf,iCAAW,CAAC;AAAA,oBACd;AAAA,oBAEA,aAAa,CAAC,MAAW,EAAE,gBAAgB;AAAA,oBAC3C,WAAW,CAAC,MAAW,EAAE,gBAAgB;AAAA;AAAA,gBAC3C;AAAA,gBAEA,+CAAC,SAAI,WAAU,2BACb;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,sBACP,UAAU,CAAC,MAAM;AAEf,yCAAiB,EAAE,OAAO,KAAK;AAC/B,mCAAW,EAAE,OAAO,KAAK;AAAA,sBAC3B;AAAA,sBACA,WAAU;AAAA;AAAA,kBACZ;AAAA,kBAEA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAQ;AAAA,sBACR,SAAS,MAAM;AAEb,mCAAW,KAAK;AAChB,sCAAc,KAAK;AAAA,sBACrB;AAAA,sBACD;AAAA;AAAA,kBAED;AAAA,mBACF;AAAA,gBAEA,8CAAC,SAAI,WAAU,yBACb;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS,MAAM;AACb,iCAAW,OAAO;AAClB,oCAAc,KAAK;AACnB,8BAAQ,KAAK;AAGb,iCAAW,MAAM;AACf,gCAAQ,SAAS,MAAM;AAAA,sBACzB,GAAG,GAAG;AAAA,oBACR;AAAA,oBAGD;AAAA;AAAA,gBAED,GACF;AAAA;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAEJ;;;AGtNA,IAAAC,iBAAyB;AACzB,IAAAA,iBAAiC;AACjC,gBAAwB;AAkEhB,IAAAC,uBAAA;AAjDD,SAAS,oBAAoB;AAClC,QAAM,EAAE,OAAO,QAAI,iCAAiB;AACpC,QAAM,CAAC,MAAM,OAAO,QAAI,yBAAS,KAAK;AAEtC,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,eAAe,CAAC,WAAmB;AACvC,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,eAAe,KAAK,CAAC,EAAE,IAAI;AAClF;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI;AAC7C;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI;AAC5C;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI;AAC1C;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI;AAC1C;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI;AACzC;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI;AACvC;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI;AACxC;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI;AACvC;AAAA,MACF,KAAK;AACH,eAAO,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI;AACzC;AAAA,MACF;AACE;AAAA,IACJ;AAEA,YAAQ,KAAK;AAAA,EACf;AAEA,SACE,+CAACC,UAAA,EAAQ,MAAY,cAAc,SACjC;AAAA,kDAACC,iBAAA,EAAe,SAAO,MACrB,wDAAC,UAAO,SAAQ,eAAc,MAAK,MACnC,wDAAC,qBAAQ,MAAM,IAAI,OAAM,WAAU,GACnC,GACF;AAAA,IAEA,8CAACC,iBAAA,EAAe,WAAU,iBAAgB,OAAM,SAC9C,yDAAC,WACC;AAAA,oDAAC,gBAAa,aAAY,2BAA0B;AAAA,MACpD,8CAAC,eAAY,WAAU,iBACrB,yDAAC,gBAEC;AAAA,sDAAC,eAAY,UAAU,MAAM,aAAa,QAAQ,GAAG,0BAErD;AAAA,QAEA,8CAAC,eAAY,UAAU,MAAM,aAAa,cAAc,GAAG,+BAE3D;AAAA,QACA,8CAAC,eAAY,UAAU,MAAM,aAAa,aAAa,GAAG,8BAE1D;AAAA,QACA,8CAAC,eAAY,UAAU,MAAM,aAAa,QAAQ,GAAG,2BAErD;AAAA,QAEA,8CAAC,eAAY,UAAU,MAAM,aAAa,cAAc,GAAG,4BAE3D;AAAA,QACA,8CAAC,eAAY,UAAU,MAAM,aAAa,aAAa,GAAG,2BAE1D;AAAA,QACA,8CAAC,eAAY,UAAU,MAAM,aAAa,QAAQ,GAAG,wBAErD;AAAA,QAEA,8CAAC,eAAY,UAAU,MAAM,aAAa,OAAO,GAAG,yBAEpD;AAAA,QACA,8CAAC,eAAY,UAAU,MAAM,aAAa,OAAO,GAAG,yBAEpD;AAAA,QAEA,8CAAC,eAAY,UAAU,MAAM,aAAa,aAAa,GAAG,0BAE1D;AAAA,SAEF,GACF;AAAA,OACF,GACF;AAAA,KACF;AAEJ;;;ACzHA,IAAAC,iBAAqB;AAef,IAAAC,uBAAA;AAXC,IAAM,oBAAgB,qBAAK,CAAC,EAAE,WAAW,GAAG,MAAM,MAAgB;AACvE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAK;AAAA;AAAA,MACP;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,cAAc,cAAc;;;ACrB5B,IAAAC,iBAAoC;;;ACFpC,IAAAC,iBAAqB;;;ACArB,IAAAC,iBAAkC;AAQ3B,IAAM,aAAa,CAAC,aAA2C;AACpE,QAAM,UAAM,uBAAO,QAAQ;AAC3B,MAAI,UAAU;AAEd;AAAA,IACE,MAAM,MAAM;AACV,UAAI,QAAQ;AAAA,IACd;AAAA,IACA,CAAC;AAAA,EACH;AACF;;;ADfA,IAAAC,iBAAwB;AAOxB,IAAM,iBAAmC;AAAA,EACvC,SAAS;AAAA,EACT,UAAU;AACZ;AAWO,SAAS,qBACd,IACA,OAAO,KACP,eAAqC,CAAC,GACtC,UAA4B,gBAK5B;AACA,QAAM,cAAU;AAAA,IACd,UAAM,eAAAC,SAAY,IAAI,MAAM,OAAO;AAAA;AAAA,IAEnC;AAAA,EACF;AAEA,aAAW,MAAM;AACf,YAAQ,OAAO;AAAA,EACjB,CAAC;AAED,SAAO;AACT;;;ADLO,SAAS,gBAAiC;AAC/C,QAAM,CAAC,YAAY,aAAa,QAAI,yBAA0B;AAAA,IAC5D,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,OAAO;AAAA,EACT,CAAC;AAED,QAAM,uBAAuB,qBAAqB,MAAM;AACtD,QAAI,OAAO,WAAW,YAAa;AAEnC,UAAM,KAAK,OAAO;AAClB,QAAI,CAAC,GAAI;AAET,UAAM;AAAA,MACJ,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ;AAAA,IACV,IAAI;AAEJ,kBAAc,CAAC,cAAc;AAC3B,UACE,UAAU,UAAU,SACpB,WAAW,UAAU,UACrB,cAAc,UAAU,aACxB,eAAe,UAAU,cACzB,UAAU,UAAU,OACpB;AACA,eAAO;AAAA,MACT;AAEA,aAAO,EAAE,OAAO,QAAQ,WAAW,YAAY,MAAM;AAAA,IACvD,CAAC;AAAA,EACH,GAAG,GAAG;AAEN,gCAAU,MAAM;AACd,UAAM,iBAAiB,OAAO;AAC9B,QAAI,CAAC,eAAgB;AAErB,mBAAe,iBAAiB,UAAU,oBAAoB;AAE9D,yBAAqB;AAErB,WAAO,MAAM;AACX,qBAAe,oBAAoB,UAAU,oBAAoB;AAAA,IACnE;AAAA,EACF,GAAG,CAAC,oBAAoB,CAAC;AAEzB,SAAO;AACT;;;AG1FA,IAAAC,iBAAiD;AAyBjD,IAAM,cAAyB;AAAA,EAC7B,GAAG;AAAA,EACH,GAAG;AAAA,EACH,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AAEA,IAAM,QAAQ,OAAO,WAAW;AAChC,IAAM,oBAAoB,CAAC,SAAS,OAAO,mBAAmB;AAK9D,IAAM,eAAe,MAAe,CAAC;AAQ9B,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,UAAU;AAAA,EACV,aAAa;AAAA,EACb,oBAAoB;AACtB,IAAwB,CAAC,GAAc;AACrC,QAAM,CAAC,MAAM,OAAO,QAAI,yBAAoB,WAAW;AAEvD,QAAM,uBAAmB,4BAAY,MAAsB;AACzD,QAAI,CAAC,WAAW,CAAC,aAAa,EAAG,QAAO;AAExC,QAAI,CAAC,SAAS;AACZ,aAAO,SAAS;AAAA,IAClB;AAEA,QAAI,OAAO,YAAY,UAAU;AAC/B,aAAO,SAAS,cAAc,OAAO;AAAA,IACvC;AAEA,QAAI,aAAa,SAAS;AACxB,aAAO,QAAQ;AAAA,IACjB;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,OAAO,CAAC;AAErB,QAAM,aAAa;AAAA,IACjB,MAAM;AACJ,UAAI,CAAC,WAAW,CAAC,aAAa,EAAG;AAEjC,YAAM,gBAAgB,iBAAiB;AACvC,UAAI,CAAC,eAAe;AAClB,gBAAQ,WAAW;AACnB;AAAA,MACF;AAEA,YAAM,UAAU,cAAc,sBAAsB;AACpD,cAAQ;AAAA,QACN,GAAG,QAAQ;AAAA,QACX,GAAG,QAAQ;AAAA,QACX,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,QAChB,KAAK,QAAQ;AAAA,QACb,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IACA;AAAA,IACA,CAAC,SAAS,gBAAgB;AAAA,IAC1B,EAAE,SAAS,MAAM,UAAU,KAAK;AAAA,EAClC;AAEA,gCAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,aAAa,GAAG;AAC/B,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,gBAAgB,iBAAiB;AACvC,QAAI,CAAC,cAAe;AAEpB,eAAW;AAEX,UAAM,UAA0B,CAAC;AAEjC,QAAI,qBAAqB,mBAAmB;AAC1C,YAAM,iBAAiB,IAAI,eAAe,MAAM;AAC9C,eAAO,sBAAsB,UAAU;AAAA,MACzC,CAAC;AACD,qBAAe,QAAQ,aAAa;AACpC,cAAQ,KAAK,MAAM,eAAe,WAAW,CAAC;AAAA,IAChD;AAEA,UAAM,eAAe,MAAM,WAAW;AAEtC,WAAO,iBAAiB,UAAU,cAAc,IAAI;AACpD,WAAO,iBAAiB,UAAU,cAAc,IAAI;AAEpD,YAAQ,KAAK,MAAM;AACjB,aAAO,oBAAoB,UAAU,YAAY;AACjD,aAAO,oBAAoB,UAAU,YAAY;AAAA,IACnD,CAAC;AAED,WAAO,MAAM;AACX,cAAQ,QAAQ,CAAC,OAAO,GAAG,CAAC;AAC5B,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,SAAS,kBAAkB,YAAY,iBAAiB,CAAC;AAE7D,SAAO;AACT;AAKO,SAAS,YACd,UAA+C,CAAC,GACrC;AACX,SAAO,eAAe;AAAA,IACpB,GAAG;AAAA,IACH,SAAS,aAAa,IAAI,SAAS,OAAO;AAAA,EAC5C,CAAC;AACH;AAKO,SAAS,WACd,KACA,UAA+C,CAAC,GACrC;AACX,SAAO,eAAe,EAAE,GAAG,SAAS,SAAS,IAAI,CAAC;AACpD;;;AChKA,IAAAC,iBAA0B;AAqBnB,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,gBAAgB;AAClB,GAA4B;AAC1B,QAAM,EAAE,QAAQ,aAAa,IAAI,cAAc;AAC/C,QAAM,OAAO,YAAY;AAAA,IACvB,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,mBAAmB;AAAA,EACrB,CAAC;AAED,gCAAU,MAAM;AACd,UAAM,yBAAyB,MAAM;AACnC,UAAI,CAAC,OAAQ;AAEb,YAAM,EAAE,OAAO,KAAK,IAAI;AACxB,UAAI,CAAC,KAAK,SAAS,EAAG;AAGtB,YAAM,EAAE,KAAK,IAAI,MAAM;AACvB,YAAM,eAAe,KAAK,YAAY,IAAI;AAE1C,UAAI,eAAe,KAAK,UAAU,cAAc;AAC9C,cAAM,iBAAiB,eAAe,aAAa;AAGnD,YAAI,iBAAiB,eAAe;AAClC,gBAAM,gBAAgB,KAAK,IAAI,eAAe,GAAG,aAAa;AAC9D,gBAAM,iBAAiB,OAAO;AAC9B,gBAAM,kBAAkB,aAAa,MAAM;AAC3C,gBAAM,aAAa,kBAAkB;AAErC,iBAAO,SAAS;AAAA,YACd,KAAK,KAAK,IAAI,GAAG,UAAU;AAAA,YAC3B,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,2BAAuB;AAAA,EACzB,GAAG,CAAC,QAAQ,eAAe,cAAc,KAAK,MAAM,CAAC;AAErD,SAAO;AACT;;;AhG8BI,IAAAC,uBAAA;AAVJ,IAAM,qBAAqB,CAAC;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,MAIM;AACJ,SACE,gFACE;AAAA,kDAAC,UAAO;AAAA,IACR,8CAAC,sBAAmB;AAAA,IACpB,8CAAC,eAAY,MAAK,QAAO;AAAA,IACzB,+CAAC,gBACC;AAAA,oDAAC,cAAW,MAAK,QAAO;AAAA,MACxB,8CAAC,cAAW,MAAK,UAAS;AAAA,MAC1B,8CAAC,cAAW,MAAK,UAAS;AAAA,MAC1B,8CAAC,cAAW,MAAK,QAAO;AAAA,MACxB,8CAAC,cAAW,MAAK,aAAY;AAAA,MAC7B,8CAAC,kBAAe,QAAO,QAAO;AAAA,MAC9B,8CAAC,kBAAe,QAAO,QAAO;AAAA,OAChC;AAAA,IAEA,8CAAC,oBAAiB;AAAA,IAElB,+CAAC,gBACC;AAAA,oDAAC,mBAAgB,OAAM,QAAO;AAAA,MAC9B,8CAAC,mBAAgB,OAAM,UAAS;AAAA,MAChC,8CAAC,mBAAgB,OAAM,SAAQ;AAAA,MAC/B,8CAAC,mBAAgB,OAAM,WAAU;AAAA,OAQnC;AAAA,IAEA,8CAAC,oBAAiB;AAAA,IAElB,+CAAC,gBACC;AAAA,oDAAC,uBAAoB,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,QAAQ,UAAU;AAAA,MAC7D;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,CAAC,cAAc,eAAe,UAAU;AAAA,UAC/C,QAAQ;AAAA;AAAA,MACV;AAAA,MACA,8CAAC,oBAAiB;AAAA,OAEpB;AAAA,IACA,8CAAC,gBACC,wDAAC,qBAAkB,GASrB;AAAA,IAEA,8CAAC,gBAKD;AAAA,IAEA,8CAAC,oBAAiB;AAAA,IAElB,8CAAC,gBACC,wDAAC,qBAAkB,MAAK,OAAM,GAChC;AAAA,IAEA,8CAAC,UAAO;AAAA,IAEP,YAAY,8CAAC,oBAAiB;AAAA,KAKjC;AAEJ;AAEA,IAAM,uBAAuB,CAAC;AAAA,EAC5B;AAAA,EACA;AACF,MAIE,gFACE;AAAA,gDAAC,gBACC,yDAACC,SAAA,EAAO,cAAW,SAAQ,SAAS,QAClC;AAAA,kDAAC,iBAAc,WAAU,sBAAqB;AAAA,IAC7C,SAAS,gBACR,8CAAC,mBAAgB,WAAU,sBAAqB,IAEhD,8CAAC,YAAS,WAAU,sBAAqB;AAAA,KAE7C,GACF;AAAA,EAEA,8CAAC,oBAAiB;AAAA,EAEjB,SAAS,gBACR,8CAAC,gCAA6B,IAE9B,8CAAC,eAAY;AAAA,GAEjB;AAGK,SAAS,eAAe;AAC7B,QAAM,EAAE,kBAAkB,cAAa,IAAI,gBAAgB;AAC3D,QAAM,WAAW,gBAAgB;AACjC,QAAM,EAAE,OAAO,IAAI,cAAc;AACjC,QAAM,CAAC,YAAY,aAAa,QAAI;AAAA,IAClC;AAAA,EACF;AACA,QAAM,iBAAa,uBAAuB,IAAI;AAG9C,QAAM,aAAS,0BAAU;AAAA,IACvB,mBAAmB;AAAA,IACnB,aAAa;AAAA,MACX,YAAY;AAAA,QACV,cAAc;AAAA,QACd,aAAa;AAAA,QACb,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,8BAAW,UAAU;AAAA,QACnB,gBAAgB;AAAA,QAChB,MAAM;AAAA,UACJ,aAAa;AAAA,UACb,sBAAsB;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,MACD;AAAA,MACA;AAAA,MACAC;AAAA,MACAA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,aAAa,GAAG,CAAC;AAAA,MAC9D,wCAAW,UAAU;AAAA,QACnB,OAAO,CAAC,WAAW;AAAA,MACrB,CAAC;AAAA,MACD,uBAAAC,QAAM,UAAU,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;AAAA,MACxC,qCAAU,UAAU,EAAE,YAAY,KAAK,CAAC;AAAA,MACxC,gCAAS,UAAU;AAAA,QACjB,OAAO,EAAE,WAAW,KAAK;AAAA,MAC3B,CAAC;AAAA,MACD;AAAA,MACA,sCAAU,UAAU,EAAE,OAAO,CAAC,WAAW,WAAW,EAAE,CAAC;AAAA,MACvD;AAAA,MACA,+BAAS,UAAU,EAAE,QAAQ,KAAK,CAAC;AAAA,MACnC,qCAAU,UAAU,EAAE,YAAY,KAAK,CAAC;AAAA,MACxC,uBAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACAC,iBAAgB,UAAU;AAAA,QACxB,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS,CAAC,UAAU,QAAQ,MAAM,kBAAkB,KAAK;AAAA,MAC3D,CAAC;AAAA,IACH;AAAA,IACA,SAAS;AAAA,IACT,UAAU,CAAC,EAAE,QAAAC,QAAO,MAAM;AACxB,cAAQ,IAAI,0BAAmB;AAC/B,uBAAiBA,OAAM;AAAA,IACzB;AAAA,IACA,UAAU,CAAC,EAAE,QAAAA,QAAO,MAAM;AACxB,cAAQ,IAAI,yDAA+C;AAC3D,oBAAcA,OAAM;AAAA,IACtB;AAAA,EACF,CAAC;AAGD,gCAAU,MAAM;AACd,QAAI,QAAQ;AACV,cAAQ,IAAI,6CAAsC;AAClD,uBAAiB,MAAM;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,CAAC;AAI7B,QAAM,OAAO,oBAAoB;AAAA,IAC/B;AAAA,IACA,eAAe,WAAW,SAAS,sBAAsB,EAAE,UAAU;AAAA,EACvE,CAAC;AAKD,gCAAU,MAAM;AACd,QAAI,CAAC,YAAY,eAAe,QAAQ;AACtC,oBAAc,MAAM;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,UAAU,UAAU,CAAC;AACzB,gCAAU,MAAM;AACd,QAAI,QAAQ;AACV,aAAO,SAAS,MAAM,OAAO;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,gCAAU,MAAM;AACd,QAAI,CAAC,QAAQ,eAAgB;AAE7B,UAAM,UAAU,SAAS;AAAA,MACvB;AAAA,IACF;AAEA,QAAI,CAAC,QAAS;AAEd,UAAM,iBAAiB,MAAM;AAC3B,cAAQ,MAAM,MAAM,GAAG,OAAO,gBAAgB,SAAS;AAAA,IACzD;AAEA,WAAO,eAAe,iBAAiB,UAAU,cAAc;AAC/D,WAAO,eAAe,iBAAiB,UAAU,cAAc;AAE/D,mBAAe;AAEf,WAAO,MAAM;AACX,aAAO,gBAAgB,oBAAoB,UAAU,cAAc;AACnE,aAAO,gBAAgB,oBAAoB,UAAU,cAAc;AAAA,IACrE;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SACE,8CAAC,SAAI,WAAU,yBACb,yDAAC,6BAAc,UAAd,EAAuB,OAAO,EAAE,OAAO,GACtC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,OAAO;AAAA,UACL,GAAI,WACA;AAAA,YACE,QAAQ,eAAe,SAAS,KAAK,CAAC;AAAA,UACxC,IACA,CAAC;AAAA,QACP;AAAA,QAEC,yBAAe,SACd;AAAA,UAAC;AAAA;AAAA,YACC,oBAAoB,MAAM,cAAc,aAAa;AAAA,YACrD,aAAa,MAAM,cAAc,MAAM;AAAA,YACvC;AAAA;AAAA,QACF,IAEA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,eAAe,gBAAgB,gBAAgB;AAAA,YACrD,QAAQ,MAAM,cAAc,MAAM;AAAA;AAAA,QACpC;AAAA;AAAA,IAEJ;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAS;AAAA,QACT,WAAU;AAAA,QAET,oBAAU,8CAAC,oBAAiB;AAAA;AAAA,IAC/B;AAAA,KACF,GACF;AAEJ;;;AiG/VU,IAAAC,uBAAA;AALH,SAAS,OAAO,EAAE,UAAU,WAAW,OAAO,cAAc,YAAY,GAAgB;AAC7F,SACE,8CAAC,SAAI,WAAsB,OACzB,wDAAC,eACC,wDAAC,gBAAa,UAAoB,aAA0B,cAC1D,wDAAC,gBAAa,GAChB,GACF,GACF;AAEJ;;;ACxBA,IAAAC,iBAAoC;AAU7B,SAAS,aACd,QACA,UAA+B,CAAC,GACvB;AACT,QAAM,EAAE,UAAAC,YAAW,KAAK,qBAAqB,KAAK,IAAI;AACtD,QAAM,CAAC,aAAa,cAAc,QAAI,yBAAS,KAAK;AAEpD,gCAAU,MAAM;AAEd,UAAM,UACJ,UAAU,OAAO,WAAW,eAAe,kBAAkB,SACzD,SACE,QAAmC,WAAW;AAGtD,UAAM,cACJ,sBACA,YAAY,UACZ,OAAO,aAAa,cAChB,WACA;AAEN,UAAM,KAAK,CACT,IACA,OACA,YACG,GAAG,iBAAiB,OAAO,SAAS,IAAI;AAE7C,UAAM,MAAM,CACV,IACA,OACA,YACG,GAAG,oBAAoB,OAAO,OAAO;AAE1C,QAAI;AACJ,UAAM,oBAAoB,YAAY,UAAU,iBAAiB;AAEjE,UAAM,eAA8B,MAAM;AACxC,UAAI,CAAC,YAAa,gBAAe,IAAI;AAErC,UAAI,CAAC,mBAAmB;AACtB,qBAAa,OAAO;AACpB,kBAAU,WAAW,MAAM,eAAe,KAAK,GAAGA,SAAQ;AAAA,MAC5D;AAAA,IACF;AAEA,UAAM,kBAAiC,MAAM,eAAe,KAAK;AAEjE,OAAG,aAAa,UAAU,YAAY;AACtC,QAAI,mBAAmB;AACrB,SAAG,aAAa,aAAa,eAAe;AAAA,IAC9C;AAEA,WAAO,MAAM;AACX,UAAI,aAAa,UAAU,YAAY;AACvC,UAAI,mBAAmB;AACrB,YAAI,aAAa,aAAa,eAAe;AAAA,MAC/C;AACA,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,QAAQA,WAAU,oBAAoB,WAAW,CAAC;AAEtD,SAAO;AACT;;;ACpEA,IAAM,cAAc;AACpB,IAAM,iBAAiB;AAGhB,SAAS,WAAwB;AACtC,MAAI,OAAO,WAAW,YAAa,QAAO,CAAC;AAE3C,MAAI;AACF,UAAM,MAAM,aAAa,QAAQ,gBAAgB;AACjD,QAAI,CAAC,IAAK,QAAO,CAAC;AAElB,UAAM,SAAS,KAAK,MAAM,GAAG;AAG7B,QAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AAEpC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,SAAS,MAAmB;AAC1C,MAAI,OAAO,WAAW,YAAa;AACnC,eAAa,QAAQ,aAAa,KAAK,UAAU,IAAI,CAAC;AACxD;AAEO,SAAS,gBAAwB;AACtC,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,SAAO,aAAa,QAAQ,cAAc,KAAK;AACjD;AAEO,SAAS,cAAc,IAAY;AACxC,MAAI,OAAO,WAAW,YAAa;AACnC,eAAa,QAAQ,gBAAgB,EAAE;AACzC;;;ACxCO,SAAS,aAAa,MAA6B;AACtD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,IAAI,WAAW;AAC9B,WAAO,cAAc,IAAI;AACzB,WAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,WAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AAAA,EAC1C,CAAC;AACH;AAEO,SAAS,gBAAgB,KAAa,QAAgB;AAC3D,eAAa,QAAQ,KAAK,MAAM;AAClC;AAEO,SAAS,gBAAgB,KAA4B;AAC1D,SAAO,aAAa,QAAQ,GAAG;AACjC;","names":["React","import_react_slot","import_class_variance_authority","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","open","import_jsx_runtime","import_react","import_lucide_react","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_core","index_default","import_core","index_default","import_extension_text_style","import_extensions","import_core","import_react","import_react","import_jsx_runtime","Tooltip","TooltipTrigger","TooltipContent","import_core","cn","isMac","import_jsx_runtime","Button","cn","Tooltip","TooltipTrigger","TooltipContent","import_jsx_runtime","import_react","import_react","import_jsx_runtime","Separator","cn","import_react","import_react","import_jsx_runtime","cn","Separator","import_react","import_lucide_react","import_jsx_runtime","editor","import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","Button","ImageUploadNode","import_react","TiptapHorizontalRule","import_react","import_react","import_jsx_runtime","import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","canToggle","Button","import_react","import_state","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","DropdownMenuPrimitive","import_jsx_runtime","DropdownMenu","DropdownMenuTrigger","DropdownMenuItem","cn","DropdownMenuContent","import_react","import_jsx_runtime","cn","import_jsx_runtime","canToggle","DropdownMenu","DropdownMenuTrigger","Button","DropdownMenuContent","DropdownMenuItem","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","Button","import_react","import_react","import_react","import_jsx_runtime","shouldShowButton","import_react","import_react","import_jsx_runtime","canToggle","Button","import_react","import_state","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","canToggle","import_react","import_jsx_runtime","canToggle","DropdownMenu","DropdownMenuTrigger","Button","DropdownMenuContent","DropdownMenuItem","import_react","import_jsx_runtime","canToggle","Button","import_react","import_state","import_react","import_jsx_runtime","shouldShowButton","canToggle","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","cn","import_react","import_jsx_runtime","canColorHighlight","Button","import_react","import_react_hotkeys_hook","shouldShowButton","import_jsx_runtime","Button","Separator","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","Input","cn","import_jsx_runtime","Button","Input","Separator","import_react","import_react","import_jsx_runtime","canToggle","Button","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","canToggle","import_react","import_jsx_runtime","Button","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","import_react","import_jsx_runtime","Button","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","shouldShowButton","import_react","import_lucide_react","import_lucide_react","import_jsx_runtime","CommandPrimitive","CommandPrimitive","CommandPrimitive","PopoverPrimitive","import_jsx_runtime","Popover","PopoverTrigger","PopoverContent","import_jsx_runtime","Popover","PopoverTrigger","PopoverContent","import_react","import_jsx_runtime","Label","import_react","import_jsx_runtime","React","Popover","PopoverTrigger","PopoverContent","Label","import_react","import_jsx_runtime","Popover","PopoverTrigger","PopoverContent","import_react","import_jsx_runtime","import_react","import_lodash","import_react","import_react","throttle","import_react","import_react","import_jsx_runtime","Button","index_default","Color","Image","ImageUploadNode","editor","import_jsx_runtime","import_react","debounce"]}