) that the ThreeView will append to.\n */\n\n const bodyContainer = useRef
(null);\n const canvasContainer = useRef(null);\n\n const isFirstGraphView: boolean =\n viewStore ===\n dashboardStore.openViews.find((view) => view.viewType !== 'Table');\n\n // called only once when the view is created\n useEffect(() => {\n if (!canvasContainer.current) return;\n viewStore.threeView = new ThreeView(viewStore, canvasContainer.current);\n return () => {\n viewStore.close();\n };\n }, []);\n\n /**\n * Mouse events are handled here and passed to the ThreeView.\n */\n\n // Touchpad feeds are very high frequency compared to external mouse\n const debouncedZoom = debounce(\n (event: React.WheelEvent) => viewStore.threeView?.handleZoom(event),\n true,\n 5,\n );\n const debouncedMove = debounce(\n (event: React.WheelEvent) =>\n viewStore.threeView?.cameraMoveFromWheel(event),\n true,\n 5,\n );\n\n useEffect(() => {\n if (!canvasContainer.current) return;\n\n const wheelEventListener = (event: MouseEvent) => {\n event.preventDefault();\n const reactEvent = event as unknown as React.WheelEvent; // cast to react event\n if (event.ctrlKey) {\n // Pinch zoom -> wheel event + cntrl\n if (viewStore.threeView)\n viewStore.threeView.lastPeripheral = 'touchpad';\n return debouncedZoom(reactEvent);\n }\n\n if (\n reactEvent.deltaX === 0 &&\n viewStore.threeView?.lastPeripheral == 'mouse'\n ) {\n // if deltaX is 0, then likely it is a mouse scroll event\n // However deltaX might still be zero when panning on a touchpad.\n // To avoid weird behaviour, we require a time delta of MIN_DELTA_TIME_MILLIS\n // before allowing the zoom to be triggered.\n viewStore.threeView?.handleZoom(reactEvent);\n } else {\n debouncedMove(reactEvent);\n }\n };\n\n canvasContainer.current.addEventListener('wheel', wheelEventListener, {\n passive: false,\n });\n return () => {\n canvasContainer.current?.removeEventListener('wheel', wheelEventListener);\n };\n }, [canvasContainer.current]);\n\n const cursor = 'auto';\n\n const theme = useTheme();\n\n return (\n <>\n \n \n \n \n \n\n {/* Bottom Left filler */}\n {viewStore.showRulers ? (\n \n \n \n ) : null}\n\n {/* Toolbar icon */}\n e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n >\n \n \n (viewStore.toolbarOpen = !viewStore.toolbarOpen)}\n >\n {viewStore.toolbarOpen ? (\n \n ) : (\n \n )}\n \n \n \n \n\n {/* Toolbar */}\n \n \n \n \n \n\n {/* Canvas */}\n \n \n \n \n \n \n {/* Footer */}\n \n {/* Nodes/Edges */}\n \n Nodes: {numberFormatter(viewStore.totalSelectedNodes)} /{' '}\n {numberFormatter(viewStore.totalNodes)}\n \n \n Edges: {numberFormatter(viewStore.totalSelectedEdges)} /{' '}\n {numberFormatter(viewStore.totalEdges)}\n \n\n {/* Mouse Coordinates */}\n \n \n >\n );\n});\n\n/**\n * The displayed (intrinsic) x/y coordinates of the mouse.\n */\nconst NodeXYCoordinates = observer(({ viewStore }: ViewProps): JSX.Element => {\n let x = dashboardStore.appMouseX;\n let y = dashboardStore.appMouseY;\n\n if (viewStore.threeView) {\n const { x: xGl, y: yGl } = viewStore.threeView.pixelsToGLSpace(x, y);\n if (xGl >= -1 && xGl <= 1 && yGl >= -1 && yGl <= 1) {\n const projected = viewStore.threeView.getProjectedCoordinates(xGl, yGl);\n const intrinsic = viewStore.threeView.toIntrinsicCoordinates(projected);\n x = intrinsic.x;\n y = intrinsic.y;\n } else {\n x = 0;\n y = 0;\n }\n }\n\n return (\n \n x:\n \n {viewStore.datetimeFormat\n ? new Date(x).toLocaleDateString()\n : numberFormatter(x)}\n \n y:\n {numberFormatter(y)}\n \n );\n});\n\nexport default GraphView;\n","\"use client\";\n\nimport createSvgIcon from './utils/createSvgIcon';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 20H4v-4h4v4zm0-6H4v-4h4v4zm0-6H4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4z\"\n}), 'GridOn');","\"use client\";\n\nimport createSvgIcon from './utils/createSvgIcon';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M15 21h2v-2h-2v2zm4 0h2v-2h-2v2zM7 21h2v-2H7v2zm4 0h2v-2h-2v2zm8-4h2v-2h-2v2zm0-4h2v-2h-2v2zM3 3v18h2V5h16V3H3zm16 6h2V7h-2v2z\"\n}), 'BorderStyle');","\"use client\";\n\nimport createSvgIcon from './utils/createSvgIcon';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon( /*#__PURE__*/_jsx(\"path\", {\n d: \"M8 4v1.45l2 2V4h4v4h-3.45l2 2H14v1.45l2 2V10h4v4h-3.45l2 2H20v1.45l2 2V4c0-1.1-.9-2-2-2H4.55l2 2H8zm8 0h4v4h-4V4zM1.27 1.27 0 2.55l2 2V20c0 1.1.9 2 2 2h15.46l2 2 1.27-1.27L1.27 1.27zM10 12.55 11.45 14H10v-1.45zm-6-6L5.45 8H4V6.55zM8 20H4v-4h4v4zm0-6H4v-4h3.45l.55.55V14zm6 6h-4v-4h3.45l.55.54V20zm2 0v-1.46L17.46 20H16z\"\n}), 'GridOff');","import React, { useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Box, IconButton, Popover, Tooltip } from '@mui/material';\nimport { GridOn, GridOff, BorderStyle } from '@mui/icons-material';\nimport ViewStore from '../stores/GraphViewStore';\n\nconst icon = (showAxes: boolean, showGrid: boolean) => {\n if (showAxes && showGrid) {\n return ;\n } else if (showAxes) {\n return ;\n } else {\n return ;\n }\n};\n\nconst GridOptionsButton = observer(\n ({ viewStore }: { viewStore: ViewStore }): JSX.Element => {\n const styles = {\n container: {\n display: 'flex',\n justifyContent: 'center',\n },\n iconButton: {\n padding: 0,\n backgroundColor: 'transparent',\n fontSize: 18,\n },\n };\n\n const [popoverOpen, setPopoverOpen] = useState(false);\n const [anchorEl, setAnchorEl] = useState(null);\n\n return (\n \n \n ) => {\n setAnchorEl(event.currentTarget);\n setPopoverOpen(true);\n }}\n size=\"large\"\n >\n {icon(viewStore.showRulers, viewStore.showGrid)}\n \n \n\n setPopoverOpen(false)}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'center',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'center',\n }}\n >\n \n \n {\n viewStore.updateViewProperties({\n showAxes: false,\n showGrid: false,\n });\n setPopoverOpen(false);\n }}\n size=\"large\"\n >\n \n \n \n \n {\n viewStore.updateViewProperties({\n showAxes: true,\n showGrid: false,\n });\n setPopoverOpen(false);\n }}\n size=\"large\"\n >\n \n \n \n \n {\n viewStore.updateViewProperties({\n showGrid: true,\n showAxes: true,\n });\n setPopoverOpen(false);\n }}\n size=\"large\"\n >\n \n \n \n \n \n \n );\n },\n);\nexport default GridOptionsButton;\n","import React from 'react';\nimport { fetchAuthSession } from 'aws-amplify/auth';\nimport { useTheme } from '@mui/material/styles';\nimport { observer } from 'mobx-react-lite';\nimport { useNavigate } from 'react-router-dom';\nimport { Box, IconButton, Tooltip, Typography } from '@mui/material';\nimport {\n SmsOutlined,\n GridView,\n QuestionMark,\n VpnKeyOutlined,\n ExitToAppOutlined,\n} from '@mui/icons-material';\nimport zIndex from '@mui/material/styles/zIndex';\nimport MenuBar from './MenuBar';\nimport ConodeLogo from './ConodeLogo';\nimport EditBar from './EditBar';\nimport NodeEditBar from './NodeEditBar';\nimport Avatar from './UserAvatar';\nimport SwitchButton from './lib/SwitchButton';\nimport { AppProps } from '../types/app';\nimport routeStore from '../stores/RouteStore';\nimport ErrorStore from '../stores/ErrorStore';\nimport dashboardStore from '../stores/DashboardStore';\nimport Actions from '../actions/actions';\nimport { BackgroundTasksButton } from './RunningTasks';\nimport { MonitoredTasks } from '../services/TaskService';\n\nconst pageSwitchOptions = [\n { label: 'View', value: 'view', icon: },\n { label: 'Ask', value: 'chat', icon: },\n];\n\nconst Header = observer(({ signOut, user }: AppProps) => {\n const theme = useTheme();\n const navigate = useNavigate();\n\n const userMenuActions = [\n {\n type: 'custom',\n shortLabel: 'User Info',\n disabled: true,\n action: () => {},\n customComponent: () => (\n \n {user.username}\n \n {dashboardStore.userEmailAddress}\n \n \n ),\n },\n {\n type: 'divider',\n },\n {\n shortLabel: 'Copy Token Key',\n icon: () => ,\n disabled: false,\n action: () => {\n fetchAuthSession().then((session) => {\n const token = session.tokens?.accessToken?.toString() ?? '';\n navigator.clipboard.writeText(`\"${token}\"`);\n ErrorStore.setSuccess('API Authorization Token copied to clipboard');\n });\n },\n },\n {\n shortLabel: 'Log out',\n disabled: false,\n icon: () => ,\n action: async () => {\n const expireSuccess = await dashboardStore.expireAllSessions();\n if (!expireSuccess) {\n return;\n }\n // Call the original sign-out function\n if (signOut) {\n dashboardStore.closeGraphStore();\n signOut();\n navigate('/');\n }\n },\n },\n ];\n\n const { isChatPage, isGraphPage } = dashboardStore;\n\n const headerConfig = {\n showToolBar: isGraphPage,\n showPageSwitchButton: isChatPage || isGraphPage,\n showHelpMenu: !isChatPage,\n };\n\n const styles = {\n toolbar: {\n display: 'flex',\n alignContent: 'baseline',\n justifyContent: 'space-between',\n margin: `${theme.spacing(2)} ${theme.spacing(3)}`,\n zIndex: zIndex.appBar,\n },\n toolbarLeft: {\n display: 'flex',\n },\n toolbarCenter: {\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n marginLeft: 'auto',\n },\n menuBar: {\n display: 'flex',\n alignItems: 'center',\n },\n editBar: {\n display: 'flex',\n alignItems: 'center',\n marginRight: '15px',\n },\n nodeEditBar: {\n display: 'flex',\n alignItems: 'center',\n marginLeft: '15px',\n },\n toolbarRight: {\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n marginLeft: 'auto',\n },\n iconButton: {\n width: '30px',\n height: '30px',\n padding: theme.spacing(2),\n border: `1px solid ${theme.palette.grey[900]}`,\n overflow: 'hidden',\n color: theme.palette.primary.main,\n backgroundColor: theme.palette.grey[100],\n },\n };\n\n const onSwitchChange = () => {\n const urlParams = new URLSearchParams(window.location.search);\n const graphId = urlParams.get('graphId');\n const viewIds = urlParams.getAll('viewId');\n if (!graphId) {\n throw new Error('Graph ID is missing in the URL');\n }\n\n const basePath = dashboardStore.isGraphPage ? 'chat' : 'graph';\n const extraParam = dashboardStore.isChatPage ? '&from=chat' : '';\n const allViewIds = [...viewIds, ...routeStore.hiddenViewIds];\n\n navigate(\n `/${basePath}?graphId=${graphId}${extraParam}&${allViewIds\n .map((id) => `viewId=${id}`)\n .join('&')}`,\n );\n };\n\n return (\n \n \n \n navigate('/')}\n size=\"large\"\n >\n \n \n \n \n {headerConfig.showToolBar && (\n \n \n \n \n \n \n \n \n \n \n \n \n \n )}\n \n 0 ? 'visible' : 'hidden',\n width: 'fit-content',\n height: 'fit-content',\n }}\n >\n \n \n {headerConfig.showPageSwitchButton && (\n \n \n \n )}\n {headerConfig.showHelpMenu && (\n \n \n \n \n \n \n \n )}\n \n {\n dashboardStore.generalMenuStore.openMenu(\n e.currentTarget,\n userMenuActions,\n );\n e.stopPropagation();\n }}\n >\n \n \n \n \n \n );\n});\n\nexport default Header;\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { InAppHelpItem } from '../in-app-help/InAppHelp';\nimport InAppHelpStore from '../stores/InAppHelpStore';\nimport NavigationStore from '../stores/NavigationStore';\nimport RightDrawerStore from '../stores/RightDrawerStore';\nimport dashboardStore from '../stores/DashboardStore';\nimport GraphViewStore from '../stores/GraphViewStore';\n\nimport Tooltip from '@mui/material/Tooltip';\nimport { Box, Typography, Button, IconButton, useTheme } from '@mui/material';\n\nimport CloseIcon from '@mui/icons-material/Close';\nimport makeStyles from '@mui/styles/makeStyles';\nimport HelpOutlineOutlinedIcon from '@mui/icons-material/HelpOutlineOutlined';\n\nconst MEDIA_WIDTH = 450;\n\n/**\n * Todo: makeStyles is deprecated. Replace with sx prop.\n * Todo: Currently, the entire tooltip is rendered when the tooltip is closed. Should remove from\n * the DOM entirely.\n */\nconst HelperToolTip = observer(\n // eslint-disable-next-line react/display-name\n React.forwardRef(\n (\n {\n children,\n inAppHelpItem,\n inAppHelpStore,\n allowOpen,\n childrenSx,\n tooltipSx,\n store,\n }: {\n children: JSX.Element;\n inAppHelpItem: InAppHelpItem;\n inAppHelpStore: InAppHelpStore;\n allowOpen?: boolean | undefined;\n childrenSx?: React.CSSProperties | undefined;\n tooltipSx?: React.CSSProperties | undefined;\n store?: NavigationStore | RightDrawerStore | undefined;\n },\n ref,\n ): JSX.Element => {\n const theme = useTheme();\n\n // Check if the tooltip should be open\n const isOpen =\n allowOpen === undefined\n ? inAppHelpItem.enabled\n : allowOpen && inAppHelpItem.enabled;\n\n // Make sure that the store is open if the tooltip is open\n if (isOpen && store !== undefined && !store.open) {\n store.open = true;\n }\n\n const styles = {\n root: {\n bgcolor: 'transparent',\n color: 'black',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'start',\n gap: '1em',\n margin: '5px',\n },\n textBox: {\n display: 'flex',\n justifyContent: 'space-between',\n flexDirection: 'column',\n },\n title: {\n fontWeight: 'bold',\n fontSize: '14px',\n color: theme.palette.base.main,\n marginBottom: theme.spacing(2),\n },\n textBody: {\n color: theme.palette.base.main,\n },\n iconButton: {\n position: 'absolute',\n top: 0,\n color: theme.palette.base.main,\n margin: '8px',\n },\n button: {\n marginLeft: '4px',\n },\n media: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n flexDirection: 'row',\n },\n footer: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n flexDirection: 'row',\n marginTop: theme.spacing(2),\n },\n childrenOutline: {\n border: isOpen ? `2px solid ${theme.palette.grey[700]}` : 'none',\n display: 'inherit',\n borderRadius: `${theme.shape.borderRadius}px`,\n backgroundColor: 'transparent',\n ...childrenSx,\n },\n };\n\n const majorTooltipStyles = makeStyles((theme) => ({\n arrow: {\n '&:before': {\n boxShadow: '0px 0px 2px rgba(0, 0, 0, 0.2)',\n },\n },\n tooltip: {\n padding: theme.spacing(3),\n color: theme.palette.grey[700],\n boxShadow: '0px 0px 5px rgba(0, 0, 0, 0.2)',\n maxWidth: `${MEDIA_WIDTH + 25}px`,\n ...tooltipSx,\n },\n }));\n\n const minorTooltipStyles = makeStyles((theme) => ({\n arrow: {\n '&:before': {\n border: `1px solid ${theme.palette.base.main}`,\n },\n },\n tooltip: {\n border: `1px solid ${theme.palette.base.main}`,\n },\n }));\n\n // Define styles for tooltips\n const majorStyles = majorTooltipStyles();\n const minorStyles = minorTooltipStyles();\n\n const nextButton = () => {\n const hasGraphView =\n !!dashboardStore.openViews.length &&\n dashboardStore.openViews.some(\n (view) => view instanceof GraphViewStore,\n );\n\n return (\n \n \n \n \n \n );\n };\n\n return (\n \n \n {/* Title of the in App Help Tooltip */}\n \n {inAppHelpItem.title}\n \n {/* Button to read more in the docs */}\n \n {\n window.open(inAppHelpItem.link, '_blank');\n }}\n >\n \n \n \n {/* Button to close onboarding help */}\n \n {\n inAppHelpStore.stop();\n }}\n >\n \n \n \n {/* Body of the in App Help Tooltip */}\n \n {inAppHelpItem.body.split('\\n').map((line, index) => (\n \n {' '}\n {line}\n \n ))}\n \n \n {/* Media of the in App Help Tooltip */}\n \n
\n \n {/* Buttons and status of the in App Help Tooltip */}\n \n \n {`${\n inAppHelpStore.getActiveItemIndex() + 1\n } of ${inAppHelpStore.getItemsCount()}`}\n \n \n {!inAppHelpStore.hasJustStarted() && (\n \n )}\n {!inAppHelpStore.hasJustFinished() && nextButton()}\n {inAppHelpStore.hasJustFinished() && (\n \n )}\n \n \n \n }\n >\n {children}\n \n );\n },\n ),\n);\n\nexport default HelperToolTip;\n","import React from 'react';\nimport { observer } from 'mobx-react-lite';\nimport {\n Box,\n Button,\n Typography,\n useTheme,\n Card,\n CardContent,\n CardMedia,\n CardActions,\n} from '@mui/material';\nimport dashboardStore from '../../stores/DashboardStore';\nimport { withDashboardBackdrop } from '../../utils/backdrop';\nimport { textEllipsis } from '../../styles/common';\nimport { GraphTableData, convertToGraphMeta } from './GraphTable';\n\ntype ExampleGraphCardProps = {\n graph: GraphTableData;\n handleClick: ({ id, path }: { id: string; path: string }) => void;\n};\n\nconst ExampleGraphCard = ({ graph, handleClick }: ExampleGraphCardProps) => {\n const theme = useTheme();\n const [isHovered, setIsHovered] = React.useState(false);\n\n const styles = {\n cardContainer: {\n position: 'relative',\n cursor: 'pointer',\n width: '100%',\n height: 'max-content',\n transition: '.2s',\n boxShadow: 'none',\n borderRadius: `${theme.shape.borderRadius}px`,\n border: `1px solid ${theme.palette.base.main}`,\n '&:hover': {\n border: `1px solid ${theme.palette.primary.main}`,\n },\n },\n cardMedia: {\n height: 140,\n borderRadius: '5px 5px 0 0',\n boxSizing: 'border-box',\n padding: '16px',\n paddingBottom: 0,\n },\n cardTitle: {\n ...textEllipsis({ lines: 1 }),\n fontWeight: 'bold',\n },\n cardSubTitle: {\n fontSize: '10px',\n fontWeight: '600',\n paddingBottom: '10px',\n ...textEllipsis({ lines: 1 }),\n },\n cardDescription: {\n ...textEllipsis({ lines: 3 }),\n height: '50px',\n },\n cardActions: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n p: theme.spacing(2, 3),\n gap: 2,\n width: '100%',\n flexWrap: 'wrap',\n // remove mui default padding\n '&.MuiCardActions-root>:not(:first-of-type)': {\n m: 0,\n },\n },\n actionButton: {\n flex: 1,\n whiteSpace: 'nowrap',\n minWidth: '100px',\n },\n hoveredTypography: {\n opacity: isHovered ? 1 : 0,\n color: theme.palette.primary.main,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n pb: theme.spacing(1),\n transition: '.2s',\n },\n };\n\n const hasDocLinks =\n graph.docLinks !== undefined && graph.docLinks?.length > 0;\n\n return (\n setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() => handleClick({ id: graph.id, path: 'graph' })}\n >\n {\n e.currentTarget.src = require('../../images/no-media.png');\n e.currentTarget.style.objectFit = 'contain';\n }}\n />\n \n \n {graph.name}\n \n \n {graph.tags?.join(' · ') || '-'}\n \n \n {graph.description || 'No description available'}\n \n \n \n \n \n \n \n Open Graph\n \n \n );\n};\n\nexport const ExampleGraphTable = observer((): JSX.Element => {\n const theme = useTheme();\n\n const graphs = convertToGraphMeta(\n dashboardStore.graphs.filter((g) => g.isBlueprint),\n );\n\n const handleClick = withDashboardBackdrop(\n async ({ path, id }: { path: string; id: string }) => {\n const name = undefined; // keep the existing name + ' (${user} copy)'\n const newGraphMetaData = await dashboardStore.cloneGraphById(\n id,\n name,\n true,\n );\n if (newGraphMetaData) {\n dashboardStore.routeStore.navigateTo(\n `/${path}?graphId=${newGraphMetaData.id}`,\n );\n }\n },\n );\n\n const styles = {\n root: {\n label: 'example-graph-table',\n width: '100%',\n },\n graphsContainer: {\n height: `calc(100vh - 200px)`,\n width: '100%',\n paddingRight: '1em',\n overflow: 'auto',\n [theme.breakpoints.down('xl')]: {\n gridTemplateColumns: 'repeat(4, 1fr)',\n },\n [theme.breakpoints.down('lg')]: {\n gridTemplateColumns: 'repeat(3, 1fr)',\n },\n [theme.breakpoints.down('md')]: {\n gridTemplateColumns: 'repeat(2, 1fr)',\n },\n },\n };\n\n return (\n \n {graphs.length ? (\n \n {graphs.map((graph) => (\n \n ))}\n \n ) : (\n \n No example graphs yet\n \n )}\n \n );\n});\n","import React, { useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { useNavigate } from 'react-router-dom';\nimport { GraphId, GraphMetaData } from '../../types/app';\nimport {\n Box,\n Button,\n IconButton,\n Tooltip,\n Typography,\n useTheme,\n Portal,\n} from '@mui/material';\nimport {\n DeleteOutlineOutlined,\n MoreHorizOutlined,\n Add,\n EditOutlined,\n SmsOutlined,\n} from '@mui/icons-material';\nimport {\n DataGrid,\n GridEventListener,\n GridRenderCellParams,\n GridToolbarQuickFilter,\n GridFilterItem,\n GridToolbarQuickFilterProps,\n} from '@mui/x-data-grid';\nimport Actions from '../../actions/actions';\nimport dashboardStore from '../../stores/DashboardStore';\nimport AlertDialogStore from '../../stores/AlertDialogStore';\nimport Avatar from '../UserAvatar';\nimport { LoadingBackdrop } from '../../components/LoadingBackdrop';\nimport { dateFormatter, numberFormatter } from '../../utils/utils';\n\nexport type GraphTableData = {\n id: GraphId;\n name: string | undefined;\n description: string | undefined;\n tags: string[] | undefined;\n thumbnail: string | undefined;\n nodeCount: number | undefined;\n edgeCount: number | undefined;\n owner: string | undefined;\n groups: string[] | undefined;\n createdAt: Date | undefined;\n updatedAt: Date | undefined;\n docLinks: string[] | undefined;\n};\n\nconst tooltipProps = {\n enterDelay: 700,\n enterNextDelay: 700,\n arrow: true,\n};\n\nexport function convertToGraphMeta(graphs: GraphMetaData[]): GraphTableData[] {\n return graphs.map((graph) => ({\n id: graph.id,\n name: graph.name,\n description: graph.description,\n tags: graph.tags,\n thumbnail: graph.thumbnail,\n owner: graph.ownerEmail,\n groups: graph.groups,\n nodeCount: graph.nodeCount,\n edgeCount: graph.edgeCount,\n createdAt: graph.createdAt ? new Date(graph.createdAt * 1000) : undefined,\n updatedAt: graph.updatedAt ? new Date(graph.updatedAt * 1000) : undefined,\n docLinks: graph.docLinks,\n }));\n}\n\ninterface TableFilterFieldProps {\n quickFilterProps: GridToolbarQuickFilterProps;\n}\n\nconst TableFilterField = ({ quickFilterProps }: TableFilterFieldProps) => {\n const theme = useTheme();\n\n return (\n document.getElementById('table-filter-field')!}>\n \n \n );\n};\n\nconst UploadButton = () => (\n \n }\n color=\"primary\"\n variant=\"contained\"\n onClick={Actions.uniqueActions.fileUpload.action}\n size=\"small\"\n sx={{\n fontWeight: 'bold',\n textTransform: 'none',\n maginTop: 0,\n }}\n >\n Upload Data\n \n \n);\n\ninterface GraphTableProps {\n initialFilter?: GridFilterItem[];\n}\n\nexport const GraphTable = observer(\n ({ initialFilter }: GraphTableProps): JSX.Element => {\n const theme = useTheme();\n const navigate = useNavigate();\n const [checkedGraphIds, setCheckedGraphIds] = useState([]);\n const [filterValues, setFilterValues] = useState();\n const graphs = convertToGraphMeta(\n dashboardStore.graphs.filter((g) => !g.isBlueprint),\n );\n\n const { shareGraph, copyGraphLink, duplicateGraph, deleteGraph } =\n Actions.uniqueActions;\n\n const getMenuItems = (menuGraphId: GraphId) => [\n {\n ...shareGraph,\n icon: () => shareGraph.icon,\n action: () => menuGraphId && shareGraph.action(menuGraphId),\n },\n {\n ...copyGraphLink,\n icon: () => copyGraphLink.icon,\n action: () => menuGraphId && copyGraphLink.action(menuGraphId),\n },\n {\n shortLabel: 'Rename',\n icon: () => ,\n disabled: false,\n action: () => {\n if (!menuGraphId) return;\n const store = dashboardStore.renameGraphDialogStore;\n store.openDialog(menuGraphId);\n },\n },\n {\n ...duplicateGraph,\n icon: () => duplicateGraph.icon,\n disabled: false,\n action: () => {\n if (!menuGraphId) return;\n dashboardStore.duplicateGraphById(menuGraphId);\n dashboardStore.loadAndStoreGraphs();\n },\n },\n {\n ...deleteGraph,\n icon: () => deleteGraph.icon,\n disabled:\n dashboardStore.graphs.find((item) => item.id === menuGraphId)\n ?.ownerEmail !== dashboardStore.userEmailAddress,\n action: () => {\n if (!menuGraphId) return;\n AlertDialogStore.yesNoAlert(\n 'Are you sure you want to delete this graph?',\n async () => {\n await dashboardStore.deleteGraphByIds([menuGraphId]);\n },\n );\n },\n },\n ];\n\n const columns = [\n {\n field: 'name',\n headerName: 'Graph name',\n flex: 2,\n editable: false,\n renderCell: (params: GridRenderCellParams) => (\n \n {params.value}\n \n ),\n },\n {\n field: 'owner',\n headerName: 'Owner',\n flex: 1,\n editable: false,\n renderCell: (params: GridRenderCellParams) => (\n \n \n \n \n \n ),\n },\n {\n field: 'groups',\n headerName: 'Shared with',\n flex: 1,\n editable: false,\n renderCell: (params: GridRenderCellParams) => (\n \n {params.value}\n \n ),\n },\n {\n field: 'nodeCount',\n headerName: 'Nodes',\n flex: 1,\n editable: false,\n renderCell: (params: GridRenderCellParams) => {\n let value = numberFormatter(params.value ?? 0);\n if (value === '0') value = '-';\n\n return (\n \n {value}\n \n );\n },\n },\n {\n field: 'createdAt',\n type: 'dateTime',\n headerName: 'Created',\n flex: 1,\n editable: false,\n renderCell: (params: GridRenderCellParams) => (\n \n \n {dateFormatter(params.value)}\n \n \n ),\n },\n {\n field: 'updatedAt',\n type: 'dateTime',\n headerName: 'Last modified',\n flex: 1,\n editable: false,\n renderCell: (params: GridRenderCellParams) => (\n \n \n {dateFormatter(params.value)}\n \n \n ),\n },\n {\n field: 'options',\n type: 'options',\n headerName: 'Options',\n flex: 1,\n editable: false,\n renderCell: (params: GridRenderCellParams) => {\n return (\n <>\n \n {\n e.stopPropagation();\n navigate(`/chat?graphId=${params.row.id}`);\n }}\n >\n \n \n \n \n {\n const menuItems = getMenuItems(params.row.id);\n dashboardStore.generalMenuStore.openMenu(\n e.currentTarget,\n menuItems,\n );\n e.stopPropagation();\n }}\n >\n \n \n \n >\n );\n },\n },\n ];\n\n const handleRowClick: GridEventListener<'rowClick'> = (params) => {\n navigate(`/graph?graphId=${params.row.id}`);\n };\n\n const handleDeleteGraphByIds = () => {\n AlertDialogStore.yesNoAlert(\n 'Are you sure you want to delete the selected graphs?',\n async () => {\n await dashboardStore.deleteGraphByIds(checkedGraphIds);\n setCheckedGraphIds([]);\n },\n );\n };\n\n return (\n \n {/* Table Toolbar */}\n \n {checkedGraphIds.length > 0 && (\n \n \n \n )}\n \n \n \n \n {/* Table */}\n \n setCheckedGraphIds(ids as GraphId[])\n }\n checkboxSelection\n rows={graphs}\n columns={columns}\n slots={{\n toolbar: TableFilterField,\n }}\n initialState={{\n pagination: {\n paginationModel: {\n pageSize: 50,\n },\n },\n filter: {\n filterModel: {\n items: [...(initialFilter ?? [])],\n quickFilterExcludeHiddenColumns: true,\n },\n },\n sorting: {\n sortModel: [{ field: 'updatedAt', sort: 'desc' }],\n },\n }}\n filterModel={{\n items: [...(initialFilter ?? [])],\n quickFilterValues: filterValues,\n quickFilterExcludeHiddenColumns: true,\n }}\n onFilterModelChange={(newModel) => {\n if (newModel.items) {\n const filterItems = newModel.items as GridFilterItem[];\n const values = filterItems.map((item) => item.value);\n setFilterValues(values);\n }\n }}\n pageSizeOptions={[25, 50, 100]}\n columnHeaderHeight={35}\n onRowClick={handleRowClick}\n slotProps={{\n toolbar: {\n showQuickFilter: true,\n quickFilterProps: {\n variant: 'outlined',\n placeholder: 'Search',\n onChange: (event) => setFilterValues([event.target.value]),\n },\n },\n }}\n sx={{\n cursor: 'pointer',\n userSelect: 'none',\n border: 'none',\n '& .MuiDataGrid-cell:focus': {\n outline: 'none',\n },\n '& .MuiDataGrid-cell:focus-within': {\n outline: 'none',\n },\n '& .MuiDataGrid-columnHeaders': {\n background: theme.palette.grey[200],\n borderRadius: `${theme.shape.borderRadius}px`,\n fontSize: '12px',\n border: 'none',\n },\n '& .MuiDataGrid-columnHeader:focus-within': {\n outline: 'none',\n },\n '.MuiDataGrid-columnSeparator': {\n display: 'none',\n },\n '.MuiDataGrid-overlay': {\n background: theme.palette.common.white,\n },\n borderLeft: 'none',\n borderRight: 'none',\n }}\n localeText={{\n footerRowSelected: () => '',\n }}\n />\n \n \n \n );\n },\n);\n","import React from 'react';\nimport { useNavigate } from 'react-router';\nimport { useSearchParams } from 'react-router-dom';\nimport {\n Box,\n ListSubheader,\n List,\n ListItemButton,\n ListItemIcon,\n Collapse,\n Typography,\n useTheme,\n alpha,\n} from '@mui/material';\nimport {\n SchoolOutlined,\n OpenInNew,\n ExpandMore,\n ExpandLess,\n} from '@mui/icons-material';\nimport { getMenuItems, IMenuItem } from '../../configs/homeMenuConfig';\n\ninterface MenuSidebarItemProps {\n item: IMenuItem;\n sx?: object;\n}\n\nconst MIN_SIDE_MENU_WIDTH = 260;\n\nconst MenuSidebarItem = ({ item, sx }: MenuSidebarItemProps) => {\n const theme = useTheme();\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const [open, setOpen] = React.useState(false);\n\n const { label, items, link } = item || {};\n const hasItems = items?.length > 0;\n const isDocs = link?.startsWith('/docs');\n const tabParam = searchParams.get('tab') || 'all';\n const isCurrentTab = link?.includes(tabParam);\n\n const styles = {\n icon: {\n minWidth: '30px',\n color: theme.palette.primary.main,\n fontSize: '16px',\n },\n };\n\n const onClick = () => {\n if (hasItems) setOpen(!open);\n if (isDocs) {\n window.open(link, '_blank');\n } else if (link) {\n navigate(link);\n }\n };\n\n const renderIcon = (sx: object) => {\n if (isDocs) {\n return ;\n }\n if (hasItems) return open ? : ;\n return null;\n };\n\n return (\n \n \n \n \n {item.icon ? item.icon : }\n \n {label}\n \n {renderIcon(styles.icon)}\n \n \n \n {items.map((child: IMenuItem) => (\n \n ))}\n
\n \n \n );\n};\n\nexport default function MenuSidebar() {\n const theme = useTheme();\n const menuItems = getMenuItems();\n\n const styles = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n list: {\n minWidth: MIN_SIDE_MENU_WIDTH,\n },\n subheader: {\n backgroundColor: 'transparent',\n fontWeight: 'bold',\n color: 'black',\n display: 'flex',\n alignItems: 'center',\n },\n listItemIcon: {\n minWidth: '24px',\n fontSize: '16px',\n color: theme.palette.primary.main,\n },\n };\n\n return (\n \n {Object.entries(menuItems).map(([key, value]) => (\n \n ))}\n \n );\n}\n","import React, { useState } from 'react';\nimport { observer } from 'mobx-react-lite';\nimport { Box, IconButton, Popover, Tooltip } from '@mui/material';\nimport { actionToButton } from './View';\nimport Actions from '../actions/actions';\n\nimport { LabelOutlined } from '@mui/icons-material';\nimport dashboardStore from '../stores/DashboardStore';\n\nconst LabelButton = observer((): JSX.Element => {\n const styles = {\n container: {\n display: 'flex',\n justifyContent: 'center',\n },\n iconButton: {\n padding: 0,\n backgroundColor: 'transparent',\n fontSize: 18,\n },\n };\n\n const [showTooltip, setShowTooltip] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n const [anchorEl, setAnchorEl] = useState(null);\n\n return (\n \n \n ) => {\n setAnchorEl(event.currentTarget);\n setPopoverOpen(true);\n }}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => {\n setShowTooltip(false);\n }}\n size=\"large\"\n disabled={!dashboardStore.currentGraphStore?.anyNodesSelected}\n >\n \n \n \n\n setPopoverOpen(false)}\n anchorEl={anchorEl}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'center',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'center',\n }}\n >\n \n \n {actionToButton(\n Actions.uniqueActions.turnLabelsForSelectedNodesOff,\n )}\n \n \n {actionToButton(Actions.uniqueActions.turnLabelsForSelectedNodesOn)}\n \n \n \n \n );\n});\n\nexport default LabelButton;\n","import React from 'react';\nimport { NodeSelectionBox } from './lib/NodeSelectionBox';\nimport dashboardStore from '../stores/DashboardStore';\nimport { observer } from 'mobx-react-lite';\n\nexport const LinearFit = observer((): JSX.Element => {\n const fitStore = dashboardStore.rightDrawerStore.fitStore;\n return (\n <>\n \n \n >\n );\n});\n","import React from 'react';\nimport { useTheme, Button, Typography } from '@mui/material';\nimport { IconWrapper } from '../../icons/IconWrapper';\nimport { LlmActionIconContent } from '../../icons/LlmChatIcons';\n\ninterface ActionButtonProps {\n onClick: () => void;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nconst ActionButton = ({\n onClick,\n disabled = false,\n children,\n}: ActionButtonProps) => {\n const theme = useTheme();\n return (\n \n );\n};\n\nexport default ActionButton;\n","import React, { useEffect, useState } from 'react';\nimport { Box, Typography, useTheme } from '@mui/material';\nimport { LLMChatState } from '../../types/app';\n\nconst SystemMessages = [\n 'Thinking',\n 'Retrieving',\n 'Analyzing',\n 'Finalizing response',\n];\n\nconst AwaitingDot = ({\n text,\n state,\n typographySx,\n}: {\n text?: string | null;\n state: LLMChatState;\n typographySx?: object;\n}) => {\n const theme = useTheme();\n const [thinkingStep, setThinkingStep] = useState(0);\n\n useEffect(() => {\n if (state === 'systemThinking') {\n setThinkingStep(0);\n\n const interval = setInterval(() => {\n setThinkingStep((prev) => {\n if (prev < SystemMessages.length - 1) {\n return prev + 1;\n } else {\n clearInterval(interval);\n return prev;\n }\n });\n }, 3000);\n\n return () => clearInterval(interval);\n }\n }, [state]);\n\n let displayText = text;\n if (!text) {\n if (state === 'systemThinking') {\n displayText = SystemMessages[thinkingStep];\n } else if (state === 'actionExecuting') {\n displayText = 'Analyzing';\n }\n }\n\n if (!displayText) return null;\n\n const dotSize = 12;\n\n const styles = {\n root: {\n label: 'awaiting-dot-root',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-start',\n gap: 2,\n mb: theme.spacing(3),\n },\n dot: {\n label: 'awaiting-dot-dot',\n animation: 'scale .8s ease-in-out infinite alternate',\n width: dotSize,\n height: dotSize,\n minHeight: dotSize,\n minWidth: dotSize,\n borderRadius: '50%',\n backgroundColor: theme.palette.primary.main,\n '@keyframes scale': {\n '0%': {\n transform: 'scale(1)',\n },\n '50%': {\n transform: 'scale(1)',\n },\n '100%': {\n transform: 'scale(0.7)',\n },\n },\n },\n };\n\n return (\n \n \n {displayText}\n {'...'}\n \n \n \n );\n};\n\nexport default AwaitingDot;\n","import React, { useState, useMemo, useEffect } from 'react';\nimport { Box, Typography, useTheme, alpha } from '@mui/material';\nimport Markdown, { RuleType } from 'markdown-to-jsx';\nimport TeX from '@matejmazur/react-katex';\nimport { useTypewriterEffect } from '../../hooks/useTypewriterEffect';\nimport CopyButton from '../lib/CopyButton';\nimport CodeEditor from './CodeEditor';\nimport { formatLLMResponse } from '../../utils/utils';\nimport 'katex/dist/katex.min.css';\n\ntype ChatMessageProps = {\n text: string | undefined;\n type?: string;\n containerRef: React.RefObject | null;\n additionalContent?: React.ReactNode;\n helperTexts?: string[];\n hasNewMessage: boolean;\n isLastMessage: boolean;\n onTypingComplete: () => void;\n typographySx?: object;\n markdownRules?: object;\n variant?: string;\n};\n\ntype MessageActionMenuProps = {\n type: string;\n children: React.ReactNode | undefined;\n show?: boolean;\n};\n\nconst MessageActionMenu = ({\n type,\n children,\n show,\n}: MessageActionMenuProps) => {\n const theme = useTheme();\n\n return (\n \n {children}\n \n );\n};\n\nconst SystemMessageBox = ({\n text,\n hasNewMessage,\n isLastMessage,\n containerRef,\n onTypingComplete,\n additionalContent,\n typographySx,\n markdownRules,\n variant,\n}: ChatMessageProps) => {\n const theme = useTheme();\n const [hovered, setHovered] = useState(false);\n\n const { displayedText, isTypingFinished } = useTypewriterEffect(\n text as string,\n hasNewMessage && isLastMessage,\n onTypingComplete,\n );\n\n const isFullScreen = variant === 'fullscreen';\n const formattedText = formatLLMResponse(displayedText);\n\n const styles = {\n agentMessageBox: {\n label: 'chat-message-agentMessageBox',\n width: '100%',\n position: 'relative',\n backgroundColor: alpha(theme.palette.common.white, 1),\n borderRadius: '20px',\n border: `1px solid ${theme.palette.grey[300]}`,\n p: isFullScreen ? theme.spacing(3) : theme.spacing(2, 3),\n },\n };\n\n const iconProps = {\n size: 14,\n contentSize: 14,\n strokeWidth: 1,\n stroke: theme.palette.grey[800],\n };\n\n useEffect(() => {\n const scrollToLatestMessage = () => {\n if (!containerRef) return;\n\n setTimeout(() => {\n if (containerRef.current)\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }, 0);\n };\n\n scrollToLatestMessage();\n }, [displayedText]);\n\n const showActionMenu = isTypingFinished && (hovered || isLastMessage);\n\n return (\n setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n \n \n \n {node.text}\n \n );\n }\n\n return (\n \n );\n }\n return next();\n },\n overrides: {\n ...markdownRules,\n // **Inline Code**\n code: ({ children }: { children: React.ReactNode }) => (\n \n {children}\n \n ),\n\n // **Code blocks** (ex: ```python code ```)\n pre: ({ children }: { children: React.ReactNode }) => {\n const codeString = children?.toString() ?? '';\n\n return ;\n },\n },\n }}\n >\n {formattedText}\n \n \n {isTypingFinished && additionalContent && (\n {additionalContent}\n )}\n \n \n \n \n \n );\n};\n\nconst UserMessageBox = ({\n text,\n helperTexts = [],\n isLastMessage,\n hasNewMessage,\n containerRef,\n typographySx,\n}: ChatMessageProps) => {\n const theme = useTheme();\n const [hovered, setHovered] = useState(false);\n\n useEffect(() => {\n const scrollToLatestMessage = () => {\n if (!containerRef) return;\n\n setTimeout(() => {\n containerRef.current?.scrollTo({\n top: containerRef.current.scrollHeight,\n behavior: 'smooth',\n });\n }, 100);\n };\n\n scrollToLatestMessage();\n }, []);\n\n const styles = {\n root: {\n label: 'chat-message-userMessageBox',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'flex-end',\n position: 'relative',\n animation:\n hasNewMessage && isLastMessage ? 'fadein 0.3s ease-out' : 'none',\n '@keyframes fadein': {\n '0%': {\n opacity: '0',\n transform: 'translateY(5px)',\n },\n '100%': {\n opacity: '1',\n transform: 'translateY(0)',\n },\n },\n },\n box: {\n maxWidth: '90%',\n minWidth: '50px',\n p: theme.spacing(3),\n display: 'flex',\n alignSelf: 'flex-end',\n flexDirection: 'column',\n justifyContent: 'center',\n gap: 2,\n alignItems: 'flex-end',\n backgroundColor: alpha(theme.palette.common.black, 0.07),\n borderRadius: '15px',\n },\n text: {\n overflowWrap: 'anywhere',\n },\n helperText: {\n color: theme.palette.secondary.dark,\n lineHeight: '1',\n fontWeight: '600',\n },\n };\n\n const iconProps = {\n size: 14,\n contentSize: 14,\n strokeWidth: 1,\n stroke: theme.palette.grey[800],\n };\n\n return (\n setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n sx={styles.root}\n >\n \n \n {text}\n \n {/* Display the message hint */}\n {helperTexts.length > 0 &&\n helperTexts.map((hint: string, index) => (\n \n {hint}\n \n ))}\n \n \n \n \n \n );\n};\n\nconst ChatMessage = ({ text = '', type, ...props }: ChatMessageProps) => {\n const isUserMessage = type === 'user';\n\n const key = useMemo(() => `${type}-${text}-${Date.now()}`, [text, type]);\n\n const styles = {\n root: {\n label: 'chat-message-root',\n display: 'flex',\n justifyContent: isUserMessage ? 'flex-end' : 'flex-start',\n },\n };\n\n return (\n \n {isUserMessage ? (\n \n ) : (\n \n )}\n \n );\n};\n\nexport default ChatMessage;\n","import React from 'react';\nimport { Box, useTheme, Tooltip, Typography, alpha } from '@mui/material';\nimport { IconButton, InputBase } from '@mui/material';\nimport { IconWrapper } from '../../icons/IconWrapper';\nimport {\n SendIconContent,\n SendLargeIconContent,\n PauseIconContent,\n} from '../../icons/LlmChatIcons';\nimport { textEllipsis } from '../../styles/common';\n\ninterface ChatQueryBoxProps {\n isProcessing: boolean;\n onSubmit: () => void;\n onPause?: () => void | undefined;\n onChange: (\n e: React.ChangeEvent,\n ) => void;\n value: string;\n placeholder: string;\n graphName?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n variant?: 'default' | 'fullscreen';\n}\n\nconst GraphNameWidget = ({ name }: { name: string }) => {\n const theme = useTheme();\n const styles = {\n root: {\n borderRadius: '10px',\n backgroundColor: alpha(theme.palette.common.black, 0.05),\n padding: theme.spacing(1, 3),\n ...textEllipsis({ lines: 1 }),\n },\n sourceTypo: {\n color: theme.palette.grey[400],\n },\n };\n\n return (\n \n \n Data Source:{' '}\n \n \n \n {name}\n \n \n \n );\n};\n\nconst ChatQueryBox = ({\n isProcessing,\n value,\n graphName,\n placeholder,\n onSubmit,\n onPause,\n onChange,\n children,\n disabled,\n variant = 'default',\n}: ChatQueryBoxProps) => {\n const theme = useTheme();\n\n const styles = {\n root: {\n label: 'chat-query-box-root',\n width: '100%',\n padding: '1.5px',\n },\n box: {\n label: 'chat-query-box',\n display: 'flex',\n },\n inputBase: {\n label: 'chat-query-box-inputBase',\n border: 'none',\n maxHeight: '200px',\n overflow: 'auto',\n },\n default: {\n root: {\n borderRadius: '10px',\n background: 'linear-gradient(to left, #41DB89, #07ead7)',\n },\n box: {\n label: 'chat-query-box-box',\n borderRadius: children ? `8px 8px 0 0` : '8px',\n backgroundColor: 'white',\n px: theme.spacing(1),\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n },\n inputBase: {\n m: theme.spacing(2),\n fontSize: '12px',\n },\n iconButton: {},\n },\n fullscreen: {\n root: {},\n box: {\n width: '100%', //move?\n backgroundColor: 'white',\n borderRadius: '20px',\n p: theme.spacing(3),\n flexDirection: 'column',\n alignItems: 'flex-end',\n justifyContent: 'space-between',\n },\n inputBase: {\n fontSize: '15px',\n minHeight: '100px',\n maxHeight: '300px',\n overflow: 'scroll',\n display: 'flex',\n alignItems: 'flex-start',\n },\n iconButton: {\n backgroundColor: theme.palette.secondary.light,\n '&:disabled': {\n backgroundColor: theme.palette.secondary.light,\n },\n },\n bottom: {\n display: 'flex',\n flexDirection: 'row',\n gap: 3,\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n },\n },\n attachedFields: {\n label: 'chat-query-box-attachedFields',\n width: '100%',\n backgroundColor: theme.palette.grey[100],\n borderRadius: '0 0 8px 8px',\n borderTop: `1px solid ${theme.palette.grey[300]}`,\n px: theme.spacing(2),\n },\n };\n\n const currentStyles = styles[variant];\n\n const sendIconProps = {\n size: 25,\n height: 25,\n contentSize: 25,\n stroke: 'white',\n };\n\n return (\n \n \n onChange(e)}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n if (!disabled) onSubmit();\n }\n }}\n sx={{ ...styles.inputBase, ...currentStyles.inputBase }}\n />\n {variant === 'fullscreen' ? (\n \n \n {isProcessing && onPause ? (\n \n \n \n \n \n \n \n ) : (\n \n \n \n \n \n )}\n \n ) : isProcessing && onPause ? (\n \n \n \n \n \n \n \n ) : (\n \n \n \n \n \n )}\n \n {/* Attached Fields */}\n {children && {children}}\n \n );\n};\n\nexport default ChatQueryBox;\n","/**\n * @typedef {import('./info.js').Info} Info\n * @typedef {Record} Properties\n * @typedef {Record} Normal\n */\n\nexport class Schema {\n /**\n * @constructor\n * @param {Properties} property\n * @param {Normal} normal\n * @param {string} [space]\n */\n constructor(property, normal, space) {\n this.property = property\n this.normal = normal\n if (space) {\n this.space = space\n }\n }\n}\n\n/** @type {Properties} */\nSchema.prototype.property = {}\n/** @type {Normal} */\nSchema.prototype.normal = {}\n/** @type {string|null} */\nSchema.prototype.space = null\n","/**\n * @typedef {import('./schema.js').Properties} Properties\n * @typedef {import('./schema.js').Normal} Normal\n */\n\nimport {Schema} from './schema.js'\n\n/**\n * @param {Schema[]} definitions\n * @param {string} [space]\n * @returns {Schema}\n */\nexport function merge(definitions, space) {\n /** @type {Properties} */\n const property = {}\n /** @type {Normal} */\n const normal = {}\n let index = -1\n\n while (++index < definitions.length) {\n Object.assign(property, definitions[index].property)\n Object.assign(normal, definitions[index].normal)\n }\n\n return new Schema(property, normal, space)\n}\n","/**\n * @param {string} value\n * @returns {string}\n */\nexport function normalize(value) {\n return value.toLowerCase()\n}\n","export class Info {\n /**\n * @constructor\n * @param {string} property\n * @param {string} attribute\n */\n constructor(property, attribute) {\n /** @type {string} */\n this.property = property\n /** @type {string} */\n this.attribute = attribute\n }\n}\n\n/** @type {string|null} */\nInfo.prototype.space = null\nInfo.prototype.boolean = false\nInfo.prototype.booleanish = false\nInfo.prototype.overloadedBoolean = false\nInfo.prototype.number = false\nInfo.prototype.commaSeparated = false\nInfo.prototype.spaceSeparated = false\nInfo.prototype.commaOrSpaceSeparated = false\nInfo.prototype.mustUseProperty = false\nInfo.prototype.defined = false\n","let powers = 0\n\nexport const boolean = increment()\nexport const booleanish = increment()\nexport const overloadedBoolean = increment()\nexport const number = increment()\nexport const spaceSeparated = increment()\nexport const commaSeparated = increment()\nexport const commaOrSpaceSeparated = increment()\n\nfunction increment() {\n return 2 ** ++powers\n}\n","import {Info} from './info.js'\nimport * as types from './types.js'\n\n/** @type {Array} */\n// @ts-expect-error: hush.\nconst checks = Object.keys(types)\n\nexport class DefinedInfo extends Info {\n /**\n * @constructor\n * @param {string} property\n * @param {string} attribute\n * @param {number|null} [mask]\n * @param {string} [space]\n */\n constructor(property, attribute, mask, space) {\n let index = -1\n\n super(property, attribute)\n\n mark(this, 'space', space)\n\n if (typeof mask === 'number') {\n while (++index < checks.length) {\n const check = checks[index]\n mark(this, checks[index], (mask & types[check]) === types[check])\n }\n }\n }\n}\n\nDefinedInfo.prototype.defined = true\n\n/**\n * @param {DefinedInfo} values\n * @param {string} key\n * @param {unknown} value\n */\nfunction mark(values, key, value) {\n if (value) {\n // @ts-expect-error: assume `value` matches the expected value of `key`.\n values[key] = value\n }\n}\n","/**\n * @typedef {import('./schema.js').Properties} Properties\n * @typedef {import('./schema.js').Normal} Normal\n *\n * @typedef {Record} Attributes\n *\n * @typedef {Object} Definition\n * @property {Record} properties\n * @property {(attributes: Attributes, property: string) => string} transform\n * @property {string} [space]\n * @property {Attributes} [attributes]\n * @property {Array} [mustUseProperty]\n */\n\nimport {normalize} from '../normalize.js'\nimport {Schema} from './schema.js'\nimport {DefinedInfo} from './defined-info.js'\n\nconst own = {}.hasOwnProperty\n\n/**\n * @param {Definition} definition\n * @returns {Schema}\n */\nexport function create(definition) {\n /** @type {Properties} */\n const property = {}\n /** @type {Normal} */\n const normal = {}\n /** @type {string} */\n let prop\n\n for (prop in definition.properties) {\n if (own.call(definition.properties, prop)) {\n const value = definition.properties[prop]\n const info = new DefinedInfo(\n prop,\n definition.transform(definition.attributes || {}, prop),\n value,\n definition.space\n )\n\n if (\n definition.mustUseProperty &&\n definition.mustUseProperty.includes(prop)\n ) {\n info.mustUseProperty = true\n }\n\n property[prop] = info\n\n normal[normalize(prop)] = prop\n normal[normalize(info.attribute)] = prop\n }\n }\n\n return new Schema(property, normal, definition.space)\n}\n","import {create} from './util/create.js'\n\nexport const xlink = create({\n space: 'xlink',\n transform(_, prop) {\n return 'xlink:' + prop.slice(5).toLowerCase()\n },\n properties: {\n xLinkActuate: null,\n xLinkArcRole: null,\n xLinkHref: null,\n xLinkRole: null,\n xLinkShow: null,\n xLinkTitle: null,\n xLinkType: null\n }\n})\n","import {create} from './util/create.js'\n\nexport const xml = create({\n space: 'xml',\n transform(_, prop) {\n return 'xml:' + prop.slice(3).toLowerCase()\n },\n properties: {xmlLang: null, xmlBase: null, xmlSpace: null}\n})\n","/**\n * @param {Record} attributes\n * @param {string} attribute\n * @returns {string}\n */\nexport function caseSensitiveTransform(attributes, attribute) {\n return attribute in attributes ? attributes[attribute] : attribute\n}\n","import {caseSensitiveTransform} from './case-sensitive-transform.js'\n\n/**\n * @param {Record} attributes\n * @param {string} property\n * @returns {string}\n */\nexport function caseInsensitiveTransform(attributes, property) {\n return caseSensitiveTransform(attributes, property.toLowerCase())\n}\n","import {create} from './util/create.js'\nimport {caseInsensitiveTransform} from './util/case-insensitive-transform.js'\n\nexport const xmlns = create({\n space: 'xmlns',\n attributes: {xmlnsxlink: 'xmlns:xlink'},\n transform: caseInsensitiveTransform,\n properties: {xmlns: null, xmlnsXLink: null}\n})\n","import {booleanish, number, spaceSeparated} from './util/types.js'\nimport {create} from './util/create.js'\n\nexport const aria = create({\n transform(_, prop) {\n return prop === 'role' ? prop : 'aria-' + prop.slice(4).toLowerCase()\n },\n properties: {\n ariaActiveDescendant: null,\n ariaAtomic: booleanish,\n ariaAutoComplete: null,\n ariaBusy: booleanish,\n ariaChecked: booleanish,\n ariaColCount: number,\n ariaColIndex: number,\n ariaColSpan: number,\n ariaControls: spaceSeparated,\n ariaCurrent: null,\n ariaDescribedBy: spaceSeparated,\n ariaDetails: null,\n ariaDisabled: booleanish,\n ariaDropEffect: spaceSeparated,\n ariaErrorMessage: null,\n ariaExpanded: booleanish,\n ariaFlowTo: spaceSeparated,\n ariaGrabbed: booleanish,\n ariaHasPopup: null,\n ariaHidden: booleanish,\n ariaInvalid: null,\n ariaKeyShortcuts: null,\n ariaLabel: null,\n ariaLabelledBy: spaceSeparated,\n ariaLevel: number,\n ariaLive: null,\n ariaModal: booleanish,\n ariaMultiLine: booleanish,\n ariaMultiSelectable: booleanish,\n ariaOrientation: null,\n ariaOwns: spaceSeparated,\n ariaPlaceholder: null,\n ariaPosInSet: number,\n ariaPressed: booleanish,\n ariaReadOnly: booleanish,\n ariaRelevant: null,\n ariaRequired: booleanish,\n ariaRoleDescription: spaceSeparated,\n ariaRowCount: number,\n ariaRowIndex: number,\n ariaRowSpan: number,\n ariaSelected: booleanish,\n ariaSetSize: number,\n ariaSort: null,\n ariaValueMax: number,\n ariaValueMin: number,\n ariaValueNow: number,\n ariaValueText: null,\n role: null\n }\n})\n","import {\n boolean,\n overloadedBoolean,\n booleanish,\n number,\n spaceSeparated,\n commaSeparated\n} from './util/types.js'\nimport {create} from './util/create.js'\nimport {caseInsensitiveTransform} from './util/case-insensitive-transform.js'\n\nexport const html = create({\n space: 'html',\n attributes: {\n acceptcharset: 'accept-charset',\n classname: 'class',\n htmlfor: 'for',\n httpequiv: 'http-equiv'\n },\n transform: caseInsensitiveTransform,\n mustUseProperty: ['checked', 'multiple', 'muted', 'selected'],\n properties: {\n // Standard Properties.\n abbr: null,\n accept: commaSeparated,\n acceptCharset: spaceSeparated,\n accessKey: spaceSeparated,\n action: null,\n allow: null,\n allowFullScreen: boolean,\n allowPaymentRequest: boolean,\n allowUserMedia: boolean,\n alt: null,\n as: null,\n async: boolean,\n autoCapitalize: null,\n autoComplete: spaceSeparated,\n autoFocus: boolean,\n autoPlay: boolean,\n blocking: spaceSeparated,\n capture: null,\n charSet: null,\n checked: boolean,\n cite: null,\n className: spaceSeparated,\n cols: number,\n colSpan: null,\n content: null,\n contentEditable: booleanish,\n controls: boolean,\n controlsList: spaceSeparated,\n coords: number | commaSeparated,\n crossOrigin: null,\n data: null,\n dateTime: null,\n decoding: null,\n default: boolean,\n defer: boolean,\n dir: null,\n dirName: null,\n disabled: boolean,\n download: overloadedBoolean,\n draggable: booleanish,\n encType: null,\n enterKeyHint: null,\n fetchPriority: null,\n form: null,\n formAction: null,\n formEncType: null,\n formMethod: null,\n formNoValidate: boolean,\n formTarget: null,\n headers: spaceSeparated,\n height: number,\n hidden: boolean,\n high: number,\n href: null,\n hrefLang: null,\n htmlFor: spaceSeparated,\n httpEquiv: spaceSeparated,\n id: null,\n imageSizes: null,\n imageSrcSet: null,\n inert: boolean,\n inputMode: null,\n integrity: null,\n is: null,\n isMap: boolean,\n itemId: null,\n itemProp: spaceSeparated,\n itemRef: spaceSeparated,\n itemScope: boolean,\n itemType: spaceSeparated,\n kind: null,\n label: null,\n lang: null,\n language: null,\n list: null,\n loading: null,\n loop: boolean,\n low: number,\n manifest: null,\n max: null,\n maxLength: number,\n media: null,\n method: null,\n min: null,\n minLength: number,\n multiple: boolean,\n muted: boolean,\n name: null,\n nonce: null,\n noModule: boolean,\n noValidate: boolean,\n onAbort: null,\n onAfterPrint: null,\n onAuxClick: null,\n onBeforeMatch: null,\n onBeforePrint: null,\n onBeforeToggle: null,\n onBeforeUnload: null,\n onBlur: null,\n onCancel: null,\n onCanPlay: null,\n onCanPlayThrough: null,\n onChange: null,\n onClick: null,\n onClose: null,\n onContextLost: null,\n onContextMenu: null,\n onContextRestored: null,\n onCopy: null,\n onCueChange: null,\n onCut: null,\n onDblClick: null,\n onDrag: null,\n onDragEnd: null,\n onDragEnter: null,\n onDragExit: null,\n onDragLeave: null,\n onDragOver: null,\n onDragStart: null,\n onDrop: null,\n onDurationChange: null,\n onEmptied: null,\n onEnded: null,\n onError: null,\n onFocus: null,\n onFormData: null,\n onHashChange: null,\n onInput: null,\n onInvalid: null,\n onKeyDown: null,\n onKeyPress: null,\n onKeyUp: null,\n onLanguageChange: null,\n onLoad: null,\n onLoadedData: null,\n onLoadedMetadata: null,\n onLoadEnd: null,\n onLoadStart: null,\n onMessage: null,\n onMessageError: null,\n onMouseDown: null,\n onMouseEnter: null,\n onMouseLeave: null,\n onMouseMove: null,\n onMouseOut: null,\n onMouseOver: null,\n onMouseUp: null,\n onOffline: null,\n onOnline: null,\n onPageHide: null,\n onPageShow: null,\n onPaste: null,\n onPause: null,\n onPlay: null,\n onPlaying: null,\n onPopState: null,\n onProgress: null,\n onRateChange: null,\n onRejectionHandled: null,\n onReset: null,\n onResize: null,\n onScroll: null,\n onScrollEnd: null,\n onSecurityPolicyViolation: null,\n onSeeked: null,\n onSeeking: null,\n onSelect: null,\n onSlotChange: null,\n onStalled: null,\n onStorage: null,\n onSubmit: null,\n onSuspend: null,\n onTimeUpdate: null,\n onToggle: null,\n onUnhandledRejection: null,\n onUnload: null,\n onVolumeChange: null,\n onWaiting: null,\n onWheel: null,\n open: boolean,\n optimum: number,\n pattern: null,\n ping: spaceSeparated,\n placeholder: null,\n playsInline: boolean,\n popover: null,\n popoverTarget: null,\n popoverTargetAction: null,\n poster: null,\n preload: null,\n readOnly: boolean,\n referrerPolicy: null,\n rel: spaceSeparated,\n required: boolean,\n reversed: boolean,\n rows: number,\n rowSpan: number,\n sandbox: spaceSeparated,\n scope: null,\n scoped: boolean,\n seamless: boolean,\n selected: boolean,\n shadowRootClonable: boolean,\n shadowRootDelegatesFocus: boolean,\n shadowRootMode: null,\n shape: null,\n size: number,\n sizes: null,\n slot: null,\n span: number,\n spellCheck: booleanish,\n src: null,\n srcDoc: null,\n srcLang: null,\n srcSet: null,\n start: number,\n step: null,\n style: null,\n tabIndex: number,\n target: null,\n title: null,\n translate: null,\n type: null,\n typeMustMatch: boolean,\n useMap: null,\n value: booleanish,\n width: number,\n wrap: null,\n writingSuggestions: null,\n\n // Legacy.\n // See: https://html.spec.whatwg.org/#other-elements,-attributes-and-apis\n align: null, // Several. Use CSS `text-align` instead,\n aLink: null, // ``. Use CSS `a:active {color}` instead\n archive: spaceSeparated, // `