analytica-frontend-lib 1.2.81 → 1.2.82
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/ActivitiesHistory/index.js +34 -43
- package/dist/ActivitiesHistory/index.js.map +1 -1
- package/dist/ActivitiesHistory/index.mjs +34 -43
- package/dist/ActivitiesHistory/index.mjs.map +1 -1
- package/dist/ActivityDetails/index.js +30 -38
- package/dist/ActivityDetails/index.js.map +1 -1
- package/dist/ActivityDetails/index.mjs +30 -38
- package/dist/ActivityDetails/index.mjs.map +1 -1
- package/dist/ActivityFilters/index.js +30 -38
- package/dist/ActivityFilters/index.js.map +1 -1
- package/dist/ActivityFilters/index.mjs +30 -38
- package/dist/ActivityFilters/index.mjs.map +1 -1
- package/dist/AlertManager/index.js +30 -38
- package/dist/AlertManager/index.js.map +1 -1
- package/dist/AlertManager/index.mjs +30 -38
- package/dist/AlertManager/index.mjs.map +1 -1
- package/dist/RecommendedLessonsHistory/index.js +34 -43
- package/dist/RecommendedLessonsHistory/index.js.map +1 -1
- package/dist/RecommendedLessonsHistory/index.mjs +34 -43
- package/dist/RecommendedLessonsHistory/index.mjs.map +1 -1
- package/dist/SendActivityModal/SendActivityModal.js +30 -38
- package/dist/SendActivityModal/SendActivityModal.js.map +1 -1
- package/dist/SendActivityModal/SendActivityModal.mjs +30 -38
- package/dist/SendActivityModal/SendActivityModal.mjs.map +1 -1
- package/dist/SendActivityModal/index.js +30 -38
- package/dist/SendActivityModal/index.js.map +1 -1
- package/dist/SendActivityModal/index.mjs +30 -38
- package/dist/SendActivityModal/index.mjs.map +1 -1
- package/dist/TableProvider/index.js +30 -38
- package/dist/TableProvider/index.js.map +1 -1
- package/dist/TableProvider/index.mjs +30 -38
- package/dist/TableProvider/index.mjs.map +1 -1
- package/dist/hooks/useSendActivity/index.js +1 -1
- package/dist/hooks/useSendActivity/index.js.map +1 -1
- package/dist/hooks/useSendActivity/index.mjs +1 -1
- package/dist/hooks/useSendActivity/index.mjs.map +1 -1
- package/dist/index.js +39 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +39 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ActivityDetails/ActivityDetails.tsx","../../src/utils/utils.ts","../../src/components/Quiz/useQuizStore.ts","../../src/types/activityDetails.ts","../../src/utils/activityDetailsUtils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Badge/Badge.tsx","../../src/components/EmptyState/EmptyState.tsx","../../src/components/Skeleton/Skeleton.tsx","../../src/components/TableProvider/TableProvider.tsx","../../src/components/Table/Table.tsx","../../src/components/NoSearchResult/NoSearchResult.tsx","../../src/components/Table/TablePagination.tsx","../../src/components/Filter/useTableFilter.ts","../../src/components/Search/Search.tsx","../../src/components/DropdownMenu/DropdownMenu.tsx","../../src/components/Modal/Modal.tsx","../../src/components/Modal/utils/videoUtils.ts","../../src/components/ThemeToggle/ThemeToggle.tsx","../../src/components/SelectionButton/SelectionButton.tsx","../../src/hooks/useTheme.ts","../../src/store/themeStore.ts","../../src/components/CheckBoxGroup/CheckBoxGroup.tsx","../../src/components/LatexRenderer/LatexRenderer.tsx","../../src/components/CheckBox/CheckBox.tsx","../../src/components/CheckBox/CheckboxList.tsx","../../src/components/TextArea/TextArea.tsx","../../src/components/Divider/Divider.tsx","../../src/components/Radio/Radio.tsx","../../src/components/Toast/utils/ToastStore.ts","../../src/components/ProgressBar/ProgressBar.tsx","../../src/components/CorrectActivityModal/CorrectActivityModal.tsx","../../src/components/Accordation/Accordation.tsx","../../src/components/Card/Card.tsx","../../src/components/IconRender/IconRender.tsx","../../src/assets/icons/subjects/ChatPT.tsx","../../src/assets/icons/subjects/ChatEN.tsx","../../src/assets/icons/subjects/ChatES.tsx","../../src/components/Accordation/AccordionGroup.tsx","../../src/components/FileAttachment/FileAttachment.tsx","../../src/utils/studentActivityCorrection/constants.ts","../../src/utils/studentActivityCorrection/utils.ts","../../src/utils/studentActivityCorrection/converter.ts","../../src/components/Alternative/Alternative.tsx","../../src/utils/questionRenderer/alternative/index.tsx","../../src/components/MultipleChoice/MultipleChoice.tsx","../../src/utils/questionRenderer/multipleChoice/index.tsx","../../src/components/Quiz/QuizContent.tsx","../../src/utils/questionRenderer/components/index.tsx","../../src/utils/questionRenderer/trueOrFalse/index.tsx","../../src/utils/questionRenderer/dissertative/index.tsx","../../src/utils/questionRenderer/fill/index.tsx","../../src/utils/questionRenderer/image/index.tsx","../../src/utils/questionRenderer/connectDots/index.tsx","../../src/utils/questionRenderer/index.tsx","../../src/hooks/useMobile.ts","../../src/assets/icons/subjects/BookOpenText.tsx","../../src/assets/icons/subjects/HeadCircuit.tsx","../../src/assets/icons/subjects/Microscope.tsx","../../src/components/SubjectInfo/SubjectInfo.tsx","../../src/hooks/useQuestionsList.ts","../../src/components/ActivityCreate/ActivityCreate.utils.ts","../../src/components/QuestionsPdfGenerator/QuestionsPdfGenerator.tsx","../../src/hooks/useActivityDetails.ts","../../src/components/CheckBoxGroup/CheckBoxGroup.helpers.ts","../../src/components/Filter/FilterModal.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect, useRef } from 'react';\nimport {\n Medal,\n Star,\n CaretRight,\n WarningCircle,\n DownloadSimple,\n} from 'phosphor-react';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Badge from '../Badge/Badge';\nimport EmptyState from '../EmptyState/EmptyState';\nimport {\n SkeletonText,\n SkeletonRounded,\n SkeletonTable,\n} from '../Skeleton/Skeleton';\nimport { TableProvider } from '../TableProvider/TableProvider';\nimport CorrectActivityModal from '../CorrectActivityModal/CorrectActivityModal';\nimport { getSubjectInfo, type SubjectData } from '../SubjectInfo/SubjectInfo';\nimport { useMobile } from '../../hooks/useMobile';\nimport { cn } from '../../utils/utils';\nimport { SubjectEnum } from '../../enums/SubjectEnum';\nimport type { ColumnConfig, TableParams } from '../TableProvider/TableProvider';\nimport type {\n StudentActivityCorrectionData,\n SaveQuestionCorrectionPayload,\n} from '../../utils/studentActivityCorrection';\nimport { convertApiResponseToCorrectionData } from '../../utils/studentActivityCorrection';\nimport {\n STUDENT_ACTIVITY_STATUS,\n type ActivityDetailsData,\n type ActivityStudentTableItem,\n type StudentActivityStatus,\n} from '../../types/activityDetails';\nimport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from '../../utils/activityDetailsUtils';\nimport type { BaseApiClient } from '../../types/api';\nimport { useActivityDetails } from '../../hooks/useActivityDetails';\nimport {\n useQuestionsPdfPrint,\n QuestionsPdfContent,\n} from '../QuestionsPdfGenerator';\nimport type { PreviewQuestion } from '../ActivityPreview/ActivityPreview';\nimport { convertQuestionToPreview } from '../ActivityCreate/ActivityCreate.utils';\nimport type { Question } from '../../types/questions';\nimport { createUseQuestionsList } from '../../hooks/useQuestionsList';\nimport useToastStore from '../Toast/utils/ToastStore';\n\n/**\n * Props for the ActivityDetails component\n */\nexport interface ActivityDetailsProps {\n /** Activity ID to display details for */\n activityId: string;\n /** API client instance for making requests */\n apiClient: BaseApiClient;\n /** Callback when back button is clicked */\n onBack?: () => void;\n /** Image for empty state */\n emptyStateImage?: string;\n /** Function to map subject name to SubjectEnum */\n mapSubjectNameToEnum?: (subjectName: string) => SubjectEnum | null;\n}\n\n/**\n * Create table columns configuration\n * @param onCorrectActivity - Callback for correction action\n * @returns Column configuration array\n */\nconst createTableColumns = (\n onCorrectActivity: (studentId: string) => void\n): ColumnConfig<ActivityStudentTableItem>[] => [\n {\n key: 'studentName',\n label: 'Aluno',\n sortable: true,\n render: (value: unknown) => {\n const name = typeof value === 'string' ? value : '';\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"w-6 h-6 bg-blue-100 rounded-full flex items-center justify-center\">\n <Text className=\"text-xs font-semibold text-primary-700\">\n {name.charAt(0).toUpperCase()}\n </Text>\n </div>\n <Text className=\"text-sm font-normal text-text-950\">{name}</Text>\n </div>\n );\n },\n },\n {\n key: 'status',\n label: 'Status',\n sortable: false,\n render: (value: unknown) => {\n const config = getStatusBadgeConfig(value as StudentActivityStatus);\n return (\n <Badge\n className={`${config.bgColor} ${config.textColor} text-xs px-2 py-1`}\n >\n {config.label}\n </Badge>\n );\n },\n },\n {\n key: 'answeredAt',\n label: 'Respondido em',\n sortable: true,\n render: (value: unknown) => {\n if (!value || typeof value !== 'string') {\n return <Text className=\"text-sm text-text-400\">-</Text>;\n }\n return (\n <Text className=\"text-sm text-text-700\">\n {formatDateToBrazilian(value)}\n </Text>\n );\n },\n },\n {\n key: 'timeSpent',\n label: 'Duração',\n sortable: false,\n render: (value: unknown) =>\n Number(value) > 0 ? (\n <Text className=\"text-sm text-text-700\">\n {formatTimeSpent(Number(value))}\n </Text>\n ) : (\n <Text className=\"text-sm text-text-400\">-</Text>\n ),\n },\n {\n key: 'score',\n label: 'Nota',\n sortable: true,\n render: (value: unknown) =>\n value === null ? (\n <Text className=\"text-sm text-text-400\">-</Text>\n ) : (\n <Text className=\"text-sm font-semibold text-text-950\">\n {Number(value).toFixed(1)}\n </Text>\n ),\n },\n {\n key: 'actions',\n label: 'Resultado',\n sortable: false,\n render: (_value: unknown, row: ActivityStudentTableItem) => {\n if (row.status === STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO) {\n return (\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={() => onCorrectActivity(row.studentId)}\n className=\"text-xs\"\n >\n Corrigir atividade\n </Button>\n );\n }\n\n if (\n row.status === STUDENT_ACTIVITY_STATUS.CONCLUIDO ||\n row.status === STUDENT_ACTIVITY_STATUS.NAO_ENTREGUE\n ) {\n return (\n <Button\n variant=\"link\"\n size=\"small\"\n onClick={() => onCorrectActivity(row.studentId)}\n className=\"text-xs\"\n >\n Ver detalhes\n </Button>\n );\n }\n\n return null;\n },\n },\n];\n\n/**\n * Normalize questions with positions\n */\nconst normalizeWithPositions = (items: PreviewQuestion[]) =>\n items.map((item, index) => ({\n ...item,\n position: index + 1,\n }));\n\n/**\n * ActivityDetails component\n * Displays detailed information about an activity including statistics and student progress\n */\nexport const ActivityDetails = ({\n activityId,\n apiClient,\n onBack,\n emptyStateImage,\n mapSubjectNameToEnum,\n}: ActivityDetailsProps) => {\n const { isMobile } = useMobile();\n\n // Pagination and sorting state\n const [page, setPage] = useState(1);\n const [limit, setLimit] = useState(10);\n const [sortBy, setSortBy] = useState<\n 'name' | 'score' | 'answeredAt' | undefined\n >(undefined);\n const [sortOrder, setSortOrder] = useState<'asc' | 'desc' | undefined>(\n undefined\n );\n\n // Data state\n const [data, setData] = useState<ActivityDetailsData | null>(null);\n const [correctionData, setCorrectionData] =\n useState<StudentActivityCorrectionData | null>(null);\n\n // Loading/Error state\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Modal state\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [isViewOnlyModal, setIsViewOnlyModal] = useState(false);\n const [correctionError, setCorrectionError] = useState<string | null>(null);\n\n // PDF download state\n const [activityQuestions, setActivityQuestions] = useState<PreviewQuestion[]>(\n []\n );\n const [isLoadingQuestions, setIsLoadingQuestions] = useState(false);\n const [shouldPrint, setShouldPrint] = useState(false);\n const [activityQuestionsError, setActivityQuestionsError] = useState<\n string | null\n >(null);\n\n // Toast store for notifications\n const addToast = useToastStore((state) => state.addToast);\n\n // Use activity details hook\n const {\n fetchActivityDetails,\n fetchStudentCorrection,\n submitObservation,\n submitQuestionCorrection,\n } = useActivityDetails(apiClient);\n\n // Use questions list hook for fetching questions by IDs\n // Store hook factory in ref to preserve identity across renders\n const hookFactoryRef = useRef<ReturnType<\n typeof createUseQuestionsList\n > | null>(null);\n const apiClientRef = useRef<BaseApiClient | null>(null);\n\n // Create hook factory only when apiClient changes\n if (apiClientRef.current !== apiClient || !hookFactoryRef.current) {\n hookFactoryRef.current = createUseQuestionsList(apiClient);\n apiClientRef.current = apiClient;\n }\n\n const { fetchQuestionsByIds } = hookFactoryRef.current();\n\n /**\n * Reset PDF/question state when activityId changes\n * Prevents printing stale data when navigating between activities\n */\n useEffect(() => {\n setActivityQuestions([]);\n setIsLoadingQuestions(false);\n setShouldPrint(false);\n setActivityQuestionsError(null);\n }, [activityId]);\n\n /**\n * Fetch activity details when params change\n */\n useEffect(() => {\n const loadData = async () => {\n if (!activityId) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await fetchActivityDetails(activityId, {\n page,\n limit,\n sortBy,\n sortOrder,\n });\n setData(result);\n } catch (err) {\n setError(\n err instanceof Error ? err.message : 'Erro ao carregar detalhes'\n );\n } finally {\n setLoading(false);\n }\n };\n\n loadData();\n }, [activityId, page, limit, sortBy, sortOrder, fetchActivityDetails]);\n\n /**\n * Handle correct activity button click\n */\n const handleCorrectActivity = useCallback(\n async (studentId: string) => {\n const student = data?.students.find((s) => s.studentId === studentId);\n if (!student || !activityId) return;\n\n const isViewOnly =\n student.status !== STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO;\n setIsViewOnlyModal(isViewOnly);\n\n setCorrectionError(null);\n try {\n const apiResponse = await fetchStudentCorrection(activityId, studentId);\n // Convert API response to StudentActivityCorrectionData format\n const correction = convertApiResponseToCorrectionData(\n apiResponse,\n studentId,\n student.studentName || 'Aluno'\n );\n setCorrectionData(correction);\n setIsModalOpen(true);\n } catch (err) {\n console.error('Failed to fetch student correction:', err);\n setCorrectionError(\n err instanceof Error\n ? err.message\n : 'Erro ao carregar dados de correção'\n );\n }\n },\n [data?.students, activityId, fetchStudentCorrection]\n );\n\n /**\n * Handle modal close\n */\n const handleCloseModal = useCallback(() => {\n setIsModalOpen(false);\n }, []);\n\n /**\n * Handle observation submit\n * @param studentId - Student ID from modal (passed explicitly to avoid stale closure)\n * @param observation - Observation text\n * @param files - Attached files (only first file is used)\n */\n const handleObservationSubmit = useCallback(\n async (studentId: string, observation: string, files: File[]) => {\n if (!activityId || !studentId) return;\n try {\n const file = files.length > 0 ? files[0] : null;\n await submitObservation(activityId, studentId, observation, file);\n } catch (err) {\n console.error('Failed to submit observation:', err);\n }\n },\n [activityId, submitObservation]\n );\n\n /**\n * Handle question correction submit\n * @param studentId - Student ID from modal\n * @param payload - Question correction payload\n */\n const handleQuestionCorrectionSubmit = useCallback(\n async (studentId: string, payload: SaveQuestionCorrectionPayload) => {\n if (!activityId || !studentId) return;\n try {\n await submitQuestionCorrection(activityId, studentId, payload);\n } catch (err) {\n console.error('Failed to submit question correction:', err);\n throw err;\n }\n },\n [activityId, submitQuestionCorrection]\n );\n\n /**\n * Convert student data to table format\n */\n const tableData: ActivityStudentTableItem[] = useMemo(() => {\n if (!data?.students) return [];\n\n return data.students.map((student) => ({\n id: student.studentId,\n studentId: student.studentId,\n studentName: student.studentName,\n status: student.status,\n answeredAt: student.answeredAt,\n timeSpent: student.timeSpent,\n score: student.score,\n }));\n }, [data?.students]);\n\n /**\n * Table columns configuration\n */\n const columns = useMemo(\n () => createTableColumns(handleCorrectActivity),\n [handleCorrectActivity]\n );\n\n /**\n * Handle table parameters change\n */\n const handleTableParamsChange = (params: TableParams) => {\n if (params.page) setPage(params.page);\n if (params.limit) setLimit(params.limit);\n if (params.sortBy !== undefined) {\n // Map table column keys to API parameter names\n const sortByMap: Record<string, 'name' | 'score' | 'answeredAt'> = {\n studentName: 'name',\n answeredAt: 'answeredAt',\n score: 'score',\n };\n setSortBy(params.sortBy ? sortByMap[params.sortBy] : undefined);\n }\n if (params.sortOrder !== undefined) {\n setSortOrder(params.sortOrder as 'asc' | 'desc' | undefined);\n }\n };\n\n const orderedQuestions = useMemo(\n () => normalizeWithPositions(activityQuestions),\n [activityQuestions]\n );\n\n /**\n * Use PDF print hook\n */\n const { contentRef, handlePrint } = useQuestionsPdfPrint(orderedQuestions);\n\n /**\n * Extract questions from API response\n * Handles both direct questions array and questionIds array\n */\n const extractQuestionsFromResponse = useCallback(\n async (\n response:\n | Awaited<\n ReturnType<\n typeof apiClient.get<{\n data: { questions?: Question[]; questionIds?: string[] };\n }>\n >\n >\n | undefined\n ): Promise<Question[]> => {\n if (!response?.data?.data) {\n return [];\n }\n\n if (response.data.data.questions) {\n return response.data.data.questions;\n }\n\n if (response.data.data.questionIds) {\n return await fetchQuestionsByIds(response.data.data.questionIds);\n }\n\n return [];\n },\n [fetchQuestionsByIds]\n );\n\n /**\n * Try to fetch questions from quiz endpoint\n */\n const tryFetchQuizResponse = useCallback(async () => {\n try {\n const response = await apiClient.get<{\n data: { questions?: Question[]; questionIds?: string[] };\n }>(`/activities/${activityId}/quiz`);\n return { response, error: undefined };\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n return { response: undefined, error };\n }\n }, [activityId, apiClient]);\n\n /**\n * Try to fetch questions from activity endpoint\n */\n const tryFetchActivityResponse = useCallback(async () => {\n try {\n const response = await apiClient.get<{\n data: { questions?: Question[]; questionIds?: string[] };\n }>(`/activities/${activityId}`);\n return { response, error: undefined };\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n return { response: undefined, error };\n }\n }, [activityId, apiClient]);\n\n /**\n * Fetch questions from both endpoints (quiz and activity)\n * Returns questions array or throws error if both fail\n */\n const fetchQuestionsFromEndpoints = useCallback(async (): Promise<\n Question[]\n > => {\n // Try quiz endpoint first\n const { response: quizResponse, error: quizError } =\n await tryFetchQuizResponse();\n let questions = await extractQuestionsFromResponse(quizResponse);\n\n // If quiz endpoint didn't return questions, try activity endpoint\n if (questions.length === 0) {\n const { response: activityResponse, error: activityError } =\n await tryFetchActivityResponse();\n\n // If both endpoints failed, throw error\n if (!quizResponse && !activityResponse) {\n const errorMessage =\n quizError?.message ||\n activityError?.message ||\n 'Erro ao buscar questões da atividade. Tente novamente.';\n throw new Error(errorMessage);\n }\n\n questions = await extractQuestionsFromResponse(activityResponse);\n }\n\n return questions;\n }, [\n tryFetchQuizResponse,\n tryFetchActivityResponse,\n extractQuestionsFromResponse,\n ]);\n\n /**\n * Handle fetch error and show toast notification\n */\n const handleQuestionsFetchError = useCallback(\n (errorMessage: string) => {\n console.error('Erro ao buscar questões da atividade:', errorMessage);\n setActivityQuestions([]);\n setActivityQuestionsError(errorMessage);\n addToast({\n title: 'Erro ao carregar questões',\n description: errorMessage,\n variant: 'solid',\n action: 'warning',\n position: 'top-right',\n });\n },\n [addToast]\n );\n\n /**\n * Fetch activity questions for PDF download\n * @returns Promise that resolves to true if questions were successfully loaded (non-empty), false otherwise\n */\n const fetchActivityQuestions = useCallback(async (): Promise<boolean> => {\n if (!activityId) return false;\n\n setIsLoadingQuestions(true);\n setActivityQuestionsError(null);\n try {\n const questions = await fetchQuestionsFromEndpoints();\n\n // Convert questions to PreviewQuestion format\n const previewQuestions = questions.map((q) =>\n convertQuestionToPreview(q)\n );\n setActivityQuestions(previewQuestions);\n setActivityQuestionsError(null);\n\n // Notify user if no questions were found\n if (previewQuestions.length === 0) {\n addToast({\n title: 'Nenhuma questão encontrada',\n description: 'Esta atividade não possui questões para download.',\n variant: 'solid',\n action: 'info',\n position: 'top-right',\n });\n }\n\n return previewQuestions.length > 0;\n } catch (err) {\n const errorMessage =\n err instanceof Error\n ? err.message\n : 'Erro ao buscar questões da atividade. Tente novamente.';\n handleQuestionsFetchError(errorMessage);\n return false;\n } finally {\n setIsLoadingQuestions(false);\n }\n }, [fetchQuestionsFromEndpoints, handleQuestionsFetchError, addToast]);\n\n /**\n * Handle download PDF button click\n */\n const handleDownloadPdf = useCallback(async () => {\n try {\n // If questions are not loaded yet, fetch them first\n if (activityQuestions.length === 0) {\n const success = await fetchActivityQuestions();\n // Only set print flag if fetch succeeded and returned questions\n setShouldPrint(success);\n } else if (activityQuestions.length > 0) {\n setShouldPrint(true);\n } else {\n setShouldPrint(false);\n }\n } catch {\n // Error already handled in fetchActivityQuestions, ensure print flag is false\n setShouldPrint(false);\n }\n }, [activityQuestions.length, fetchActivityQuestions]);\n\n /**\n * Effect to handle PDF printing when shouldPrint flag is set\n * Waits for contentRef to be ready and questions to be loaded\n */\n useEffect(() => {\n if (!shouldPrint) {\n return;\n }\n\n // Guard against empty activityQuestions - reset flag if empty\n if (activityQuestions.length === 0) {\n setShouldPrint(false);\n return;\n }\n\n // Check if all conditions are met for printing\n if (\n contentRef.current &&\n handlePrint &&\n typeof handlePrint === 'function'\n ) {\n handlePrint();\n setShouldPrint(false);\n return;\n }\n\n // If conditions aren't met but shouldPrint is true, reset it to prevent getting stuck\n // This handles cases where contentRef or handlePrint aren't ready yet\n setShouldPrint(false);\n }, [shouldPrint, activityQuestions.length, contentRef, handlePrint]);\n\n /**\n * Handle back navigation\n */\n const handleBack = () => {\n if (onBack) {\n onBack();\n }\n };\n\n /**\n * Get subject info for icon display\n */\n const subjectEnum =\n data?.activity?.subjectName && mapSubjectNameToEnum\n ? mapSubjectNameToEnum(data.activity.subjectName)\n : null;\n const subjectInfo: SubjectData | null = subjectEnum\n ? getSubjectInfo(subjectEnum)\n : null;\n\n // Loading state\n if (loading && !data) {\n return (\n <div className=\"flex flex-col w-full h-auto relative justify-center items-center mb-5 overflow-hidden\">\n <div className=\"flex flex-col w-full h-full max-w-[1150px] mx-auto z-10 lg:px-0 px-4 pt-4 gap-4\">\n {/* Breadcrumb Skeleton */}\n <div className=\"flex items-center gap-2 py-4\">\n <SkeletonText width={100} height={14} />\n </div>\n\n {/* Header Card Skeleton */}\n <SkeletonRounded className=\"w-full h-[120px]\" />\n\n {/* Statistics Cards Skeleton */}\n <div\n className={cn(\n 'grid gap-5',\n isMobile ? 'grid-cols-2' : 'grid-cols-5'\n )}\n >\n {[\n 'total-students',\n 'completed',\n 'pending',\n 'avg-score',\n 'avg-time',\n ].map((id) => (\n <SkeletonRounded key={id} className=\"w-full h-[150px]\" />\n ))}\n </div>\n\n {/* Table Skeleton */}\n <div className=\"w-full bg-background rounded-xl p-6\">\n <SkeletonTable rows={5} columns={6} showHeader />\n </div>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error || !data) {\n return (\n <div className=\"flex flex-col w-full h-auto relative justify-center items-center mb-5\">\n <div className=\"flex flex-col w-full h-full max-w-[1150px] mx-auto z-10 lg:px-0 px-4 pt-4\">\n <EmptyState\n image={emptyStateImage}\n title=\"Erro ao carregar detalhes\"\n description={\n error || 'Não foi possível carregar os detalhes da atividade'\n }\n />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col w-full h-auto relative justify-center items-center mb-5 overflow-hidden\">\n {/* Main container */}\n <div className=\"flex flex-col w-full h-full max-w-[1150px] mx-auto z-10 lg:px-0 px-4 pt-4 gap-4\">\n {/* Breadcrumb */}\n <div className=\"flex items-center gap-2 py-4\">\n <button\n onClick={handleBack}\n className=\"text-text-500 hover:text-text-700 text-sm font-bold underline\"\n >\n Atividades\n </button>\n <CaretRight size={16} className=\"text-text-500\" />\n <Text className=\"text-text-950 text-sm font-bold\">\n {data.activity?.title || 'Atividade'}\n </Text>\n </div>\n\n {/* Activity header card */}\n {data.activity && (\n <div className=\"bg-background rounded-xl p-4 flex flex-col gap-2\">\n <div className=\"flex justify-between items-start\">\n <div className=\"flex flex-col gap-2\">\n <Text className=\"text-2xl font-bold text-text-950\">\n {data.activity.title}\n </Text>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Text className=\"text-sm text-text-500\">\n Início{' '}\n {data.activity.startDate\n ? formatDateToBrazilian(data.activity.startDate)\n : '00/00/0000'}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n Prazo final{' '}\n {data.activity.finalDate\n ? formatDateToBrazilian(data.activity.finalDate)\n : '00/00/0000'}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n {data.activity.schoolName}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n {data.activity.year}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n {subjectInfo ? (\n <div className=\"flex items-center gap-1\">\n <span\n className={cn(\n 'w-[21px] h-[21px] flex items-center justify-center rounded-sm text-text-950 shrink-0',\n subjectInfo.colorClass\n )}\n >\n {subjectInfo.icon}\n </span>\n <Text className=\"text-sm text-text-500\">\n {data.activity.subjectName}\n </Text>\n </div>\n ) : (\n <Text className=\"text-sm text-text-500\">\n {data.activity.subjectName}\n </Text>\n )}\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n {data.activity.className}\n </Text>\n </div>\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Button\n size=\"small\"\n onClick={handleDownloadPdf}\n disabled={isLoadingQuestions}\n iconLeft={<DownloadSimple size={16} />}\n className=\"bg-primary-950 text-text gap-2\"\n >\n {isLoadingQuestions ? 'Carregando...' : 'Baixar Atividade'}\n </Button>\n {activityQuestionsError && (\n <div className=\"flex items-center gap-2 max-w-[300px]\">\n <WarningCircle\n size={16}\n className=\"text-error-600 shrink-0\"\n weight=\"fill\"\n />\n <Text className=\"text-error-700 text-xs\">\n {activityQuestionsError}\n </Text>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Statistics cards */}\n <div\n className={cn('grid gap-5', isMobile ? 'grid-cols-2' : 'grid-cols-5')}\n >\n {/* Completion percentage */}\n <div className=\"border border-border-50 rounded-xl py-4 px-0 flex flex-col items-center justify-center gap-2 bg-primary-50\">\n <div className=\"relative w-[90px] h-[90px]\">\n <svg className=\"w-full h-full transform -rotate-90\">\n <circle\n cx=\"45\"\n cy=\"45\"\n r=\"40\"\n stroke=\"var(--color-primary-100)\"\n strokeWidth=\"8\"\n fill=\"none\"\n />\n <circle\n cx=\"45\"\n cy=\"45\"\n r=\"40\"\n stroke=\"var(--color-primary-700)\"\n strokeWidth=\"8\"\n fill=\"none\"\n strokeDasharray={`${(data.generalStats.completionPercentage / 100) * 251.2} 251.2`}\n strokeLinecap=\"round\"\n />\n </svg>\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\n <Text className=\"text-xl font-medium text-primary-600\">\n {Math.round(data.generalStats.completionPercentage)}%\n </Text>\n <Text className=\"text-2xs font-bold text-text-600 uppercase\">\n Concluído\n </Text>\n </div>\n </div>\n </div>\n\n {/* Average score */}\n <div className=\"border border-border-50 rounded-xl py-4 px-3 flex flex-col items-center justify-center gap-1 bg-warning-background\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-warning-300\">\n <Star size={16} className=\"text-white\" weight=\"regular\" />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-warning-600\">\n Média da Turma\n </Text>\n <Text className=\"text-xl font-bold text-warning-600\">\n {data.generalStats.averageScore.toFixed(1)}\n </Text>\n </div>\n\n {/* Most correct questions */}\n <div className=\"border border-border-50 rounded-xl py-2 px-3 flex flex-col items-center justify-center gap-1 bg-success-200\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-indicator-positive\">\n <Medal size={16} className=\"text-text-950\" weight=\"regular\" />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-success-700\">\n Questões com mais acertos\n </Text>\n <Text className=\"text-xl font-bold text-success-700\">\n {formatQuestionNumbers(data.questionStats.mostCorrect)}\n </Text>\n </div>\n\n {/* Most incorrect questions */}\n <div className=\"border border-border-50 rounded-xl py-2 px-3 flex flex-col items-center justify-center gap-1 bg-error-100\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-indicator-negative\">\n <WarningCircle\n size={16}\n className=\"text-white\"\n weight=\"regular\"\n />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-error-700\">\n Questões com mais erros\n </Text>\n <Text className=\"text-xl font-bold text-error-700\">\n {formatQuestionNumbers(data.questionStats.mostIncorrect)}\n </Text>\n </div>\n\n {/* Not answered questions */}\n <div className=\"border border-border-50 rounded-xl py-2 px-3 flex flex-col items-center justify-center gap-1 bg-info-background\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-info-500\">\n <WarningCircle\n size={16}\n className=\"text-white\"\n weight=\"regular\"\n />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-info-700\">\n Questões não respondidas\n </Text>\n <Text className=\"text-xl font-bold text-info-700\">\n {formatQuestionNumbers(data.questionStats.notAnswered)}\n </Text>\n </div>\n </div>\n\n {/* Correction error message */}\n {correctionError && (\n <div className=\"w-full bg-error-50 border border-error-200 rounded-xl p-4 flex items-center gap-3\">\n <WarningCircle size={20} className=\"text-error-600\" weight=\"fill\" />\n <Text className=\"text-error-700 text-sm\">{correctionError}</Text>\n </div>\n )}\n\n {/* Students table */}\n <div className=\"w-full bg-background rounded-xl p-6 space-y-4\">\n <TableProvider<ActivityStudentTableItem>\n data={tableData}\n headers={columns}\n loading={false}\n variant=\"borderless\"\n enableTableSort\n enablePagination\n paginationConfig={{\n itemLabel: 'alunos',\n itemsPerPageOptions: [10, 20, 50],\n defaultItemsPerPage: 10,\n totalItems: data.pagination.total,\n totalPages: data.pagination.totalPages,\n }}\n emptyState={{\n component: (\n <EmptyState\n image={emptyStateImage}\n title=\"Nenhum aluno encontrado\"\n description=\"Não há alunos matriculados nesta atividade\"\n />\n ),\n }}\n onParamsChange={handleTableParamsChange}\n >\n {({ table, pagination }) => (\n <>\n {table}\n {pagination}\n </>\n )}\n </TableProvider>\n </div>\n </div>\n\n {/* Correct Activity Modal */}\n <CorrectActivityModal\n isOpen={isModalOpen}\n onClose={handleCloseModal}\n data={correctionData}\n isViewOnly={isViewOnlyModal}\n onObservationSubmit={handleObservationSubmit}\n onQuestionCorrectionSubmit={handleQuestionCorrectionSubmit}\n />\n\n {/* Hidden PDF content for printing */}\n <div style={{ display: 'none' }}>\n <QuestionsPdfContent ref={contentRef} questions={orderedQuestions} />\n </div>\n </div>\n );\n};\n\nexport default ActivityDetails;\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\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n areFiltersEqual,\n} from './activityFilters';\nexport {\n mapQuestionTypeToEnum,\n mapQuestionTypeToEnumRequired,\n} from './questionTypeUtils';\nexport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from './activityDetailsUtils';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n","import { create } from 'zustand';\nimport { devtools } from 'zustand/middleware';\n\nexport enum QUESTION_DIFFICULTY {\n FACIL = 'FACIL',\n MEDIO = 'MEDIO',\n DIFICIL = 'DIFICIL',\n}\n\n// Enum para tipos de quiz\nexport enum QUIZ_TYPE {\n SIMULADO = 'SIMULADO',\n QUESTIONARIO = 'QUESTIONARIO',\n ATIVIDADE = 'ATIVIDADE',\n}\n\nexport enum QUESTION_TYPE {\n ALTERNATIVA = 'ALTERNATIVA',\n DISSERTATIVA = 'DISSERTATIVA',\n MULTIPLA_ESCOLHA = 'MULTIPLA_ESCOLHA',\n VERDADEIRO_FALSO = 'VERDADEIRO_FALSO',\n LIGAR_PONTOS = 'LIGAR_PONTOS',\n PREENCHER = 'PREENCHER',\n IMAGEM = 'IMAGEM',\n}\n\nexport enum QUESTION_STATUS {\n PENDENTE_AVALIACAO = 'PENDENTE_AVALIACAO',\n RESPOSTA_CORRETA = 'RESPOSTA_CORRETA',\n RESPOSTA_INCORRETA = 'RESPOSTA_INCORRETA',\n NAO_RESPONDIDO = 'NAO_RESPONDIDO',\n}\n\nexport enum ANSWER_STATUS {\n RESPOSTA_CORRETA = 'RESPOSTA_CORRETA',\n RESPOSTA_INCORRETA = 'RESPOSTA_INCORRETA',\n PENDENTE_AVALIACAO = 'PENDENTE_AVALIACAO',\n NAO_RESPONDIDO = 'NAO_RESPONDIDO',\n}\n\nexport enum SUBTYPE_ENUM {\n PROVA = 'PROVA',\n ENEM_PROVA_1 = 'ENEM_PROVA_1',\n ENEM_PROVA_2 = 'ENEM_PROVA_2',\n VESTIBULAR = 'VESTIBULAR',\n SIMULADO = 'SIMULADO',\n SIMULADAO = 'SIMULADAO',\n}\n\nexport interface QuestionResult {\n answers: {\n id: string;\n questionId: string;\n answer: string | null;\n selectedOptions: {\n optionId: string;\n }[];\n answerStatus: ANSWER_STATUS;\n statement: string;\n questionType: QUESTION_TYPE;\n difficultyLevel: QUESTION_DIFFICULTY;\n solutionExplanation: string | null;\n correctOption: string;\n createdAt: string;\n updatedAt: string;\n options?: {\n id: string;\n option: string;\n isCorrect: boolean;\n }[];\n knowledgeMatrix: {\n areaKnowledge: {\n id: string;\n name: string;\n } | null;\n subject: {\n id: string;\n name: string;\n color: string;\n icon: string;\n } | null;\n topic: {\n id: string;\n name: string;\n } | null;\n subtopic: {\n id: string;\n name: string;\n } | null;\n content: {\n id: string;\n name: string;\n } | null;\n }[];\n teacherFeedback: string | null;\n attachment: string | null;\n score: number | null;\n gradedAt: string | null;\n gradedBy: string | null;\n }[];\n statistics: {\n totalAnswered: number;\n correctAnswers: number;\n incorrectAnswers: number;\n pendingAnswers: number;\n score: number;\n timeSpent: number;\n };\n}\n\nexport interface Question {\n id: string;\n statement: string;\n questionType: QUESTION_TYPE;\n difficultyLevel: QUESTION_DIFFICULTY;\n description: string;\n examBoard: string | null;\n examYear: string | null;\n solutionExplanation: string | null;\n answer: null;\n answerStatus: ANSWER_STATUS;\n options: {\n id: string;\n option: string;\n }[];\n knowledgeMatrix: {\n areaKnowledge: {\n id: string;\n name: string;\n };\n subject: {\n id: string;\n name: string;\n color: string;\n icon: string;\n };\n topic: {\n id: string;\n name: string;\n };\n subtopic: {\n id: string;\n name: string;\n };\n content: {\n id: string;\n name: string;\n };\n }[];\n correctOptionIds?: string[];\n}\n\nexport interface QuizInterface {\n id: string;\n title: string;\n type: QUIZ_TYPE;\n subtype: SUBTYPE_ENUM | string;\n difficulty: string | null;\n notification: string | null;\n status: string;\n startDate: string | null;\n finalDate: string | null;\n canRetry: boolean;\n createdAt: string | null;\n updatedAt: string | null;\n questions: Question[];\n}\n\nexport interface UserAnswerItem {\n questionId: string;\n activityId: string;\n userId: string;\n answer: string | null;\n optionId: string | null;\n questionType: QUESTION_TYPE;\n answerStatus: ANSWER_STATUS;\n}\n\nexport interface QuizState {\n // Data\n quiz: QuizInterface | null;\n\n // UI State\n currentQuestionIndex: number;\n selectedAnswers: Record<string, string>;\n userAnswers: UserAnswerItem[];\n timeElapsed: number;\n isStarted: boolean;\n isFinished: boolean;\n userId: string;\n variant: 'result' | 'default';\n minuteCallback: (() => void) | null;\n dissertativeCharLimit?: number;\n // Actions\n setQuiz: (quiz: QuizInterface) => void;\n setQuestionResult: (questionResult: QuestionResult) => void;\n setUserId: (userId: string) => void;\n setUserAnswers: (userAnswers: UserAnswerItem[]) => void;\n setVariant: (variant: 'result' | 'default') => void;\n setDissertativeCharLimit: (limit?: number) => void;\n getDissertativeCharLimit: () => number | undefined;\n // Quiz Navigation\n goToNextQuestion: () => void;\n goToPreviousQuestion: () => void;\n goToQuestion: (index: number) => void;\n\n // Quiz Actions\n selectAnswer: (questionId: string, answerId: string) => void;\n selectMultipleAnswer: (questionId: string, answerIds: string[]) => void;\n selectDissertativeAnswer: (questionId: string, answer: string) => void;\n skipQuestion: () => void;\n skipCurrentQuestionIfUnanswered: () => void;\n addUserAnswer: (questionId: string, answerId?: string) => void;\n startQuiz: () => void;\n finishQuiz: () => void;\n resetQuiz: () => void;\n\n // Timer\n updateTime: (time: number) => void;\n startTimer: () => void;\n stopTimer: () => void;\n\n // Minute Callback\n setMinuteCallback: (callback: (() => void) | null) => void;\n startMinuteCallback: () => void;\n stopMinuteCallback: () => void;\n\n // Getters\n getCurrentQuestion: () => Question | null;\n getTotalQuestions: () => number;\n getAnsweredQuestions: () => number;\n getUnansweredQuestions: () => number[];\n getSkippedQuestions: () => number;\n getProgress: () => number;\n isQuestionAnswered: (questionId: string) => boolean;\n isQuestionSkipped: (questionId: string) => boolean;\n getCurrentAnswer: () => UserAnswerItem | undefined;\n getAllCurrentAnswer: () => UserAnswerItem[] | undefined;\n getQuizTitle: () => string;\n formatTime: (seconds: number) => string;\n getUserAnswers: () => UserAnswerItem[];\n getUnansweredQuestionsFromUserAnswers: () => number[];\n getQuestionsGroupedBySubject: () => { [key: string]: Question[] };\n getUserId: () => string;\n setCurrentQuestion: (question: Question) => void;\n\n // New methods for userAnswers\n getQuestionIndex: (questionId: string) => number;\n getUserAnswerByQuestionId: (questionId: string) => UserAnswerItem | null;\n isQuestionAnsweredByUserAnswers: (questionId: string) => boolean;\n getQuestionStatusFromUserAnswers: (\n questionId: string\n ) => 'answered' | 'unanswered' | 'skipped';\n getUserAnswersForActivity: () => UserAnswerItem[];\n // Answer status management\n setAnswerStatus: (questionId: string, status: ANSWER_STATUS) => void;\n getAnswerStatus: (questionId: string) => ANSWER_STATUS | null;\n\n // Question Result\n questionsResult: QuestionResult | null;\n currentQuestionResult: QuestionResult['answers'] | null;\n setQuestionsResult: (questionsResult: QuestionResult) => void;\n setCurrentQuestionResult: (\n currentQuestionResult: QuestionResult['answers']\n ) => void;\n getQuestionResultByQuestionId: (\n questionId: string\n ) => QuestionResult['answers'][number] | null;\n getQuestionResultStatistics: () => QuestionResult['statistics'] | null;\n getQuestionResult: () => QuestionResult | null;\n getCurrentQuestionResult: () => QuestionResult['answers'] | null;\n}\n\n// Constants\nexport const MINUTE_INTERVAL_MS = 60000; // 60 seconds = 1 minute\n\nexport const useQuizStore = create<QuizState>()(\n devtools(\n (set, get) => {\n let timerInterval: ReturnType<typeof setInterval> | null = null;\n let minuteCallbackInterval: ReturnType<typeof setInterval> | null = null;\n\n const startTimer = () => {\n if (get().isFinished) {\n return;\n }\n\n if (timerInterval) {\n clearInterval(timerInterval);\n }\n\n timerInterval = setInterval(() => {\n const { timeElapsed } = get();\n set({ timeElapsed: timeElapsed + 1 });\n }, 1000);\n };\n\n const stopTimer = () => {\n if (timerInterval) {\n clearInterval(timerInterval);\n timerInterval = null;\n }\n };\n\n const setMinuteCallback = (callback: (() => void) | null) => {\n set({ minuteCallback: callback });\n };\n\n const startMinuteCallback = () => {\n const { minuteCallback, isFinished } = get();\n\n if (isFinished || !minuteCallback) {\n return;\n }\n\n if (minuteCallbackInterval) {\n clearInterval(minuteCallbackInterval);\n }\n\n minuteCallbackInterval = setInterval(() => {\n const {\n minuteCallback: currentCallback,\n isFinished: currentIsFinished,\n } = get();\n\n if (currentIsFinished || !currentCallback) {\n stopMinuteCallback();\n return;\n }\n\n currentCallback();\n }, MINUTE_INTERVAL_MS);\n };\n\n const stopMinuteCallback = () => {\n if (minuteCallbackInterval) {\n clearInterval(minuteCallbackInterval);\n minuteCallbackInterval = null;\n }\n };\n\n return {\n // Initial State\n quiz: null,\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n variant: 'default',\n minuteCallback: null,\n dissertativeCharLimit: undefined,\n questionsResult: null,\n currentQuestionResult: null,\n // Setters\n setQuiz: (quiz) => set({ quiz }),\n setUserId: (userId) => set({ userId }),\n setUserAnswers: (userAnswers) => set({ userAnswers }),\n getUserId: () => get().userId,\n setVariant: (variant) => set({ variant }),\n setQuestionResult: (questionsResult) => set({ questionsResult }),\n setDissertativeCharLimit: (limit?: number) =>\n set({ dissertativeCharLimit: limit }),\n getDissertativeCharLimit: () => get().dissertativeCharLimit,\n // Navigation\n goToNextQuestion: () => {\n const { currentQuestionIndex, getTotalQuestions } = get();\n const totalQuestions = getTotalQuestions();\n\n if (currentQuestionIndex < totalQuestions - 1) {\n set({ currentQuestionIndex: currentQuestionIndex + 1 });\n }\n },\n\n goToPreviousQuestion: () => {\n const { currentQuestionIndex } = get();\n\n if (currentQuestionIndex > 0) {\n set({ currentQuestionIndex: currentQuestionIndex - 1 });\n }\n },\n\n goToQuestion: (index) => {\n const { getTotalQuestions } = get();\n const totalQuestions = getTotalQuestions();\n\n if (index >= 0 && index < totalQuestions) {\n set({ currentQuestionIndex: index });\n }\n },\n\n selectAnswer: (questionId, answerId) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? answerId\n : null,\n optionId:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? null\n : answerId,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n selectMultipleAnswer: (questionId, answerIds) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n // Remove all existing answers for this questionId\n const filteredUserAnswers = userAnswers.filter(\n (answer) => answer.questionId !== questionId\n );\n\n // Create new UserAnswerItem objects for each answerId\n const newUserAnswers: UserAnswerItem[] = answerIds.map(\n (answerId) => ({\n questionId,\n activityId,\n userId,\n answer: null, // selectMultipleAnswer is for non-dissertative questions\n optionId: answerId, // selectMultipleAnswer should only set optionId\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n })\n );\n\n // Combine filtered answers with new answers\n const updatedUserAnswers = [\n ...filteredUserAnswers,\n ...newUserAnswers,\n ];\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n selectDissertativeAnswer: (questionId, answer) => {\n const { quiz, userAnswers, dissertativeCharLimit } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (\n !question ||\n question.questionType !== QUESTION_TYPE.DISSERTATIVA\n ) {\n // Silent validation - wrong question type\n return;\n }\n\n // Validate character limit if set\n let validatedAnswer = answer;\n if (\n dissertativeCharLimit !== undefined &&\n answer.length > dissertativeCharLimit\n ) {\n validatedAnswer = answer.substring(0, dissertativeCharLimit);\n }\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answerItem) => answerItem.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer: validatedAnswer,\n optionId: null,\n questionType: QUESTION_TYPE.DISSERTATIVA,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n skipQuestion: () => {\n const { getCurrentQuestion, userAnswers, quiz } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!quiz) return;\n\n if (currentQuestion) {\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId: currentQuestion.id,\n activityId,\n userId,\n answer: null,\n optionId: null,\n questionType: currentQuestion.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n // Update existing answer\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n // Add new answer\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n }\n },\n\n skipCurrentQuestionIfUnanswered: () => {\n const { getCurrentQuestion, getCurrentAnswer, skipQuestion } = get();\n const currentQuestion = getCurrentQuestion();\n const currentAnswer = getCurrentAnswer();\n\n // Se não há questão atual, não faz nada\n if (!currentQuestion) return;\n\n // Se não há resposta ou a resposta está vazia (null), marca como pulada\n if (\n !currentAnswer ||\n (currentAnswer.optionId === null && currentAnswer.answer === null)\n ) {\n skipQuestion();\n }\n },\n\n addUserAnswer: (questionId, answerId) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n // Add to userAnswers array with new structure\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? answerId || null\n : null,\n optionId:\n question.questionType !== QUESTION_TYPE.DISSERTATIVA\n ? answerId || null\n : null,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n if (existingAnswerIndex !== -1) {\n // Update existing answer\n const updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n set({ userAnswers: updatedUserAnswers });\n } else {\n // Add new answer\n set({ userAnswers: [...userAnswers, newUserAnswer] });\n }\n },\n\n startQuiz: () => {\n set({ isStarted: true, timeElapsed: 0 });\n startTimer();\n startMinuteCallback();\n },\n\n finishQuiz: () => {\n set({ isFinished: true });\n stopTimer();\n stopMinuteCallback();\n },\n\n resetQuiz: () => {\n stopTimer();\n stopMinuteCallback();\n set({\n quiz: null,\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n variant: 'default',\n minuteCallback: null,\n dissertativeCharLimit: undefined,\n questionsResult: null,\n currentQuestionResult: null,\n });\n },\n\n // Timer\n updateTime: (time) => set({ timeElapsed: time }),\n startTimer,\n stopTimer,\n\n // Minute Callback\n setMinuteCallback,\n startMinuteCallback,\n stopMinuteCallback,\n\n // Getters\n getCurrentQuestion: () => {\n const { currentQuestionIndex, quiz } = get();\n\n if (!quiz) {\n return null;\n }\n\n return quiz.questions[currentQuestionIndex];\n },\n\n getTotalQuestions: () => {\n const { quiz } = get();\n\n return quiz?.questions?.length || 0;\n },\n\n getAnsweredQuestions: () => {\n const { userAnswers } = get();\n return userAnswers.filter(\n (answer) => answer.optionId !== null || answer.answer !== null\n ).length;\n },\n\n getUnansweredQuestions: () => {\n const { quiz, userAnswers } = get();\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const isAnswered =\n userAnswer &&\n (userAnswer.optionId !== null || userAnswer.answer !== null);\n const isSkipped =\n userAnswer &&\n userAnswer.optionId === null &&\n userAnswer.answer === null;\n\n if (!isAnswered && !isSkipped) {\n unansweredQuestions.push(index + 1); // index + 1 para mostrar número da questão\n }\n });\n return unansweredQuestions;\n },\n\n getSkippedQuestions: () => {\n const { userAnswers } = get();\n return userAnswers.filter(\n (answer) => answer.optionId === null && answer.answer === null\n ).length;\n },\n\n getProgress: () => {\n const { getTotalQuestions, getAnsweredQuestions } = get();\n const total = getTotalQuestions();\n const answered = getAnsweredQuestions();\n\n return total > 0 ? (answered / total) * 100 : 0;\n },\n\n isQuestionAnswered: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer\n ? userAnswer.optionId !== null || userAnswer.answer !== null\n : false;\n },\n\n isQuestionSkipped: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer\n ? userAnswer.optionId === null && userAnswer.answer === null\n : false;\n },\n\n getCurrentAnswer: () => {\n const { getCurrentQuestion, userAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!currentQuestion) return undefined;\n\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n // Retorna undefined se a resposta está vazia (não respondida)\n const hasAnswerContent = (ua?: UserAnswerItem | null) =>\n !!ua &&\n ((ua.optionId !== null && ua.optionId !== '') ||\n (ua.answer !== null && ua.answer !== ''));\n\n if (!hasAnswerContent(userAnswer)) {\n return undefined;\n }\n\n return userAnswer;\n },\n\n getAllCurrentAnswer: () => {\n const { getCurrentQuestion, userAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!currentQuestion) return undefined;\n\n const userAnswer = userAnswers.filter(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n return userAnswer;\n },\n\n getQuizTitle: () => {\n const { quiz } = get();\n\n return quiz?.title || 'Quiz';\n },\n\n formatTime: (seconds: number) => {\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\n },\n\n getUserAnswers: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n\n getUnansweredQuestionsFromUserAnswers: () => {\n const { quiz, userAnswers } = get();\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const hasAnswer =\n userAnswer &&\n (userAnswer.optionId !== null || userAnswer.answer !== null);\n const isSkipped =\n userAnswer &&\n userAnswer.optionId === null &&\n userAnswer.answer === null;\n\n // Se não há resposta do usuário OU se a questão foi pulada\n if (!hasAnswer || isSkipped) {\n unansweredQuestions.push(index + 1); // index + 1 para mostrar número da questão\n }\n });\n\n return unansweredQuestions;\n },\n\n getQuestionsGroupedBySubject: () => {\n const { getQuestionResult, quiz, variant } = get();\n const questions =\n variant == 'result'\n ? getQuestionResult()?.answers\n : quiz?.questions;\n if (!questions) return {};\n const groupedQuestions: {\n [key: string]: (Question | QuestionResult['answers'][number])[];\n } = {};\n questions.forEach((question) => {\n const subjectId =\n question.knowledgeMatrix?.[0]?.subject?.id || 'Sem matéria';\n\n if (!groupedQuestions[subjectId]) {\n groupedQuestions[subjectId] = [];\n }\n\n groupedQuestions[subjectId].push(question);\n });\n\n return groupedQuestions;\n },\n\n // New methods for userAnswers\n getUserAnswerByQuestionId: (questionId) => {\n const { userAnswers } = get();\n return (\n userAnswers.find((answer) => answer.questionId === questionId) ||\n null\n );\n },\n isQuestionAnsweredByUserAnswers: (questionId) => {\n const { userAnswers } = get();\n const answer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return answer\n ? answer.optionId !== null || answer.answer !== null\n : false;\n },\n getQuestionStatusFromUserAnswers: (questionId) => {\n const { userAnswers } = get();\n const answer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n if (!answer) return 'unanswered';\n if (answer.optionId === null) return 'skipped';\n return 'answered';\n },\n getUserAnswersForActivity: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n setCurrentQuestion: (question) => {\n const { quiz, variant, questionsResult } = get();\n if (!quiz) return;\n let questionIndex = 0;\n if (variant == 'result') {\n if (!questionsResult) return;\n const questionResult =\n questionsResult.answers.find((q) => q.id === question.id) ??\n questionsResult.answers.find((q) => q.questionId === question.id);\n if (!questionResult) return;\n questionIndex = quiz.questions.findIndex(\n (q) => q.id === questionResult.questionId\n );\n } else {\n questionIndex = quiz.questions.findIndex(\n (q) => q.id === question.id\n );\n }\n\n // Validate that the question was found before updating currentQuestionIndex\n if (questionIndex === -1) {\n // Silent validation - question not found\n return;\n }\n\n set({ currentQuestionIndex: questionIndex });\n },\n\n setAnswerStatus: (questionId, status) => {\n const { userAnswers } = get();\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n if (existingAnswerIndex !== -1) {\n const updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = {\n ...updatedUserAnswers[existingAnswerIndex],\n answerStatus: status,\n };\n set({ userAnswers: updatedUserAnswers });\n }\n },\n\n getAnswerStatus: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer ? userAnswer.answerStatus : null;\n },\n getQuestionIndex: (questionId) => {\n const { questionsResult, variant, quiz } = get();\n if (variant == 'result') {\n if (!questionsResult) return 0;\n\n let idx = questionsResult.answers.findIndex(\n (q) => q.questionId === questionId\n );\n if (idx === -1) {\n idx = questionsResult.answers.findIndex(\n (q) => q.id === questionId\n );\n }\n return idx !== -1 ? idx + 1 : 0;\n } else {\n if (!quiz) return 0;\n const idx = quiz.questions.findIndex((q) => q.id === questionId);\n return idx !== -1 ? idx + 1 : 0;\n }\n },\n\n // Question Result\n getQuestionResultByQuestionId: (questionId) => {\n const { questionsResult } = get();\n const question = questionsResult?.answers.find(\n (answer) => answer.questionId === questionId\n );\n\n return question || null;\n },\n getQuestionResultStatistics: () => {\n const { questionsResult } = get();\n return questionsResult?.statistics || null;\n },\n getQuestionResult: () => {\n const { questionsResult } = get();\n return questionsResult;\n },\n setQuestionsResult: (questionsResult) => {\n set({ questionsResult });\n },\n setCurrentQuestionResult: (currentQuestionResult) => {\n set({ currentQuestionResult });\n },\n getCurrentQuestionResult: () => {\n const { currentQuestionResult } = get();\n return currentQuestionResult;\n },\n };\n },\n {\n name: 'quiz-store',\n }\n )\n);\n","/**\n * Activity Details Types\n * Types and helper functions for activity details components\n */\n\nimport { z } from 'zod';\n\n/**\n * Student activity status enum\n */\nexport const STUDENT_ACTIVITY_STATUS = {\n CONCLUIDO: 'CONCLUIDO',\n AGUARDANDO_CORRECAO: 'AGUARDANDO_CORRECAO',\n AGUARDANDO_RESPOSTA: 'AGUARDANDO_RESPOSTA',\n NAO_ENTREGUE: 'NAO_ENTREGUE',\n} as const;\n\nexport type StudentActivityStatus =\n (typeof STUDENT_ACTIVITY_STATUS)[keyof typeof STUDENT_ACTIVITY_STATUS];\n\n/**\n * Zod schema for student activity status\n */\nexport const studentActivityStatusSchema = z.enum([\n STUDENT_ACTIVITY_STATUS.CONCLUIDO,\n STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO,\n STUDENT_ACTIVITY_STATUS.AGUARDANDO_RESPOSTA,\n STUDENT_ACTIVITY_STATUS.NAO_ENTREGUE,\n]);\n\n/**\n * Student data interface\n */\nexport interface ActivityStudentData {\n studentId: string;\n studentName: string;\n answeredAt: string | null;\n timeSpent: number;\n score: number | null;\n status: StudentActivityStatus;\n}\n\n/**\n * Pagination interface\n */\nexport interface Pagination {\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n hasNext?: boolean;\n hasPrev?: boolean;\n}\n\n/**\n * General statistics interface\n */\nexport interface GeneralStats {\n averageScore: number;\n completionPercentage: number;\n}\n\n/**\n * Question statistics interface\n */\nexport interface QuestionStats {\n mostCorrect: number[];\n mostIncorrect: number[];\n notAnswered: number[];\n}\n\n/**\n * Activity metadata interface\n */\nexport interface ActivityMetadata {\n id: string;\n title: string;\n type?: string;\n startDate: string | null;\n finalDate: string | null;\n schoolName: string;\n year: string;\n subjectName: string;\n className: string;\n}\n\n/**\n * Activity details data interface\n */\nexport interface ActivityDetailsData {\n activity?: ActivityMetadata;\n students: ActivityStudentData[];\n pagination: Pagination;\n generalStats: GeneralStats;\n questionStats: QuestionStats;\n}\n\n/**\n * Activity details query params interface\n */\nexport interface ActivityDetailsQueryParams {\n page?: number;\n limit?: number;\n sortBy?: 'name' | 'score' | 'answeredAt';\n sortOrder?: 'asc' | 'desc';\n status?: StudentActivityStatus;\n}\n\n/**\n * Activity student table item interface\n */\nexport interface ActivityStudentTableItem extends Record<string, unknown> {\n id: string;\n studentId: string;\n studentName: string;\n status: StudentActivityStatus;\n answeredAt: string | null;\n timeSpent: number;\n score: number | null;\n}\n\n/**\n * Status badge configuration interface\n */\nexport interface StatusBadgeConfig {\n label: string;\n bgColor: string;\n textColor: string;\n}\n\n/**\n * Activity availability status enum\n * Used to determine if an activity is available based on start/end dates\n */\nexport const ACTIVITY_AVAILABILITY = {\n DISPONIVEL: 'DISPONIVEL',\n NAO_INICIADA: 'NAO_INICIADA',\n EXPIRADA: 'EXPIRADA',\n} as const;\n\nexport type ActivityAvailability =\n (typeof ACTIVITY_AVAILABILITY)[keyof typeof ACTIVITY_AVAILABILITY];\n\n/**\n * Quiz API response\n */\nexport interface QuizResponse {\n message: string;\n data: ActivityMetadata;\n}\n\n/**\n * Activity details API response (without activity)\n */\nexport interface ActivityDetailsApiResponse {\n message: string;\n data: Omit<ActivityDetailsData, 'activity'>;\n}\n\n/**\n * Presigned URL response\n */\nexport interface PresignedUrlResponse {\n data: {\n url: string;\n fields: Record<string, string>;\n };\n}\n","/**\n * Activity Details Utilities\n * Helper functions for activity details components\n */\n\nimport type {\n StudentActivityStatus,\n StatusBadgeConfig,\n} from '../types/activityDetails';\nimport { STUDENT_ACTIVITY_STATUS } from '../types/activityDetails';\n\n/**\n * Get status badge configuration\n * @param status - Student activity status\n * @returns Status badge configuration with label and colors\n */\nexport const getStatusBadgeConfig = (\n status: StudentActivityStatus\n): StatusBadgeConfig => {\n const configs: Record<StudentActivityStatus, StatusBadgeConfig> = {\n [STUDENT_ACTIVITY_STATUS.CONCLUIDO]: {\n label: 'Concluído',\n bgColor: 'bg-green-50',\n textColor: 'text-green-800',\n },\n [STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO]: {\n label: 'Aguardando Correção',\n bgColor: 'bg-yellow-50',\n textColor: 'text-yellow-800',\n },\n [STUDENT_ACTIVITY_STATUS.AGUARDANDO_RESPOSTA]: {\n label: 'Aguardando Resposta',\n bgColor: 'bg-blue-50',\n textColor: 'text-blue-800',\n },\n [STUDENT_ACTIVITY_STATUS.NAO_ENTREGUE]: {\n label: 'Não Entregue',\n bgColor: 'bg-red-50',\n textColor: 'text-red-800',\n },\n };\n\n return configs[status];\n};\n\n/**\n * Format time spent in seconds to HH:MM:SS\n * @param seconds - Time in seconds\n * @returns Formatted time string in HH:MM:SS format\n */\nexport const formatTimeSpent = (seconds: number): string => {\n const totalSeconds = Math.floor(Math.abs(seconds));\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const secs = totalSeconds % 60;\n\n return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n};\n\n/**\n * Format question numbers to display\n * @param numbers - Array of zero-based question indices\n * @returns Formatted string with question numbers (1-indexed, padded)\n */\nexport const formatQuestionNumbers = (numbers: number[]): string => {\n if (numbers.length === 0) return '-';\n\n return numbers.map((n) => String(n + 1).padStart(2, '0')).join(', ');\n};\n\n/**\n * Format date string to Brazilian format (DD/MM/YYYY)\n * @param dateString - ISO date string\n * @returns Formatted date string\n */\nexport const formatDateToBrazilian = (dateString: string): string => {\n const date = new Date(dateString);\n const day = String(date.getUTCDate()).padStart(2, '0');\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const year = date.getUTCFullYear();\n return `${day}/${month}/${year}`;\n};\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n secondary:\n 'bg-text-950 text-text border border-text-800 hover:bg-text-800 hover:border-text-950 focus-visible:outline-none focus-visible:bg-text-900 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-text-700 active:border-text-700 disabled:bg-text-500 disabled:border-text-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n secondary:\n 'bg-transparent text-text-950 border border-text-800 hover:bg-background-50 hover:text-text-700 hover:border-text-700 focus-visible:border-0 focus-visible:outline-none focus-visible:text-text-900 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-text-700 active:border-text-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n secondary:\n 'bg-transparent text-text-950 hover:text-text-800 focus-visible:outline-none focus-visible:text-text-900 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-text-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'secondary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, secondary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { HTMLAttributes, ReactNode } from 'react';\nimport { Bell } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n error: 'bg-error-background text-error-700 focus-visible:outline-none',\n warning: 'bg-warning text-warning-800 focus-visible:outline-none',\n success: 'bg-success text-success-800 focus-visible:outline-none',\n info: 'bg-info text-info-800 focus-visible:outline-none',\n muted: 'bg-background-muted text-background-800 focus-visible:outline-none',\n },\n outlined: {\n error:\n 'bg-error text-error-700 border border-error-300 focus-visible:outline-none',\n warning:\n 'bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none',\n success:\n 'bg-success text-success-800 border border-success-300 focus-visible:outline-none',\n info: 'bg-info text-info-800 border border-info-300 focus-visible:outline-none',\n muted:\n 'bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none',\n },\n exams: {\n exam1: 'bg-exam-1 text-info-700 focus-visible:outline-none',\n exam2: 'bg-exam-2 text-typography-1 focus-visible:outline-none',\n exam3: 'bg-exam-3 text-typography-2 focus-visible:outline-none',\n exam4: 'bg-exam-4 text-success-700 focus-visible:outline-none',\n },\n examsOutlined: {\n exam1:\n 'bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none',\n exam2:\n 'bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none',\n exam3:\n 'bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none',\n exam4:\n 'bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none',\n },\n resultStatus: {\n negative: 'bg-error text-error-800 focus-visible:outline-none',\n positive: 'bg-success text-success-800 focus-visible:outline-none',\n },\n notification: 'text-primary',\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-2xs px-2 py-1',\n medium: 'text-xs px-2 py-1',\n large: 'text-sm px-2 py-1',\n} as const;\n\nconst SIZE_CLASSES_ICON = {\n small: 'size-3',\n medium: 'size-3.5',\n large: 'size-4',\n} as const;\n\n/**\n * Badge component props interface\n */\ntype BadgeProps = {\n /** Content to be displayed inside the badge */\n children?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Size of the badge */\n size?: 'small' | 'medium' | 'large';\n /** Visual variant of the badge */\n variant?:\n | 'solid'\n | 'outlined'\n | 'exams'\n | 'examsOutlined'\n | 'resultStatus'\n | 'notification';\n /** Action type of the badge */\n action?:\n | 'error'\n | 'warning'\n | 'success'\n | 'info'\n | 'muted'\n | 'exam1'\n | 'exam2'\n | 'exam3'\n | 'exam4'\n | 'positive'\n | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n notificationActive?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\n/**\n * Badge component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the badge\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard div HTML attributes\n * @returns A styled badge element\n *\n * @example\n * ```tsx\n * <Badge variant=\"solid\" action=\"info\" size=\"medium\">\n * Information\n * </Badge>\n * ```\n */\nconst Badge = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'error',\n className = '',\n notificationActive = false,\n ...props\n}: BadgeProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const sizeClassesIcon = SIZE_CLASSES_ICON[size];\n const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};\n const variantClasses =\n typeof variantActionMap === 'string'\n ? variantActionMap\n : ((variantActionMap as Record<string, string>)[action] ??\n (variantActionMap as Record<string, string>).muted ??\n '');\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-xs font-normal gap-1 relative';\n\n const baseClassesIcon = 'flex items-center';\n if (variant === 'notification') {\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n <Bell size={24} className=\"text-current\" aria-hidden=\"true\" />\n\n {notificationActive && (\n <span\n data-testid=\"notification-dot\"\n className=\"absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white\"\n />\n )}\n </div>\n );\n }\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n {iconLeft && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>{iconLeft}</span>\n )}\n {children}\n {iconRight && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>\n {iconRight}\n </span>\n )}\n </div>\n );\n};\n\nexport default Badge;\n","import { type ReactNode } from 'react';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\n\nexport interface EmptyStateProps {\n /**\n * Image source for the illustration (optional)\n */\n image?: string;\n /**\n * Title text to display\n * @default \"Nenhum dado disponível\"\n */\n title?: string;\n /**\n * Description text to display below the title\n * @default \"Não há dados para exibir no momento.\"\n */\n description?: string;\n /**\n * Button text (optional - if not provided, button won't be displayed)\n */\n buttonText?: string;\n /**\n * Icon to display on the left side of the button\n */\n buttonIcon?: ReactNode;\n /**\n * Callback function when button is clicked\n */\n onButtonClick?: () => void;\n /**\n * Button variant\n * @default \"solid\"\n */\n buttonVariant?: 'solid' | 'outline' | 'link';\n /**\n * Button action color\n * @default \"primary\"\n */\n buttonAction?: 'primary' | 'positive' | 'negative';\n}\n\n/**\n * Component displayed when there is no data to show (empty state)\n * Shows an illustration with customizable title, description, and optional button in horizontal layout\n *\n * @example\n * ```tsx\n * import { EmptyState } from 'analytica-frontend-lib';\n * import activityImage from './assets/activity.png';\n * import { Plus } from 'phosphor-react';\n *\n * <EmptyState\n * image={activityImage}\n * title=\"Incentive sua turma ao aprendizado\"\n * description=\"Crie uma nova atividade e ajude seus alunos a colocarem o conteúdo em prática!\"\n * buttonText=\"Criar atividade\"\n * buttonIcon={<Plus size={18} />}\n * buttonVariant=\"outline\"\n * onButtonClick={handleCreateActivity}\n * />\n * ```\n */\nconst EmptyState = ({\n image,\n title,\n description,\n buttonText,\n buttonIcon,\n onButtonClick,\n buttonVariant = 'solid',\n buttonAction = 'primary',\n}: EmptyStateProps) => {\n const displayTitle = title || 'Nenhum dado disponível';\n const displayDescription =\n description || 'Não há dados para exibir no momento.';\n\n return (\n <div className=\"flex flex-col justify-center items-center gap-6 w-full min-h-[705px] bg-background rounded-xl p-6\">\n {/* Illustration */}\n {image && (\n <img src={image} alt={displayTitle} className=\"w-[170px] h-[150px]\" />\n )}\n\n {/* Text Content Container */}\n <div className=\"flex flex-col items-center gap-4 w-full max-w-[600px] px-6\">\n {/* Title */}\n <Text\n as=\"h2\"\n className=\"text-text-950 font-semibold text-3xl leading-[35px] text-center\"\n >\n {displayTitle}\n </Text>\n\n {/* Description */}\n <Text className=\"text-text-600 font-normal text-[18px] leading-[27px] text-center\">\n {displayDescription}\n </Text>\n </div>\n\n {/* Button */}\n {buttonText && onButtonClick && (\n <Button\n variant={buttonVariant}\n action={buttonAction}\n size=\"large\"\n onClick={onButtonClick}\n iconLeft={buttonIcon}\n className=\"rounded-full px-5 py-2.5\"\n >\n {buttonText}\n </Button>\n )}\n </div>\n );\n};\n\nexport default EmptyState;\n","import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\nimport { cn } from '../../utils/utils';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col', spacingClass, className)}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={cn(variantClass, animationClass)}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={cn(variantClass, animationClass, className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full p-4 bg-background border border-border-200 rounded-lg',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('space-y-3', className)} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n","import { useState, useEffect, useMemo, useCallback, ReactNode } from 'react';\nimport Table, {\n TableBody,\n TableHead,\n TableRow,\n TableCell,\n useTableSort,\n TablePagination,\n} from '../Table/Table';\nimport { useTableFilter, FilterConfig } from '../Filter/useTableFilter';\nimport Search from '../Search/Search';\nimport { FilterModal } from '../Filter/FilterModal';\nimport Button from '../Button/Button';\nimport { Funnel } from 'phosphor-react';\n\n/**\n * Column configuration with flexible rendering options\n */\nexport interface ColumnConfig<T = Record<string, unknown>> {\n /** Column key (must match data object key) */\n key: string;\n /** Column label - can be string or JSX */\n label: string | ReactNode;\n /** Enable sorting for this column */\n sortable?: boolean;\n /** Custom render function for cell content */\n render?: (value: unknown, row: T, index: number) => ReactNode;\n /** Column width */\n width?: string;\n /** Additional CSS classes */\n className?: string;\n /** Text alignment */\n align?: 'left' | 'center' | 'right';\n}\n\n/**\n * Combined parameters sent via onParamsChange\n */\nexport interface TableParams {\n /** Current page number */\n page: number;\n /** Items per page */\n limit: number;\n /** Search query */\n search?: string;\n /** Active filters (dynamic keys based on filter configs) */\n [key: string]: unknown;\n /** Sort column */\n sortBy?: string;\n /** Sort direction */\n sortOrder?: 'asc' | 'desc';\n}\n\n/**\n * Pagination configuration\n */\nexport interface PaginationConfig {\n /** Label for items (e.g., \"atividades\") */\n itemLabel?: string;\n /** Items per page options */\n itemsPerPageOptions?: number[];\n /** Default items per page */\n defaultItemsPerPage?: number;\n /** Total items (for displaying pagination info) */\n totalItems?: number;\n /** Total pages (if known from backend) */\n totalPages?: number;\n}\n\n/**\n * Empty state configuration\n */\nexport interface EmptyStateConfig {\n /** Custom component to render when table is empty (no data and no search active) */\n component?: ReactNode;\n /** Image to display in empty state (path from project) */\n image?: string;\n /** Title text for empty state */\n title?: string;\n /** Description text for empty state */\n description?: string;\n /** Button text for empty state action (optional) */\n buttonText?: string;\n /** Icon to display on button (optional) */\n buttonIcon?: ReactNode;\n /** Callback when empty state button is clicked */\n onButtonClick?: () => void;\n /** Button variant (solid, outline, or link) */\n buttonVariant?: 'solid' | 'outline' | 'link';\n /** Button action color (primary, positive, or negative) */\n buttonAction?: 'primary' | 'positive' | 'negative';\n}\n\n/**\n * Loading state configuration\n */\nexport interface LoadingStateConfig {\n /** Custom component to render when table is loading */\n component?: ReactNode;\n}\n\n/**\n * No search result state configuration\n */\nexport interface NoSearchResultConfig {\n /** Custom component to render when search returns no results */\n component?: ReactNode;\n /** Title for no search result state */\n title?: string;\n /** Description for no search result state */\n description?: string;\n /** Image to display in no search result state */\n image?: string;\n}\n\n/**\n * Table components exposed via render prop\n */\nexport interface TableComponents {\n /** Search and filter controls */\n controls: ReactNode;\n /** Table with data */\n table: ReactNode;\n /** Pagination controls */\n pagination: ReactNode;\n}\n\n/**\n * TableProvider Props\n */\nexport interface TableProviderProps<T = Record<string, unknown>> {\n /** Data to display in the table */\n readonly data: T[];\n /** Column configurations */\n readonly headers: ColumnConfig<T>[];\n /** Loading state */\n readonly loading?: boolean;\n /** Table variant */\n readonly variant?: 'default' | 'borderless';\n\n /** Enable search functionality */\n readonly enableSearch?: boolean;\n /** Enable filters functionality */\n readonly enableFilters?: boolean;\n /** Enable table sorting */\n readonly enableTableSort?: boolean;\n /** Enable pagination */\n readonly enablePagination?: boolean;\n /** Enable row click functionality */\n readonly enableRowClick?: boolean;\n\n /** Initial filter configurations */\n readonly initialFilters?: FilterConfig[];\n /** Pagination configuration */\n readonly paginationConfig?: PaginationConfig;\n /** Search placeholder text */\n readonly searchPlaceholder?: string;\n /** Empty state configuration (when table is empty with no search) */\n readonly emptyState?: EmptyStateConfig;\n /** Loading state configuration (when table is loading) */\n readonly loadingState?: LoadingStateConfig;\n /** No search result state configuration (when search returns no results) */\n readonly noSearchResultState?: NoSearchResultConfig;\n /** Key field name to use for unique row identification (recommended for better performance) */\n readonly rowKey?: keyof T;\n\n /** Callback when any parameter changes */\n readonly onParamsChange?: (params: TableParams) => void;\n /** Callback when row is clicked */\n readonly onRowClick?: (row: T, index: number) => void;\n\n /**\n * Content to display in the header area (e.g., action buttons)\n * Rendered above the search/filter controls\n */\n readonly headerContent?: ReactNode;\n\n /**\n * Additional CSS classes for the container wrapper\n */\n readonly containerClassName?: string;\n\n /**\n * Render prop for custom layout control\n * When provided, gives full control over component positioning\n * @param components - Table components (controls, table, pagination)\n * @returns Custom layout JSX\n *\n * @example\n * ```tsx\n * <TableProvider {...props}>\n * {({ controls, table, pagination }) => (\n * <>\n * <div className=\"mb-4\">{controls}</div>\n * <div className=\"bg-white p-6\">\n * {table}\n * {pagination}\n * </div>\n * </>\n * )}\n * </TableProvider>\n * ```\n */\n readonly children?: (components: TableComponents) => ReactNode;\n}\n\n/**\n * TableProvider - Self-contained table component with search, filters, sorting, and pagination\n *\n * @example\n * ```tsx\n * <TableProvider\n * data={activities}\n * headers={[\n * { key: 'title', label: 'Título', sortable: true },\n * { key: 'status', label: 'Status', render: (value) => <Badge>{value}</Badge> }\n * ]}\n * loading={loading}\n * variant=\"borderless\"\n * enableSearch\n * enableFilters\n * enableTableSort\n * enablePagination\n * enableRowClick\n * initialFilters={filterConfigs}\n * paginationConfig={{ itemLabel: 'atividades' }}\n * onParamsChange={handleParamsChange}\n * onRowClick={handleRowClick}\n * />\n * ```\n */\nexport function TableProvider<T extends Record<string, unknown>>({\n data,\n headers,\n loading = false,\n variant = 'default',\n enableSearch = false,\n enableFilters = false,\n enableTableSort = false,\n enablePagination = false,\n enableRowClick = false,\n initialFilters = [],\n paginationConfig = {},\n searchPlaceholder = 'Buscar...',\n emptyState,\n loadingState,\n noSearchResultState,\n rowKey,\n onParamsChange,\n onRowClick,\n headerContent,\n containerClassName,\n children,\n}: TableProviderProps<T>) {\n // Search state\n const [searchQuery, setSearchQuery] = useState('');\n\n // Sorting state - always call hook (React Rules of Hooks)\n const sortResultRaw = useTableSort(data, { syncWithUrl: true });\n const sortResult = enableTableSort\n ? sortResultRaw\n : {\n sortedData: data,\n sortColumn: null,\n sortDirection: null,\n handleSort: () => {},\n };\n\n const { sortedData, sortColumn, sortDirection, handleSort } = sortResult;\n\n // Filter state - always call hook (React Rules of Hooks)\n const filterResultRaw = useTableFilter(initialFilters, { syncWithUrl: true });\n\n // Memoize disabled filter result to prevent recreating object on every render\n const disabledFilterResult = useMemo(\n () => ({\n filterConfigs: [],\n activeFilters: {},\n hasActiveFilters: false,\n updateFilters: () => {},\n applyFilters: () => {},\n clearFilters: () => {},\n }),\n []\n );\n\n const filterResult = enableFilters ? filterResultRaw : disabledFilterResult;\n\n const {\n filterConfigs,\n activeFilters,\n hasActiveFilters,\n updateFilters,\n applyFilters,\n clearFilters,\n } = filterResult;\n\n // Pagination state (only if enabled)\n const {\n defaultItemsPerPage = 10,\n itemsPerPageOptions = [10, 20, 50, 100],\n itemLabel = 'itens',\n totalItems,\n totalPages,\n } = paginationConfig;\n\n const [currentPage, setCurrentPage] = useState(1);\n const [itemsPerPage, setItemsPerPage] = useState(defaultItemsPerPage);\n\n // Filter modal state\n const [isFilterModalOpen, setIsFilterModalOpen] = useState(false);\n\n // Combine all parameters\n const combinedParams = useMemo((): TableParams => {\n const params: TableParams = {\n page: currentPage,\n limit: itemsPerPage,\n };\n\n if (enableSearch && searchQuery) {\n params.search = searchQuery;\n }\n\n if (enableFilters) {\n Object.assign(params, activeFilters);\n }\n\n if (enableTableSort && sortColumn && sortDirection) {\n params.sortBy = sortColumn;\n params.sortOrder = sortDirection;\n }\n\n return params;\n }, [\n currentPage,\n itemsPerPage,\n searchQuery,\n activeFilters,\n sortColumn,\n sortDirection,\n enableSearch,\n enableFilters,\n enableTableSort,\n ]);\n\n // Notify parent when parameters change\n // Note: onParamsChange is omitted from dependencies intentionally to prevent infinite loops\n useEffect(() => {\n onParamsChange?.(combinedParams);\n }, [combinedParams]);\n\n // Handle search changes\n const handleSearchChange = useCallback((value: string) => {\n setSearchQuery(value);\n setCurrentPage(1); // Reset to first page on search\n }, []);\n\n // Handle filter apply\n const handleFilterApply = useCallback(() => {\n applyFilters();\n setIsFilterModalOpen(false);\n setCurrentPage(1); // Reset to first page on filter\n }, [applyFilters]);\n\n // Handle pagination change\n const handlePageChange = useCallback((page: number) => {\n setCurrentPage(page);\n }, []);\n\n const handleItemsPerPageChange = useCallback((items: number) => {\n setItemsPerPage(items);\n setCurrentPage(1); // Reset to first page when changing items per page\n }, []);\n\n // Handle row click\n const handleRowClickInternal = useCallback(\n (row: T, index: number) => {\n if (enableRowClick && onRowClick) {\n onRowClick(row, index);\n }\n },\n [enableRowClick, onRowClick]\n );\n\n // Detect if pagination should be managed internally\n const useInternalPagination = useMemo(\n () =>\n enablePagination &&\n !onParamsChange &&\n totalItems === undefined &&\n totalPages === undefined,\n [enablePagination, onParamsChange, totalItems, totalPages]\n );\n\n // Calculate total pages from data if not provided\n const calculatedTotalPages =\n totalPages ??\n Math.ceil(\n (totalItems ??\n (useInternalPagination ? sortedData.length : data.length)) /\n itemsPerPage\n );\n const calculatedTotalItems =\n totalItems ?? (useInternalPagination ? sortedData.length : data.length);\n\n // Apply pagination to data when managed internally\n const displayData = useMemo(() => {\n if (!useInternalPagination) {\n return sortedData;\n }\n\n const start = (currentPage - 1) * itemsPerPage;\n return sortedData.slice(start, start + itemsPerPage);\n }, [useInternalPagination, sortedData, currentPage, itemsPerPage]);\n\n // Empty state check\n const isEmpty = data.length === 0;\n\n // Calculate state control booleans - Table is responsible for rendering, TableProvider controls WHEN\n const showLoading = loading;\n const showNoSearchResult =\n !loading && data.length === 0 && searchQuery.trim() !== '';\n const showEmpty = !loading && data.length === 0 && searchQuery.trim() === '';\n\n // Extract components for render prop pattern\n const controls = (enableSearch || enableFilters) && (\n <div className=\"flex items-center gap-4\">\n {/* Filter Button */}\n {enableFilters && (\n <Button\n variant=\"outline\"\n size=\"medium\"\n onClick={() => setIsFilterModalOpen(true)}\n >\n <Funnel size={20} />\n Filtros\n {hasActiveFilters && (\n <span className=\"ml-2 rounded-full bg-primary-500 px-2 py-0.5 text-xs text-white\">\n {Object.keys(activeFilters).length}\n </span>\n )}\n </Button>\n )}\n\n {/* Search */}\n {enableSearch && (\n <div className=\"flex-1\">\n <Search\n value={searchQuery}\n onSearch={handleSearchChange}\n onClear={() => handleSearchChange('')}\n options={[]}\n placeholder={searchPlaceholder}\n />\n </div>\n )}\n </div>\n );\n\n // Header with content and controls\n const headerSection = (headerContent || controls) && (\n <div className=\"flex flex-col md:flex-row items-stretch md:items-center justify-between gap-4\">\n {/* Header Content (e.g., action buttons) */}\n {headerContent && <div>{headerContent}</div>}\n\n {/* Controls (search and filters) */}\n {controls && <div className=\"flex-1 md:flex-none\">{controls}</div>}\n </div>\n );\n\n const table = (\n <div className=\"w-full overflow-x-auto\">\n <Table\n variant={variant}\n showLoading={showLoading}\n loadingState={loadingState}\n showNoSearchResult={showNoSearchResult}\n noSearchResultState={noSearchResultState}\n showEmpty={showEmpty}\n emptyState={emptyState}\n >\n {/* Table Header */}\n <thead>\n <TableRow\n variant={variant === 'borderless' ? 'defaultBorderless' : 'default'}\n >\n {headers.map((header, index) => (\n <TableHead\n key={`header-${header.key}-${index}`}\n sortable={enableTableSort && header.sortable}\n sortDirection={\n enableTableSort && sortColumn === header.key\n ? sortDirection\n : null\n }\n onSort={() =>\n enableTableSort && header.sortable && handleSort(header.key)\n }\n className={header.className}\n style={header.width ? { width: header.width } : undefined}\n >\n {header.label}\n </TableHead>\n ))}\n </TableRow>\n </thead>\n\n {/* Table Body */}\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={headers.length} className=\"text-center py-8\">\n <span className=\"text-text-400 text-sm\">Carregando...</span>\n </TableCell>\n </TableRow>\n ) : (\n displayData.map((row, rowIndex) => {\n // Calculate effective index for row click and keys\n const effectiveIndex = useInternalPagination\n ? (currentPage - 1) * itemsPerPage + rowIndex\n : rowIndex;\n\n const rowKeyValue = rowKey\n ? (() => {\n const keyValue = row[rowKey];\n if (keyValue === null || keyValue === undefined) {\n return `row-${effectiveIndex}`;\n }\n if (typeof keyValue === 'object') {\n return JSON.stringify(keyValue);\n }\n return String(keyValue);\n })()\n : `row-${effectiveIndex}`;\n return (\n <TableRow\n key={rowKeyValue}\n variant={\n variant === 'borderless' ? 'defaultBorderless' : 'default'\n }\n clickable={enableRowClick}\n onClick={() => handleRowClickInternal(row, effectiveIndex)}\n >\n {headers.map((header, cellIndex) => {\n const value = row[header.key];\n\n let defaultContent = '';\n\n if (value !== null && value !== undefined) {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'bigint'\n ) {\n // Only convert primitives directly to string\n defaultContent = String(value);\n } else if (typeof value === 'object') {\n // Serialize objects and arrays with JSON\n defaultContent = JSON.stringify(value);\n } else if (typeof value === 'function') {\n // Handle functions - don't expose function code\n defaultContent = '[Function]';\n } else if (typeof value === 'symbol') {\n // Handle symbols\n defaultContent = String(value);\n }\n // All possible types covered - no else needed\n }\n\n const content = header.render\n ? header.render(value, row, effectiveIndex)\n : defaultContent;\n\n return (\n <TableCell\n key={`cell-${effectiveIndex}-${cellIndex}`}\n className={header.className}\n style={{\n textAlign: header.align,\n }}\n >\n {content}\n </TableCell>\n );\n })}\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n );\n\n const pagination = enablePagination && !isEmpty && (\n <div className=\"flex justify-end\">\n <TablePagination\n currentPage={currentPage}\n totalPages={calculatedTotalPages}\n totalItems={calculatedTotalItems}\n itemsPerPage={itemsPerPage}\n itemsPerPageOptions={itemsPerPageOptions}\n onPageChange={handlePageChange}\n onItemsPerPageChange={handleItemsPerPageChange}\n itemLabel={itemLabel}\n />\n </div>\n );\n\n // If children prop provided, use render props pattern\n if (children) {\n return (\n <>\n {children({\n controls: headerSection || controls || null,\n table,\n pagination,\n })}\n {/* Filter Modal */}\n {enableFilters && (\n <FilterModal\n isOpen={isFilterModalOpen}\n onClose={() => setIsFilterModalOpen(false)}\n filterConfigs={filterConfigs}\n onFiltersChange={updateFilters}\n onApply={handleFilterApply}\n onClear={clearFilters}\n />\n )}\n </>\n );\n }\n\n // Default layout (backward compatible)\n const wrapperClassName = containerClassName || 'w-full space-y-4';\n return (\n <div className={wrapperClassName}>\n {headerSection}\n {table}\n {pagination}\n\n {/* Filter Modal */}\n {enableFilters && (\n <FilterModal\n isOpen={isFilterModalOpen}\n onClose={() => setIsFilterModalOpen(false)}\n filterConfigs={filterConfigs}\n onFiltersChange={updateFilters}\n onApply={handleFilterApply}\n onClear={clearFilters}\n />\n )}\n </div>\n );\n}\n\nexport default TableProvider;\n","import React, {\n forwardRef,\n HTMLAttributes,\n TdHTMLAttributes,\n ThHTMLAttributes,\n useState,\n useMemo,\n useEffect,\n Children,\n isValidElement,\n ReactNode,\n} from 'react';\nimport { cn } from '../../utils/utils';\nimport { CaretUp, CaretDown } from 'phosphor-react';\nimport NoSearchResult from '../NoSearchResult/NoSearchResult';\nimport EmptyState from '../EmptyState/EmptyState';\nimport { SkeletonTable } from '../Skeleton/Skeleton';\nimport type {\n EmptyStateConfig,\n LoadingStateConfig,\n NoSearchResultConfig,\n} from '../TableProvider/TableProvider';\n\ntype TableVariant = 'default' | 'borderless';\ntype TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';\nexport type SortDirection = 'asc' | 'desc' | null;\n\nexport interface UseTableSortOptions {\n /** Se true, sincroniza o estado de ordenação com os parâmetros da URL */\n syncWithUrl?: boolean;\n}\n\n/**\n * Hook para gerenciar ordenação de dados da tabela\n *\n * @param data - Array de dados a serem ordenados\n * @param options - Opções de configuração do hook\n * @returns Objeto com dados ordenados, coluna/direção atual e função de sort\n *\n * @example\n * ```tsx\n * const activities = [\n * { id: 1, name: 'Task A', date: '2024-01-01' },\n * { id: 2, name: 'Task B', date: '2024-01-02' },\n * ];\n *\n * // Sem sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);\n *\n * // Com sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });\n *\n * <TableHead\n * sortDirection={sortColumn === 'name' ? sortDirection : null}\n * onSort={() => handleSort('name')}\n * >\n * Name\n * </TableHead>\n * ```\n */\nexport function useTableSort<T extends Record<string, unknown>>(\n data: T[],\n options: UseTableSortOptions = {}\n) {\n const { syncWithUrl = false } = options;\n\n // Inicializar estado a partir da URL se syncWithUrl estiver habilitado\n const getInitialState = () => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return { column: null, direction: null };\n }\n\n const params = new URLSearchParams(globalThis.location.search);\n const sortBy = params.get('sortBy');\n const sort = params.get('sort');\n\n if (sortBy && sort && (sort === 'ASC' || sort === 'DESC')) {\n return {\n column: sortBy,\n direction: sort.toLowerCase() as SortDirection,\n };\n }\n\n return { column: null, direction: null };\n };\n\n const initialState = getInitialState();\n const [sortColumn, setSortColumn] = useState<string | null>(\n initialState.column\n );\n const [sortDirection, setSortDirection] = useState<SortDirection>(\n initialState.direction\n );\n\n // Atualizar URL quando o estado de ordenação mudar\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) return;\n\n const url = new URL(globalThis.location.href);\n const params = url.searchParams;\n\n if (sortColumn && sortDirection) {\n params.set('sortBy', sortColumn);\n params.set('sort', sortDirection.toUpperCase());\n } else {\n params.delete('sortBy');\n params.delete('sort');\n }\n\n // Atualizar URL sem recarregar a página\n globalThis.history.replaceState({}, '', url.toString());\n }, [sortColumn, sortDirection, syncWithUrl]);\n\n const handleSort = (column: string) => {\n if (sortColumn === column) {\n if (sortDirection === 'asc') {\n setSortDirection('desc');\n } else if (sortDirection === 'desc') {\n setSortColumn(null);\n setSortDirection(null);\n }\n } else {\n setSortColumn(column);\n setSortDirection('asc');\n }\n };\n\n const sortedData = useMemo(() => {\n if (!sortColumn || !sortDirection) {\n return data;\n }\n\n return [...data].sort((a, b) => {\n const aValue = a[sortColumn as keyof T];\n const bValue = b[sortColumn as keyof T];\n\n if (typeof aValue === 'string' && typeof bValue === 'string') {\n const comparison = aValue.localeCompare(bValue);\n return sortDirection === 'asc' ? comparison : -comparison;\n }\n\n if (typeof aValue === 'number' && typeof bValue === 'number') {\n return sortDirection === 'asc' ? aValue - bValue : bValue - aValue;\n }\n\n return 0;\n });\n }, [data, sortColumn, sortDirection]);\n\n return { sortedData, sortColumn, sortDirection, handleSort };\n}\n\ninterface TableProps extends HTMLAttributes<HTMLTableElement> {\n variant?: TableVariant;\n\n /** Show loading state (controlled by TableProvider) */\n showLoading?: boolean;\n /** Loading state configuration */\n loadingState?: LoadingStateConfig;\n\n /** Show no search result state (controlled by TableProvider) */\n showNoSearchResult?: boolean;\n /** No search result state configuration */\n noSearchResultState?: NoSearchResultConfig;\n\n /** Show empty state (controlled by TableProvider) */\n showEmpty?: boolean;\n /** Empty state configuration */\n emptyState?: EmptyStateConfig;\n}\n\ninterface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n state?: TableRowState;\n}\n\n/**\n * Renders the table header and caption from children\n */\nconst renderHeaderElements = (children: ReactNode) => {\n return Children.map(children, (child) => {\n if (\n isValidElement(child) &&\n (child.type === TableCaption || child.type === TableHeader)\n ) {\n return child;\n }\n return null;\n });\n};\n\n/**\n * Gets no search result content based on configuration\n */\nconst getNoSearchResultContent = (\n config: NoSearchResultConfig,\n defaultTitle: string,\n defaultDescription: string\n) => {\n if (config.component) {\n return config.component;\n }\n\n if (config.image) {\n return (\n <NoSearchResult\n image={config.image}\n title={config.title || defaultTitle}\n description={config.description || defaultDescription}\n />\n );\n }\n\n return (\n <div className=\"text-center\">\n <p className=\"text-text-600 text-lg font-semibold mb-2\">\n {config.title || defaultTitle}\n </p>\n <p className=\"text-text-500 text-sm\">\n {config.description || defaultDescription}\n </p>\n </div>\n );\n};\n\n/**\n * Gets empty state content based on configuration\n */\nconst getEmptyStateContent = (\n config: EmptyStateConfig | undefined,\n defaultTitle: string,\n defaultDescription: string\n) => {\n if (config?.component) {\n return config.component;\n }\n\n return (\n <EmptyState\n image={config?.image}\n title={config?.title || defaultTitle}\n description={config?.description || defaultDescription}\n buttonText={config?.buttonText}\n buttonIcon={config?.buttonIcon}\n onButtonClick={config?.onButtonClick}\n buttonVariant={config?.buttonVariant}\n buttonAction={config?.buttonAction}\n />\n );\n};\n\n/**\n * Renders table wrapper with header and state content\n */\nconst renderTableWrapper = (\n variant: TableVariant,\n tableRef: React.Ref<HTMLTableElement>,\n className: string | undefined,\n children: ReactNode,\n stateContent: ReactNode,\n tableProps: HTMLAttributes<HTMLTableElement>\n) => {\n return (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={tableRef}\n className={cn(\n 'analytica-table w-full caption-bottom text-sm border-separate border-spacing-0',\n className\n )}\n {...tableProps}\n >\n {renderHeaderElements(children)}\n </table>\n <div className=\"py-8 flex justify-center\">{stateContent}</div>\n </div>\n );\n};\n\nconst Table = forwardRef<HTMLTableElement, TableProps>(\n (\n {\n variant = 'default',\n className,\n children,\n showLoading = false,\n loadingState,\n showNoSearchResult = false,\n noSearchResultState,\n showEmpty = false,\n emptyState,\n ...props\n },\n ref\n ) => {\n // Default configurations\n const defaultNoSearchResultState: NoSearchResultConfig = {\n title: 'Nenhum resultado encontrado',\n description:\n 'Não encontramos nenhum resultado com esse nome. Tente revisar a busca ou usar outra palavra-chave.',\n };\n\n const defaultEmptyState: EmptyStateConfig = {\n title: 'Nenhum dado disponível',\n description: 'Não há dados para exibir no momento.',\n };\n\n const finalNoSearchResultState =\n noSearchResultState || defaultNoSearchResultState;\n const finalEmptyState = emptyState || defaultEmptyState;\n\n // Render Loading State FIRST (highest priority)\n if (showLoading) {\n const loadingContent = loadingState?.component || (\n <SkeletonTable rows={5} columns={4} showHeader={false} />\n );\n return renderTableWrapper(\n variant,\n ref,\n className,\n children,\n loadingContent,\n props\n );\n }\n\n // Render NoSearchResult outside table\n if (showNoSearchResult) {\n const noSearchContent = getNoSearchResultContent(\n finalNoSearchResultState,\n defaultNoSearchResultState.title || '',\n defaultNoSearchResultState.description || ''\n );\n return renderTableWrapper(\n variant,\n ref,\n className,\n children,\n noSearchContent,\n props\n );\n }\n\n // Render Empty State outside table (same pattern as NoSearchResult)\n if (showEmpty) {\n const emptyContent = getEmptyStateContent(\n finalEmptyState,\n defaultEmptyState.title || 'Nenhum dado disponível',\n defaultEmptyState.description || 'Não há dados para exibir no momento.'\n );\n return renderTableWrapper(\n variant,\n ref,\n className,\n children,\n emptyContent,\n props\n );\n }\n\n return (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={ref}\n className={cn(\n variant === 'default' && 'analytica-table',\n variant === 'default' && 'border-separate border-spacing-0',\n 'w-full caption-bottom text-sm',\n className\n )}\n {...props}\n >\n {/* Render fallback caption only if no TableCaption provided */}\n {!Children.toArray(children).some(\n (child) => isValidElement(child) && child.type === TableCaption\n ) && <caption className=\"sr-only\">My Table</caption>}\n {children}\n </table>\n </div>\n );\n }\n);\n\nTable.displayName = 'Table';\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead\n ref={ref}\n className={cn('[&_tr:first-child]:border-0', className)}\n {...props}\n />\n));\nTableHeader.displayName = 'TableHeader';\n\ninterface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, variant = 'default', ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-border-200',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableBody.displayName = 'TableBody';\n\ninterface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableFooter = forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ variant = 'default', className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'bg-background-50 font-medium [&>tr]:last:border-b-0 px-6 py-3.5',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableFooter.displayName = 'TableFooter';\n\nconst VARIANT_STATES_ROW = {\n default: {\n default: 'border border-border-200',\n defaultBorderless: 'border-b border-border-200',\n borderless: '',\n },\n selected: {\n default: 'border-b-2 border-indicator-primary',\n defaultBorderless: 'border-b border-indicator-primary',\n borderless: 'bg-indicator-primary/10',\n },\n invalid: {\n default: 'border-b-2 border-indicator-error',\n defaultBorderless: 'border-b border-indicator-error',\n borderless: 'bg-indicator-error/10',\n },\n disabled: {\n default:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n defaultBorderless:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n borderless: 'bg-background-50 opacity-50 cursor-not-allowed',\n },\n} as const;\n\ninterface TableRowPropsExtended extends TableRowProps {\n variant?: TableVariant | 'defaultBorderless';\n clickable?: boolean;\n}\n\nconst TableRow = forwardRef<HTMLTableRowElement, TableRowPropsExtended>(\n (\n {\n variant = 'default',\n state = 'default',\n clickable = false,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <tr\n ref={ref}\n className={cn(\n 'transition-colors',\n state === 'disabled' ? '' : 'hover:bg-muted/50',\n state === 'disabled' || !clickable ? '' : 'cursor-pointer',\n VARIANT_STATES_ROW[state][variant],\n className\n )}\n aria-disabled={state === 'disabled'}\n {...props}\n />\n );\n }\n);\nTableRow.displayName = 'TableRow';\n\ninterface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Enable sorting on this column (default: true) */\n sortable?: boolean;\n /** Current sort direction for this column */\n sortDirection?: SortDirection;\n /** Callback when column header is clicked */\n onSort?: () => void;\n}\n\nconst TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n sortable = true,\n sortDirection = null,\n onSort,\n children,\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (sortable && onSort) {\n onSort();\n }\n };\n\n return (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-6 py-3.5 text-left align-middle font-bold text-base text-text-800 tracking-[0.2px] leading-none [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] whitespace-nowrap',\n sortable && 'cursor-pointer select-none hover:bg-muted/30',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' && (\n <CaretUp size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n {sortDirection === 'desc' && (\n <CaretDown size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n </div>\n )}\n </div>\n </th>\n );\n }\n);\nTableHead.displayName = 'TableHead';\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-base font-normal text-text-800 leading-[150%] tracking-normal px-6 py-3.5 whitespace-nowrap',\n className\n )}\n {...props}\n />\n));\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = forwardRef<\n HTMLTableCaptionElement,\n HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn(\n 'border-t border-border-200 text-sm text-text-800 px-6 py-3.5',\n className\n )}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport { default as TablePagination } from './TablePagination';\nexport type { TablePaginationProps } from './TablePagination';\n\nexport default Table;\nexport {\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n","import Text from '../Text/Text';\n\nexport interface NoSearchResultProps {\n /**\n * Image source for the illustration\n */\n image: string;\n /**\n * Title text to display\n * @default \"Nenhum resultado encontrado\"\n */\n title?: string;\n /**\n * Description text to display below the title\n * @default \"Não encontramos nenhum resultado com esse nome. Tente revisar a busca ou usar outra palavra-chave.\"\n */\n description?: string;\n}\n\n/**\n * Component displayed when no search results are found\n * Shows an illustration with customizable title and description in horizontal layout\n *\n * @example\n * ```tsx\n * import { NoSearchResult } from 'analytica-frontend-lib';\n * import noSearchImage from './assets/no-search.png';\n *\n * <NoSearchResult\n * image={noSearchImage}\n * title=\"Nenhum resultado encontrado\"\n * description=\"Tente usar outros filtros\"\n * />\n * ```\n */\nconst NoSearchResult = ({ image, title, description }: NoSearchResultProps) => {\n const displayTitle = title || 'Nenhum resultado encontrado';\n const displayDescription =\n description ||\n 'Não encontramos nenhum resultado com esse nome. Tente revisar a busca ou usar outra palavra-chave.';\n\n return (\n <div className=\"flex flex-row justify-center items-center gap-8 w-full max-w-4xl min-h-96\">\n {/* Illustration */}\n <div className=\"w-72 h-72 flex-shrink-0 relative\">\n <img\n src={image}\n alt=\"No search results\"\n className=\"w-full h-full object-contain\"\n />\n </div>\n\n {/* Text Content */}\n <div className=\"flex flex-col items-start w-full max-w-md\">\n {/* Header Container */}\n <div className=\"flex flex-row justify-between items-end px-6 pt-6 pb-4 w-full rounded-t-xl\">\n {/* Title */}\n <Text\n as=\"h2\"\n className=\"text-text-950 font-semibold text-3xl leading-tight w-full flex items-center\"\n >\n {displayTitle}\n </Text>\n </div>\n\n {/* Description Container */}\n <div className=\"flex flex-row justify-center items-center px-6 gap-2 w-full\">\n {/* Description */}\n <Text className=\"text-text-600 font-normal text-lg leading-relaxed w-full text-justify\">\n {displayDescription}\n </Text>\n </div>\n </div>\n </div>\n );\n};\n\nexport default NoSearchResult;\n","import { HTMLAttributes, ChangeEvent } from 'react';\nimport { CaretLeft, CaretRight, CaretDown } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nexport interface TablePaginationProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Total number of items\n */\n totalItems: number;\n /**\n * Current page (1-based)\n */\n currentPage: number;\n /**\n * Total number of pages\n */\n totalPages: number;\n /**\n * Items per page\n */\n itemsPerPage: number;\n /**\n * Available options for items per page\n * @default [10, 20, 50, 100]\n */\n itemsPerPageOptions?: number[];\n /**\n * Callback when page changes\n */\n onPageChange: (page: number) => void;\n /**\n * Callback when items per page changes\n */\n onItemsPerPageChange?: (itemsPerPage: number) => void;\n /**\n * Customizable label for items (e.g., \"escolas\", \"alunos\", \"atividades\")\n * @default \"itens\"\n */\n itemLabel?: string;\n}\n\n/**\n * Table pagination component with navigation controls and items per page selector\n *\n * @example\n * ```tsx\n * import { TablePagination } from 'analytica-frontend-lib';\n *\n * <TablePagination\n * totalItems={1000}\n * currentPage={1}\n * totalPages={10}\n * itemsPerPage={10}\n * itemsPerPageOptions={[10, 20, 50, 100]}\n * onPageChange={(page) => setCurrentPage(page)}\n * onItemsPerPageChange={(items) => setItemsPerPage(items)}\n * itemLabel=\"escolas\"\n * />\n * ```\n */\nconst TablePagination = ({\n totalItems,\n currentPage,\n totalPages,\n itemsPerPage,\n itemsPerPageOptions = [10, 20, 50, 100],\n onPageChange,\n onItemsPerPageChange,\n itemLabel = 'itens',\n className,\n ...props\n}: TablePaginationProps) => {\n const startItem = (currentPage - 1) * itemsPerPage + 1;\n\n const handlePrevious = () => {\n if (currentPage > 1) {\n onPageChange(currentPage - 1);\n }\n };\n\n const handleNext = () => {\n if (currentPage < totalPages) {\n onPageChange(currentPage + 1);\n }\n };\n\n const handleItemsPerPageChange = (e: ChangeEvent<HTMLSelectElement>) => {\n if (onItemsPerPageChange) {\n onItemsPerPageChange(Number(e.target.value));\n }\n };\n\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n return (\n <div\n className={cn(\n 'flex flex-col sm:flex-row items-center gap-3 sm:gap-4 w-full bg-background-50 rounded-xl p-4',\n 'sm:justify-between',\n className\n )}\n {...props}\n >\n {/* Items count - isolado à esquerda no desktop */}\n <span className=\"font-normal text-xs leading-[14px] text-text-800\">\n {startItem} de {totalItems} {itemLabel}\n </span>\n\n {/* Grupo direita: selector + page info + botões */}\n <div className=\"flex flex-wrap sm:flex-nowrap items-center gap-2 sm:gap-4 justify-center sm:justify-start\">\n {/* Items per page selector */}\n {onItemsPerPageChange && (\n <div className=\"relative\">\n <select\n value={itemsPerPage}\n onChange={handleItemsPerPageChange}\n className=\"w-24 h-9 py-0 px-3 pr-8 bg-background border border-border-300 rounded appearance-none cursor-pointer font-normal text-sm leading-[21px] text-text-900\"\n aria-label=\"Items por página\"\n >\n {itemsPerPageOptions.map((option) => (\n <option key={option} value={option}>\n {option} itens\n </option>\n ))}\n </select>\n <CaretDown\n size={14}\n weight=\"regular\"\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-background-600 pointer-events-none\"\n />\n </div>\n )}\n\n {/* Page info */}\n <span className=\"font-normal text-xs leading-[14px] text-text-950\">\n Página {currentPage} de {totalPages}\n </span>\n\n {/* Previous button */}\n <button\n onClick={handlePrevious}\n disabled={isFirstPage}\n className={cn(\n 'flex flex-row justify-center items-center py-2 px-4 gap-2 rounded-3xl transition-all',\n isFirstPage\n ? 'opacity-50 cursor-not-allowed'\n : 'hover:bg-primary-950/10 cursor-pointer'\n )}\n aria-label=\"Página anterior\"\n >\n <CaretLeft size={12} weight=\"bold\" className=\"text-primary-950\" />\n <span className=\"font-medium text-xs leading-[14px] text-primary-950\">\n Anterior\n </span>\n </button>\n\n {/* Next button */}\n <button\n onClick={handleNext}\n disabled={isLastPage}\n className={cn(\n 'flex flex-row justify-center items-center py-2 px-4 gap-2 rounded-3xl transition-all',\n isLastPage\n ? 'opacity-50 cursor-not-allowed'\n : 'hover:bg-primary-950/10 cursor-pointer'\n )}\n aria-label=\"Próxima página\"\n >\n <span className=\"font-medium text-xs leading-[14px] text-primary-950\">\n Próxima\n </span>\n <CaretRight size={12} weight=\"bold\" className=\"text-primary-950\" />\n </button>\n </div>\n </div>\n );\n};\n\nTablePagination.displayName = 'TablePagination';\n\nexport default TablePagination;\n","import { useEffect, useState, useCallback, useMemo } from 'react';\nimport type { CategoryConfig } from '../CheckBoxGroup/CheckBoxGroup';\n\nexport type FilterConfig = {\n key: string;\n label: string;\n categories: CategoryConfig[];\n};\n\nexport type UseTableFilterOptions = {\n syncWithUrl?: boolean;\n};\n\nexport type UseTableFilterReturn = {\n filterConfigs: FilterConfig[];\n activeFilters: Record<string, string[]>;\n hasActiveFilters: boolean;\n updateFilters: (configs: FilterConfig[]) => void;\n applyFilters: () => void;\n clearFilters: () => void;\n};\n\n/**\n * Hook for managing table filters with URL synchronization\n *\n * @param initialConfigs - Initial filter configurations\n * @param options - Hook options including URL sync\n * @returns Filter state and management functions\n *\n * @example\n * ```tsx\n * const { filterConfigs, activeFilters, updateFilters, applyFilters } = useTableFilter(\n * [\n * {\n * key: 'academic',\n * label: 'Dados Acadêmicos',\n * categories: [...]\n * }\n * ],\n * { syncWithUrl: true }\n * );\n * ```\n */\nexport const useTableFilter = (\n initialConfigs: FilterConfig[],\n options: UseTableFilterOptions = {}\n): UseTableFilterReturn => {\n const { syncWithUrl = false } = options;\n\n // Get initial state from URL if syncWithUrl is enabled\n const getInitialState = useCallback((): FilterConfig[] => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return initialConfigs;\n }\n\n const params = new URLSearchParams(globalThis.window.location.search);\n const configsWithUrlState = initialConfigs.map((config) => ({\n ...config,\n categories: config.categories.map((category) => {\n const urlValue = params.get(`filter_${category.key}`);\n const selectedIds = urlValue ? urlValue.split(',').filter(Boolean) : [];\n return {\n ...category,\n selectedIds,\n };\n }),\n }));\n\n return configsWithUrlState;\n }, [initialConfigs, syncWithUrl]);\n\n const [filterConfigs, setFilterConfigs] =\n useState<FilterConfig[]>(getInitialState);\n\n // Calculate active filters (only categories with selections)\n // Memoize to prevent creating new object reference on every render\n const activeFilters = useMemo(() => {\n const filters: Record<string, string[]> = {};\n\n for (const config of filterConfigs) {\n for (const category of config.categories) {\n if (category.selectedIds && category.selectedIds.length > 0) {\n filters[category.key] = category.selectedIds;\n }\n }\n }\n\n return filters;\n }, [filterConfigs]);\n\n const hasActiveFilters = Object.keys(activeFilters).length > 0;\n\n /**\n * Update filter configs (temporary state, not applied to URL yet)\n */\n const updateFilters = useCallback((configs: FilterConfig[]) => {\n setFilterConfigs(configs);\n }, []);\n\n /**\n * Apply filters to URL (commit the changes)\n */\n const applyFilters = useCallback(() => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return;\n }\n\n const url = new URL(globalThis.window.location.href);\n const params = url.searchParams;\n\n // Update URL parameters for each category\n for (const config of filterConfigs) {\n for (const category of config.categories) {\n const paramKey = `filter_${category.key}`;\n\n if (category.selectedIds && category.selectedIds.length > 0) {\n params.set(paramKey, category.selectedIds.join(','));\n } else {\n params.delete(paramKey);\n }\n }\n }\n\n // Update URL without page reload\n globalThis.window.history.replaceState({}, '', url.toString());\n }, [filterConfigs, syncWithUrl]);\n\n /**\n * Clear all filters\n */\n const clearFilters = useCallback(() => {\n const clearedConfigs = filterConfigs.map((config) => ({\n ...config,\n categories: config.categories.map((category) => ({\n ...category,\n selectedIds: [],\n })),\n }));\n\n setFilterConfigs(clearedConfigs);\n\n // If syncWithUrl, also clear URL parameters\n if (syncWithUrl && globalThis.window !== undefined) {\n const url = new URL(globalThis.window.location.href);\n const params = url.searchParams;\n\n for (const config of filterConfigs) {\n for (const category of config.categories) {\n params.delete(`filter_${category.key}`);\n }\n }\n\n globalThis.window.history.replaceState({}, '', url.toString());\n }\n }, [filterConfigs, syncWithUrl]);\n\n // Sync with URL on mount and when URL changes externally\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return;\n }\n\n const handlePopState = () => {\n setFilterConfigs(getInitialState());\n };\n\n globalThis.window.addEventListener('popstate', handlePopState);\n return () =>\n globalThis.window.removeEventListener('popstate', handlePopState);\n }, [syncWithUrl, getInitialState]);\n\n return {\n filterConfigs,\n activeFilters,\n hasActiveFilters,\n updateFilters,\n applyFilters,\n clearFilters,\n };\n};\n","import { X, MagnifyingGlass } from 'phosphor-react';\nimport {\n InputHTMLAttributes,\n forwardRef,\n useState,\n useId,\n useMemo,\n useEffect,\n useRef,\n ChangeEvent,\n MouseEvent,\n KeyboardEvent,\n} from 'react';\nimport DropdownMenu, {\n DropdownMenuContent,\n DropdownMenuItem,\n createDropdownStore,\n} from '../DropdownMenu/DropdownMenu';\n\n/**\n * Search component props interface\n */\ntype SearchProps = {\n /** List of options to show in dropdown */\n options: string[];\n /** Callback when an option is selected from dropdown */\n onSelect?: (value: string) => void;\n /** Callback when search input changes */\n onSearch?: (query: string) => void;\n /** Control dropdown visibility externally */\n showDropdown?: boolean;\n /** Callback when dropdown open state changes */\n onDropdownChange?: (open: boolean) => void;\n /** Maximum height of dropdown in pixels */\n dropdownMaxHeight?: number;\n /** Text to show when no results are found */\n noResultsText?: string;\n /** Additional CSS classes to apply to the input */\n className?: string;\n /** Additional CSS classes to apply to the container */\n containerClassName?: string;\n /** Callback when clear button is clicked */\n onClear?: () => void;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'onSelect'>;\n\n/**\n * Search component for Analytica Ensino platforms\n *\n * A specialized search input component with dropdown suggestions.\n * Features filtering, keyboard navigation, and customizable options.\n *\n * @param options - Array of search options to display in dropdown\n * @param onSelect - Callback when an option is selected\n * @param onSearch - Callback when search query changes\n * @param placeholder - Placeholder text for the input\n * @param noResultsText - Text to show when no results are found\n * @param dropdownMaxHeight - Maximum height of dropdown in pixels\n * @param className - Additional CSS classes for the input\n * @param containerClassName - Additional CSS classes for the container\n * @param props - All other standard input HTML attributes\n * @returns A styled search input with dropdown functionality\n *\n * @example\n * ```tsx\n * // Basic search\n * <Search\n * options={['Filosofia', 'Física', 'Matemática']}\n * placeholder=\"Buscar matéria...\"\n * onSelect={(value) => console.log('Selected:', value)}\n * />\n *\n * // With custom filtering\n * <Search\n * options={materias}\n * onSearch={(query) => setFilteredMaterias(filterMaterias(query))}\n * noResultsText=\"Nenhum resultado encontrado\"\n * />\n * ```\n */\n\n/**\n * Filter options based on search query\n */\nconst filterOptions = (options: string[], query: string): string[] => {\n if (!query || query.length < 1) return [];\n\n return options.filter((option) =>\n option.toLowerCase().includes(query.toLowerCase())\n );\n};\n\n/**\n * Updates input value and creates appropriate change event\n */\nconst updateInputValue = (\n value: string,\n ref:\n | { current: HTMLInputElement | null }\n | ((instance: HTMLInputElement | null) => void)\n | null,\n onChange?: (event: ChangeEvent<HTMLInputElement>) => void\n) => {\n if (!onChange) return;\n\n if (ref && 'current' in ref && ref.current) {\n ref.current.value = value;\n const event = new Event('input', { bubbles: true });\n Object.defineProperty(event, 'target', {\n writable: false,\n value: ref.current,\n });\n onChange(event as unknown as ChangeEvent<HTMLInputElement>);\n } else {\n // Fallback for cases where ref is not available\n const event = {\n target: { value },\n currentTarget: { value },\n } as ChangeEvent<HTMLInputElement>;\n onChange(event);\n }\n};\n\nconst Search = forwardRef<HTMLInputElement, SearchProps>(\n (\n {\n options = [],\n onSelect,\n onSearch,\n showDropdown: controlledShowDropdown,\n onDropdownChange,\n dropdownMaxHeight = 240,\n noResultsText = 'Nenhum resultado encontrado',\n className = '',\n containerClassName = '',\n disabled,\n readOnly,\n id,\n onClear,\n value,\n onChange,\n placeholder = 'Buscar...',\n onKeyDown: userOnKeyDown,\n ...props\n },\n ref\n ) => {\n // Dropdown state and logic\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const [forceClose, setForceClose] = useState(false);\n const justSelectedRef = useRef(false);\n const dropdownStore = useRef(createDropdownStore()).current;\n const dropdownRef = useRef<HTMLDivElement>(null);\n const inputElRef = useRef<HTMLInputElement>(null);\n\n // Filter options based on input value\n const filteredOptions = useMemo(() => {\n if (!options.length) {\n return [];\n }\n const filtered = filterOptions(options, (value as string) || '');\n return filtered;\n }, [options, value]);\n\n // Control dropdown visibility\n const showDropdown =\n !forceClose &&\n (controlledShowDropdown ??\n (dropdownOpen && value && String(value).length > 0));\n\n // Helper to keep all consumers in sync\n const setOpenAndNotify = (open: boolean) => {\n setDropdownOpen(open);\n dropdownStore.setState({ open });\n onDropdownChange?.(open);\n };\n\n // Handle dropdown visibility changes\n useEffect(() => {\n // Don't reopen dropdown if we just selected an option\n if (justSelectedRef.current) {\n justSelectedRef.current = false;\n return;\n }\n // Respect forceClose even if value is non-empty\n if (forceClose) {\n setOpenAndNotify(false);\n return;\n }\n\n const shouldShow = Boolean(value && String(value).length > 0);\n setOpenAndNotify(shouldShow);\n }, [value, forceClose, onDropdownChange, dropdownStore]);\n\n // Handle option selection\n const handleSelectOption = (option: string) => {\n justSelectedRef.current = true; // Prevent immediate dropdown reopen\n setForceClose(true); // Force dropdown to close immediately\n onSelect?.(option);\n setOpenAndNotify(false);\n\n // Update input value if onChange is provided\n updateInputValue(option, ref, onChange);\n };\n\n // Handle click outside dropdown\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n dropdownRef.current &&\n !dropdownRef.current.contains(event.target as Node)\n ) {\n setOpenAndNotify(false);\n }\n };\n\n if (showDropdown) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [showDropdown, dropdownStore, onDropdownChange]);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `search-${generatedId}`;\n const dropdownId = `${inputId}-dropdown`;\n\n // Handle clear button\n const handleClear = () => {\n if (onClear) {\n onClear();\n } else {\n updateInputValue('', ref, onChange);\n }\n };\n\n // Handle clear button click - mantém foco no input\n const handleClearClick = (e: MouseEvent) => {\n e.preventDefault(); // Evita que o input perca foco\n e.stopPropagation(); // Para propagação do evento\n handleClear();\n };\n\n // Handle search icon click - focus on input\n const handleSearchIconClick = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setTimeout(() => {\n inputElRef.current?.focus();\n }, 0);\n };\n\n // Handle input change\n const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {\n setForceClose(false); // Allow dropdown to open when user types\n onChange?.(e);\n onSearch?.(e.target.value);\n };\n\n // Handle keyboard events\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n // Let consumer run first; if they prevent default, skip our logic\n userOnKeyDown?.(e);\n if (e.defaultPrevented) return;\n\n if (e.key === 'Enter') {\n e.preventDefault();\n\n // If dropdown is open and there are filtered options, select the first one\n if (showDropdown && filteredOptions.length > 0) {\n handleSelectOption(filteredOptions[0]);\n } else if (value) {\n // If no dropdown or no options, execute search\n onSearch?.(String(value));\n setForceClose(true);\n setOpenAndNotify(false);\n }\n }\n };\n\n // Helper function for input state classes\n const getInputStateClasses = (disabled?: boolean, readOnly?: boolean) => {\n if (disabled) return 'cursor-not-allowed opacity-40';\n if (readOnly) return 'cursor-default focus:outline-none !text-text-900';\n return 'hover:border-border-400';\n };\n\n // Determine which icon to show\n const hasValue = String(value ?? '').length > 0;\n const showClearButton = hasValue && !disabled && !readOnly;\n const showSearchIcon = !hasValue && !disabled && !readOnly;\n\n return (\n <div\n ref={dropdownRef}\n className={`w-full max-w-lg md:w-[488px] ${containerClassName}`}\n >\n {/* Search Input Container */}\n <div className=\"relative flex items-center\">\n {/* Search Input Field */}\n <input\n ref={(node) => {\n // Forward to parent\n if (ref) {\n if (typeof ref === 'function') ref(node);\n else\n (ref as { current: HTMLInputElement | null }).current = node;\n }\n // Keep our own handle\n inputElRef.current = node;\n }}\n id={inputId}\n type=\"text\"\n className={`w-full py-0 px-4 pr-10 font-normal text-text-900 focus:outline-primary-950 border rounded-full bg-background focus:bg-primary-50 border-border-300 focus:border-2 focus:border-primary-950 h-10 placeholder:text-text-600 ${getInputStateClasses(disabled, readOnly)} ${className}`}\n value={value}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={placeholder}\n aria-expanded={showDropdown ? 'true' : undefined}\n aria-haspopup={options.length > 0 ? 'listbox' : undefined}\n aria-controls={showDropdown ? dropdownId : undefined}\n aria-autocomplete=\"list\"\n role={options.length > 0 ? 'combobox' : undefined}\n {...props}\n />\n\n {/* Right Icon - Clear Button */}\n {showClearButton && (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2\">\n <button\n type=\"button\"\n className=\"p-0 border-0 bg-transparent cursor-pointer\"\n onMouseDown={handleClearClick}\n aria-label=\"Limpar busca\"\n >\n <span className=\"w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors\">\n <X />\n </span>\n </button>\n </div>\n )}\n\n {/* Right Icon - Search Icon */}\n {showSearchIcon && (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2\">\n <button\n type=\"button\"\n className=\"p-0 border-0 bg-transparent cursor-pointer\"\n onMouseDown={handleSearchIconClick}\n aria-label=\"Buscar\"\n >\n <span className=\"w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors\">\n <MagnifyingGlass />\n </span>\n </button>\n </div>\n )}\n </div>\n\n {/* Search Dropdown */}\n {showDropdown && (\n <DropdownMenu open={showDropdown} onOpenChange={setDropdownOpen}>\n <DropdownMenuContent\n id={dropdownId}\n className=\"w-full mt-1\"\n style={{ maxHeight: dropdownMaxHeight }}\n align=\"start\"\n >\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option) => (\n <DropdownMenuItem\n key={option}\n onClick={() => handleSelectOption(option)}\n className=\"text-text-700 text-base leading-6 cursor-pointer\"\n >\n {option}\n </DropdownMenuItem>\n ))\n ) : (\n <div className=\"px-3 py-3 text-text-700 text-base\">\n {noResultsText}\n </div>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n }\n);\n\nSearch.displayName = 'Search';\n\nexport default Search;\n","import { CaretRight, SignOut, User } from 'phosphor-react';\nimport {\n forwardRef,\n ReactNode,\n ButtonHTMLAttributes,\n useEffect,\n useLayoutEffect,\n useRef,\n HTMLAttributes,\n MouseEvent,\n KeyboardEvent,\n isValidElement,\n Children,\n cloneElement,\n ReactElement,\n useState,\n RefObject,\n CSSProperties,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { create, StoreApi, useStore } from 'zustand';\nimport Button from '../Button/Button';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\nimport Modal from '../Modal/Modal';\nimport { ThemeToggle } from '../ThemeToggle/ThemeToggle';\nimport type { ThemeMode } from '@/hooks/useTheme';\nimport { useTheme } from '../../hooks/useTheme';\n\ninterface DropdownStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\ntype DropdownStoreApi = StoreApi<DropdownStore>;\n\nexport function createDropdownStore(): DropdownStoreApi {\n return create<DropdownStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n }));\n}\n\nexport const useDropdownStore = (externalStore?: DropdownStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a DropdownMenu (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nconst injectStore = (\n children: ReactNode,\n store: DropdownStoreApi\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: DropdownStoreApi;\n children?: ReactNode;\n }>;\n\n // Aqui tu checa o displayName do componente\n const displayName = (\n typedChild.type as unknown as { displayName: string }\n ).displayName;\n\n // Lista de componentes que devem receber o store\n const allowed = [\n 'DropdownMenuTrigger',\n 'DropdownContent',\n 'DropdownMenuContent',\n 'DropdownMenuSeparator',\n 'DropdownMenuItem',\n 'MenuLabel',\n 'ProfileMenuTrigger',\n 'ProfileMenuHeader',\n 'ProfileMenuFooter',\n 'ProfileToggleTheme',\n ];\n\n let newProps: Partial<{\n store: DropdownStoreApi;\n children: ReactNode;\n }> = {};\n\n if (allowed.includes(displayName)) {\n newProps.store = store;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(typedChild.props.children, store);\n }\n\n return cloneElement(typedChild, newProps);\n }\n\n return child;\n });\n};\n\ninterface DropdownMenuProps {\n children: ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst DropdownMenu = ({\n children,\n open: propOpen,\n onOpenChange,\n}: DropdownMenuProps) => {\n const storeRef = useRef<DropdownStoreApi | null>(null);\n storeRef.current ??= createDropdownStore();\n const store = storeRef.current;\n const { open, setOpen: storeSetOpen } = useStore(store, (s) => s);\n\n const setOpen = (newOpen: boolean) => {\n storeSetOpen(newOpen);\n };\n\n const menuRef = useRef<HTMLDivElement | null>(null);\n\n const handleArrowDownOrArrowUp = (event: globalThis.KeyboardEvent) => {\n const menuContent = menuRef.current?.querySelector('[role=\"menu\"]');\n if (menuContent) {\n event.preventDefault();\n\n const items = Array.from(\n menuContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n if (items.length === 0) return;\n\n const focusedItem = document.activeElement as HTMLElement;\n const currentIndex = items.indexOf(focusedItem);\n\n let nextIndex;\n if (event.key === 'ArrowDown') {\n nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n // ArrowUp\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n\n items[nextIndex]?.focus();\n }\n };\n\n const handleDownkey = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false);\n } else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n handleArrowDownOrArrowUp(event);\n }\n };\n\n const handleClickOutside = (event: Event) => {\n const target = event.target as Node;\n\n if (menuRef.current?.contains(target)) {\n return;\n }\n\n if (\n target instanceof Element &&\n target.closest('[data-dropdown-content=\"true\"]')\n ) {\n return;\n }\n\n setOpen(false);\n };\n\n useEffect(() => {\n if (open) {\n document.addEventListener('pointerdown', handleClickOutside);\n document.addEventListener('keydown', handleDownkey);\n }\n\n return () => {\n document.removeEventListener('pointerdown', handleClickOutside);\n document.removeEventListener('keydown', handleDownkey);\n };\n }, [open]);\n\n useEffect(() => {\n onOpenChange?.(open);\n }, [open, onOpenChange]);\n\n useEffect(() => {\n if (propOpen !== undefined) {\n setOpen(propOpen);\n }\n }, [propOpen]);\n\n return (\n <div className=\"relative\" ref={menuRef}>\n {injectStore(children, store)}\n </div>\n );\n};\n\n// Componentes genéricos do DropdownMenu\nconst DropdownMenuTrigger = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n }\n>(({ className, children, onClick, store: externalStore, ...props }, ref) => {\n const store = useDropdownStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n onClick?.(e);\n }}\n aria-expanded={open}\n className={cn(\n 'appearance-none bg-transparent border-none p-0',\n className\n )}\n {...props}\n >\n {children}\n </button>\n );\n});\nDropdownMenuTrigger.displayName = 'DropdownMenuTrigger';\n\nconst ITEM_SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full',\n right: 'top-full',\n bottom: 'top-full',\n left: 'top-full',\n};\n\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\nconst MENUCONTENT_VARIANT_CLASSES = {\n menu: 'p-1',\n profile: 'p-6',\n};\n\nconst MenuLabel = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n store?: DropdownStoreApi;\n }\n>(({ className, inset, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('text-sm w-full', inset ? 'pl-8' : '', className)}\n {...props}\n />\n );\n});\nMenuLabel.displayName = 'MenuLabel';\n\nconst DropdownMenuContent = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n variant?: 'menu' | 'profile';\n sideOffset?: number;\n store?: DropdownStoreApi;\n portal?: boolean;\n triggerRef?: RefObject<HTMLElement | null>;\n }\n>(\n (\n {\n className,\n align = 'start',\n side = 'bottom',\n variant = 'menu',\n sideOffset = 4,\n children,\n store: externalStore,\n portal = false,\n triggerRef,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const [isVisible, setIsVisible] = useState(open);\n const [portalPosition, setPortalPosition] = useState({ top: 0, left: 0 });\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (open) {\n setIsVisible(true);\n } else {\n const timer = setTimeout(() => setIsVisible(false), 200);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n useLayoutEffect(() => {\n if (portal && open && triggerRef?.current) {\n const rect = triggerRef.current.getBoundingClientRect();\n let top = rect.bottom + sideOffset;\n let left = rect.left;\n\n // Handle horizontal sides (left/right)\n if (side === 'left') {\n left = rect.left - sideOffset;\n top = rect.top;\n } else if (side === 'right') {\n left = rect.right + sideOffset;\n top = rect.top;\n } else {\n // Handle vertical sides (top/bottom)\n if (align === 'end') {\n left = rect.right;\n } else if (align === 'center') {\n left = rect.left + rect.width / 2;\n }\n\n if (side === 'top') {\n top = rect.top - sideOffset;\n }\n }\n\n setPortalPosition({ top, left });\n }\n }, [portal, open, triggerRef, align, side, sideOffset]);\n\n if (!isVisible) return null;\n\n const getPositionClasses = () => {\n if (portal) {\n return 'fixed';\n }\n const vertical = SIDE_CLASSES[side];\n const horizontal = ALIGN_CLASSES[align];\n\n return `absolute ${vertical} ${horizontal}`;\n };\n\n const getPortalAlignStyle = () => {\n if (!portal) return {};\n\n const baseStyle: CSSProperties = {\n top: portalPosition.top,\n };\n\n if (align === 'end') {\n baseStyle.right = window.innerWidth - portalPosition.left;\n } else if (align === 'center') {\n baseStyle.left = portalPosition.left;\n baseStyle.transform = 'translateX(-50%)';\n } else {\n baseStyle.left = portalPosition.left;\n }\n\n return baseStyle;\n };\n\n const variantClasses = MENUCONTENT_VARIANT_CLASSES[variant];\n\n const content = (\n <div\n ref={portal ? contentRef : ref}\n role=\"menu\"\n data-dropdown-content=\"true\"\n className={`\n bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md border-border-100\n ${open ? 'animate-in fade-in-0 zoom-in-95' : 'animate-out fade-out-0 zoom-out-95'}\n ${getPositionClasses()}\n ${variantClasses}\n ${className}\n `}\n style={{\n ...(portal\n ? getPortalAlignStyle()\n : {\n marginTop: side === 'bottom' ? sideOffset : undefined,\n marginBottom: side === 'top' ? sideOffset : undefined,\n marginLeft: side === 'right' ? sideOffset : undefined,\n marginRight: side === 'left' ? sideOffset : undefined,\n }),\n }}\n {...props}\n >\n {children}\n </div>\n );\n\n if (portal && typeof document !== 'undefined') {\n return createPortal(content, document.body);\n }\n\n return content;\n }\n);\nDropdownMenuContent.displayName = 'DropdownMenuContent';\n\nconst DropdownMenuItem = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n size?: 'small' | 'medium';\n iconLeft?: ReactNode;\n iconRight?: ReactNode;\n disabled?: boolean;\n variant?: 'profile' | 'menu';\n store?: DropdownStoreApi;\n preventClose?: boolean;\n }\n>(\n (\n {\n className,\n size = 'small',\n children,\n iconRight,\n iconLeft,\n disabled = false,\n onClick,\n variant = 'menu',\n store: externalStore,\n preventClose = false,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n const sizeClasses = ITEM_SIZE_CLASSES[size];\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.type === 'click') {\n onClick?.(e as MouseEvent<HTMLDivElement>);\n } else if (e.type === 'keydown') {\n // For keyboard events, call onClick if Enter or Space was pressed\n if (\n (e as KeyboardEvent<HTMLDivElement>).key === 'Enter' ||\n (e as KeyboardEvent<HTMLDivElement>).key === ' '\n ) {\n onClick?.(e as unknown as MouseEvent<HTMLDivElement>);\n }\n // honor any user-provided key handler\n props.onKeyDown?.(e as KeyboardEvent<HTMLDivElement>);\n }\n if (!preventClose) {\n setOpen(false);\n }\n };\n\n const getVariantClasses = () => {\n if (variant === 'profile') {\n return 'relative flex flex-row justify-between select-none items-center gap-2 rounded-sm p-4 text-sm outline-none transition-colors [&>svg]:size-6 [&>svg]:shrink-0';\n }\n return 'relative flex select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0';\n };\n\n const getVariantProps = () => {\n return variant === 'profile' ? { 'data-variant': 'profile' } : {};\n };\n\n return (\n <div\n ref={ref}\n role=\"menuitem\"\n {...getVariantProps()}\n aria-disabled={disabled}\n className={`\n focus-visible:bg-background-50\n ${getVariantClasses()}\n ${sizeClasses}\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n handleClick(e);\n }\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n {iconLeft}\n <div className=\"w-full\">{children}</div>\n {iconRight}\n </div>\n );\n }\n);\nDropdownMenuItem.displayName = 'DropdownMenuItem';\n\nconst DropdownMenuSeparator = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, store: _store, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('my-1 h-px bg-border-200', className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = 'DropdownMenuSeparator';\n\n// Componentes específicos do ProfileMenu\nconst ProfileMenuTrigger = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & { store?: DropdownStoreApi }\n>(({ className, onClick, store: externalStore, ...props }, ref) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <button\n ref={ref}\n className={cn(\n 'rounded-lg size-10 bg-primary-50 flex items-center justify-center cursor-pointer',\n className\n )}\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n onClick?.(e);\n }}\n aria-expanded={open}\n {...props}\n >\n <span className=\"size-6 rounded-full bg-primary-100 flex items-center justify-center\">\n <User className=\"text-primary-950\" size={18} />\n </span>\n </button>\n );\n});\nProfileMenuTrigger.displayName = 'ProfileMenuTrigger';\n\nconst ProfileMenuHeader = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n name: string;\n email: string;\n photoUrl?: string | null;\n store?: DropdownStoreApi;\n }\n>(({ className, name, email, photoUrl, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-component=\"ProfileMenuHeader\"\n className={cn(\n 'flex flex-row gap-4 items-center min-w-[280px]',\n className\n )}\n {...props}\n >\n <span className=\"w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center overflow-hidden flex-shrink-0\">\n {photoUrl ? (\n <img\n src={photoUrl}\n alt=\"Foto de perfil\"\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <User size={34} className=\"text-primary-800\" />\n )}\n </span>\n <div className=\"flex flex-col min-w-0\">\n <Text\n size=\"xl\"\n weight=\"bold\"\n color=\"text-text-950\"\n className=\"truncate\"\n >\n {name}\n </Text>\n <Text size=\"md\" color=\"text-text-600\" className=\"truncate\">\n {email}\n </Text>\n </div>\n </div>\n );\n});\nProfileMenuHeader.displayName = 'ProfileMenuHeader';\n\nconst ProfileMenuInfo = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n schoolName: string;\n classYearName: string;\n schoolYearName: string;\n store?: DropdownStoreApi;\n }\n>(\n (\n {\n className,\n schoolName,\n classYearName,\n schoolYearName,\n store: _store,\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n data-component=\"ProfileMenuInfo\"\n className={cn('flex flex-row gap-4 items-center', className)}\n {...props}\n >\n <span className=\"w-16 h-16\" />\n <div className=\"flex flex-col \">\n <Text size=\"md\" color=\"text-text-600\">\n {schoolName}\n </Text>\n\n <span className=\"flex flex-row items-center gap-2\">\n <Text size=\"md\" color=\"text-text-600\">\n {classYearName}\n </Text>\n <p className=\"text-text-600 text-xs align-middle\">●</p>\n <Text size=\"md\" color=\"text-text-600\">\n {schoolYearName}\n </Text>\n </span>\n </div>\n </div>\n );\n }\n);\nProfileMenuInfo.displayName = 'ProfileMenuInfo';\n\nconst ProfileToggleTheme = ({\n store: externalStore,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }) => {\n const { themeMode, setTheme } = useTheme();\n const [modalThemeToggle, setModalThemeToggle] = useState(false);\n const [selectedTheme, setSelectedTheme] = useState<ThemeMode>(themeMode);\n\n const internalStoreRef = useRef<DropdownStoreApi | null>(null);\n internalStoreRef.current ??= createDropdownStore();\n const store = externalStore ?? internalStoreRef.current;\n const setOpen = useStore(store, (s) => s.setOpen);\n\n const handleClick = (e: MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setModalThemeToggle(true);\n };\n\n const handleSave = () => {\n setTheme(selectedTheme);\n setModalThemeToggle(false);\n setOpen(false); // Close dropdown after saving\n };\n\n const handleCancel = () => {\n setSelectedTheme(themeMode); // Reset to current theme\n setModalThemeToggle(false);\n setOpen(false); // Close dropdown after canceling\n };\n\n return (\n <>\n <DropdownMenuItem\n variant=\"profile\"\n preventClose={true}\n store={store}\n iconLeft={\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12.5 2.75C15.085 2.75276 17.5637 3.78054 19.3916 5.6084C21.2195 7.43628 22.2473 9.915 22.25 12.5C22.25 14.4284 21.6778 16.3136 20.6064 17.917C19.5352 19.5201 18.0128 20.7699 16.2314 21.5078C14.4499 22.2458 12.489 22.4387 10.5977 22.0625C8.70642 21.6863 6.96899 20.758 5.60547 19.3945C4.24197 18.031 3.31374 16.2936 2.9375 14.4023C2.56129 12.511 2.75423 10.5501 3.49219 8.76855C4.23012 6.98718 5.47982 5.46483 7.08301 4.39355C8.68639 3.32221 10.5716 2.75 12.5 2.75ZM11.75 4.28516C9.70145 4.47452 7.7973 5.42115 6.41016 6.94043C5.02299 8.4599 4.25247 10.4426 4.25 12.5C4.25247 14.5574 5.02299 16.5401 6.41016 18.0596C7.7973 19.5789 9.70145 20.5255 11.75 20.7148V4.28516Z\"\n fill=\"currentColor\"\n />\n </svg>\n }\n iconRight={<CaretRight />}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n setModalThemeToggle(true);\n }\n }}\n {...props}\n >\n <Text size=\"md\" color=\"text-text-700\">\n Aparência\n </Text>\n </DropdownMenuItem>\n\n <Modal\n isOpen={modalThemeToggle}\n onClose={handleCancel}\n title=\"Aparência\"\n size=\"md\"\n footer={\n <div className=\"flex gap-3\">\n <Button variant=\"outline\" onClick={handleCancel}>\n Cancelar\n </Button>\n <Button variant=\"solid\" onClick={handleSave}>\n Salvar\n </Button>\n </div>\n }\n >\n <div className=\"flex flex-col\">\n <p className=\"text-sm text-text-500\">Escolha o tema:</p>\n <ThemeToggle variant=\"with-save\" onToggle={setSelectedTheme} />\n </div>\n </Modal>\n </>\n );\n};\nProfileToggleTheme.displayName = 'ProfileToggleTheme';\n\nconst ProfileMenuSection = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, children, store: _store, ...props }, ref) => {\n return (\n <div ref={ref} className={cn('flex flex-col p-2', className)} {...props}>\n {children}\n </div>\n );\n});\nProfileMenuSection.displayName = 'ProfileMenuSection';\n\nconst ProfileMenuFooter = ({\n className,\n disabled = false,\n onClick,\n store: externalStore,\n ...props\n}: HTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n}) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n\n return (\n <Button\n variant=\"outline\"\n className={cn('w-full', className)}\n disabled={disabled}\n onClick={(e) => {\n setOpen(false);\n onClick?.(e);\n }}\n {...props}\n >\n <span className=\"mr-2 flex items-center\">\n <SignOut className=\"text-inherit\" />\n </span>\n <Text color=\"inherit\">Sair</Text>\n </Button>\n );\n};\nProfileMenuFooter.displayName = 'ProfileMenuFooter';\n\n// Exportações\nexport default DropdownMenu;\nexport {\n // Componentes genéricos\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n MenuLabel,\n DropdownMenuSeparator,\n\n // Componentes específicos do ProfileMenu\n ProfileMenuTrigger,\n ProfileMenuHeader,\n ProfileMenuSection,\n ProfileMenuFooter,\n ProfileToggleTheme,\n ProfileMenuInfo,\n};\n","import { ReactNode, useEffect, useId } from 'react';\nimport { X } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\nimport Button from '../Button/Button';\nimport {\n isYouTubeUrl,\n getYouTubeVideoId,\n getYouTubeEmbedUrl,\n} from './utils/videoUtils';\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n xs: 'max-w-[360px]',\n sm: 'max-w-[420px]',\n md: 'max-w-[510px]',\n lg: 'max-w-[640px]',\n xl: 'max-w-[970px]',\n} as const;\n\n/**\n * Modal component props interface\n */\ntype ModalProps = {\n contentClassName?: string;\n /** Whether the modal is open */\n isOpen: boolean;\n /** Function to close the modal */\n onClose: () => void;\n /** Modal title */\n title: string;\n /** Modal description/content */\n children?: ReactNode;\n /** Size of the modal */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n /** Additional CSS classes for the modal content */\n className?: string;\n /** Whether pressing Escape should close the modal */\n closeOnEscape?: boolean;\n /** Footer content (typically buttons) */\n footer?: ReactNode;\n /** Hide the close button */\n hideCloseButton?: boolean;\n /** Modal variant */\n variant?: 'default' | 'activity';\n /** Description for activity variant */\n description?: string;\n /** Image URL for activity variant */\n image?: string;\n /** Alt text for activity image (leave empty for decorative images) */\n imageAlt?: string;\n /** Action link for activity variant */\n actionLink?: string;\n /** Action button label for activity variant */\n actionLabel?: string;\n};\n\n/**\n * Modal component for Analytica Ensino platforms\n *\n * A flexible modal component with multiple size variants and customizable behavior.\n *\n * @param isOpen - Whether the modal is currently open\n * @param onClose - Callback function called when the modal should be closed\n * @param title - The title displayed at the top of the modal\n * @param children - The main content of the modal\n * @param size - The size variant (xs, sm, md, lg, xl)\n * @param className - Additional CSS classes for the modal content\n * @param closeOnEscape - Whether pressing Escape closes the modal (default: true)\n * @param footer - Footer content, typically action buttons\n * @param hideCloseButton - Whether to hide the X close button (default: false)\n * @returns A modal overlay with content\n *\n * @example\n * ```tsx\n * <Modal\n * isOpen={isModalOpen}\n * onClose={() => setIsModalOpen(false)}\n * title=\"Invite your team\"\n * size=\"md\"\n * footer={\n * <div className=\"flex gap-3\">\n * <Button variant=\"outline\" onClick={() => setIsModalOpen(false)}>Cancel</Button>\n * <Button variant=\"solid\" onClick={handleExplore}>Explore</Button>\n * </div>\n * }\n * >\n * Elevate user interactions with our versatile modals.\n * </Modal>\n * ```\n */\nconst Modal = ({\n isOpen,\n onClose,\n title,\n children,\n size = 'md',\n className = '',\n closeOnEscape = true,\n footer,\n hideCloseButton = false,\n variant = 'default',\n description,\n image,\n imageAlt,\n actionLink,\n actionLabel,\n contentClassName = '',\n}: ModalProps) => {\n const titleId = useId();\n\n // Handle escape key\n useEffect(() => {\n if (!isOpen || !closeOnEscape) return;\n\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen, closeOnEscape, onClose]);\n\n // Handle body scroll lock and scrollbar shift fix\n useEffect(() => {\n if (!isOpen) return;\n\n // Calculate scrollbar width before hiding overflow\n const scrollbarWidth =\n window.innerWidth - document.documentElement.clientWidth;\n\n // Save original styles\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n // Apply scroll lock\n document.body.style.overflow = 'hidden';\n\n // Fix scrollbar shift: add padding to compensate for lost scrollbar\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n\n // Create overlay to cover the padding area with backdrop color\n const overlay = document.createElement('div');\n overlay.id = 'modal-scrollbar-overlay';\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n right: 0;\n width: ${scrollbarWidth}px;\n height: 100vh;\n background-color: rgb(0 0 0 / 0.6);\n z-index: 40;\n pointer-events: none;\n `;\n document.body.appendChild(overlay);\n }\n\n return () => {\n // Restore original styles\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n\n // Remove overlay\n const overlay = document.getElementById('modal-scrollbar-overlay');\n if (overlay) {\n overlay.remove();\n }\n };\n }, [isOpen]);\n\n if (!isOpen) return null;\n\n const sizeClasses = SIZE_CLASSES[size];\n const baseClasses =\n 'bg-secondary-50 rounded-3xl shadow-hard-shadow-2 border border-border-100 w-full mx-4';\n // Reset dialog default styles to prevent positioning issues\n const dialogResetClasses =\n 'p-0 m-0 border-none outline-none max-h-none static';\n const modalClasses = cn(\n baseClasses,\n sizeClasses,\n dialogResetClasses,\n className\n );\n\n // Normalize URLs missing protocol\n const normalizeUrl = (href: string) =>\n /^https?:\\/\\//i.test(href) ? href : `https://${href}`;\n\n // Handle action link click\n const handleActionClick = () => {\n if (actionLink) {\n window.open(normalizeUrl(actionLink), '_blank', 'noopener,noreferrer');\n }\n };\n\n // Activity variant rendering\n if (variant === 'activity') {\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default\">\n <dialog\n className={modalClasses}\n aria-labelledby={titleId}\n aria-modal=\"true\"\n open\n >\n {/* Header simples com X */}\n <div className=\"flex justify-end p-6 pb-0\">\n {!hideCloseButton && (\n <button\n onClick={onClose}\n className=\"p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2\"\n aria-label=\"Fechar modal\"\n >\n <X size={18} />\n </button>\n )}\n </div>\n\n {/* Conteúdo centralizado */}\n <div className=\"flex flex-col items-center px-6 pb-6 gap-5\">\n {/* Imagem ilustrativa */}\n {image && (\n <div className=\"flex justify-center\">\n <img\n src={image}\n alt={imageAlt ?? ''}\n className=\"w-[122px] h-[122px] object-contain\"\n />\n </div>\n )}\n\n {/* Título */}\n <h2\n id={titleId}\n className=\"text-lg font-semibold text-text-950 text-center\"\n >\n {title}\n </h2>\n\n {/* Descrição */}\n {description && (\n <p className=\"text-sm font-normal text-text-400 text-center max-w-md leading-[21px]\">\n {description}\n </p>\n )}\n\n {/* Ação: Botão ou Vídeo Embedado */}\n {actionLink && (\n <div className=\"w-full\">\n {(() => {\n const normalized = normalizeUrl(actionLink);\n const isYT = isYouTubeUrl(normalized);\n if (!isYT) return null;\n const id = getYouTubeVideoId(normalized);\n if (!id) {\n return (\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"large\"\n className=\"w-full\"\n onClick={handleActionClick}\n >\n {actionLabel || 'Iniciar Atividade'}\n </Button>\n );\n }\n return (\n <iframe\n src={getYouTubeEmbedUrl(id)}\n className=\"w-full aspect-video rounded-lg\"\n allowFullScreen\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n title=\"Vídeo YouTube\"\n />\n );\n })()}\n {!isYouTubeUrl(normalizeUrl(actionLink)) && (\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"large\"\n className=\"w-full\"\n onClick={handleActionClick}\n >\n {actionLabel || 'Iniciar Atividade'}\n </Button>\n )}\n </div>\n )}\n </div>\n </dialog>\n </div>\n );\n }\n\n // Default variant rendering\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default\">\n <dialog\n className={modalClasses}\n aria-labelledby={titleId}\n aria-modal=\"true\"\n open\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-6\">\n <h2 id={titleId} className=\"text-lg font-semibold text-text-950\">\n {title}\n </h2>\n {!hideCloseButton && (\n <button\n onClick={onClose}\n className=\"p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2\"\n aria-label=\"Fechar modal\"\n >\n <X size={18} />\n </button>\n )}\n </div>\n\n {/* Content */}\n {children && (\n <div className={cn('px-6 pb-6', contentClassName)}>\n <div className=\"text-text-500 font-normal text-sm leading-6\">\n {children}\n </div>\n </div>\n )}\n\n {/* Footer */}\n {footer && (\n <div className=\"flex justify-end gap-3 px-6 pb-6\">{footer}</div>\n )}\n </dialog>\n </div>\n );\n};\n\nexport default Modal;\n","/**\n * Video utilities for Modal component\n *\n * Utilities to handle YouTube video embedding and URL detection\n */\n\n/**\n * Check if a given URL is a YouTube URL\n *\n * @param url - The URL to check\n * @returns true if the URL is from YouTube, false otherwise\n */\nexport const isYouTubeUrl = (url: string): boolean => {\n const youtubeRegex =\n /^(https?:\\/\\/)?((www|m|music)\\.)?(youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/.+/i;\n return youtubeRegex.test(url);\n};\n\n/**\n * Validate if hostname is a legitimate YouTube host\n *\n * @param host - The hostname to validate\n * @returns The type of YouTube host or null if invalid\n */\nconst isValidYouTubeHost = (\n host: string\n): 'youtu.be' | 'youtube' | 'nocookie' | null => {\n if (host === 'youtu.be') return 'youtu.be';\n\n const isValidYouTubeCom =\n host === 'youtube.com' ||\n (host.endsWith('.youtube.com') &&\n /^(www|m|music)\\.youtube\\.com$/.test(host));\n\n if (isValidYouTubeCom) return 'youtube';\n\n const isValidNoCookie =\n host === 'youtube-nocookie.com' ||\n (host.endsWith('.youtube-nocookie.com') &&\n /^(www|m|music)\\.youtube-nocookie\\.com$/.test(host));\n\n if (isValidNoCookie) return 'nocookie';\n\n return null;\n};\n\n/**\n * Extract video ID from youtu.be path\n *\n * @param pathname - The URL pathname\n * @returns The video ID or null\n */\nconst extractYoutuBeId = (pathname: string): string | null => {\n const firstSeg = pathname.split('/').filter(Boolean)[0];\n return firstSeg || null;\n};\n\n/**\n * Extract video ID from YouTube or nocookie domains\n *\n * @param pathname - The URL pathname\n * @param searchParams - The URL search parameters\n * @returns The video ID or null\n */\nconst extractYouTubeId = (\n pathname: string,\n searchParams: URLSearchParams\n): string | null => {\n const parts = pathname.split('/').filter(Boolean);\n const [first, second] = parts;\n\n if (first === 'embed' && second) return second;\n if (first === 'shorts' && second) return second;\n if (first === 'live' && second) return second;\n\n const v = searchParams.get('v');\n if (v) return v;\n\n return null;\n};\n\n/**\n * Extract YouTube video ID from URL\n *\n * @param url - The YouTube URL\n * @returns The video ID if found, null otherwise\n */\nexport const getYouTubeVideoId = (url: string): string | null => {\n try {\n const u = new URL(url);\n const hostType = isValidYouTubeHost(u.hostname.toLowerCase());\n\n if (!hostType) return null;\n\n if (hostType === 'youtu.be') {\n return extractYoutuBeId(u.pathname);\n }\n\n return extractYouTubeId(u.pathname, u.searchParams);\n } catch {\n return null;\n }\n};\n\n/**\n * Generate YouTube embed URL for iframe\n *\n * @param videoId - The YouTube video ID\n * @returns The embed URL for the video\n */\nexport const getYouTubeEmbedUrl = (videoId: string): string => {\n return `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=0&rel=0&modestbranding=1`;\n};\n","import { Moon, Sun } from 'phosphor-react';\nimport { useState, useEffect } from 'react';\nimport SelectionButton from '../SelectionButton/SelectionButton';\nimport type { ThemeMode } from '@/hooks/useTheme';\nimport { useTheme } from '../../hooks/useTheme';\n\ninterface ThemeToggleProps {\n variant?: 'default' | 'with-save';\n onToggle?: (theme: ThemeMode) => void;\n}\n\nexport const ThemeToggle = ({\n variant = 'default',\n onToggle,\n}: ThemeToggleProps) => {\n const { themeMode, setTheme } = useTheme();\n const [tempTheme, setTempTheme] = useState<ThemeMode>(themeMode);\n\n // Update temp theme when themeMode changes externally\n useEffect(() => {\n setTempTheme(themeMode);\n }, [themeMode]);\n\n const problemTypes = [\n {\n id: 'light' as ThemeMode,\n title: 'Claro',\n icon: <Sun size={24} />,\n },\n {\n id: 'dark' as ThemeMode,\n title: 'Escuro',\n icon: <Moon size={24} />,\n },\n {\n id: 'system' as ThemeMode,\n title: 'Sistema',\n icon: (\n <svg\n width=\"25\"\n height=\"25\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12.5 2.75C15.085 2.75276 17.5637 3.78054 19.3916 5.6084C21.2195 7.43628 22.2473 9.915 22.25 12.5C22.25 14.4284 21.6778 16.3136 20.6064 17.917C19.5352 19.5201 18.0128 20.7699 16.2314 21.5078C14.4499 22.2458 12.489 22.4387 10.5977 22.0625C8.70642 21.6863 6.96899 20.758 5.60547 19.3945C4.24197 18.031 3.31374 16.2936 2.9375 14.4023C2.56129 12.511 2.75423 10.5501 3.49219 8.76855C4.23012 6.98718 5.47982 5.46483 7.08301 4.39355C8.68639 3.32221 10.5716 2.75 12.5 2.75ZM11.75 4.28516C9.70145 4.47452 7.7973 5.42115 6.41016 6.94043C5.02299 8.4599 4.25247 10.4426 4.25 12.5C4.25247 14.5574 5.02299 16.5401 6.41016 18.0596C7.7973 19.5789 9.70145 20.5255 11.75 20.7148V4.28516Z\"\n fill=\"#525252\"\n />\n </svg>\n ),\n },\n ];\n\n const handleThemeSelect = (selectedTheme: ThemeMode) => {\n if (variant === 'with-save') {\n setTempTheme(selectedTheme);\n } else {\n setTheme(selectedTheme);\n }\n\n if (onToggle) {\n onToggle(selectedTheme);\n }\n };\n\n const currentTheme = variant === 'with-save' ? tempTheme : themeMode;\n\n return (\n <div className=\"flex flex-row gap-2 sm:gap-4 py-2\">\n {problemTypes.map((type) => (\n <SelectionButton\n key={type.id}\n icon={type.icon}\n label={type.title}\n selected={currentTheme === type.id}\n onClick={() => handleThemeSelect(type.id)}\n className=\"w-full p-2 sm:p-4\"\n />\n ))}\n </div>\n );\n};\n","import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * SelectionButton component props interface\n */\ntype SelectionButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * SelectionButton component for Analytica Ensino platforms\n *\n * Um botão com ícone e texto para ações e navegação com estado de seleção.\n * Ideal para filtros, tags, categorias, seleção de tipos, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado\n *\n * @example\n * ```tsx\n * <SelectionButton\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={false}\n * onClick={() => handleSelection()}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <SelectionButton\n * ref={buttonRef}\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={isSelected}\n * onClick={() => setSelected(!isSelected)}\n * />\n * ```\n */\nconst SelectionButton = forwardRef<HTMLButtonElement, SelectionButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'inline-flex',\n 'items-center',\n 'justify-start',\n 'gap-2',\n 'p-4',\n 'rounded-xl',\n 'cursor-pointer',\n 'border',\n 'border-border-50',\n 'bg-background',\n 'text-sm',\n 'text-text-700',\n 'font-bold',\n 'shadow-soft-shadow-1',\n 'hover:bg-background-100',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-indicator-info',\n 'focus-visible:ring-offset-0',\n 'focus-visible:shadow-none',\n 'active:ring-2',\n 'active:ring-primary-950',\n 'active:ring-offset-0',\n 'active:shadow-none',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n ];\n\n const stateClasses = selected\n ? ['ring-primary-950', 'ring-2', 'ring-offset-0', 'shadow-none']\n : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(allClasses, className)}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-6 h-6\">{icon}</span>\n <span>{label}</span>\n </button>\n );\n }\n);\n\nSelectionButton.displayName = 'SelectionButton';\n\nexport default SelectionButton;\n","import { useEffect } from 'react';\nimport { useThemeStore, ThemeMode } from '../store/themeStore';\n\nexport type { ThemeMode };\n\n/**\n * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema\n * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema\n * Utiliza Zustand para persistir o estado entre múltiplos arquivos e sessões\n */\nexport const useTheme = () => {\n const {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n initializeTheme,\n handleSystemThemeChange,\n } = useThemeStore();\n\n useEffect(() => {\n // Initialize theme on first render\n initializeTheme();\n\n // Listener para mudanças nas preferências do sistema (apenas quando mode é 'system')\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, [initializeTheme, handleSystemThemeChange]);\n\n return {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n };\n};\n","import { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n/**\n * Theme store state interface\n */\nexport interface ThemeState {\n /**\n * Current theme mode\n */\n themeMode: ThemeMode;\n /**\n * Whether the current theme is dark\n */\n isDark: boolean;\n}\n\n/**\n * Theme store actions interface\n */\nexport interface ThemeActions {\n /**\n * Apply theme based on the mode selected\n */\n applyTheme: (mode: ThemeMode) => void;\n /**\n * Toggle between themes\n */\n toggleTheme: () => void;\n /**\n * Set a specific theme mode\n */\n setTheme: (mode: ThemeMode) => void;\n /**\n * Initialize theme on app start\n */\n initializeTheme: () => void;\n /**\n * Handle system theme change\n */\n handleSystemThemeChange: () => void;\n}\n\nexport type ThemeStore = ThemeState & ThemeActions;\n\n/**\n * Apply theme to DOM based on mode\n */\nconst applyThemeToDOM = (mode: ThemeMode): boolean => {\n const htmlElement = document.documentElement;\n const originalTheme = htmlElement.getAttribute('data-original-theme');\n\n if (mode === 'dark') {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (mode === 'light') {\n if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n }\n return false;\n } else if (mode === 'system') {\n const isSystemDark = window.matchMedia(\n '(prefers-color-scheme: dark)'\n ).matches;\n if (isSystemDark) {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n return false;\n }\n }\n return false;\n};\n\n/**\n * Save original theme from white label\n */\nconst saveOriginalTheme = () => {\n const htmlElement = document.documentElement;\n const currentTheme = htmlElement.getAttribute('data-theme');\n if (currentTheme && !htmlElement.getAttribute('data-original-theme')) {\n htmlElement.setAttribute('data-original-theme', currentTheme);\n }\n};\n\n/**\n * Theme store using Zustand with persistence\n */\nexport const useThemeStore = create<ThemeStore>()(\n devtools(\n persist(\n (set, get) => ({\n // Initial state\n themeMode: 'system',\n isDark: false,\n\n // Actions\n applyTheme: (mode: ThemeMode) => {\n const isDark = applyThemeToDOM(mode);\n set({ isDark });\n },\n\n toggleTheme: () => {\n const { themeMode, applyTheme } = get();\n let newMode: ThemeMode;\n\n if (themeMode === 'light') {\n newMode = 'dark';\n } else if (themeMode === 'dark') {\n newMode = 'light';\n } else {\n // Se estiver em 'system', vai para 'dark'\n newMode = 'dark';\n }\n\n set({ themeMode: newMode });\n applyTheme(newMode);\n },\n\n setTheme: (mode: ThemeMode) => {\n const { applyTheme } = get();\n set({ themeMode: mode });\n applyTheme(mode);\n },\n\n initializeTheme: () => {\n const { themeMode, applyTheme } = get();\n\n // Save original theme from white label\n saveOriginalTheme();\n\n // Apply the current theme mode\n applyTheme(themeMode);\n },\n\n handleSystemThemeChange: () => {\n const { themeMode, applyTheme } = get();\n // Only respond to system changes when in system mode\n if (themeMode === 'system') {\n applyTheme('system');\n }\n },\n }),\n {\n name: 'theme-store', // Nome da chave no localStorage\n partialize: (state) => ({\n themeMode: state.themeMode,\n }), // Só persiste o themeMode, não o isDark\n }\n ),\n {\n name: 'theme-store',\n }\n )\n);\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n AccordionGroup,\n Badge,\n CardAccordation,\n CheckBox,\n cn,\n Text,\n Divider,\n} from '../../';\nimport {\n areSelectedIdsEqual,\n isCategoryEnabled as isCategoryEnabledHelper,\n getBadgeText as getBadgeTextHelper,\n handleAccordionValueChange as handleAccordionValueChangeHelper,\n calculateFormattedItemsForAutoSelection,\n} from './CheckBoxGroup.helpers';\n\nexport type Item = {\n id: string;\n name: string;\n [key: string]: unknown;\n};\n\nexport type CategoryConfig = {\n key: string;\n label: string;\n selectedIds?: string[];\n dependsOn?: string[];\n itens?: Item[];\n filteredBy?: { key: string; internalField: string }[];\n};\n\nexport const CheckboxGroup = ({\n categories,\n onCategoriesChange,\n compactSingleItem = true,\n showDivider = true,\n showSingleItem = false,\n}: {\n categories: CategoryConfig[];\n onCategoriesChange: (categories: CategoryConfig[]) => void;\n compactSingleItem?: boolean;\n showDivider?: boolean;\n showSingleItem?: boolean;\n}) => {\n const [openAccordion, setOpenAccordion] = useState<string>('');\n\n // Refs to prevent infinite loops and track auto-selection state\n const autoSelectionAppliedRef = useRef<boolean>(false);\n const onCategoriesChangeRef = useRef(onCategoriesChange);\n const previousCategoriesRef = useRef<CategoryConfig[]>(categories);\n\n // Update ref when onCategoriesChange changes\n useEffect(() => {\n onCategoriesChangeRef.current = onCategoriesChange;\n }, [onCategoriesChange]);\n\n // Use helper function for comparing selectedIds arrays\n\n // Auto-seleciona categorias com apenas um item (considerando itens filtrados)\n const categoriesWithAutoSelection = useMemo(() => {\n return categories.map((category) => {\n // Get filtered/visible items for this category\n const filteredItems = calculateFormattedItemsForAutoSelection(\n category,\n categories\n );\n\n // Se tem apenas um item filtrado/visível e nenhum está selecionado, auto-seleciona\n if (\n filteredItems.length === 1 &&\n (!category.selectedIds || category.selectedIds.length === 0)\n ) {\n return {\n ...category,\n selectedIds: [filteredItems[0].id],\n };\n }\n return category;\n });\n }, [categories]);\n\n // Aplica a auto-seleção se necessário\n // Note: onCategoriesChange should be memoized by the parent component to prevent re-renders\n useEffect(() => {\n // Check if categories have actually changed by comparing with previous reference\n const categoriesChanged = categories !== previousCategoriesRef.current;\n\n if (!categoriesChanged && autoSelectionAppliedRef.current) {\n // No changes and auto-selection already applied, skip\n return;\n }\n\n // Update previous categories reference\n previousCategoriesRef.current = categories;\n\n // Check for auto-selection changes using efficient comparison\n const hasAutoSelectionChanges = categoriesWithAutoSelection.some(\n (cat, index) => {\n const originalCat = categories[index];\n return !areSelectedIdsEqual(cat.selectedIds, originalCat.selectedIds);\n }\n );\n\n if (hasAutoSelectionChanges) {\n autoSelectionAppliedRef.current = true;\n // Use ref to avoid dependency on potentially non-memoized callback\n onCategoriesChangeRef.current(categoriesWithAutoSelection);\n } else if (categoriesChanged) {\n // Reset auto-selection flag when categories change externally\n autoSelectionAppliedRef.current = false;\n }\n }, [categoriesWithAutoSelection, categories]);\n\n const isCheckBoxIsSelected = (categoryKey: string, itemId: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return false;\n return category.selectedIds?.includes(itemId) || false;\n };\n\n const isMinimalOneCheckBoxIsSelected = (categoryKey: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return false;\n\n // Obtém apenas os itens filtrados (visíveis)\n const formattedItems = getFormattedItems(categoryKey);\n const filteredItems = formattedItems.flatMap((group) => group.itens || []);\n const filteredItemIds = filteredItems.map((item) => item.id);\n\n // Verifica se pelo menos um item filtrado está selecionado\n return filteredItemIds.some((itemId) =>\n category.selectedIds?.includes(itemId)\n );\n };\n\n // Helper function to create combination of two arrays\n const createCombinations = (\n acc: string[][],\n currentArray: string[]\n ): string[][] => {\n const combinations: string[][] = [];\n for (const existingCombo of acc) {\n for (const item of currentArray) {\n combinations.push([...existingCombo, item]);\n }\n }\n return combinations;\n };\n\n // Helper function to calculate cartesian product of arrays\n const cartesian = (arr: string[][]): string[][] => {\n return arr.reduce(createCombinations, [[]] as string[][]);\n };\n\n // Helper function to get selected IDs for filters\n const getSelectedIdsForFilters = (\n filters: { key: string; internalField: string; label?: string }[]\n ) => {\n return filters.map((f) => {\n const parentCat = categories.find((c) => c.key === f.key);\n if (!parentCat?.selectedIds?.length) {\n return [];\n }\n return parentCat.selectedIds;\n });\n };\n\n // Helper function to generate group label for single filter\n const generateSingleFilterLabel = (\n filter: { key: string; internalField: string },\n comboId: string\n ) => {\n const cat = categories.find((c) => c.key === filter.key);\n return cat?.itens?.find((i) => i.id === comboId)?.name || comboId;\n };\n\n // Helper function to generate group label for multiple filters\n const generateMultipleFiltersLabel = (\n filters: { key: string; internalField: string }[],\n comboIds: string[]\n ) => {\n const firstCat = categories.find((c) => c.key === filters[0].key);\n const firstVal =\n firstCat?.itens?.find((i) => i.id === comboIds[0])?.name || comboIds[0];\n\n const labelParts: string[] = [firstVal];\n\n for (let idx = 1; idx < filters.length; idx++) {\n const f = filters[idx];\n const cat = categories.find((c) => c.key === f.key);\n const val =\n cat?.itens?.find((i) => i.id === comboIds[idx])?.name || comboIds[idx];\n labelParts.push(`(${val})`);\n }\n return labelParts.join(' ');\n };\n\n // Helper function to process combination and add to grouped map\n const processCombination = (\n comboIds: string[],\n filters: { key: string; internalField: string; label?: string }[],\n category: CategoryConfig,\n groupedMap: Record<string, { groupLabel?: string; itens: Item[] }>\n ) => {\n const filteredItems = (category?.itens || []).filter((item) =>\n filters.every((f, idx) => item[f.internalField] === comboIds[idx])\n );\n\n if (filteredItems.length === 0) return;\n\n let groupLabel: string | undefined = undefined;\n\n if (filters.length === 1) {\n groupLabel = generateSingleFilterLabel(filters[0], comboIds[0]);\n } else if (filters.length > 1) {\n groupLabel = generateMultipleFiltersLabel(filters, comboIds);\n }\n\n const key = groupLabel || '';\n if (!groupedMap[key]) {\n groupedMap[key] = groupLabel ? { groupLabel, itens: [] } : { itens: [] };\n }\n groupedMap[key].itens.push(...filteredItems);\n };\n\n // Helper function to calculate formatted items for a category\n const calculateFormattedItems = (categoryKey: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n\n if (!category?.dependsOn || category.dependsOn.length === 0) {\n return [{ itens: category?.itens || [] }];\n }\n\n // Check if category is enabled based on dependencies (inline to avoid stale closure)\n const isEnabled = category.dependsOn.every((depKey) => {\n const depCat = categories.find((c) => c.key === depKey);\n return depCat?.selectedIds && depCat.selectedIds.length > 0;\n });\n\n // If category is disabled, return empty items array to hide all items\n if (!isEnabled) {\n return [{ itens: [] }];\n }\n\n const filters =\n (category.filteredBy as {\n key: string;\n internalField: string;\n label?: string;\n }[]) || [];\n\n if (filters.length === 0) {\n return [{ itens: category?.itens || [] }];\n }\n\n const selectedIdsArr = getSelectedIdsForFilters(filters);\n\n if (selectedIdsArr.some((arr) => arr.length === 0)) {\n return [{ itens: [] }];\n }\n\n const combinations = cartesian(selectedIdsArr);\n const groupedMap: Record<string, { groupLabel?: string; itens: Item[] }> =\n {};\n\n for (const comboIds of combinations) {\n processCombination(comboIds, filters, category, groupedMap);\n }\n\n const groupedItems = Object.values(groupedMap).filter(\n (g) => g.itens.length\n );\n\n return groupedItems.length ? groupedItems : [{ itens: [] }];\n };\n\n const formattedItemsMap = useMemo(() => {\n const formattedItemsMap: Record<\n string,\n { groupLabel?: string; itens: Item[] }[]\n > = {};\n\n for (const category of categories) {\n const formattedItems = calculateFormattedItems(category.key);\n formattedItemsMap[category.key] = formattedItems;\n }\n\n return formattedItemsMap;\n }, [categories]);\n\n const getFormattedItems = (categoryKey: string) => {\n return formattedItemsMap[categoryKey] || [{ itens: [] }];\n };\n\n // Helper function to get badge text for category\n const getBadgeText = (category: CategoryConfig): string => {\n const formattedItems = getFormattedItems(category.key);\n return getBadgeTextHelper(category, formattedItems);\n };\n\n // Helper function to check if category is enabled\n const isCategoryEnabled = (category: CategoryConfig): boolean => {\n return isCategoryEnabledHelper(category, categories);\n };\n\n // Helper function to handle accordion value change\n const handleAccordionValueChange = (value: string | string[] | undefined) => {\n const newValue = handleAccordionValueChangeHelper(\n value,\n categories,\n isCategoryEnabled\n );\n if (newValue !== null) {\n setOpenAccordion(newValue);\n }\n };\n\n const getDependentCategories = (categoryKey: string): string[] => {\n return categories\n .filter((cat) => cat.dependsOn?.includes(categoryKey))\n .map((cat) => cat.key);\n };\n\n // Helper function to find items to remove from dependent category\n const findItemsToRemove = (\n depCategory: CategoryConfig,\n relevantFilter: { key: string; internalField: string },\n deselectedItemId: string\n ): string[] => {\n return (\n depCategory.itens\n ?.filter(\n (item) => item[relevantFilter.internalField] === deselectedItemId\n )\n .map((item) => item.id) || []\n );\n };\n\n // Helper function to process dependent category for deselection\n const processDependentCategory = (\n depCategoryKey: string,\n categoryKey: string,\n deselectedItemId: string,\n itemsToDeselect: Record<string, string[]>\n ) => {\n const depCategory = categories.find((c) => c.key === depCategoryKey);\n if (!depCategory?.filteredBy) return;\n\n const relevantFilter = depCategory.filteredBy.find(\n (f) => f.key === categoryKey\n );\n if (!relevantFilter) return;\n\n const itemsToRemove = findItemsToRemove(\n depCategory,\n relevantFilter,\n deselectedItemId\n );\n if (itemsToRemove.length > 0) {\n itemsToDeselect[depCategoryKey] = itemsToRemove;\n }\n };\n\n const getItemsToDeselect = (\n categoryKey: string,\n deselectedItemId: string\n ) => {\n const deselectedItem = categories\n .find((c) => c.key === categoryKey)\n ?.itens?.find((item) => item.id === deselectedItemId);\n if (!deselectedItem) return {};\n\n const itemsToDeselect: Record<string, string[]> = {};\n const dependentCategories = getDependentCategories(categoryKey);\n\n for (const depCategoryKey of dependentCategories) {\n processDependentCategory(\n depCategoryKey,\n categoryKey,\n deselectedItemId,\n itemsToDeselect\n );\n }\n\n return itemsToDeselect;\n };\n\n // Helper function to update category with new selected IDs\n const updateCategorySelectedIds = (\n updatedCategories: CategoryConfig[],\n depCategoryIndex: number,\n depCategory: CategoryConfig,\n itemIds: string[]\n ): CategoryConfig[] => {\n const newSelectedIds =\n depCategory.selectedIds?.filter((id) => !itemIds.includes(id)) || [];\n\n updatedCategories[depCategoryIndex] = {\n ...depCategory,\n selectedIds: newSelectedIds,\n };\n\n return updatedCategories;\n };\n\n // Helper function to apply recursive cascade deselection\n const applyRecursiveCascade = (\n depCategoryKey: string,\n itemIds: string[],\n updatedCategories: CategoryConfig[]\n ): CategoryConfig[] => {\n let result = updatedCategories;\n for (const itemId of itemIds) {\n result = applyCascadeDeselection(depCategoryKey, itemId, result);\n }\n return result;\n };\n\n const applyCascadeDeselection = (\n categoryKey: string,\n deselectedItemId: string,\n currentCategories: CategoryConfig[]\n ): CategoryConfig[] => {\n const itemsToDeselect = getItemsToDeselect(categoryKey, deselectedItemId);\n let updatedCategories = [...currentCategories];\n\n for (const [depCategoryKey, itemIds] of Object.entries(itemsToDeselect)) {\n const depCategoryIndex = updatedCategories.findIndex(\n (c) => c.key === depCategoryKey\n );\n\n if (depCategoryIndex !== -1) {\n const depCategory = updatedCategories[depCategoryIndex];\n updatedCategories = updateCategorySelectedIds(\n updatedCategories,\n depCategoryIndex,\n depCategory,\n itemIds\n );\n updatedCategories = applyRecursiveCascade(\n depCategoryKey,\n itemIds,\n updatedCategories\n );\n }\n }\n\n return updatedCategories;\n };\n\n const toggleAllInCategory = (categoryKey: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return;\n\n // Obtém apenas os itens filtrados (visíveis)\n const formattedItems = getFormattedItems(categoryKey);\n const filteredItems = formattedItems.flatMap((group) => group.itens || []);\n const filteredItemIds = filteredItems.map((item) => item.id);\n\n // Verifica quantos itens filtrados estão selecionados\n const selectedFilteredCount = filteredItemIds.filter((itemId) =>\n category.selectedIds?.includes(itemId)\n ).length;\n\n // Se NENHUM item filtrado está selecionado OU pelo menos um está selecionado mas não todos,\n // então seleciona todos os itens filtrados\n // Se TODOS os itens filtrados estão selecionados, então deseleciona todos os filtrados\n const allFilteredSelected =\n selectedFilteredCount === filteredItemIds.length;\n\n const newSelection = allFilteredSelected\n ? category.selectedIds?.filter((id) => !filteredItemIds.includes(id)) ||\n []\n : [\n ...(category.selectedIds || []),\n ...filteredItemIds.filter(\n (id) => !category.selectedIds?.includes(id)\n ),\n ];\n\n let updatedCategories = categories.map((c) =>\n c.key === categoryKey ? { ...c, selectedIds: newSelection } : c\n );\n\n // Se está deselecionando, aplica cascata para os itens que foram deselecionados\n if (allFilteredSelected) {\n for (const itemId of filteredItemIds) {\n updatedCategories = applyCascadeDeselection(\n categoryKey,\n itemId,\n updatedCategories\n );\n }\n }\n\n onCategoriesChange(updatedCategories);\n };\n\n const toggleItem = (categoryKey: string, itemId: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return;\n const isCurrentlySelected = category.selectedIds?.includes(itemId);\n const newSelection = isCurrentlySelected\n ? category.selectedIds?.filter((id) => id !== itemId)\n : [...(category.selectedIds || []), itemId];\n\n let updatedCategories = categories.map((c) =>\n c.key === categoryKey ? { ...c, selectedIds: newSelection } : c\n );\n\n // Se está deselecionando, aplica cascata\n if (isCurrentlySelected) {\n updatedCategories = applyCascadeDeselection(\n categoryKey,\n itemId,\n updatedCategories\n );\n }\n\n onCategoriesChange(updatedCategories);\n };\n\n // Helper component to render individual checkbox item\n const renderCheckboxItem = (item: Item, categoryKey: string) => {\n // Generate unique ID by combining category key and item id to avoid conflicts\n const uniqueId = `${categoryKey}-${item.id}`;\n\n return (\n <div\n key={item.id}\n className=\"flex items-center gap-3 px-2\"\n role=\"presentation\"\n onClick={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n onMouseUp={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <CheckBox\n id={uniqueId}\n checked={isCheckBoxIsSelected(categoryKey, item.id)}\n onChange={() => toggleItem(categoryKey, item.id)}\n />\n <label\n htmlFor={uniqueId}\n className=\"text-sm text-text-950 cursor-pointer select-none\"\n >\n {item.name}\n </label>\n </div>\n );\n };\n\n // Helper component to render formatted group\n const renderFormattedGroup = (\n formattedGroup: { groupLabel?: string; itens: Item[] },\n idx: number,\n categoryKey: string\n ) => (\n <div\n key={formattedGroup.groupLabel || `group-${idx}`}\n className=\"flex flex-col gap-3\"\n >\n {'groupLabel' in formattedGroup && formattedGroup.groupLabel && (\n <Text size=\"sm\" className=\"mt-2\" weight=\"semibold\">\n {formattedGroup.groupLabel}\n </Text>\n )}\n {formattedGroup.itens?.map((item: Item) =>\n renderCheckboxItem(item, categoryKey)\n )}\n </div>\n );\n\n // Helper component to render accordion trigger\n const renderAccordionTrigger = (\n category: CategoryConfig,\n isEnabled: boolean\n ) => (\n <div className=\"flex items-center justify-between w-full p-2\">\n <div className=\"flex items-center gap-3\">\n <CheckBox\n checked={isMinimalOneCheckBoxIsSelected(category.key)}\n disabled={!isEnabled}\n indeterminate={isMinimalOneCheckBoxIsSelected(category.key)}\n onChange={() => toggleAllInCategory(category.key)}\n />\n <Text\n size=\"sm\"\n weight=\"medium\"\n className={cn('text-text-800', !isEnabled && 'opacity-40')}\n >\n {category.label}\n </Text>\n </div>\n {(openAccordion === category.key || isEnabled) && (\n <Badge variant=\"solid\" action=\"info\">\n {getBadgeText(category)}\n </Badge>\n )}\n </div>\n );\n\n // Helper component to render compact single item view\n const renderCompactSingleItem = (category: CategoryConfig) => {\n const formattedItems = getFormattedItems(category.key);\n const allItems = formattedItems.flatMap((group) => group.itens || []);\n\n if (allItems.length !== 1) {\n return null;\n }\n\n const singleItem = allItems[0];\n\n return (\n <div\n key={category.key}\n className=\"flex items-center justify-between w-full px-3 py-2\"\n >\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-800\">\n {category.label}\n </Text>\n <Text size=\"sm\" className=\"text-text-950\">\n {singleItem.name}\n </Text>\n </div>\n );\n };\n\n // Helper component to render category accordion\n const renderCategoryAccordion = (category: CategoryConfig) => {\n // Check if category is enabled based on dependencies\n const isEnabled = isCategoryEnabled(category);\n const hasOnlyOneItem = category.itens?.length === 1;\n\n if (hasOnlyOneItem && !compactSingleItem && !showSingleItem) {\n return null;\n }\n\n const formattedItems = getFormattedItems(category.key);\n const allItems = formattedItems.flatMap((group) => group.itens || []);\n const hasOnlyOneAvailableItem = allItems.length === 1;\n\n // If compactSingleItem is enabled and there's only one available item, render compact version\n if (compactSingleItem && hasOnlyOneAvailableItem && isEnabled) {\n return (\n <div key={category.key}>\n {renderCompactSingleItem(category)}\n {showDivider && <Divider />}\n </div>\n );\n }\n\n const hasNoItems = formattedItems.every(\n (group) => !group.itens || group.itens.length === 0\n );\n\n return (\n <div key={category.key}>\n <CardAccordation\n value={category.key}\n disabled={!isEnabled}\n className={cn(\n 'bg-transparent border-0',\n openAccordion === category.key && 'bg-background-50 border-none'\n )}\n trigger={renderAccordionTrigger(category, isEnabled)}\n >\n <div className=\"flex flex-col gap-3 pt-2\">\n {hasNoItems && isEnabled ? (\n <div className=\"px-2 py-4\">\n <Text size=\"sm\" className=\"text-text-500 text-center\">\n Sem dados\n </Text>\n </div>\n ) : (\n formattedItems.map((formattedGroup, idx) =>\n renderFormattedGroup(formattedGroup, idx, category.key)\n )\n )}\n </div>\n </CardAccordation>\n {openAccordion !== category.key && showDivider && <Divider />}\n </div>\n );\n };\n\n // Auto-collapse accordion when category becomes disabled\n useEffect(() => {\n if (!openAccordion) return;\n\n const category = categories.find((c) => c.key === openAccordion);\n if (!category) return;\n\n // Check if the open category is now disabled\n const isEnabled = isCategoryEnabled(category);\n\n // If category is disabled, close it\n if (!isEnabled) {\n // Use setTimeout to ensure this runs after any other state updates\n setTimeout(() => {\n setOpenAccordion('');\n }, 0);\n }\n }, [categories, openAccordion]);\n\n return (\n <AccordionGroup\n type=\"single\"\n collapsible\n value={openAccordion}\n onValueChange={handleAccordionValueChange}\n >\n {categories.map(renderCategoryAccordion)}\n </AccordionGroup>\n );\n};\n","import { CSSProperties, ReactNode } from 'react';\nimport 'katex/dist/katex.min.css';\nimport { InlineMath, BlockMath } from 'react-katex';\nimport DOMPurify from 'dompurify';\nimport parse, {\n DOMNode,\n Element,\n HTMLReactParserOptions,\n} from 'html-react-parser';\nimport { cn } from '../../utils/utils';\n\n/**\n * Props for the LatexRenderer component\n */\nexport interface LatexRendererProps {\n /** HTML content containing LaTeX expressions to render */\n content: string;\n /** Additional CSS classes to apply */\n className?: string;\n /** Inline styles to apply */\n style?: CSSProperties;\n /** Custom error renderer for invalid LaTeX expressions */\n onError?: (latex: string) => ReactNode;\n}\n\n/**\n * Helper function to sanitize HTML content to prevent XSS attacks\n */\nconst sanitizeHtml = (value: string): string => {\n return DOMPurify.sanitize(value, {\n ADD_ATTR: ['data-latex', 'data-display-mode', 'data-math', 'data-math-id'],\n });\n};\n\n/**\n * Helper function to decode HTML entities\n * Converts entities like &, <, > back to their actual characters\n */\nconst decodeHtmlEntities = (str: string): string => {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = str;\n return textarea.value;\n};\n\n/**\n * Helper function to clean latex from invisible characters\n */\nconst cleanLatex = (str: string): string => {\n // Remove zero-width characters, invisible characters, and other problematic Unicode\n return str.replaceAll(/[\\u200B-\\u200D\\uFEFF]/g, '').trim();\n};\n\n/**\n * Type for math parts used in rendering\n */\ninterface MathPart {\n id: number;\n type: 'inline' | 'block';\n latex: string;\n}\n\n/**\n * Creates a replace function for html-react-parser that replaces math placeholders\n * with KaTeX components\n */\nconst createMathReplacer = (\n mathParts: MathPart[],\n errorRenderer: (latex: string) => ReactNode\n) => {\n return (domNode: DOMNode) => {\n if (\n domNode instanceof Element &&\n domNode.name === 'span' &&\n domNode.attribs['data-math-id']\n ) {\n const mathId = Number.parseInt(domNode.attribs['data-math-id'], 10);\n const mathPart = mathParts[mathId];\n\n if (!mathPart) return domNode;\n\n if (mathPart.type === 'inline') {\n return (\n <InlineMath\n key={`math-${mathId}`}\n math={mathPart.latex}\n renderError={() => errorRenderer(mathPart.latex)}\n />\n );\n } else {\n return (\n <div key={`math-${mathId}`} className=\"my-2.5 text-center\">\n <BlockMath\n math={mathPart.latex}\n renderError={() => errorRenderer(mathPart.latex)}\n />\n </div>\n );\n }\n }\n return domNode;\n };\n};\n\n/**\n * LatexRenderer component for Analytica Ensino platforms\n *\n * Renders HTML content with embedded LaTeX/KaTeX mathematical expressions.\n * Supports multiple LaTeX formats:\n * - Inline math: `$...$` or `<latex>...</latex>`\n * - Block math: `$$...$$`\n * - LaTeX environments: `\\begin{equation}...\\end{equation}`, etc.\n * - Editor format: `<span class=\"math-formula\" data-latex=\"...\">...</span>`\n *\n * @param content - HTML content with LaTeX expressions\n * @param className - Additional CSS classes\n * @param style - Inline styles\n * @param onError - Custom error renderer\n * @returns Rendered content with mathematical expressions\n *\n * @example\n * ```tsx\n * <LatexRenderer content=\"The formula is $E = mc^2$\" />\n *\n * <LatexRenderer\n * content=\"Block equation: $$\\sum_{i=1}^{n} x_i$$\"\n * className=\"my-custom-class\"\n * />\n *\n * <LatexRenderer\n * content=\"<p>Matrix: \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix}</p>\"\n * onError={(latex) => <span>Invalid: {latex}</span>}\n * />\n * ```\n */\nconst LatexRenderer = ({\n content,\n className,\n style,\n onError,\n}: LatexRendererProps) => {\n const renderContentWithMath = (htmlContent: string) => {\n if (!htmlContent) return null;\n\n let processedContent = htmlContent;\n const mathParts: MathPart[] = [];\n\n // Step 1: Handle math-formula spans (from the editor)\n const mathFormulaPattern =\n /<span[^>]*class=\"math-formula\"[^>]*data-latex=\"([^\"]*)\"[^>]*>[\\s\\S]*?<\\/span>/g;\n processedContent = processedContent.replaceAll(\n mathFormulaPattern,\n (match, latex) => {\n const isDisplayMode = match.includes('data-display-mode=\"true\"');\n const id = mathParts.length;\n mathParts.push({\n id,\n type: isDisplayMode ? 'block' : 'inline',\n latex: cleanLatex(decodeHtmlEntities(latex)),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 2: Handle wrapped math expressions (from math modal - legacy)\n const wrappedMathPattern =\n /<span[^>]*class=\"math-expression\"[^>]*data-math=\"([^\"]*)\"[^>]*>.*?<\\/span>/g;\n processedContent = processedContent.replaceAll(\n wrappedMathPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'inline',\n latex: cleanLatex(decodeHtmlEntities(latex)),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 3: Handle raw $$...$$ expressions (manual input or saved content) - BEFORE single $\n const doubleDollarPattern = /(?<!\\\\)\\$\\$([\\s\\S]+?)\\$\\$/g;\n processedContent = processedContent.replaceAll(\n doubleDollarPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'block',\n latex: cleanLatex(latex),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 4: Handle single $...$ expressions for inline math\n const singleDollarPattern = /(?<!\\\\)\\$([\\s\\S]+?)\\$/g;\n processedContent = processedContent.replaceAll(\n singleDollarPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'inline',\n latex: cleanLatex(latex),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 5: Handle <latex>...</latex> tags for inline math\n const latexTagPattern =\n /(?:<latex>|<latex>)([\\s\\S]*?)(?:<\\/latex>|<\\/latex>)/g;\n processedContent = processedContent.replaceAll(\n latexTagPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'inline',\n latex: cleanLatex(latex),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 6: Handle standalone LaTeX environments (align, equation, pmatrix, etc.) for block math\n const latexEnvPattern = /\\\\begin\\{([^}]+)\\}([\\s\\S]*?)\\\\end\\{\\1\\}/g;\n processedContent = processedContent.replaceAll(latexEnvPattern, (match) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'block',\n latex: cleanLatex(match),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n });\n\n // Sanitize the HTML with placeholders\n const sanitizedContent = sanitizeHtml(processedContent);\n\n // Default error renderer\n const defaultErrorRenderer = (latex: string) => (\n <span className=\"text-red-600\">Math Error: {latex}</span>\n );\n\n const errorRenderer = onError || defaultErrorRenderer;\n\n // Parse HTML and replace math placeholders with React components\n const options: HTMLReactParserOptions = {\n replace: createMathReplacer(mathParts, errorRenderer),\n };\n\n return <>{parse(sanitizedContent, options)}</>;\n };\n\n return (\n <div\n className={cn('whitespace-pre-wrap leading-relaxed', className)}\n style={style}\n >\n {renderContentWithMath(content)}\n </div>\n );\n};\n\nexport default LatexRenderer;\n","import {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n} from 'react';\nimport Text from '../Text/Text';\nimport { Check, Minus } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckBox size variants\n */\ntype CheckBoxSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckBox visual state\n */\ntype CheckBoxState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n checkbox: 'w-4 h-4', // 16px x 16px\n textSize: 'sm' as const,\n spacing: 'gap-1.5', // 6px\n borderWidth: 'border-2',\n iconSize: 14, // pixels for Phosphor icons\n labelHeight: 'h-[21px]',\n },\n medium: {\n checkbox: 'w-5 h-5', // 20px x 20px\n textSize: 'md' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-2',\n iconSize: 16, // pixels for Phosphor icons\n labelHeight: 'h-6',\n },\n large: {\n checkbox: 'w-6 h-6', // 24px x 24px\n textSize: 'lg' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-[3px]', // 3px border\n iconSize: 20, // pixels for Phosphor icons\n labelHeight: 'h-[27px]',\n },\n} as const;\n\n/**\n * Base checkbox styling classes using design system colors\n */\nconst BASE_CHECKBOX_CLASSES =\n 'rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked:\n 'border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-primary-800 bg-primary-800 text-text',\n },\n focused: {\n unchecked:\n 'border-indicator-info bg-background ring-2 ring-indicator-info/20',\n checked:\n 'border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20',\n },\n invalid: {\n unchecked: 'border-error-700 bg-background hover:border-error-600',\n checked: 'border-error-700 bg-primary-950 text-text',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed opacity-40',\n checked:\n 'border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40',\n },\n} as const;\n\n/**\n * CheckBox component props interface\n */\nexport type CheckBoxProps = {\n /** Label text to display next to the checkbox */\n label?: ReactNode;\n /** Size variant of the checkbox */\n size?: CheckBoxSize;\n /** Visual state of the checkbox */\n state?: CheckBoxState;\n /** Indeterminate state for partial selections */\n indeterminate?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>;\n\n/**\n * CheckBox component for Analytica Ensino platforms\n *\n * A checkbox component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic checkbox\n * <CheckBox label=\"Option\" />\n *\n * // Small size\n * <CheckBox size=\"small\" label=\"Small option\" />\n *\n * // Invalid state\n * <CheckBox state=\"invalid\" label=\"Required field\" />\n *\n * // Disabled state\n * <CheckBox disabled label=\"Disabled option\" />\n * ```\n */\nconst CheckBox = forwardRef<HTMLInputElement, CheckBoxProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n indeterminate = false,\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n disabled,\n id,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-${generatedId}`;\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalChecked(event.target.checked);\n }\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Determine checkbox visual variant\n const checkVariant = checked || indeterminate ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][checkVariant];\n\n // Special border width handling for focused/hovered states and large size\n const borderWidthClass =\n state === 'focused' || (state === 'hovered' && size === 'large')\n ? 'border-[3px]'\n : sizeClasses.borderWidth;\n\n // Get final checkbox classes\n const checkboxClasses = cn(\n BASE_CHECKBOX_CLASSES,\n sizeClasses.checkbox,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Render appropriate icon based on state\n const renderIcon = () => {\n if (indeterminate) {\n return (\n <Minus\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n if (checked) {\n return (\n <Check\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n return null;\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n\n {/* Custom styled checkbox */}\n <label htmlFor={inputId} className={checkboxClasses}>\n {/* Show appropriate icon based on state */}\n {renderIcon()}\n </label>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n 'cursor-pointer select-none leading-[150%] flex items-center font-roboto',\n labelClassName\n )}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nCheckBox.displayName = 'CheckBox';\n\nexport default CheckBox;\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n","import {\n TextareaHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n FocusEvent,\n} from 'react';\nimport { WarningCircle } from 'phosphor-react';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * TextArea size variants\n */\ntype TextAreaSize = 'small' | 'medium' | 'large' | 'extraLarge';\n\n/**\n * TextArea visual state\n */\ntype TextAreaState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations with exact pixel specifications\n */\nconst SIZE_CLASSES = {\n small: {\n textarea: 'h-24 text-sm', // 96px height, 14px font\n textSize: 'sm' as const,\n },\n medium: {\n textarea: 'h-24 text-base', // 96px height, 16px font\n textSize: 'md' as const,\n },\n large: {\n textarea: 'h-24 text-lg', // 96px height, 18px font\n textSize: 'lg' as const,\n },\n extraLarge: {\n textarea: 'h-24 text-xl', // 96px height, 20px font\n textSize: 'xl' as const,\n },\n} as const;\n\n/**\n * Base textarea styling classes using design system colors\n */\nconst BASE_TEXTAREA_CLASSES =\n 'w-full box-border p-3 bg-background border border-solid rounded-[4px] resize-none focus:outline-none font-roboto font-normal leading-[150%] placeholder:text-text-600 transition-all duration-200';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n base: 'border-border-300 bg-background text-text-600',\n hover: 'hover:border-border-400',\n focus: 'focus:border-border-500',\n },\n hovered: {\n base: 'border-border-400 bg-background text-text-600',\n hover: '',\n focus: 'focus:border-border-500',\n },\n focused: {\n base: 'border-2 border-primary-950 bg-background text-text-900',\n hover: '',\n focus: '',\n },\n invalid: {\n base: 'border-2 border-red-700 bg-white text-gray-800',\n hover: 'hover:border-red-700',\n focus: 'focus:border-red-700',\n },\n disabled: {\n base: 'border-border-300 bg-background text-text-600 cursor-not-allowed opacity-40',\n hover: '',\n focus: '',\n },\n} as const;\n\n/**\n * TextArea component props interface\n */\nexport type TextAreaProps = {\n /** Label text to display above the textarea */\n label?: ReactNode;\n /** Size variant of the textarea */\n size?: TextAreaSize;\n /** Visual state of the textarea */\n state?: TextAreaState;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperMessage?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Show character count when maxLength is provided */\n showCharacterCount?: boolean;\n} & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'size'>;\n\n/**\n * TextArea component for Analytica Ensino platforms\n *\n * A textarea component with essential states, sizes and themes.\n * Uses exact design specifications with 288px width, 96px height, and specific\n * color values. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic textarea\n * <TextArea label=\"Description\" placeholder=\"Enter description...\" />\n *\n * // Small size\n * <TextArea size=\"small\" label=\"Comment\" />\n *\n * // Invalid state\n * <TextArea state=\"invalid\" label=\"Required field\" errorMessage=\"This field is required\" />\n *\n * // Disabled state\n * <TextArea disabled label=\"Read-only field\" />\n * ```\n */\nconst TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n errorMessage,\n helperMessage,\n className = '',\n labelClassName = '',\n disabled,\n id,\n onChange,\n placeholder,\n required,\n showCharacterCount = false,\n maxLength,\n value,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `textarea-${generatedId}`;\n\n // Internal state for focus tracking\n const [isFocused, setIsFocused] = useState(false);\n\n // Calculate current character count\n const currentLength = typeof value === 'string' ? value.length : 0;\n const isNearLimit = maxLength && currentLength >= maxLength * 0.8;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n onChange?.(event);\n };\n\n // Handle focus events\n const handleFocus = (event: FocusEvent<HTMLTextAreaElement>) => {\n setIsFocused(true);\n props.onFocus?.(event);\n };\n\n // Handle blur events\n const handleBlur = (event: FocusEvent<HTMLTextAreaElement>) => {\n setIsFocused(false);\n props.onBlur?.(event);\n };\n\n // Determine current state based on props and focus\n let currentState = disabled ? 'disabled' : state;\n\n // Override state based on focus\n if (\n isFocused &&\n currentState !== 'invalid' &&\n currentState !== 'disabled'\n ) {\n currentState = 'focused';\n }\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Get styling classes\n const stateClasses = STATE_CLASSES[currentState];\n\n // Get final textarea classes\n const textareaClasses = cn(\n BASE_TEXTAREA_CLASSES,\n sizeClasses.textarea,\n stateClasses.base,\n stateClasses.hover,\n stateClasses.focus,\n className\n );\n\n return (\n <div className={`flex flex-col`}>\n {/* Label */}\n {label && (\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"medium\"\n color=\"text-text-950\"\n className={cn('mb-1.5', labelClassName)}\n >\n {label}{' '}\n {required && <span className=\"text-indicator-error\">*</span>}\n </Text>\n )}\n\n {/* Textarea */}\n <textarea\n ref={ref}\n id={inputId}\n disabled={disabled}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className={textareaClasses}\n placeholder={placeholder}\n required={required}\n maxLength={maxLength}\n value={value}\n {...props}\n />\n\n {/* Error message */}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error mt-1.5\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n\n {/* Helper text or Character count */}\n {!errorMessage && showCharacterCount && maxLength && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className={`mt-1.5 ${isNearLimit ? 'text-indicator-warning' : 'text-text-500'}`}\n >\n {currentLength}/{maxLength} caracteres\n </Text>\n )}\n {!errorMessage &&\n helperMessage &&\n !(showCharacterCount && maxLength) && (\n <Text size=\"sm\" weight=\"normal\" className=\"mt-1.5 text-text-500\">\n {helperMessage}\n </Text>\n )}\n </div>\n );\n }\n);\n\nTextArea.displayName = 'TextArea';\n\nexport default TextArea;\n","import { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Divider component props interface\n */\ntype DividerProps = {\n /** Orientation of the divider */\n orientation?: 'horizontal' | 'vertical';\n /** Additional CSS classes to apply */\n className?: string;\n} & HTMLAttributes<HTMLHRElement>;\n\n/**\n * Divider component for Analytica Ensino platforms\n *\n * A simple divider component that creates a visual separation between content sections.\n * Can be used both horizontally and vertically.\n *\n * @param orientation - The orientation of the divider (horizontal or vertical)\n * @param className - Additional CSS classes\n * @param props - All other standard hr HTML attributes\n * @returns A styled divider element\n *\n * @example\n * ```tsx\n * <Divider orientation=\"horizontal\" />\n * <Divider orientation=\"vertical\" className=\"h-8\" />\n * ```\n */\nconst Divider = ({\n orientation = 'horizontal',\n className = '',\n ...props\n}: DividerProps) => {\n const baseClasses = 'bg-border-200 border-0';\n\n const orientationClasses = {\n horizontal: 'w-full h-px',\n vertical: 'h-full w-px',\n };\n\n return (\n <hr\n className={cn(baseClasses, orientationClasses[orientation], className)}\n aria-orientation={orientation}\n {...props}\n />\n );\n};\n\nexport default Divider;\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * Radio size variants\n */\ntype RadioSize = 'small' | 'medium' | 'large' | 'extraLarge';\n\n/**\n * Radio visual state\n */\ntype RadioState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n radio: 'w-5 h-5',\n textSize: 'sm' as const,\n spacing: 'gap-1.5',\n borderWidth: 'border-2',\n dotSize: 'w-2.5 h-2.5',\n labelHeight: 'h-5',\n },\n medium: {\n radio: 'w-6 h-6',\n textSize: 'md' as const,\n spacing: 'gap-2',\n borderWidth: 'border-2',\n dotSize: 'w-3 h-3',\n labelHeight: 'h-6',\n },\n large: {\n radio: 'w-7 h-7',\n textSize: 'lg' as const,\n spacing: 'gap-2',\n borderWidth: 'border-2',\n dotSize: 'w-3.5 h-3.5',\n labelHeight: 'h-7',\n },\n extraLarge: {\n radio: 'w-8 h-8',\n textSize: 'xl' as const,\n spacing: 'gap-3',\n borderWidth: 'border-2',\n dotSize: 'w-4 h-4',\n labelHeight: 'h-8',\n },\n} as const;\n\n/**\n * Focused state maintains the same sizes as default state\n * Only adds wrapper styling, does not change radio/dot sizes\n */\n\n/**\n * Base radio styling classes using design system colors\n */\nconst BASE_RADIO_CLASSES =\n 'rounded-full border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked: 'border-primary-950 bg-background hover:border-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-info-700 bg-background',\n },\n focused: {\n unchecked: 'border-border-400 bg-background',\n checked: 'border-primary-950 bg-background',\n },\n invalid: {\n unchecked: 'border-border-400 bg-background',\n checked: 'border-primary-950 bg-background',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed',\n checked: 'border-primary-950 bg-background cursor-not-allowed',\n },\n} as const;\n\n/**\n * Dot styling classes for the inner dot when checked\n */\nconst DOT_CLASSES = {\n default: 'bg-primary-950',\n hovered: 'bg-info-700',\n focused: 'bg-primary-950',\n invalid: 'bg-primary-950',\n disabled: 'bg-primary-950',\n} as const;\n\n/**\n * Radio component props interface\n */\nexport type RadioProps = {\n /** Label text to display next to the radio */\n label?: ReactNode;\n /** Size variant of the radio */\n size?: RadioSize;\n /** Visual state of the radio */\n state?: RadioState;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Radio group name */\n name?: string;\n /** Radio value */\n value?: string;\n /** Default checked state for uncontrolled radios */\n defaultChecked?: boolean;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'defaultChecked'\n>;\n\n/**\n * Radio component for Analytica Ensino platforms\n *\n * A radio button component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic radio\n * <Radio name=\"option\" value=\"1\" label=\"Option 1\" />\n *\n * // Small size\n * <Radio size=\"small\" name=\"option\" value=\"2\" label=\"Small option\" />\n *\n * // Invalid state\n * <Radio state=\"invalid\" name=\"option\" value=\"3\" label=\"Required field\" />\n *\n * // Disabled state\n * <Radio disabled name=\"option\" value=\"4\" label=\"Disabled option\" />\n *\n * // Default checked (uncontrolled)\n * <Radio defaultChecked name=\"option\" value=\"5\" label=\"Initially checked\" />\n * ```\n */\nconst Radio = forwardRef<HTMLInputElement, RadioProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n defaultChecked = false,\n disabled,\n id,\n name,\n value,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `radio-${generatedId}`;\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newChecked = event.target.checked;\n\n if (!isControlled) {\n setInternalChecked(newChecked);\n }\n\n // Prevent automatic scroll when input changes\n if (event.target) {\n event.target.blur();\n }\n\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Focused state maintains original sizes, only adds wrapper\n const actualRadioSize = sizeClasses.radio;\n const actualDotSize = sizeClasses.dotSize;\n\n // Determine radio visual variant\n const radioVariant = checked ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][radioVariant];\n\n // Border width logic - consistent across all states and sizes\n const getBorderWidth = () => {\n if (currentState === 'focused') {\n return 'border-2';\n }\n return sizeClasses.borderWidth;\n };\n\n const borderWidthClass = getBorderWidth();\n\n // Get final radio classes\n const radioClasses = cn(\n BASE_RADIO_CLASSES,\n actualRadioSize,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Get dot classes\n const dotClasses = cn(\n actualDotSize,\n 'rounded-full',\n DOT_CLASSES[currentState],\n 'transition-all duration-200'\n );\n\n // Determine if wrapper is needed only for focused or invalid states\n const isWrapperNeeded =\n currentState === 'focused' || currentState === 'invalid';\n const wrapperBorderColor =\n currentState === 'focused'\n ? 'border-indicator-info'\n : 'border-indicator-error';\n\n // Determine text color based on state and checked status\n const getTextColor = () => {\n if (currentState === 'disabled') {\n return checked ? 'text-text-900' : 'text-text-600';\n }\n\n if (currentState === 'focused') {\n return 'text-text-900';\n }\n\n return checked ? 'text-text-900' : 'text-text-600';\n };\n\n // Determine cursor class based on disabled state\n const getCursorClass = () => {\n return currentState === 'disabled'\n ? 'cursor-not-allowed'\n : 'cursor-pointer';\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n isWrapperNeeded\n ? cn('p-1 border-2', wrapperBorderColor, 'rounded-lg gap-1.5')\n : sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={(node) => {\n inputRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"radio\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n name={name}\n value={value}\n onChange={handleChange}\n className=\"sr-only\"\n style={{\n position: 'absolute',\n left: '-9999px',\n visibility: 'hidden',\n }}\n {...props}\n />\n\n {/* Custom styled radio */}\n <button\n type=\"button\"\n className={radioClasses}\n disabled={disabled}\n aria-pressed={checked}\n onClick={(e) => {\n // Prevent scroll when radio is clicked\n e.preventDefault();\n if (!disabled) {\n // Simulate click on hidden input\n if (inputRef.current) {\n inputRef.current.click();\n // Remove focus to prevent scroll behavior\n inputRef.current.blur();\n }\n }\n }}\n onKeyDown={(e) => {\n // Handle keyboard activation (Enter or Space)\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault();\n if (inputRef.current) {\n inputRef.current.click();\n inputRef.current.blur();\n }\n }\n }}\n >\n {/* Show dot when checked */}\n {checked && <div className={dotClasses} />}\n </button>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight,\n 'flex-1 min-w-0'\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n getCursorClass(),\n 'select-none leading-normal flex items-center font-roboto truncate',\n labelClassName\n )}\n color={getTextColor()}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5 truncate\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5 truncate\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nRadio.displayName = 'Radio';\n\n/**\n * RadioGroup store interface\n */\ninterface RadioGroupStore {\n value: string;\n setValue: (value: string) => void;\n onValueChange?: (value: string) => void;\n disabled: boolean;\n name: string;\n}\n\ntype RadioGroupStoreApi = StoreApi<RadioGroupStore>;\n\n/**\n * Create a new RadioGroup store\n */\nconst createRadioGroupStore = (\n name: string,\n defaultValue: string,\n disabled: boolean,\n onValueChange?: (value: string) => void\n): RadioGroupStoreApi =>\n create<RadioGroupStore>((set, get) => ({\n value: defaultValue,\n setValue: (value) => {\n if (!get().disabled) {\n set({ value });\n get().onValueChange?.(value);\n }\n },\n onValueChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access RadioGroup store\n */\nexport const useRadioGroupStore = (externalStore?: RadioGroupStoreApi) => {\n if (!externalStore) {\n throw new Error('RadioGroupItem must be used within a RadioGroup');\n }\n return externalStore;\n};\n\n/**\n * Inject store into RadioGroupItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: RadioGroupStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n const typedChild = child as ReactElement<any>;\n const shouldInject = typedChild.type === RadioGroupItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * RadioGroup component props interface\n */\nexport type RadioGroupProps = {\n /** Current selected value */\n value?: string;\n /** Default selected value for uncontrolled usage */\n defaultValue?: string;\n /** Callback when selection changes */\n onValueChange?: (value: string) => void;\n /** Group name for all radios */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'>;\n\n/**\n * RadioGroup component for flexible radio group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with RadioGroupItem.\n *\n * @example\n * ```tsx\n * <RadioGroup defaultValue=\"option1\" onValueChange={setValue}>\n * <div className=\"flex items-center gap-3\">\n * <RadioGroupItem value=\"option1\" id=\"r1\" />\n * <label htmlFor=\"r1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <RadioGroupItem value=\"option2\" id=\"r2\" />\n * <label htmlFor=\"r2\">Option 2</label>\n * </div>\n * </RadioGroup>\n * ```\n */\nconst RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(\n (\n {\n value: propValue,\n defaultValue = '',\n onValueChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `radio-group-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<RadioGroupStoreApi>(null);\n storeRef.current ??= createRadioGroupStore(\n name,\n defaultValue,\n disabled,\n onValueChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValue } = useStore(store, (s) => s);\n\n // Call onValueChange with initial value\n useEffect(() => {\n const currentValue = store.getState().value;\n if (currentValue && onValueChange) {\n onValueChange(currentValue);\n }\n }, []); // Empty dependency array for mount only\n\n // Handle controlled value changes\n useEffect(() => {\n if (propValue !== undefined) {\n setValue(propValue);\n }\n }, [propValue, setValue]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={className}\n role=\"radiogroup\"\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nRadioGroup.displayName = 'RadioGroup';\n\n/**\n * RadioGroupItem component props interface\n */\nexport type RadioGroupItemProps = {\n /** Value for this radio item */\n value: string;\n /** Store reference (automatically injected by RadioGroup) */\n store?: RadioGroupStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: RadioSize;\n /** Visual state */\n state?: RadioState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * RadioGroupItem component for use within RadioGroup\n *\n * A radio button without label that works within RadioGroup context.\n * Provides just the radio input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <RadioGroup defaultValue=\"option1\">\n * <div className=\"flex items-center gap-3\">\n * <RadioGroupItem value=\"option1\" id=\"r1\" />\n * <label htmlFor=\"r1\">Option 1</label>\n * </div>\n * </RadioGroup>\n * ```\n */\nconst RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useRadioGroupStore(externalStore);\n const {\n value: groupValue,\n setValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `radio-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValue === value;\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard Radio component for consistency and simplicity\n return (\n <Radio\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={(e) => {\n if (e.target.checked && !isDisabled) {\n setValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nRadioGroupItem.displayName = 'RadioGroupItem';\n\nexport default Radio;\nexport { RadioGroup, RadioGroupItem };\n","import { create } from 'zustand';\n\ntype ToastPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right'\n | 'default';\n\ntype ToastData = {\n id: string;\n title: string;\n description?: string;\n variant?: 'solid' | 'outlined';\n action?: 'warning' | 'success' | 'info';\n position?: ToastPosition;\n};\n\ntype ToastStore = {\n toasts: ToastData[];\n addToast: (toast: Omit<ToastData, 'id'>) => void;\n removeToast: (id: string) => void;\n};\n\nconst useToastStore = create<ToastStore>((set) => ({\n toasts: [],\n addToast: (toast) => {\n const id = crypto.randomUUID();\n\n set((state) => ({\n toasts: [...state.toasts, { id, ...toast }],\n }));\n },\n removeToast: (id) => {\n set((state) => ({\n toasts: state.toasts.filter((t) => t.id !== id),\n }));\n },\n}));\n\nexport default useToastStore;\n","import { ReactNode } from 'react';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * Progress bar size variants\n */\ntype ProgressBarSize = 'small' | 'medium';\n\n/**\n * Progress bar color variants\n */\ntype ProgressBarVariant = 'blue' | 'green';\n\n/**\n * Progress bar layout variants\n */\ntype ProgressBarLayout = 'default' | 'stacked' | 'compact';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'h-1', // 4px height (h-1 = 4px in Tailwind)\n bar: 'h-1', // 4px height for the fill bar\n spacing: 'gap-2', // 8px gap between label and progress bar\n layout: 'flex-col', // vertical layout for small\n borderRadius: 'rounded-full', // 9999px border radius\n },\n medium: {\n container: 'h-2', // 8px height (h-2 = 8px in Tailwind)\n bar: 'h-2', // 8px height for the fill bar\n spacing: 'gap-2', // 8px gap between progress bar and label\n layout: 'flex-row items-center', // horizontal layout for medium\n borderRadius: 'rounded-lg', // 8px border radius\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-primary-700', // Blue for activity progress (#2271C4)\n },\n green: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-success-200', // Green for performance (#84D3A2)\n },\n} as const;\n\n/**\n * Type for size classes\n */\ntype SizeClassType = (typeof SIZE_CLASSES)[keyof typeof SIZE_CLASSES];\n\n/**\n * Type for variant classes\n */\ntype VariantClassType = (typeof VARIANT_CLASSES)[keyof typeof VARIANT_CLASSES];\n\n/**\n * Common props shared across all layout components\n */\ninterface BaseLayoutProps {\n className: string;\n label: ReactNode;\n showPercentage: boolean;\n showHitCount: boolean;\n labelClassName: string;\n percentageClassName: string;\n clampedValue: number;\n max: number;\n percentage: number;\n variantClasses: VariantClassType;\n}\n\n/**\n * Dimensions configuration for layouts\n */\ninterface LayoutDimensions {\n width: string;\n height: string;\n}\n\n/**\n * Props for StackedLayout component\n */\ninterface StackedLayoutProps extends BaseLayoutProps {\n dimensions: LayoutDimensions;\n}\n\n/**\n * Props for CompactLayout component\n */\ninterface CompactLayoutProps extends BaseLayoutProps {\n dimensions: LayoutDimensions;\n}\n\n/**\n * Props for DefaultLayout component\n */\ninterface DefaultLayoutProps {\n className: string;\n size: ProgressBarSize;\n sizeClasses: SizeClassType;\n variantClasses: VariantClassType;\n label: ReactNode;\n showPercentage: boolean;\n labelClassName: string;\n percentageClassName: string;\n clampedValue: number;\n max: number;\n percentage: number;\n}\n\n/**\n * ProgressBar component props interface\n */\nexport type ProgressBarProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress bar */\n size?: ProgressBarSize;\n /** Color variant of the progress bar */\n variant?: ProgressBarVariant;\n /** Layout variant of the progress bar */\n layout?: ProgressBarLayout;\n /** Optional label to display */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /**\n * Show hit count (e.g., \"28 de 30\") instead of percentage\n *\n * PRIORITY: When both showHitCount and showPercentage are true,\n * showHitCount takes precedence (stacked and compact layouts only).\n * Default layout does not support showHitCount.\n */\n showHitCount?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n /** Custom width for stacked layout (defaults to w-[380px]) */\n stackedWidth?: string;\n /** Custom height for stacked layout (defaults to h-[35px]) */\n stackedHeight?: string;\n /** Custom width for compact layout (defaults to w-[131px]) */\n compactWidth?: string;\n /** Custom height for compact layout (defaults to h-[24px]) */\n compactHeight?: string;\n};\n\n/**\n * Helper function to calculate safe progress values\n */\nconst calculateProgressValues = (value: number, max: number) => {\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n return { clampedValue, percentage };\n};\n\n/**\n * Helper function to determine if header content should be shown\n */\nconst shouldShowHeader = (\n label: ReactNode,\n showPercentage: boolean,\n showHitCount: boolean\n): boolean => {\n return !!(label || showPercentage || showHitCount);\n};\n\n/**\n * Centralized function to determine display priority and content\n *\n * PRIORITY ORDER (consistent across all layouts):\n * 1. showHitCount (highest priority) - displays \"X de Y\" format\n * 2. showPercentage - displays \"X%\" format\n * 3. label (lowest priority) - displays custom label\n *\n * @param showHitCount - Whether to show hit count format\n * @param showPercentage - Whether to show percentage format\n * @param label - Custom label to display\n * @param clampedValue - Current progress value\n * @param max - Maximum progress value\n * @param percentage - Calculated percentage value\n * @returns Object with content type and formatted content\n */\nconst getDisplayPriority = (\n showHitCount: boolean,\n showPercentage: boolean,\n label: ReactNode,\n clampedValue: number,\n max: number,\n percentage: number\n) => {\n if (showHitCount) {\n return {\n type: 'hitCount' as const,\n content: `${Math.round(clampedValue)} de ${max}`,\n hasMetrics: true,\n };\n }\n\n if (showPercentage) {\n return {\n type: 'percentage' as const,\n content: `${Math.round(percentage)}%`,\n hasMetrics: true,\n };\n }\n\n return {\n type: 'label' as const,\n content: label,\n hasMetrics: false,\n };\n};\n\n/**\n * Parameters for compact layout configuration\n */\ninterface CompactLayoutConfigParams {\n showPercentage: boolean;\n showHitCount: boolean;\n percentage: number;\n clampedValue: number;\n max: number;\n label: ReactNode;\n percentageClassName: string;\n labelClassName: string;\n}\n\n/**\n * Helper function to get compact layout configuration\n *\n * PRIORITY ORDER (consistent across all layouts):\n * 1. showHitCount (highest priority) - displays \"X de Y\" format\n * 2. showPercentage - displays \"X%\" format\n * 3. label (lowest priority) - displays custom label\n *\n * When both showHitCount and showPercentage are true, showHitCount takes precedence.\n */\nconst getCompactLayoutConfig = ({\n showPercentage,\n showHitCount,\n percentage,\n clampedValue,\n max,\n label,\n percentageClassName,\n labelClassName,\n}: CompactLayoutConfigParams) => {\n // Use centralized priority logic for consistency\n const displayPriority = getDisplayPriority(\n showHitCount,\n showPercentage,\n label,\n clampedValue,\n max,\n percentage\n );\n\n return {\n color: displayPriority.hasMetrics ? 'text-primary-600' : 'text-primary-700',\n className: displayPriority.hasMetrics\n ? percentageClassName\n : labelClassName,\n content: displayPriority.content,\n };\n};\n\n/**\n * Helper function to get default layout display configuration\n *\n * PRIORITY ORDER for default layout (showHitCount is not supported):\n * 1. showPercentage (when enabled, takes precedence over label)\n * 2. label (shown only when showPercentage is false)\n *\n * Note: Default layout does not support showHitCount feature.\n */\nconst getDefaultLayoutDisplayConfig = (\n size: ProgressBarSize,\n label: ReactNode,\n showPercentage: boolean\n) => ({\n showHeader: size === 'small' && !!(label || showPercentage),\n showPercentage: size === 'medium' && showPercentage,\n showLabel: size === 'medium' && !!label && !showPercentage, // Only show label when percentage is not shown\n});\n\n/**\n * Helper function to render hit count or percentage display for stacked layout\n *\n * PRIORITY ORDER (consistent across all layouts):\n * 1. showHitCount (highest priority) - displays \"X de Y\" format\n * 2. showPercentage - displays \"X%\" format\n *\n * When both showHitCount and showPercentage are true, showHitCount takes precedence.\n */\nconst renderStackedHitCountDisplay = (\n showHitCount: boolean,\n showPercentage: boolean,\n clampedValue: number,\n max: number,\n percentage: number,\n percentageClassName: string\n): ReactNode => {\n if (!showHitCount && !showPercentage) return null;\n\n // Use centralized priority logic for consistency\n const displayPriority = getDisplayPriority(\n showHitCount,\n showPercentage,\n null, // label is not relevant for stacked layout metrics display\n clampedValue,\n max,\n percentage\n );\n\n return (\n <div\n className={cn(\n 'text-xs font-medium leading-[14px] text-right',\n percentageClassName\n )}\n >\n {displayPriority.type === 'hitCount' ? (\n <>\n <span className=\"text-success-200\">{Math.round(clampedValue)}</span>\n <span className=\"text-text-600\"> de {max}</span>\n </>\n ) : (\n <Text size=\"xs\" weight=\"medium\" className=\"text-success-200\">\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n );\n};\n\n/**\n * Base progress bar component with common rendering logic\n */\nconst ProgressBarBase = ({\n clampedValue,\n max,\n percentage,\n label,\n variantClasses,\n containerClassName,\n fillClassName,\n}: {\n clampedValue: number;\n max: number;\n percentage: number;\n label: ReactNode;\n variantClasses: VariantClassType;\n containerClassName: string;\n fillClassName: string;\n}) => (\n <div\n className={cn(\n containerClassName,\n variantClasses.background,\n 'overflow-hidden relative'\n )}\n >\n <progress\n value={clampedValue}\n max={max}\n aria-label={\n typeof label === 'string'\n ? `${label}: ${Math.round(percentage)}% complete`\n : `Progress: ${Math.round(percentage)}% of ${max}`\n }\n className=\"absolute inset-0 w-full h-full opacity-0\"\n />\n <div\n className={cn(\n fillClassName,\n variantClasses.fill,\n 'transition-all duration-300 ease-out'\n )}\n style={{ width: `${percentage}%` }}\n />\n </div>\n);\n\n/**\n * Stacked layout component\n */\nconst StackedLayout = ({\n className,\n label,\n showPercentage,\n showHitCount,\n labelClassName,\n percentageClassName,\n clampedValue,\n max,\n percentage,\n variantClasses,\n dimensions,\n}: StackedLayoutProps) => (\n <div\n className={cn(\n 'flex flex-col items-start gap-2',\n dimensions.width,\n dimensions.height,\n className\n )}\n >\n {shouldShowHeader(label, showPercentage, showHitCount) && (\n <div className=\"flex flex-row justify-between items-center w-full h-[19px]\">\n {label && (\n <Text\n as=\"div\"\n size=\"md\"\n weight=\"medium\"\n className={cn('text-text-600 leading-[19px]', labelClassName)}\n >\n {label}\n </Text>\n )}\n\n {renderStackedHitCountDisplay(\n showHitCount,\n showPercentage,\n clampedValue,\n max,\n percentage,\n percentageClassName\n )}\n </div>\n )}\n\n <ProgressBarBase\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n label={label}\n variantClasses={variantClasses}\n containerClassName=\"w-full h-2 rounded-lg\"\n fillClassName=\"h-2 rounded-lg shadow-hard-shadow-3\"\n />\n </div>\n);\n\n/**\n * Compact layout component\n */\nconst CompactLayout = ({\n className,\n label,\n showPercentage,\n showHitCount,\n labelClassName,\n percentageClassName,\n clampedValue,\n max,\n percentage,\n variantClasses,\n dimensions,\n}: CompactLayoutProps) => {\n const {\n color,\n className: compactClassName,\n content,\n } = getCompactLayoutConfig({\n showPercentage,\n showHitCount,\n percentage,\n clampedValue,\n max,\n label,\n percentageClassName,\n labelClassName,\n });\n\n return (\n <div\n className={cn(\n 'flex flex-col items-start gap-1',\n dimensions.width,\n dimensions.height,\n className\n )}\n >\n {shouldShowHeader(label, showPercentage, showHitCount) && (\n <Text\n as=\"div\"\n size=\"sm\"\n weight=\"medium\"\n color={color}\n className={cn('leading-4 w-full', compactClassName)}\n >\n {content}\n </Text>\n )}\n\n <ProgressBarBase\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n label={label}\n variantClasses={variantClasses}\n containerClassName=\"w-full h-1 rounded-full\"\n fillClassName=\"h-1 rounded-full\"\n />\n </div>\n );\n};\n\n/**\n * Default layout component\n */\nconst DefaultLayout = ({\n className,\n size,\n sizeClasses,\n variantClasses,\n label,\n showPercentage,\n labelClassName,\n percentageClassName,\n clampedValue,\n max,\n percentage,\n}: DefaultLayoutProps) => {\n const gapClass = size === 'medium' ? 'gap-2' : sizeClasses.spacing;\n const progressBarClass = size === 'medium' ? 'flex-grow' : 'w-full';\n const displayConfig = getDefaultLayoutDisplayConfig(\n size,\n label,\n showPercentage\n );\n\n return (\n <div className={cn('flex', sizeClasses.layout, gapClass, className)}>\n {displayConfig.showHeader && (\n <div className=\"flex flex-row items-center justify-between w-full\">\n {label && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center',\n labelClassName\n )}\n >\n {label}\n </Text>\n )}\n\n {showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center',\n percentageClassName\n )}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n )}\n\n <ProgressBarBase\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n label={label}\n variantClasses={variantClasses}\n containerClassName={cn(\n progressBarClass,\n sizeClasses.container,\n sizeClasses.borderRadius\n )}\n fillClassName={cn(\n sizeClasses.bar,\n sizeClasses.borderRadius,\n 'shadow-hard-shadow-3'\n )}\n />\n\n {displayConfig.showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none',\n percentageClassName\n )}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {displayConfig.showLabel && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none',\n labelClassName\n )}\n >\n {label}\n </Text>\n )}\n </div>\n );\n};\n\n/**\n * ProgressBar component for Analytica Ensino platforms\n *\n * A progress bar component with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * CONTENT DISPLAY PRIORITY (Consistent across all layouts):\n * 1. showHitCount (highest) - \"X de Y\" format (stacked/compact only)\n * 2. showPercentage - \"X%\" format\n * 3. label (lowest) - Custom label text\n *\n * When multiple display options are enabled, higher priority options take precedence.\n *\n * @example\n * ```tsx\n * // Basic progress bar\n * <ProgressBar value={65} />\n *\n * // Activity progress (blue)\n * <ProgressBar variant=\"blue\" value={45} label=\"Progress\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressBar variant=\"green\" size=\"medium\" value={85} label=\"Performance\" />\n *\n * // Small size with custom max value\n * <ProgressBar size=\"small\" value={3} max={5} showPercentage />\n *\n * // Stacked layout with fixed width and hit count\n * <ProgressBar layout=\"stacked\" variant=\"green\" value={28} max={30} label=\"Fáceis\" showHitCount />\n *\n * // Compact layout for small cards\n * <ProgressBar layout=\"compact\" variant=\"blue\" value={70} label=\"Questão 08\" />\n * ```\n */\nconst ProgressBar = ({\n value,\n max = 100,\n size = 'medium',\n variant = 'blue',\n layout = 'default',\n label,\n showPercentage = false,\n showHitCount = false,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n stackedWidth,\n stackedHeight,\n compactWidth,\n compactHeight,\n}: ProgressBarProps) => {\n const { clampedValue, percentage } = calculateProgressValues(value, max);\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n if (layout === 'stacked') {\n return (\n <StackedLayout\n className={className}\n label={label}\n showPercentage={showPercentage}\n showHitCount={showHitCount}\n labelClassName={labelClassName}\n percentageClassName={percentageClassName}\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n variantClasses={variantClasses}\n dimensions={{\n width: stackedWidth ?? 'w-[380px]',\n height: stackedHeight ?? 'h-[35px]',\n }}\n />\n );\n }\n\n if (layout === 'compact') {\n return (\n <CompactLayout\n className={className}\n label={label}\n showPercentage={showPercentage}\n showHitCount={showHitCount}\n labelClassName={labelClassName}\n percentageClassName={percentageClassName}\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n variantClasses={variantClasses}\n dimensions={{\n width: compactWidth ?? 'w-[131px]',\n height: compactHeight ?? 'h-[24px]',\n }}\n />\n );\n }\n\n return (\n <DefaultLayout\n className={className}\n size={size}\n sizeClasses={sizeClasses}\n variantClasses={variantClasses}\n label={label}\n showPercentage={showPercentage}\n labelClassName={labelClassName}\n percentageClassName={percentageClassName}\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n />\n );\n};\n\nexport default ProgressBar;\n","import {\n useState,\n useRef,\n useEffect,\n useCallback,\n type ReactNode,\n} from 'react';\nimport {\n PencilSimple,\n Paperclip,\n X,\n Star,\n Medal,\n WarningCircle,\n} from 'phosphor-react';\nimport type { Icon } from 'phosphor-react';\nimport Modal from '../Modal/Modal';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Badge from '../Badge/Badge';\nimport Radio from '../Radio/Radio';\nimport TextArea from '../TextArea/TextArea';\nimport { CardAccordation, AccordionGroup } from '../Accordation';\nimport { generateFileId } from '../FileAttachment/FileAttachment';\nimport type { AttachedFile } from '../FileAttachment/FileAttachment';\nimport { cn } from '../../utils/utils';\nimport { QUESTION_TYPE } from '../Quiz/useQuizStore';\nimport {\n type StudentActivityCorrectionData,\n type SaveQuestionCorrectionPayload,\n getQuestionStatusBadgeConfig,\n getQuestionStatusFromData,\n} from '../../utils/studentActivityCorrection';\nimport {\n renderQuestionAlternative,\n renderQuestionMultipleChoice,\n renderQuestionTrueOrFalse,\n renderQuestionDissertative,\n renderQuestionFill,\n renderQuestionImage,\n renderQuestionConnectDots,\n} from '../../utils/questionRenderer/index';\n\n/**\n * Props for the CorrectActivityModal component\n */\nexport interface CorrectActivityModalProps {\n /** Whether the modal is open */\n isOpen: boolean;\n /** Function to close the modal */\n onClose: () => void;\n /** Student activity correction data */\n data: StudentActivityCorrectionData | null;\n /** Whether the modal is in view-only mode */\n isViewOnly?: boolean;\n /** Callback when observation is submitted with optional files */\n onObservationSubmit?: (\n studentId: string,\n observation: string,\n files: File[]\n ) => void;\n /** Callback when question correction is saved (for essay questions) */\n onQuestionCorrectionSubmit?: (\n studentId: string,\n payload: SaveQuestionCorrectionPayload\n ) => Promise<void>;\n}\n\n/**\n * Props for the StatCard component\n */\ninterface StatCardProps {\n label: string;\n value: string | number;\n variant: 'score' | 'correct' | 'incorrect';\n}\n\n/**\n * Configuration for each stat card variant\n */\nconst variantConfig: Record<\n StatCardProps['variant'],\n {\n bg: string;\n text: string;\n iconBg: string;\n iconColor: string;\n IconComponent: Icon;\n }\n> = {\n score: {\n bg: 'bg-warning-background',\n text: 'text-warning-600',\n iconBg: 'bg-warning-300',\n iconColor: 'text-white',\n IconComponent: Star,\n },\n correct: {\n bg: 'bg-success-200',\n text: 'text-success-700',\n iconBg: 'bg-indicator-positive',\n iconColor: 'text-text-950',\n IconComponent: Medal,\n },\n incorrect: {\n bg: 'bg-error-100',\n text: 'text-error-700',\n iconBg: 'bg-indicator-negative',\n iconColor: 'text-white',\n IconComponent: WarningCircle,\n },\n};\n\n/**\n * Stat card component for displaying statistics with icon\n * @param props - Component props\n * @returns JSX element\n */\nconst StatCard = ({ label, value, variant }: StatCardProps) => {\n const config = variantConfig[variant];\n const IconComponent = config.IconComponent;\n\n return (\n <div\n className={cn(\n 'border border-border-50 rounded-xl py-4 px-3 flex flex-col items-center justify-center gap-1',\n config.bg\n )}\n >\n <div\n className={cn(\n 'w-[30px] h-[30px] rounded-2xl flex items-center justify-center',\n config.iconBg\n )}\n >\n <IconComponent\n size={16}\n className={config.iconColor}\n weight=\"regular\"\n />\n </div>\n <Text\n className={cn('text-2xs font-bold uppercase text-center', config.text)}\n >\n {label}\n </Text>\n <Text className={cn('text-xl font-bold', config.text)}>{value}</Text>\n </div>\n );\n};\n\n/**\n * Modal component for correcting or viewing student activity details\n *\n * Displays student information, statistics cards, observation section,\n * and a list of questions with their status.\n *\n * @param props - Component props\n * @returns JSX element\n *\n * @example\n * ```tsx\n * <CorrectActivityModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * data={studentData}\n * isViewOnly={false}\n * onObservationSubmit={(obs, files) => console.log(obs, files)}\n * />\n * ```\n */\nconst CorrectActivityModal = ({\n isOpen,\n onClose,\n data,\n isViewOnly = false,\n onObservationSubmit,\n onQuestionCorrectionSubmit,\n}: CorrectActivityModalProps) => {\n const [observation, setObservation] = useState('');\n const [isObservationExpanded, setIsObservationExpanded] = useState(false);\n const [isObservationSaved, setIsObservationSaved] = useState(false);\n const [savedObservation, setSavedObservation] = useState('');\n const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]);\n const [savedFiles, setSavedFiles] = useState<AttachedFile[]>([]);\n const [existingAttachment, setExistingAttachment] = useState<string | null>(\n null\n );\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // State for essay question corrections\n const [essayCorrections, setEssayCorrections] = useState<\n Record<\n number,\n {\n isCorrect: boolean | null;\n teacherFeedback: string;\n isSaving: boolean;\n }\n >\n >({});\n\n /**\n * Reset state when modal opens or student changes\n * Load existing observation and attachment if available\n */\n useEffect(() => {\n if (isOpen) {\n setObservation('');\n setIsObservationExpanded(false);\n setAttachedFiles([]);\n setSavedFiles([]);\n setExistingAttachment(data?.attachment ?? null);\n\n // Load existing observation/attachment if available\n if (data?.observation || data?.attachment) {\n setIsObservationSaved(true);\n setSavedObservation(data.observation || '');\n } else {\n setIsObservationSaved(false);\n setSavedObservation('');\n }\n\n // Initialize essay corrections from data\n const initialCorrections: Record<\n number,\n {\n isCorrect: boolean | null;\n teacherFeedback: string;\n isSaving: boolean;\n }\n > = {};\n data?.questions?.forEach((questionData) => {\n if (questionData.question.questionType === QUESTION_TYPE.DISSERTATIVA) {\n initialCorrections[questionData.questionNumber] = {\n isCorrect: questionData.correction?.isCorrect ?? null,\n teacherFeedback: questionData.correction?.teacherFeedback || '',\n isSaving: false,\n };\n }\n });\n setEssayCorrections(initialCorrections);\n }\n }, [\n isOpen,\n data?.studentId,\n data?.observation,\n data?.attachment,\n data?.questions,\n ]);\n\n /**\n * Handle opening observation section\n */\n const handleOpenObservation = () => {\n setIsObservationExpanded(true);\n };\n\n /**\n * Handle adding files (single file mode - replaces existing file)\n * @param files - Files to add\n */\n const handleFilesAdd = (files: File[]) => {\n const newFile = files[0];\n if (newFile) {\n setAttachedFiles([{ file: newFile, id: generateFileId() }]);\n }\n };\n\n /**\n * Handle removing a file\n * @param id - File ID to remove\n */\n const handleFileRemove = (id: string) => {\n setAttachedFiles((prev) => prev.filter((f) => f.id !== id));\n };\n\n /**\n * Handle saving observation\n */\n const handleSaveObservation = () => {\n if (observation.trim() || attachedFiles.length > 0 || existingAttachment) {\n // Validate studentId before saving to prevent silent no-op\n if (!data?.studentId) {\n return;\n }\n\n setSavedObservation(observation);\n setSavedFiles([...attachedFiles]);\n setIsObservationSaved(true);\n setIsObservationExpanded(false);\n\n // Pass studentId explicitly from data prop to avoid stale closure issues\n onObservationSubmit?.(\n data.studentId,\n observation,\n attachedFiles.map((f) => f.file)\n );\n }\n };\n\n /**\n * Handle editing observation\n */\n const handleEditObservation = () => {\n setObservation(savedObservation);\n setAttachedFiles([...savedFiles]);\n setIsObservationSaved(false);\n setIsObservationExpanded(true);\n };\n\n /**\n * Handle saving essay question correction\n */\n const handleSaveEssayCorrection = useCallback(\n async (questionNumber: number) => {\n if (!data?.studentId || !onQuestionCorrectionSubmit) return;\n\n const correction = essayCorrections[questionNumber];\n if (correction?.isCorrect == null) {\n return;\n }\n\n setEssayCorrections((prev) => ({\n ...prev,\n [questionNumber]: { ...prev[questionNumber], isSaving: true },\n }));\n\n try {\n // Find the question data to get questionId\n const questionData = data?.questions.find(\n (q) => q.questionNumber === questionNumber\n );\n if (!questionData) {\n console.error('Questão não encontrada:', questionNumber);\n return;\n }\n\n await onQuestionCorrectionSubmit(data.studentId, {\n questionId: questionData.question.id,\n isCorrect: correction.isCorrect,\n teacherFeedback: correction.teacherFeedback,\n });\n } catch (error) {\n console.error('Erro ao salvar correção da questão:', error);\n } finally {\n setEssayCorrections((prev) => ({\n ...prev,\n [questionNumber]: { ...prev[questionNumber], isSaving: false },\n }));\n }\n },\n [\n data?.studentId,\n data?.questions,\n essayCorrections,\n onQuestionCorrectionSubmit,\n ]\n );\n\n /**\n * Update essay correction state\n */\n const updateEssayCorrection = useCallback(\n (\n questionNumber: number,\n field: 'isCorrect' | 'teacherFeedback',\n value: boolean | string\n ) => {\n setEssayCorrections((prev) => ({\n ...prev,\n [questionNumber]: {\n ...prev[questionNumber],\n [field]: value,\n },\n }));\n },\n []\n );\n\n /**\n * Get accordion title based on question type\n */\n const getAccordionTitle = (questionType: QUESTION_TYPE): string => {\n switch (questionType) {\n case QUESTION_TYPE.ALTERNATIVA:\n case QUESTION_TYPE.MULTIPLA_ESCOLHA:\n case QUESTION_TYPE.VERDADEIRO_FALSO:\n return 'Alternativas';\n case QUESTION_TYPE.DISSERTATIVA:\n return 'Resposta';\n case QUESTION_TYPE.PREENCHER:\n return 'Preencher Lacunas';\n case QUESTION_TYPE.IMAGEM:\n return 'Imagem';\n case QUESTION_TYPE.LIGAR_PONTOS:\n return 'Ligar Pontos';\n default:\n return 'Resposta';\n }\n };\n\n /**\n * Render question content using Quiz format renderers with accordion\n */\n const renderQuestionContent = (\n questionData: StudentActivityCorrectionData['questions'][number]\n ) => {\n const { question, result } = questionData;\n const questionType = question.questionType;\n const accordionTitle = getAccordionTitle(questionType);\n\n let content: ReactNode;\n\n switch (questionType) {\n case QUESTION_TYPE.ALTERNATIVA:\n content = renderQuestionAlternative({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.MULTIPLA_ESCOLHA:\n content = renderQuestionMultipleChoice({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.VERDADEIRO_FALSO:\n content = renderQuestionTrueOrFalse({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.DISSERTATIVA:\n content = (\n <>\n {renderQuestionDissertative({\n result,\n })}\n {onQuestionCorrectionSubmit && (\n <div className=\"space-y-4 border-t border-border-100 pt-4 mt-4\">\n {renderEssayCorrectionFields(questionData)}\n </div>\n )}\n </>\n );\n break;\n case QUESTION_TYPE.PREENCHER:\n content = renderQuestionFill({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.IMAGEM:\n content = renderQuestionImage({\n result,\n });\n break;\n case QUESTION_TYPE.LIGAR_PONTOS:\n content = renderQuestionConnectDots({ paddingBottom: '' });\n break;\n default:\n // Fallback: try to render based on options presence\n if (question.options && question.options.length > 0) {\n content = renderQuestionAlternative({\n question,\n result,\n });\n } else {\n content = renderQuestionDissertative({\n result,\n });\n }\n }\n\n return (\n <CardAccordation\n value={`accordion-${questionData.questionNumber}`}\n className=\"border border-border-100 rounded-lg\"\n trigger={\n <div className=\"py-3 pr-2 w-full\">\n <Text className=\"text-sm font-bold text-text-950\">\n {accordionTitle}\n </Text>\n </div>\n }\n >\n {content}\n </CardAccordation>\n );\n };\n\n /**\n * Render essay correction fields (radio group, textarea, save button)\n */\n const renderEssayCorrectionFields = (\n questionData: StudentActivityCorrectionData['questions'][number]\n ) => {\n const correction = essayCorrections[questionData.questionNumber] || {\n isCorrect: null,\n teacherFeedback: '',\n isSaving: false,\n };\n\n let radioValue;\n if (correction.isCorrect === null) {\n radioValue = undefined;\n } else if (correction.isCorrect) {\n radioValue = 'true';\n } else {\n radioValue = 'false';\n }\n\n return (\n <>\n {/* Is correct radio group */}\n <div className=\"space-y-2\">\n <Text className=\"text-sm font-semibold text-text-950\">\n Resposta está correta?\n </Text>\n <div className=\"flex gap-4\">\n <Radio\n name={`isCorrect-${questionData.questionNumber}`}\n value=\"true\"\n id={`correct-yes-${questionData.questionNumber}`}\n label=\"Sim\"\n size=\"medium\"\n checked={radioValue === 'true'}\n onChange={(e) => {\n if (e.target.checked) {\n updateEssayCorrection(\n questionData.questionNumber,\n 'isCorrect',\n true\n );\n }\n }}\n />\n <Radio\n name={`isCorrect-${questionData.questionNumber}`}\n value=\"false\"\n id={`correct-no-${questionData.questionNumber}`}\n label=\"Não\"\n size=\"medium\"\n checked={radioValue === 'false'}\n onChange={(e) => {\n if (e.target.checked) {\n updateEssayCorrection(\n questionData.questionNumber,\n 'isCorrect',\n false\n );\n }\n }}\n />\n </div>\n </div>\n\n {/* Teacher feedback textarea */}\n <div className=\"space-y-2\">\n <Text className=\"text-sm font-semibold text-text-950\">\n Incluir observação\n </Text>\n <TextArea\n value={correction.teacherFeedback}\n onChange={(e) => {\n updateEssayCorrection(\n questionData.questionNumber,\n 'teacherFeedback',\n e.target.value\n );\n }}\n placeholder=\"Escreva uma observação sobre a resposta do aluno\"\n rows={4}\n size=\"medium\"\n />\n </div>\n\n {/* Save button */}\n <Button\n size=\"small\"\n onClick={() => handleSaveEssayCorrection(questionData.questionNumber)}\n disabled={\n correction.isCorrect === null ||\n correction.isSaving ||\n !onQuestionCorrectionSubmit\n }\n >\n {correction.isSaving ? 'Salvando...' : 'Salvar'}\n </Button>\n </>\n );\n };\n\n if (!data) return null;\n\n const title = isViewOnly ? 'Detalhes da atividade' : 'Corrigir atividade';\n const formattedScore = data.score == null ? '-' : data.score.toFixed(1);\n\n /**\n * Render observation section based on current state\n * Allows observations in all activity statuses (not just pending correction)\n * @returns JSX element for observation section\n */\n const renderObservationSection = () => {\n /**\n * Get file name from URL\n * @param url - File URL\n * @returns File name extracted from URL\n */\n const getFileNameFromUrl = (url: string): string => {\n try {\n const urlObj = new URL(url);\n const urlPath = urlObj.pathname;\n return urlPath.split('/').pop() || 'Anexo';\n } catch {\n return 'Anexo';\n }\n };\n\n /**\n * Render attachment input section for expanded state\n * @returns JSX element for attachment input\n */\n const renderAttachmentInput = () => {\n if (attachedFiles.length > 0) {\n return (\n <div className=\"flex items-center justify-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px]\">\n <Paperclip size={18} className=\"text-text-800 flex-shrink-0\" />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {attachedFiles[0].file.name}\n </span>\n <button\n type=\"button\"\n onClick={() => handleFileRemove(attachedFiles[0].id)}\n className=\"text-text-700 hover:text-text-800 flex-shrink-0\"\n aria-label={`Remover ${attachedFiles[0].file.name}`}\n >\n <X size={18} />\n </button>\n </div>\n );\n }\n\n if (existingAttachment) {\n return (\n <div className=\"flex items-center gap-2\">\n <a\n href={existingAttachment}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px] hover:bg-secondary-600 transition-colors\"\n >\n <Paperclip size={18} className=\"text-text-800 flex-shrink-0\" />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {getFileNameFromUrl(existingAttachment)}\n </span>\n </a>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => fileInputRef.current?.click()}\n className=\"flex items-center gap-2\"\n >\n <Paperclip size={18} />\n Trocar\n </Button>\n </div>\n );\n }\n\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => fileInputRef.current?.click()}\n className=\"flex items-center gap-2\"\n >\n <Paperclip size={18} />\n Anexar\n </Button>\n );\n };\n\n // State: Saved\n if (isObservationSaved) {\n return (\n <div className=\"bg-background border border-border-100 rounded-lg p-4 space-y-2\">\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <Text className=\"text-sm font-bold text-text-950\">Observação</Text>\n <div className=\"flex items-center gap-3\">\n {/* Show newly attached file */}\n {savedFiles.length > 0 && (\n <div className=\"flex items-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px]\">\n <Paperclip\n size={18}\n className=\"text-text-800 flex-shrink-0\"\n />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {savedFiles[0].file.name}\n </span>\n </div>\n )}\n {/* Show existing attachment from server (URL) */}\n {savedFiles.length === 0 && existingAttachment && (\n <a\n href={existingAttachment}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px] hover:bg-secondary-600 transition-colors\"\n >\n <Paperclip\n size={18}\n className=\"text-text-800 flex-shrink-0\"\n />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {getFileNameFromUrl(existingAttachment)}\n </span>\n </a>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={handleEditObservation}\n className=\"flex items-center gap-2 flex-shrink-0\"\n >\n <PencilSimple size={16} />\n Editar\n </Button>\n </div>\n </div>\n {savedObservation && (\n <div className=\"p-3 bg-background-50 rounded-lg\">\n <Text className=\"text-sm text-text-700\">{savedObservation}</Text>\n </div>\n )}\n </div>\n );\n }\n\n // State: Expanded\n if (isObservationExpanded) {\n return (\n <div className=\"bg-background border border-border-100 rounded-lg p-4 space-y-3\">\n <Text className=\"text-sm font-bold text-text-950\">Observação</Text>\n <textarea\n value={observation}\n onChange={(e) => setObservation(e.target.value)}\n placeholder=\"Escreva uma observação para o estudante\"\n className=\"w-full min-h-[80px] p-3 border border-border-100 rounded-lg text-sm text-text-700 placeholder:text-text-400 resize-none focus:outline-none focus:ring-2 focus:ring-primary-500\"\n />\n {/* Hidden file input */}\n <input\n type=\"file\"\n ref={fileInputRef}\n className=\"hidden\"\n onChange={(e) => {\n const selectedFiles = e.target.files;\n if (selectedFiles && selectedFiles.length > 0) {\n handleFilesAdd(Array.from(selectedFiles));\n }\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n }}\n aria-label=\"Selecionar arquivo\"\n />\n {/* Buttons row: File indicator or Anexar button left, Salvar right */}\n <div className=\"flex flex-col-reverse sm:flex-row gap-3 sm:justify-between\">\n {renderAttachmentInput()}\n <Button\n type=\"button\"\n size=\"small\"\n onClick={handleSaveObservation}\n disabled={\n !observation.trim() &&\n attachedFiles.length === 0 &&\n !existingAttachment\n }\n >\n Salvar\n </Button>\n </div>\n {data.observation && (\n <div className=\"p-3 bg-background-50 rounded-lg\">\n <Text className=\"text-xs text-text-500\">\n Observação anterior:\n </Text>\n <Text className=\"text-sm text-text-700\">{data.observation}</Text>\n </div>\n )}\n </div>\n );\n }\n\n // State: Closed (default)\n return (\n <div className=\"bg-background border border-border-100 rounded-lg p-4 flex flex-col sm:flex-row gap-3 sm:items-center sm:justify-between\">\n <Text className=\"text-sm font-bold text-text-950\">Observação</Text>\n <Button type=\"button\" size=\"small\" onClick={handleOpenObservation}>\n Incluir\n </Button>\n </div>\n );\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size=\"lg\"\n contentClassName=\"max-h-[80vh] overflow-y-auto\"\n >\n <div className=\"space-y-6\">\n {/* Student Info */}\n <div className=\"flex items-center gap-3\">\n <div className=\"w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center\">\n <Text className=\"text-lg font-semibold text-primary-700\">\n {data.studentName?.charAt(0).toUpperCase() || '-'}\n </Text>\n </div>\n <Text className=\"text-lg font-medium text-text-950\">\n {data.studentName || 'Aluno'}\n </Text>\n </div>\n\n {/* Stats Cards */}\n <div className=\"grid grid-cols-3 gap-4\">\n <StatCard label=\"Nota\" value={formattedScore} variant=\"score\" />\n <StatCard\n label=\"N° de questões corretas\"\n value={data.correctCount}\n variant=\"correct\"\n />\n <StatCard\n label=\"N° de questões incorretas\"\n value={data.incorrectCount}\n variant=\"incorrect\"\n />\n </div>\n\n {/* Observation Section */}\n {renderObservationSection()}\n\n {/* Questions List */}\n <div className=\"space-y-2\">\n <Text className=\"text-sm font-bold text-text-950\">Respostas</Text>\n <AccordionGroup type=\"multiple\" className=\"space-y-2\">\n {data.questions?.map((questionData) => {\n const status = getQuestionStatusFromData(questionData);\n const badgeConfig = getQuestionStatusBadgeConfig(status);\n\n return (\n <CardAccordation\n key={questionData.questionNumber}\n value={`question-${questionData.questionNumber}`}\n className=\"bg-background rounded-xl\"\n trigger={\n <div className=\"flex items-center justify-between w-full py-3 pr-2\">\n <Text className=\"text-base font-bold text-text-950\">\n Questão {questionData.questionNumber}\n </Text>\n <Badge\n className={cn(\n 'text-xs px-2 py-1',\n badgeConfig.bgColor,\n badgeConfig.textColor\n )}\n >\n {badgeConfig.label}\n </Badge>\n </div>\n }\n >\n <div className=\"space-y-4 pt-2\">\n {/* Question statement */}\n {questionData.question.statement && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n color=\"text-text-700\"\n className=\"whitespace-pre-wrap\"\n >\n {questionData.question.statement}\n </Text>\n )}\n\n {/* Question content based on type */}\n {renderQuestionContent(questionData)}\n </div>\n </CardAccordation>\n );\n })}\n </AccordionGroup>\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default CorrectActivityModal;\n","import {\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n ReactNode,\n useId,\n useState,\n useEffect,\n} from 'react';\nimport { CardBase } from '../Card/Card';\nimport { CaretRight } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\ninterface CardAccordationProps extends HTMLAttributes<HTMLDivElement> {\n trigger: ReactNode;\n children: ReactNode;\n defaultExpanded?: boolean;\n expanded?: boolean;\n onToggleExpanded?: (isExpanded: boolean) => void;\n value?: string;\n disabled?: boolean;\n /** Additional class for the trigger button */\n triggerClassName?: string;\n /** Additional class for the content wrapper */\n contentClassName?: string;\n}\n\nconst CardAccordation = forwardRef<HTMLDivElement, CardAccordationProps>(\n (\n {\n trigger,\n children,\n className,\n defaultExpanded = false,\n expanded: controlledExpanded,\n onToggleExpanded,\n value,\n disabled = false,\n triggerClassName,\n contentClassName,\n ...props\n },\n ref\n ) => {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const generatedId = useId();\n\n // Use value as ID base for better semantics, fallback to generated ID\n const contentId = value ? `accordion-content-${value}` : generatedId;\n const headerId = value\n ? `accordion-header-${value}`\n : `${generatedId}-header`;\n\n // Determine if component is controlled\n const isControlled = controlledExpanded !== undefined;\n const isExpanded = isControlled ? controlledExpanded : internalExpanded;\n\n // Sync internal state when controlled value changes\n useEffect(() => {\n if (isControlled) {\n setInternalExpanded(controlledExpanded);\n }\n }, [isControlled, controlledExpanded]);\n\n const handleToggle = () => {\n if (disabled) return;\n\n const newExpanded = !isExpanded;\n\n if (!isControlled) {\n setInternalExpanded(newExpanded);\n }\n\n onToggleExpanded?.(newExpanded);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) return;\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleToggle();\n }\n };\n\n return (\n <CardBase\n ref={ref}\n layout=\"vertical\"\n padding=\"none\"\n minHeight=\"none\"\n className={cn('overflow-hidden', className)}\n {...props}\n >\n {/* Clickable header */}\n <button\n id={headerId}\n type=\"button\"\n onClick={handleToggle}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n className={cn(\n 'w-full cursor-pointer not-aria-expanded:rounded-xl aria-expanded:rounded-t-xl flex items-center justify-between gap-3 text-left transition-colors duration-200 focus:outline-none focus:border-2 focus:border-primary-950 focus:ring-inset px-2',\n disabled && 'cursor-not-allowed text-text-400',\n triggerClassName\n )}\n aria-expanded={isExpanded}\n aria-controls={contentId}\n aria-disabled={disabled}\n data-value={value}\n >\n {trigger}\n\n <CaretRight\n size={20}\n className={cn(\n 'transition-transform duration-200 flex-shrink-0',\n disabled ? 'text-gray-400' : 'text-text-700',\n isExpanded ? 'rotate-90' : 'rotate-0'\n )}\n data-testid=\"accordion-caret\"\n />\n </button>\n\n {/* Expandable content */}\n <section\n id={contentId}\n aria-labelledby={headerId}\n aria-hidden={!isExpanded}\n className={cn(\n 'transition-all duration-300 ease-in-out overflow-hidden',\n isExpanded ? 'max-h-screen opacity-100' : 'max-h-0 opacity-0'\n )}\n data-testid=\"accordion-content\"\n data-value={value}\n >\n <div className={cn('p-4 pt-0', contentClassName)}>{children}</div>\n </section>\n </CardBase>\n );\n }\n);\n\nCardAccordation.displayName = 'CardAccordation';\n\nexport { CardAccordation };\nexport type { CardAccordationProps };\n","import {\n forwardRef,\n Fragment,\n HTMLAttributes,\n ReactNode,\n useState,\n useRef,\n MouseEvent,\n ChangeEvent,\n KeyboardEvent,\n Ref,\n useEffect,\n} from 'react';\nimport Button from '../Button/Button';\nimport Badge from '../Badge/Badge';\nimport ProgressBar from '../ProgressBar/ProgressBar';\nimport {\n CaretRight,\n ChatCircleText,\n CheckCircle,\n Clock,\n DotsThreeVertical,\n Play,\n SpeakerHigh,\n SpeakerLow,\n SpeakerSimpleX,\n XCircle,\n} from 'phosphor-react';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\nimport IconRender from '../IconRender/IconRender';\n\n// Componente base reutilizável para todos os cards\ninterface CardBaseProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n variant?: 'default' | 'compact' | 'minimal';\n layout?: 'horizontal' | 'vertical';\n padding?: 'none' | 'small' | 'medium' | 'large';\n minHeight?: 'none' | 'small' | 'medium' | 'large';\n cursor?: 'default' | 'pointer';\n}\n\nconst CARD_BASE_CLASSES = {\n default: 'w-full bg-background border border-border-50 rounded-xl',\n compact: 'w-full bg-background border border-border-50 rounded-lg',\n minimal: 'w-full bg-background border border-border-100 rounded-md',\n};\n\nconst CARD_PADDING_CLASSES = {\n none: '',\n small: 'p-2',\n medium: 'p-4',\n large: 'p-6',\n};\n\nconst CARD_MIN_HEIGHT_CLASSES = {\n none: '',\n small: 'min-h-16',\n medium: 'min-h-20',\n large: 'min-h-24',\n};\n\nconst CARD_LAYOUT_CLASSES = {\n horizontal: 'flex flex-row',\n vertical: 'flex flex-col',\n};\n\nconst CARD_CURSOR_CLASSES = {\n default: '',\n pointer: 'cursor-pointer',\n};\n\nconst CardBase = forwardRef<HTMLDivElement, CardBaseProps>(\n (\n {\n children,\n variant = 'default',\n layout = 'horizontal',\n padding = 'medium',\n minHeight = 'medium',\n cursor = 'default',\n className = '',\n ...props\n },\n ref\n ) => {\n const baseClasses = CARD_BASE_CLASSES[variant];\n const paddingClasses = CARD_PADDING_CLASSES[padding];\n const minHeightClasses = CARD_MIN_HEIGHT_CLASSES[minHeight];\n const layoutClasses = CARD_LAYOUT_CLASSES[layout];\n const cursorClasses = CARD_CURSOR_CLASSES[cursor];\n\n return (\n <div\n ref={ref}\n className={cn(\n baseClasses,\n paddingClasses,\n minHeightClasses,\n layoutClasses,\n cursorClasses,\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\ninterface CardActivitiesResultsProps extends HTMLAttributes<HTMLDivElement> {\n icon: ReactNode;\n title: string;\n subTitle: string;\n header: string;\n description?: string;\n extended?: boolean;\n action?: 'warning' | 'success' | 'error' | 'info';\n}\n\nconst ACTION_CARD_CLASSES = {\n warning: 'bg-warning-background',\n success: 'bg-success-200',\n error: 'bg-error-100',\n info: 'bg-info-background',\n};\n\nconst ACTION_ICON_CLASSES = {\n warning: 'bg-warning-300 text-text',\n success: 'bg-indicator-positive text-text-950',\n error: 'bg-indicator-negative text-text',\n info: 'bg-info-500 text-text',\n};\n\nconst ACTION_SUBTITLE_CLASSES = {\n warning: 'text-warning-600',\n success: 'text-success-700',\n error: 'text-error-700',\n info: 'text-info-700',\n};\n\nconst ACTION_HEADER_CLASSES = {\n warning: 'text-warning-300',\n success: 'text-success-300',\n error: 'text-error-300',\n info: 'text-info-300',\n};\n\nconst CardActivitiesResults = forwardRef<\n HTMLDivElement,\n CardActivitiesResultsProps\n>(\n (\n {\n icon,\n title,\n subTitle,\n header,\n extended = false,\n action = 'success',\n description,\n className,\n ...props\n },\n ref\n ) => {\n const actionCardClasses = ACTION_CARD_CLASSES[action];\n const actionIconClasses = ACTION_ICON_CLASSES[action];\n const actionSubTitleClasses = ACTION_SUBTITLE_CLASSES[action];\n const actionHeaderClasses = ACTION_HEADER_CLASSES[action];\n\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full flex flex-col border border-border-50 bg-background rounded-xl',\n className\n )}\n {...props}\n >\n <div\n className={cn(\n 'flex flex-col gap-1 items-center justify-center p-4',\n actionCardClasses,\n extended ? 'rounded-t-xl' : 'rounded-xl'\n )}\n >\n <span\n className={cn(\n 'size-7.5 rounded-full flex items-center justify-center',\n actionIconClasses\n )}\n >\n {icon}\n </span>\n\n <Text\n size=\"2xs\"\n weight=\"medium\"\n className=\"text-text-800 uppercase truncate\"\n >\n {title}\n </Text>\n\n <p\n className={cn('text-lg font-bold truncate', actionSubTitleClasses)}\n >\n {subTitle}\n </p>\n </div>\n\n {extended && (\n <div className=\"flex flex-col items-center gap-2.5 pb-9.5 pt-2.5\">\n <p\n className={cn(\n 'text-2xs font-medium uppercase truncate',\n actionHeaderClasses\n )}\n >\n {header}\n </p>\n <Badge size=\"large\" action=\"info\">\n {description}\n </Badge>\n </div>\n )}\n </div>\n );\n }\n);\n\ninterface CardQuestionProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n state?: 'done' | 'undone';\n onClickButton?: (valueButton?: unknown) => void;\n valueButton?: unknown;\n}\n\nconst CardQuestions = forwardRef<HTMLDivElement, CardQuestionProps>(\n (\n {\n header,\n state = 'undone',\n className,\n onClickButton,\n valueButton,\n ...props\n },\n ref\n ) => {\n const isDone = state === 'done';\n const stateLabel = isDone ? 'Realizado' : 'Não Realizado';\n const buttonLabel = isDone ? 'Ver Resultado' : 'Responder';\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"medium\"\n className={cn('justify-between gap-4', className)}\n {...props}\n >\n <section className=\"flex flex-col gap-1 flex-1 min-w-0\">\n <p className=\"font-bold text-xs text-text-950 truncate\">{header}</p>\n\n <div className=\"flex flex-row gap-6 items-center\">\n <Badge\n size=\"medium\"\n variant=\"solid\"\n action={isDone ? 'success' : 'error'}\n >\n {stateLabel}\n </Badge>\n </div>\n </section>\n\n <span className=\"flex-shrink-0\">\n <Button\n size=\"extra-small\"\n onClick={() => onClickButton?.(valueButton)}\n className=\"min-w-fit\"\n >\n {buttonLabel}\n </Button>\n </span>\n </CardBase>\n );\n }\n);\n\ninterface CardProgressProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n subhead?: string;\n initialDate?: string;\n endDate?: string;\n progress?: number;\n direction?: 'horizontal' | 'vertical';\n icon: ReactNode;\n color?: string;\n progressVariant?: 'blue' | 'green';\n showDates?: boolean;\n}\n\nconst CardProgress = forwardRef<HTMLDivElement, CardProgressProps>(\n (\n {\n header,\n subhead,\n initialDate,\n endDate,\n progress = 0,\n direction = 'horizontal',\n icon,\n color = '#B7DFFF',\n progressVariant = 'blue',\n showDates = true,\n className,\n ...props\n },\n ref\n ) => {\n const isHorizontal = direction === 'horizontal';\n const contentComponent = {\n horizontal: (\n <>\n {showDates && (\n <div className=\"flex flex-row gap-6 items-center\">\n {initialDate && (\n <span className=\"flex flex-row gap-1 items-center text-2xs\">\n <p className=\"text-text-800 font-semibold\">Início</p>\n <p className=\"text-text-600\">{initialDate}</p>\n </span>\n )}\n {endDate && (\n <span className=\"flex flex-row gap-1 items-center text-2xs\">\n <p className=\"text-text-800 font-semibold\">Fim</p>\n <p className=\"text-text-600\">{endDate}</p>\n </span>\n )}\n </div>\n )}\n <span className=\"grid grid-cols-[1fr_auto] items-center gap-2\">\n <ProgressBar\n size=\"small\"\n value={progress}\n variant={progressVariant}\n data-testid=\"progress-bar\"\n />\n\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none'\n )}\n >\n {Math.round(progress)}%\n </Text>\n </span>\n </>\n ),\n vertical: <p className=\"text-sm text-text-800\">{subhead}</p>,\n };\n\n return (\n <CardBase\n ref={ref}\n layout={isHorizontal ? 'horizontal' : 'vertical'}\n padding=\"none\"\n minHeight=\"medium\"\n cursor=\"pointer\"\n className={cn(isHorizontal ? 'h-20' : '', className)}\n {...props}\n >\n <div\n className={cn(\n 'flex justify-center items-center [&>svg]:size-6 text-text-950',\n isHorizontal\n ? 'min-w-[80px] min-h-[80px] rounded-l-xl'\n : 'min-h-[50px] w-full rounded-t-xl',\n !color.startsWith('#') ? `${color}` : ''\n )}\n style={color.startsWith('#') ? { backgroundColor: color } : undefined}\n data-testid=\"icon-container\"\n >\n {icon}\n </div>\n\n <div\n className={cn(\n 'p-4 flex flex-col justify-between w-full h-full',\n !isHorizontal && 'gap-4'\n )}\n >\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-950 truncate\">\n {header}\n </Text>\n {contentComponent[direction]}\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardTopicProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n subHead?: string[];\n progress: number;\n showPercentage?: boolean;\n progressVariant?: 'blue' | 'green';\n}\n\nconst CardTopic = forwardRef<HTMLDivElement, CardTopicProps>(\n (\n {\n header,\n subHead,\n progress,\n showPercentage = false,\n progressVariant = 'blue',\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <CardBase\n ref={ref}\n layout=\"vertical\"\n padding=\"small\"\n minHeight=\"medium\"\n cursor=\"pointer\"\n className={cn('justify-center gap-2 py-2 px-4', className)}\n {...props}\n >\n {subHead && (\n <span className=\"text-text-600 text-2xs flex flex-row gap-1\">\n {subHead.map((text, index) => (\n <Fragment key={`${text} - ${index}`}>\n <p>{text}</p>\n {index < subHead.length - 1 && <p>•</p>}\n </Fragment>\n ))}\n </span>\n )}\n\n <p className=\"text-sm text-text-950 font-bold truncate\">{header}</p>\n\n <span className=\"grid grid-cols-[1fr_auto] items-center gap-2\">\n <ProgressBar\n size=\"small\"\n value={progress}\n variant={progressVariant}\n data-testid=\"progress-bar\"\n />\n {showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none'\n )}\n >\n {Math.round(progress)}%\n </Text>\n )}\n </span>\n </CardBase>\n );\n }\n);\n\ninterface CardPerformanceProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n description?: string;\n progress?: number;\n labelProgress?: string;\n actionVariant?: 'button' | 'caret';\n progressVariant?: 'blue' | 'green';\n onClickButton?: (valueButton?: unknown) => void;\n valueButton?: unknown;\n}\n\nconst CardPerformance = forwardRef<HTMLDivElement, CardPerformanceProps>(\n (\n {\n header,\n progress,\n description = 'Sem dados ainda! Você ainda não fez um questionário neste assunto.',\n actionVariant = 'button',\n progressVariant = 'blue',\n labelProgress = '',\n className = '',\n onClickButton,\n valueButton,\n ...props\n },\n ref\n ) => {\n const hasProgress = progress !== undefined;\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n actionVariant == 'caret' ? 'cursor-pointer' : '',\n className\n )}\n onClick={() => actionVariant == 'caret' && onClickButton?.(valueButton)}\n {...props}\n >\n <div className=\"w-full flex flex-col justify-between gap-2\">\n <div className=\"flex flex-row justify-between items-center gap-2\">\n <p className=\"text-lg font-bold text-text-950 truncate flex-1 min-w-0\">\n {header}\n </p>\n {actionVariant === 'button' && (\n <Button\n variant=\"outline\"\n size=\"extra-small\"\n onClick={() => onClickButton?.(valueButton)}\n className=\"min-w-fit flex-shrink-0\"\n >\n Ver Aula\n </Button>\n )}\n </div>\n\n <div className=\"w-full\">\n {hasProgress ? (\n <ProgressBar\n value={progress}\n label={`${progress}% ${labelProgress}`}\n variant={progressVariant}\n />\n ) : (\n <p className=\"text-xs text-text-600 truncate\">{description}</p>\n )}\n </div>\n </div>\n\n {actionVariant == 'caret' && (\n <CaretRight\n className=\"size-4.5 text-text-800 cursor-pointer\"\n data-testid=\"caret-icon\"\n />\n )}\n </CardBase>\n );\n }\n);\n\ninterface CardResultsProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n icon: string;\n correct_answers: number;\n incorrect_answers: number;\n direction?: 'row' | 'col';\n color?: string;\n}\n\nconst CardResults = forwardRef<HTMLDivElement, CardResultsProps>(\n (\n {\n header,\n correct_answers,\n incorrect_answers,\n icon,\n direction = 'col',\n color = '#B7DFFF',\n className,\n ...props\n },\n ref\n ) => {\n const isRow = direction == 'row';\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"none\"\n minHeight=\"medium\"\n className={cn('items-stretch cursor-pointer pr-4', className)}\n {...props}\n >\n <div\n className={cn(\n 'flex justify-center items-center [&>svg]:size-8 text-text-950 min-w-20 max-w-20 min-h-full rounded-l-xl'\n )}\n style={{\n backgroundColor: color,\n }}\n >\n <IconRender iconName={icon} color=\"currentColor\" size={20} />\n </div>\n\n <div className=\"w-full flex flex-row justify-between items-center\">\n <div\n className={cn(\n 'p-4 flex flex-wrap justify-between w-full h-full',\n isRow ? 'flex-row items-center gap-2' : 'flex-col'\n )}\n >\n <p className=\"text-sm font-bold text-text-950 flex-1\">{header}</p>\n <span className=\"flex flex-wrap flex-row gap-1 items-center\">\n <Badge\n action=\"success\"\n variant=\"solid\"\n size=\"large\"\n iconLeft={<CheckCircle />}\n >\n {correct_answers} Corretas\n </Badge>\n\n <Badge\n action=\"error\"\n variant=\"solid\"\n size=\"large\"\n iconLeft={<XCircle />}\n >\n {incorrect_answers} Incorretas\n </Badge>\n </span>\n </div>\n\n <CaretRight className=\"min-w-6 min-h-6 text-text-800\" />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardStatusProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n status?: 'correct' | 'incorrect' | 'unanswered' | 'pending';\n label?: string;\n}\n\nconst CardStatus = forwardRef<HTMLDivElement, CardStatusProps>(\n ({ header, className, status, label, ...props }, ref) => {\n const getLabelBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return 'Correta';\n case 'incorrect':\n return 'Incorreta';\n case 'unanswered':\n return 'Em branco';\n case 'pending':\n return 'Avaliação pendente';\n default:\n return 'Em branco';\n }\n };\n\n const getIconBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return <CheckCircle />;\n case 'incorrect':\n return <XCircle />;\n case 'pending':\n return <Clock />;\n default:\n return <XCircle />;\n }\n };\n\n const getActionBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return 'success';\n case 'incorrect':\n return 'error';\n case 'pending':\n return 'info';\n default:\n return 'info';\n }\n };\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"medium\"\n className={cn('items-center cursor-pointer', className)}\n {...props}\n >\n <div className=\"flex justify-between w-full h-full flex-row items-center gap-2\">\n <p className=\"text-sm font-bold text-text-950 truncate flex-1 min-w-0\">\n {header}\n </p>\n <span className=\"flex flex-row gap-1 items-center flex-shrink-0\">\n {status && (\n <Badge\n action={getActionBadge(status)}\n variant=\"solid\"\n size=\"medium\"\n iconLeft={getIconBadge(status)}\n >\n {getLabelBadge(status)}\n </Badge>\n )}\n {label && <p className=\"text-sm text-text-800\">{label}</p>}\n </span>\n <CaretRight className=\"min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2\" />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardSettingsProps extends HTMLAttributes<HTMLDivElement> {\n icon: ReactNode;\n header: string;\n}\n\nconst CardSettings = forwardRef<HTMLDivElement, CardSettingsProps>(\n ({ header, className, icon, ...props }, ref) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"small\"\n minHeight=\"none\"\n className={cn(\n 'border-none items-center gap-2 text-text-700',\n className\n )}\n {...props}\n >\n <span className=\"[&>svg]:size-6\">{icon}</span>\n\n <p className=\"w-full text-sm truncate\">{header}</p>\n\n <CaretRight size={24} className=\"cursor-pointer\" />\n </CardBase>\n );\n }\n);\n\ninterface CardSupportProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n direction?: 'row' | 'col';\n children: ReactNode;\n}\n\nconst CardSupport = forwardRef<HTMLDivElement, CardSupportProps>(\n ({ header, className, direction = 'col', children, ...props }, ref) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n 'border-none items-center gap-2 text-text-700',\n className\n )}\n {...props}\n >\n <div\n className={cn(\n 'w-full flex',\n direction == 'col' ? 'flex-col' : 'flex-row items-center'\n )}\n >\n <span className=\"w-full min-w-0\">\n <p className=\"text-sm text-text-950 font-bold truncate\">{header}</p>\n </span>\n <span className=\"flex flex-row gap-1\">{children}</span>\n </div>\n\n <CaretRight className=\"text-text-800 cursor-pointer\" size={24} />\n </CardBase>\n );\n }\n);\n\ninterface CardForumProps<T = unknown> extends HTMLAttributes<HTMLDivElement> {\n title: string;\n content: string;\n comments: number;\n date: string;\n hour: string;\n onClickComments?: (value?: T) => void;\n valueComments?: T;\n onClickProfile?: (profile?: T) => void;\n valueProfile?: T;\n}\n\nconst CardForum = forwardRef<HTMLDivElement, CardForumProps>(\n (\n {\n title,\n content,\n comments,\n onClickComments,\n valueComments,\n onClickProfile,\n valueProfile,\n className = '',\n date,\n hour,\n ...props\n },\n ref\n ) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n variant=\"minimal\"\n className={cn('w-auto h-auto gap-3', className)}\n {...props}\n >\n <button\n type=\"button\"\n aria-label=\"Ver perfil\"\n onClick={() => onClickProfile?.(valueProfile)}\n className=\"min-w-8 h-8 rounded-full bg-background-950\"\n />\n\n <div className=\"flex flex-col gap-2 flex-1 min-w-0\">\n <div className=\"flex flex-row gap-1 items-center flex-wrap\">\n <p className=\"text-xs font-semibold text-primary-700 truncate\">\n {title}\n </p>\n <p className=\"text-xs text-text-600\">\n • {date} • {hour}\n </p>\n </div>\n\n <p className=\"text-text-950 text-sm line-clamp-2 truncate\">\n {content}\n </p>\n\n <button\n type=\"button\"\n aria-label=\"Ver comentários\"\n onClick={() => onClickComments?.(valueComments)}\n className=\"text-text-600 flex flex-row gap-2 items-center\"\n >\n <ChatCircleText aria-hidden=\"true\" size={16} />\n <p className=\"text-xs\">{comments} respostas</p>\n </button>\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardAudioProps extends HTMLAttributes<HTMLDivElement> {\n src?: string;\n title?: string;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onAudioTimeUpdate?: (currentTime: number, duration: number) => void;\n loop?: boolean;\n preload?: 'none' | 'metadata' | 'auto';\n tracks?: Array<{\n kind: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata';\n src: string;\n srcLang: string;\n label: string;\n default?: boolean;\n }>;\n}\n\nconst CardAudio = forwardRef<HTMLDivElement, CardAudioProps>(\n (\n {\n src,\n title,\n onPlay,\n onPause,\n onEnded,\n onAudioTimeUpdate,\n loop = false,\n preload = 'metadata',\n tracks,\n className,\n ...props\n },\n ref\n ) => {\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [volume, setVolume] = useState(1);\n const [showVolumeControl, setShowVolumeControl] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const [playbackRate, setPlaybackRate] = useState(1);\n const audioRef = useRef<HTMLAudioElement>(null);\n const volumeControlRef = useRef<HTMLDivElement>(null);\n const speedMenuRef = useRef<HTMLDivElement>(null);\n\n const formatTime = (time: number) => {\n const minutes = Math.floor(time / 60);\n const seconds = Math.floor(time % 60);\n return `${minutes}:${seconds.toString().padStart(2, '0')}`;\n };\n\n const handlePlayPause = () => {\n if (isPlaying) {\n audioRef.current?.pause();\n setIsPlaying(false);\n onPause?.();\n } else {\n audioRef.current?.play();\n setIsPlaying(true);\n onPlay?.();\n }\n };\n\n const handleTimeUpdate = () => {\n const current = audioRef.current?.currentTime ?? 0;\n const total = audioRef.current?.duration ?? 0;\n\n setCurrentTime(current);\n setDuration(total);\n onAudioTimeUpdate?.(current, total);\n };\n\n const handleLoadedMetadata = () => {\n setDuration(audioRef.current?.duration ?? 0);\n };\n\n const handleEnded = () => {\n setIsPlaying(false);\n setCurrentTime(0);\n onEnded?.();\n };\n\n const handleProgressClick = (e: MouseEvent<HTMLButtonElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const width = rect.width;\n const percentage = clickX / width;\n const newTime = percentage * duration;\n\n if (audioRef.current) {\n audioRef.current.currentTime = newTime;\n }\n setCurrentTime(newTime);\n };\n\n const handleVolumeChange = (e: ChangeEvent<HTMLInputElement>) => {\n const newVolume = parseFloat(e.target.value);\n setVolume(newVolume);\n if (audioRef.current) {\n audioRef.current.volume = newVolume;\n }\n };\n\n const toggleVolumeControl = () => {\n setShowVolumeControl(!showVolumeControl);\n setShowSpeedMenu(false);\n };\n\n const toggleSpeedMenu = () => {\n setShowSpeedMenu(!showSpeedMenu);\n setShowVolumeControl(false);\n };\n\n const handleSpeedChange = (speed: number) => {\n setPlaybackRate(speed);\n if (audioRef.current) {\n audioRef.current.playbackRate = speed;\n }\n setShowSpeedMenu(false);\n };\n\n const getVolumeIcon = () => {\n if (volume === 0) {\n return <SpeakerSimpleX size={24} />;\n }\n if (volume < 0.5) {\n return <SpeakerLow size={24} />;\n }\n return <SpeakerHigh size={24} />;\n };\n\n useEffect(() => {\n const handleClickOutside = (event: Event) => {\n if (\n volumeControlRef.current &&\n !volumeControlRef.current.contains(event.target as Node)\n ) {\n setShowVolumeControl(false);\n }\n if (\n speedMenuRef.current &&\n !speedMenuRef.current.contains(event.target as Node)\n ) {\n setShowSpeedMenu(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n 'flex flex-row w-auto h-14 items-center gap-2',\n className\n )}\n {...props}\n >\n {/* Audio element */}\n <audio\n ref={audioRef}\n src={src}\n loop={loop}\n preload={preload}\n onTimeUpdate={handleTimeUpdate}\n onLoadedMetadata={handleLoadedMetadata}\n onEnded={handleEnded}\n data-testid=\"audio-element\"\n aria-label={title}\n >\n {tracks ? (\n tracks.map((track) => (\n <track\n key={track.src}\n kind={track.kind}\n src={track.src}\n srcLang={track.srcLang}\n label={track.label}\n default={track.default}\n />\n ))\n ) : (\n <track\n kind=\"captions\"\n src=\"data:text/vtt;base64,\"\n srcLang=\"pt\"\n label=\"Sem legendas disponíveis\"\n />\n )}\n </audio>\n\n {/* Play/Pause Button */}\n <button\n type=\"button\"\n onClick={handlePlayPause}\n disabled={!src}\n className=\"cursor-pointer text-text-950 hover:text-primary-600 disabled:text-text-400 disabled:cursor-not-allowed\"\n aria-label={isPlaying ? 'Pausar' : 'Reproduzir'}\n >\n {isPlaying ? (\n <div className=\"w-6 h-6 flex items-center justify-center\">\n <div className=\"flex gap-0.5\">\n <div className=\"w-1 h-4 bg-current rounded-sm\"></div>\n <div className=\"w-1 h-4 bg-current rounded-sm\"></div>\n </div>\n </div>\n ) : (\n <Play size={24} />\n )}\n </button>\n\n {/* Current Time */}\n <p className=\"text-text-800 text-md font-medium min-w-[2.5rem]\">\n {formatTime(currentTime)}\n </p>\n\n {/* Progress Bar */}\n <div className=\"flex-1 relative\" data-testid=\"progress-bar\">\n <button\n type=\"button\"\n className=\"w-full h-2 bg-border-100 rounded-full cursor-pointer\"\n onClick={handleProgressClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleProgressClick(\n e as unknown as MouseEvent<HTMLButtonElement>\n );\n }\n }}\n aria-label=\"Barra de progresso do áudio\"\n >\n <div\n className=\"h-full bg-primary-600 rounded-full transition-all duration-100\"\n style={{\n width:\n duration > 0 ? `${(currentTime / duration) * 100}%` : '0%',\n }}\n />\n </button>\n </div>\n\n {/* Duration */}\n <p className=\"text-text-800 text-md font-medium min-w-[2.5rem]\">\n {formatTime(duration)}\n </p>\n\n {/* Volume Control */}\n <div className=\"relative h-6\" ref={volumeControlRef}>\n <button\n type=\"button\"\n onClick={toggleVolumeControl}\n className=\"cursor-pointer text-text-950 hover:text-primary-600\"\n aria-label=\"Controle de volume\"\n >\n <div className=\"w-6 h-6 flex items-center justify-center\">\n {getVolumeIcon()}\n </div>\n </button>\n\n {showVolumeControl && (\n <button\n type=\"button\"\n className=\"absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500\"\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n setShowVolumeControl(false);\n }\n }}\n >\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.1\"\n value={volume}\n onChange={handleVolumeChange}\n onKeyDown={(e) => {\n if (e.key === 'ArrowUp' || e.key === 'ArrowRight') {\n e.preventDefault();\n const newVolume = Math.min(\n 1,\n Math.round((volume + 0.1) * 10) / 10\n );\n setVolume(newVolume);\n if (audioRef.current) audioRef.current.volume = newVolume;\n } else if (e.key === 'ArrowDown' || e.key === 'ArrowLeft') {\n e.preventDefault();\n const newVolume = Math.max(\n 0,\n Math.round((volume - 0.1) * 10) / 10\n );\n setVolume(newVolume);\n if (audioRef.current) audioRef.current.volume = newVolume;\n }\n }}\n className=\"w-20 h-2 bg-border-100 rounded-lg appearance-none cursor-pointer\"\n style={{\n background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${volume * 100}%, #e5e7eb ${volume * 100}%, #e5e7eb 100%)`,\n }}\n aria-label=\"Volume\"\n aria-valuenow={Math.round(volume * 100)}\n aria-valuemin={0}\n aria-valuemax={100}\n />\n </button>\n )}\n </div>\n\n {/* Menu Button */}\n <div className=\"relative h-6\" ref={speedMenuRef}>\n <button\n type=\"button\"\n onClick={toggleSpeedMenu}\n className=\"cursor-pointer text-text-950 hover:text-primary-600\"\n aria-label=\"Opções de velocidade\"\n >\n <DotsThreeVertical size={24} />\n </button>\n\n {showSpeedMenu && (\n <div className=\"absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg min-w-24 z-10\">\n <div className=\"flex flex-col gap-1\">\n {[\n { speed: 1, label: '1x' },\n { speed: 1.5, label: '1.5x' },\n { speed: 2, label: '2x' },\n ].map(({ speed, label }) => (\n <button\n key={speed}\n type=\"button\"\n onClick={() => handleSpeedChange(speed)}\n className={cn(\n 'px-3 py-1 text-sm text-left rounded hover:bg-border-50 transition-colors',\n playbackRate === speed\n ? 'bg-primary-950 text-secondary-100 font-medium'\n : 'text-text-950'\n )}\n >\n {label}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardSimuladoProps extends HTMLAttributes<HTMLDivElement> {\n title: string;\n duration?: string;\n info: string;\n backgroundColor: 'enem' | 'prova' | 'simuladao' | 'vestibular';\n}\n\nconst SIMULADO_BACKGROUND_CLASSES = {\n enem: 'bg-exam-1',\n prova: 'bg-exam-2',\n simuladao: 'bg-exam-3',\n vestibular: 'bg-exam-4',\n};\n\nconst CardSimulado = forwardRef<HTMLDivElement, CardSimuladoProps>(\n ({ title, duration, info, backgroundColor, className, ...props }, ref) => {\n const backgroundClass = SIMULADO_BACKGROUND_CLASSES[backgroundColor];\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n cursor=\"pointer\"\n className={cn(\n `${backgroundClass} hover:shadow-soft-shadow-2 transition-shadow duration-200`,\n className\n )}\n {...props}\n >\n <div className=\"flex justify-between items-center w-full gap-4\">\n <div className=\"flex flex-col gap-1 flex-1 min-w-0\">\n <Text size=\"lg\" weight=\"bold\" className=\"text-text-950 truncate\">\n {title}\n </Text>\n\n <div className=\"flex items-center gap-4 text-text-700\">\n {duration && (\n <div className=\"flex items-center gap-1\">\n <Clock size={16} className=\"flex-shrink-0\" />\n <Text size=\"sm\">{duration}</Text>\n </div>\n )}\n\n <Text size=\"sm\" className=\"truncate\">\n {info}\n </Text>\n </div>\n </div>\n\n <CaretRight\n size={24}\n className=\"text-text-800 flex-shrink-0\"\n data-testid=\"caret-icon\"\n />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardTestProps extends Omit<HTMLAttributes<HTMLElement>, 'onSelect'> {\n title: string;\n duration?: string;\n questionsCount?: number;\n additionalInfo?: string;\n selected?: boolean;\n onSelect?: (selected: boolean) => void;\n}\n\nconst CardTest = forwardRef<HTMLElement, CardTestProps>(\n (\n {\n title,\n duration,\n questionsCount,\n additionalInfo,\n selected = false,\n onSelect,\n className = '',\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (onSelect) {\n onSelect(!selected);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if ((event.key === 'Enter' || event.key === ' ') && onSelect) {\n event.preventDefault();\n onSelect(!selected);\n }\n };\n\n const isSelectable = !!onSelect;\n const getQuestionsText = (count: number) => {\n const singular = count === 1 ? 'questão' : 'questões';\n return `${count} ${singular}`;\n };\n\n const displayInfo = questionsCount\n ? getQuestionsText(questionsCount)\n : additionalInfo || '';\n const baseClasses =\n 'flex flex-row items-center p-4 gap-2 w-full max-w-full bg-background shadow-soft-shadow-1 rounded-xl isolate border-0 text-left';\n const interactiveClasses = isSelectable\n ? 'cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-950 focus:ring-offset-2'\n : '';\n const selectedClasses = selected\n ? 'ring-2 ring-primary-950 ring-offset-2'\n : '';\n\n if (isSelectable) {\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n type=\"button\"\n className={cn(\n `${baseClasses} ${interactiveClasses} ${selectedClasses} ${className}`.trim()\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n aria-pressed={selected}\n {...(props as HTMLAttributes<HTMLButtonElement>)}\n >\n <div className=\"flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0\">\n <Text\n size=\"md\"\n weight=\"bold\"\n className=\"text-text-950 tracking-[0.2px] leading-[19px] truncate\"\n >\n {title}\n </Text>\n\n <div className=\"flex flex-row justify-start items-end gap-4 w-full\">\n {duration && (\n <div className=\"flex flex-row items-center gap-1 flex-shrink-0\">\n <Clock size={16} className=\"text-text-700\" />\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] whitespace-nowrap\"\n >\n {duration}\n </Text>\n </div>\n )}\n\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] flex-grow truncate\"\n >\n {displayInfo}\n </Text>\n </div>\n </div>\n </button>\n );\n }\n\n return (\n <div\n ref={ref as Ref<HTMLDivElement>}\n className={cn(`${baseClasses} ${className}`.trim())}\n {...(props as HTMLAttributes<HTMLDivElement>)}\n >\n <div className=\"flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0\">\n <Text\n size=\"md\"\n weight=\"bold\"\n className=\"text-text-950 tracking-[0.2px] leading-[19px] truncate\"\n >\n {title}\n </Text>\n\n <div className=\"flex flex-row justify-start items-end gap-4 w-full\">\n {duration && (\n <div className=\"flex flex-row items-center gap-1 flex-shrink-0\">\n <Clock size={16} className=\"text-text-700\" />\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] whitespace-nowrap\"\n >\n {duration}\n </Text>\n </div>\n )}\n\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] flex-grow truncate min-w-0\"\n >\n {displayInfo}\n </Text>\n </div>\n </div>\n </div>\n );\n }\n);\n\ninterface SimulationItem {\n id: string;\n title: string;\n type: 'enem' | 'prova' | 'simulado' | 'vestibular';\n info: string;\n}\n\ninterface SimulationHistoryData {\n date: string;\n simulations: SimulationItem[];\n}\n\ninterface CardSimulationHistoryProps extends HTMLAttributes<HTMLDivElement> {\n data: SimulationHistoryData[];\n onSimulationClick?: (simulation: SimulationItem) => void;\n}\n\nconst SIMULATION_TYPE_STYLES = {\n enem: {\n background: 'bg-exam-1',\n badge: 'exam1' as const,\n text: 'Enem',\n },\n prova: {\n background: 'bg-exam-2',\n badge: 'exam2' as const,\n text: 'Prova',\n },\n simulado: {\n background: 'bg-exam-3',\n badge: 'exam3' as const,\n text: 'Simuladão',\n },\n vestibular: {\n background: 'bg-exam-4',\n badge: 'exam4' as const,\n text: 'Vestibular',\n },\n};\n\nconst CardSimulationHistory = forwardRef<\n HTMLDivElement,\n CardSimulationHistoryProps\n>(({ data, onSimulationClick, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('w-full max-w-[992px] h-auto', className)}\n {...props}\n >\n {/* Content */}\n <div className=\"flex flex-col gap-0\">\n {data.map((section, sectionIndex) => (\n <div key={section.date} className=\"flex flex-col\">\n {/* Seção com data */}\n <div\n className={cn(\n 'flex flex-row justify-center items-start px-4 py-6 gap-2 w-full bg-background',\n sectionIndex === 0 ? 'rounded-t-3xl' : ''\n )}\n >\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"text-text-800 w-11 flex-shrink-0\"\n >\n {section.date}\n </Text>\n\n <div className=\"flex flex-col gap-2 flex-1\">\n {section.simulations.map((simulation) => {\n const typeStyles = SIMULATION_TYPE_STYLES[simulation.type];\n\n return (\n <CardBase\n key={simulation.id}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n cursor=\"pointer\"\n className={cn(\n `${typeStyles.background} rounded-xl hover:shadow-soft-shadow-2 \n transition-shadow duration-200 h-auto min-h-[61px]`\n )}\n onClick={() => onSimulationClick?.(simulation)}\n >\n <div className=\"flex justify-between items-center w-full gap-2\">\n <div className=\"flex flex-wrap flex-col justify-between sm:flex-row gap-2 flex-1 min-w-0\">\n <Text\n size=\"lg\"\n weight=\"bold\"\n className=\"text-text-950 truncate\"\n >\n {simulation.title}\n </Text>\n\n <div className=\"flex items-center gap-2\">\n <Badge\n variant=\"examsOutlined\"\n action={typeStyles.badge}\n size=\"medium\"\n >\n {typeStyles.text}\n </Badge>\n\n <Text size=\"sm\" className=\"text-text-800 truncate\">\n {simulation.info}\n </Text>\n </div>\n </div>\n\n <CaretRight\n size={24}\n className=\"text-text-800 flex-shrink-0\"\n data-testid=\"caret-icon\"\n />\n </div>\n </CardBase>\n );\n })}\n </div>\n </div>\n </div>\n ))}\n\n {/* Footer rounded */}\n {data.length > 0 && (\n <div className=\"w-full h-6 bg-background rounded-b-3xl\" />\n )}\n </div>\n </div>\n );\n});\n\nexport {\n CardBase,\n CardActivitiesResults,\n CardQuestions,\n CardProgress,\n CardTopic,\n CardPerformance,\n CardResults,\n CardStatus,\n CardSettings,\n CardSupport,\n CardForum,\n CardAudio,\n CardSimulado,\n CardTest,\n CardSimulationHistory,\n};\n","import { cloneElement, ComponentType, JSX, ReactElement } from 'react';\nimport * as PhosphorIcons from 'phosphor-react';\nimport { ChatPT } from '../../assets/icons/subjects/ChatPT';\nimport { ChatEN } from '../../assets/icons/subjects/ChatEN';\nimport { ChatES } from '../../assets/icons/subjects/ChatES';\n\ntype PhosphorIconName = keyof typeof PhosphorIcons;\ntype PhosphorIconComponent = ComponentType<{\n size?: number;\n color?: string;\n weight?: 'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone';\n}>;\n\nexport interface IconRenderProps {\n /**\n * The name of the icon to render\n */\n iconName: string | ReactElement;\n /**\n * The color of the icon\n * @default '#000000'\n */\n color?: string;\n /**\n * The size of the icon in pixels\n * @default 24\n */\n size?: number;\n /**\n * The weight/style of the icon (for Phosphor icons)\n * @default 'regular'\n */\n weight?: 'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone';\n}\n\n/**\n * Dynamic icon component that renders icons based on name\n * Supports Phosphor icons and custom Chat icons (ChatPT, ChatEN, ChatES)\n *\n * @param iconName - The name of the icon to render\n * @param color - The color of the icon\n * @param size - The size of the icon in pixels\n * @param weight - The weight/style of the icon (for Phosphor icons)\n * @returns JSX element with the corresponding icon\n */\nexport const IconRender = ({\n iconName,\n color = '#000000',\n size = 24,\n weight = 'regular',\n}: IconRenderProps): JSX.Element => {\n if (typeof iconName === 'string') {\n switch (iconName) {\n case 'Chat_PT':\n return <ChatPT size={size} color={color} />;\n case 'Chat_EN':\n return <ChatEN size={size} color={color} />;\n case 'Chat_ES':\n return <ChatES size={size} color={color} />;\n default: {\n const IconComponent = (PhosphorIcons[iconName as PhosphorIconName] ||\n PhosphorIcons.Question) as PhosphorIconComponent;\n\n return <IconComponent size={size} color={color} weight={weight} />;\n }\n }\n } else {\n // Clone the ReactElement with icon props, casting to avoid TypeScript errors\n return cloneElement(iconName, {\n size,\n color: 'currentColor',\n } as Partial<{\n size: number;\n color: string;\n }>);\n }\n};\n\nexport default IconRender;\n","export const ChatPT = ({ size, color }: { size: number; color: string }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z\"\n fill={color}\n />\n <path\n d=\"M21.1758 12V20.5312H19.7168V12H21.1758ZM23.8535 12V13.1719H17.0625V12H23.8535Z\"\n fill={color}\n />\n <path\n d=\"M13.2402 17.3496H11.0195V16.1836H13.2402C13.627 16.1836 13.9395 16.1211 14.1777 15.9961C14.416 15.8711 14.5898 15.6992 14.6992 15.4805C14.8125 15.2578 14.8691 15.0039 14.8691 14.7188C14.8691 14.4492 14.8125 14.1973 14.6992 13.9629C14.5898 13.7246 14.416 13.5332 14.1777 13.3887C13.9395 13.2441 13.627 13.1719 13.2402 13.1719H11.4707V20.5312H10V12H13.2402C13.9004 12 14.4609 12.1172 14.9219 12.3516C15.3867 12.582 15.7402 12.9023 15.9824 13.3125C16.2246 13.7188 16.3457 14.1836 16.3457 14.707C16.3457 15.2578 16.2246 15.7305 15.9824 16.125C15.7402 16.5195 15.3867 16.8223 14.9219 17.0332C14.4609 17.2441 13.9004 17.3496 13.2402 17.3496Z\"\n fill={color}\n />\n </svg>\n);\n","export const ChatEN = ({ size, color }: { size: number; color: string }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z\"\n fill={color}\n />\n <path\n d=\"M22.5488 12V20.5312H21.0781L17.252 14.4199V20.5312H15.7812V12H17.252L21.0898 18.123V12H22.5488Z\"\n fill={color}\n />\n <path\n d=\"M14.584 19.3652V20.5312H10.0547V19.3652H14.584ZM10.4707 12V20.5312H9V12H10.4707ZM13.9922 15.5625V16.7109H10.0547V15.5625H13.9922ZM14.5547 12V13.1719H10.0547V12H14.5547Z\"\n fill={color}\n />\n </svg>\n);\n","export const ChatES = ({ size, color }: { size: number; color: string }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z\"\n fill={color}\n />\n <path\n d=\"M21.1426 17.8027C21.1426 17.627 21.1152 17.4707 21.0605 17.334C21.0098 17.1973 20.918 17.0723 20.7852 16.959C20.6523 16.8457 20.4648 16.7363 20.2227 16.6309C19.9844 16.5215 19.6797 16.4102 19.3086 16.2969C18.9023 16.1719 18.5273 16.0332 18.1836 15.8809C17.8438 15.7246 17.5469 15.5449 17.293 15.3418C17.0391 15.1348 16.8418 14.8984 16.7012 14.6328C16.5605 14.3633 16.4902 14.0527 16.4902 13.7012C16.4902 13.3535 16.5625 13.0371 16.707 12.752C16.8555 12.4668 17.0645 12.2207 17.334 12.0137C17.6074 11.8027 17.9297 11.6406 18.3008 11.5273C18.6719 11.4102 19.082 11.3516 19.5312 11.3516C20.1641 11.3516 20.709 11.4688 21.166 11.7031C21.627 11.9375 21.9805 12.252 22.2266 12.6465C22.4766 13.041 22.6016 13.4766 22.6016 13.9531H21.1426C21.1426 13.6719 21.082 13.4238 20.9609 13.209C20.8438 12.9902 20.6641 12.8184 20.4219 12.6934C20.1836 12.5684 19.8809 12.5059 19.5137 12.5059C19.166 12.5059 18.877 12.5586 18.6465 12.6641C18.416 12.7695 18.2441 12.9121 18.1309 13.0918C18.0176 13.2715 17.9609 13.4746 17.9609 13.7012C17.9609 13.8613 17.998 14.0078 18.0723 14.1406C18.1465 14.2695 18.2598 14.3906 18.4121 14.5039C18.5645 14.6133 18.7559 14.7168 18.9863 14.8145C19.2168 14.9121 19.4883 15.0059 19.8008 15.0957C20.2734 15.2363 20.6855 15.3926 21.0371 15.5645C21.3887 15.7324 21.6816 15.9238 21.916 16.1387C22.1504 16.3535 22.3262 16.5977 22.4434 16.8711C22.5605 17.1406 22.6191 17.4473 22.6191 17.791C22.6191 18.1504 22.5469 18.4746 22.4023 18.7637C22.2578 19.0488 22.0508 19.293 21.7812 19.4961C21.5156 19.6953 21.1953 19.8496 20.8203 19.959C20.4492 20.0645 20.0352 20.1172 19.5781 20.1172C19.168 20.1172 18.7637 20.0625 18.3652 19.9531C17.9707 19.8438 17.6113 19.6777 17.2871 19.4551C16.9629 19.2285 16.7051 18.9473 16.5137 18.6113C16.3223 18.2715 16.2266 17.875 16.2266 17.4219H17.6973C17.6973 17.6992 17.7441 17.9355 17.8379 18.1309C17.9355 18.3262 18.0703 18.4863 18.2422 18.6113C18.4141 18.7324 18.6133 18.8223 18.8398 18.8809C19.0703 18.9395 19.3164 18.9688 19.5781 18.9688C19.9219 18.9688 20.209 18.9199 20.4395 18.8223C20.6738 18.7246 20.8496 18.5879 20.9668 18.4121C21.084 18.2363 21.1426 18.0332 21.1426 17.8027Z\"\n fill={color}\n />\n <path\n d=\"M15.4512 18.834V20H10.9219V18.834H15.4512ZM11.3379 11.4688V20H9.86719V11.4688H11.3379ZM14.8594 15.0312V16.1797H10.9219V15.0312H14.8594ZM15.4219 11.4688V12.6406H10.9219V11.4688H15.4219Z\"\n fill={color}\n />\n </svg>\n);\n","import {\n Children,\n cloneElement,\n forwardRef,\n HTMLAttributes,\n isValidElement,\n ReactElement,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { create, StoreApi } from 'zustand';\nimport { CardAccordationProps } from './Accordation';\n\ninterface AccordionGroupStore {\n type: 'single' | 'multiple';\n value: string | string[];\n collapsible: boolean;\n setValue: (value: string | string[]) => void;\n isItemExpanded: (itemValue: string) => boolean;\n}\n\ntype AccordionGroupStoreApi = StoreApi<AccordionGroupStore>;\n\nfunction createAccordionGroupStore(\n type: 'single' | 'multiple',\n initialValue: string | string[],\n collapsible: boolean\n): AccordionGroupStoreApi {\n return create<AccordionGroupStore>((set, get) => ({\n type,\n value: initialValue,\n collapsible,\n setValue: (value) => set({ value }),\n isItemExpanded: (itemValue: string): boolean => {\n const state = get();\n if (state.type === 'single') {\n return state.value === itemValue;\n } else {\n return Array.isArray(state.value) && state.value.includes(itemValue);\n }\n },\n }));\n}\n\ninterface AccordionGroupProps extends HTMLAttributes<HTMLDivElement> {\n type?: 'single' | 'multiple';\n defaultValue?: string | string[];\n value?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n collapsible?: boolean;\n children: ReactNode;\n}\n\n// Helper function to inject store only to CardAccordation components\nconst injectStore = (\n children: ReactNode,\n store: AccordionGroupStoreApi,\n indexRef: { current: number },\n onItemToggle: (itemValue: string, isExpanded: boolean) => void\n): ReactNode => {\n return Children.map(children, (child) => {\n if (!isValidElement(child)) {\n return child;\n }\n\n const typedChild = child as ReactElement<\n CardAccordationProps & {\n children?: ReactNode;\n }\n >;\n\n // Check if it's a CardAccordation component\n const displayName = (typedChild.type as unknown as { displayName?: string })\n ?.displayName;\n\n let newProps: Partial<{\n children: ReactNode;\n value: string;\n expanded: boolean;\n onToggleExpanded: (isExpanded: boolean) => void;\n }> = {};\n\n if (displayName === 'CardAccordation') {\n // Generate value if not provided\n const itemValue =\n typedChild.props.value || `accordion-item-${indexRef.current++}`;\n\n // Get expanded state from store\n const storeState = store.getState();\n const expanded = storeState.isItemExpanded(itemValue);\n\n newProps.value = itemValue;\n newProps.expanded = expanded;\n newProps.onToggleExpanded = (isExpanded: boolean) => {\n onItemToggle(itemValue, isExpanded);\n typedChild.props.onToggleExpanded?.(isExpanded);\n };\n }\n\n // Recursively process children\n if (typedChild.props.children) {\n const processedChildren = injectStore(\n typedChild.props.children,\n store,\n indexRef,\n onItemToggle\n );\n\n // If it's a CardAccordation, add children to newProps\n if (displayName === 'CardAccordation') {\n newProps.children = processedChildren;\n } else if (processedChildren !== typedChild.props.children) {\n // For other elements, only clone if children changed\n return cloneElement(typedChild, { children: processedChildren });\n }\n }\n\n // Only clone if we have props to inject (only for CardAccordation)\n if (Object.keys(newProps).length > 0) {\n return cloneElement(typedChild, newProps);\n }\n\n return child;\n });\n};\n\nconst AccordionGroup = forwardRef<HTMLDivElement, AccordionGroupProps>(\n (\n {\n type = 'single',\n defaultValue,\n value: controlledValue,\n onValueChange,\n collapsible = true,\n children,\n className,\n ...props\n },\n ref\n ) => {\n const [internalValue, setInternalValue] = useState<string | string[]>(\n defaultValue || (type === 'single' ? '' : [])\n );\n\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n // Create store only once using useRef\n const storeRef = useRef<AccordionGroupStoreApi | null>(null);\n if (storeRef.current) {\n // Update store configuration when props change\n storeRef.current.setState((prev) => {\n const nextState: Partial<AccordionGroupStore> = {};\n if (prev.type !== type) {\n nextState.type = type;\n }\n if (prev.collapsible !== collapsible) {\n nextState.collapsible = collapsible;\n }\n return nextState;\n });\n } else {\n // Create store on first render\n storeRef.current = createAccordionGroupStore(\n type,\n currentValue,\n collapsible\n );\n }\n const store = storeRef.current;\n\n // Sync store value when currentValue changes\n useEffect(() => {\n store.setState({ value: currentValue });\n }, [currentValue, store]);\n\n // Normalize internal value when type changes (uncontrolled mode)\n useEffect(() => {\n if (!isControlled) {\n setInternalValue((prev) => {\n if (type === 'single') {\n if (Array.isArray(prev)) {\n return prev[0] ?? '';\n }\n return typeof prev === 'string' ? prev : '';\n }\n if (Array.isArray(prev)) {\n return prev;\n }\n return prev ? [prev] : [];\n });\n }\n }, [isControlled, type]);\n\n const handleItemToggle = (itemValue: string, isExpanded: boolean) => {\n const storeState = store.getState();\n let newValue: string | string[];\n\n if (type === 'single') {\n // Single mode: only one item can be open at a time\n if (isExpanded) {\n newValue = itemValue;\n } else {\n // If collapsible, allow closing the current item\n newValue = collapsible ? '' : (storeState.value as string);\n }\n } else {\n // Multiple mode: multiple items can be open\n const currentArray = Array.isArray(storeState.value)\n ? storeState.value\n : [];\n\n if (isExpanded) {\n newValue = [...currentArray, itemValue];\n } else {\n newValue = currentArray.filter((v) => v !== itemValue);\n }\n }\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n store.setState({ value: newValue });\n onValueChange?.(newValue);\n };\n\n // Use ref to track index across recursive calls\n const indexRef = { current: 0 };\n const enhancedChildren = injectStore(\n children,\n store,\n indexRef,\n handleItemToggle\n );\n\n return (\n <div ref={ref} className={className} {...props}>\n {enhancedChildren}\n </div>\n );\n }\n);\n\nAccordionGroup.displayName = 'AccordionGroup';\n\nexport { AccordionGroup };\n","import React, { useRef } from 'react';\nimport { Paperclip, FileText, X } from 'phosphor-react';\nimport Button from '../Button/Button';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * Represents an attached file with unique identifier\n */\nexport interface AttachedFile {\n /** The file object */\n file: File;\n /** Unique identifier for the file */\n id: string;\n}\n\n/**\n * Props for the FileAttachment component\n */\nexport interface FileAttachmentProps {\n /** List of attached files */\n files: AttachedFile[];\n /** Callback when files are added */\n onFilesAdd: (files: File[]) => void;\n /** Callback when a file is removed */\n onFileRemove: (id: string) => void;\n /** Whether the files are read-only (no removal allowed) */\n readOnly?: boolean;\n /** Text for the attach button */\n buttonLabel?: string;\n /** Whether to accept multiple files */\n multiple?: boolean;\n /** Additional CSS class */\n className?: string;\n /** Whether to hide the attach button */\n hideButton?: boolean;\n}\n\n/**\n * Formats file size to human-readable string\n * @param bytes - File size in bytes\n * @returns Formatted string (e.g., \"1.5 MB\")\n */\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n};\n\n/**\n * Generates a unique ID for file tracking\n * @returns Unique string identifier\n */\nconst generateFileId = (): string => {\n return crypto.randomUUID();\n};\n\n/**\n * Reusable file attachment component\n *\n * Allows users to attach multiple files with preview and removal functionality.\n * No file size or type restrictions are applied on the client side.\n *\n * @param props - Component props\n * @returns JSX element\n *\n * @example\n * ```tsx\n * const [files, setFiles] = useState<AttachedFile[]>([]);\n *\n * <FileAttachment\n * files={files}\n * onFilesAdd={(newFiles) => {\n * const attachedFiles = newFiles.map(file => ({\n * file,\n * id: generateFileId()\n * }));\n * setFiles(prev => [...prev, ...attachedFiles]);\n * }}\n * onFileRemove={(id) => setFiles(prev => prev.filter(f => f.id !== id))}\n * multiple\n * />\n * ```\n */\nconst FileAttachment = ({\n files,\n onFilesAdd,\n onFileRemove,\n readOnly = false,\n buttonLabel = 'Anexar',\n multiple = true,\n className,\n hideButton = false,\n}: FileAttachmentProps) => {\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n /**\n * Handle file input change\n * @param event - Input change event\n */\n const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const selectedFiles = event.target.files;\n if (selectedFiles && selectedFiles.length > 0) {\n const filesArray: File[] = Array.from(selectedFiles);\n onFilesAdd(filesArray);\n }\n // Reset input to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n /**\n * Trigger file input click\n */\n const handleAttachClick = () => {\n fileInputRef.current?.click();\n };\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {/* Hidden file input */}\n <input\n type=\"file\"\n ref={fileInputRef}\n className=\"hidden\"\n onChange={handleFileChange}\n multiple={multiple}\n aria-label=\"Selecionar arquivos\"\n />\n\n {/* Attach button */}\n {!readOnly && !hideButton && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={handleAttachClick}\n className=\"self-start flex items-center gap-2\"\n >\n <Paperclip size={16} />\n {buttonLabel}\n </Button>\n )}\n\n {/* Attached files list */}\n {files.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {files.map((attachedFile) => (\n <div\n key={attachedFile.id}\n className=\"flex items-center gap-2 bg-background-50 px-3 py-2 rounded-lg border border-border-100\"\n >\n <FileText size={16} className=\"text-text-500 shrink-0\" />\n <Text className=\"text-sm text-text-700 truncate max-w-[200px]\">\n {attachedFile.file.name}\n </Text>\n <Text className=\"text-xs text-text-400 shrink-0\">\n {formatFileSize(attachedFile.file.size)}\n </Text>\n {!readOnly && (\n <button\n type=\"button\"\n onClick={() => onFileRemove(attachedFile.id)}\n className=\"text-text-400 hover:text-error-500 transition-colors shrink-0\"\n aria-label={`Remover ${attachedFile.file.name}`}\n >\n <X size={14} />\n </button>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n\nexport { generateFileId, formatFileSize };\nexport default FileAttachment;\n","/**\n * Question status enum for student activity correction\n * Maps from ANSWER_STATUS to a simpler status for UI display\n */\nexport const QUESTION_STATUS = {\n CORRETA: 'CORRETA',\n INCORRETA: 'INCORRETA',\n EM_BRANCO: 'EM_BRANCO',\n /** Reserved for future use - pending teacher evaluation for essay questions */\n PENDENTE: 'PENDENTE',\n} as const;\n\nexport type QuestionStatus =\n (typeof QUESTION_STATUS)[keyof typeof QUESTION_STATUS];\n","import { StatusBadgeConfig } from '@/types/activityDetails';\nimport {\n ANSWER_STATUS,\n QUESTION_TYPE,\n} from '../../components/Quiz/useQuizStore';\nimport { QUESTION_STATUS, type QuestionStatus } from './constants';\nimport type { CorrectionQuestionData } from './types';\n\n/**\n * Returns whether the answer is correct, incorrect, or null based on the answer status.\n * @param answerStatus - Answer status from ANSWER_STATUS enum\n * @returns Returns true for correct, false for incorrect, or null if undefined.\n */\nexport const getIsCorrect = (answerStatus: ANSWER_STATUS): boolean | null => {\n if (answerStatus === ANSWER_STATUS.RESPOSTA_CORRETA) return true;\n if (answerStatus === ANSWER_STATUS.RESPOSTA_INCORRETA) return false;\n return null;\n};\n\n/**\n * Map ANSWER_STATUS from Quiz to QUESTION_STATUS for correction modal\n * @param answerStatus - Answer status from QuestionResult\n * @returns QuestionStatus for UI display\n */\nexport const mapAnswerStatusToQuestionStatus = (\n answerStatus: ANSWER_STATUS\n): QuestionStatus => {\n switch (answerStatus) {\n case ANSWER_STATUS.RESPOSTA_CORRETA:\n return QUESTION_STATUS.CORRETA;\n case ANSWER_STATUS.RESPOSTA_INCORRETA:\n return QUESTION_STATUS.INCORRETA;\n case ANSWER_STATUS.NAO_RESPONDIDO:\n return QUESTION_STATUS.EM_BRANCO;\n case ANSWER_STATUS.PENDENTE_AVALIACAO:\n return QUESTION_STATUS.PENDENTE;\n default:\n return QUESTION_STATUS.EM_BRANCO;\n }\n};\n\n/**\n * Get question status badge configuration\n * @param status - Question status\n * @returns Badge configuration with label and colors\n */\nexport const getQuestionStatusBadgeConfig = (status: QuestionStatus) => {\n const configs: Partial<Record<QuestionStatus, StatusBadgeConfig>> = {\n [QUESTION_STATUS.CORRETA]: {\n label: 'Correta',\n bgColor: 'bg-success-background',\n textColor: 'text-success-800',\n },\n [QUESTION_STATUS.INCORRETA]: {\n label: 'Incorreta',\n bgColor: 'bg-error-background',\n textColor: 'text-error-800',\n },\n [QUESTION_STATUS.EM_BRANCO]: {\n label: 'Em branco',\n bgColor: 'bg-gray-100',\n textColor: 'text-gray-600',\n },\n [QUESTION_STATUS.PENDENTE]: {\n label: 'Pendente',\n bgColor: 'bg-warning-background',\n textColor: 'text-warning-800',\n },\n };\n\n const defaultConfig = {\n label: 'Sem categoria',\n bgColor: 'bg-gray-100',\n textColor: 'text-gray-600',\n };\n\n return configs[status] ?? defaultConfig;\n};\n\n/**\n * Check if question can be auto-validated based on options\n * All question types can be auto-validated except DISSERTATIVA (essay questions)\n * @param questionData - Correction question data\n * @returns true if can auto-validate, false otherwise\n */\nexport const canAutoValidate = (\n questionData: CorrectionQuestionData\n): boolean => {\n const { result } = questionData;\n\n // Only dissertative questions require manual evaluation\n if (result.questionType === QUESTION_TYPE.DISSERTATIVA) {\n return false;\n }\n\n return true;\n};\n\ntype Option = {\n id: string;\n option: string;\n isCorrect: boolean;\n};\n\n/**\n * Type predicate to check if an option has isCorrect defined\n */\nconst hasIsCorrect = (op: {\n id: string;\n option: string;\n isCorrect?: boolean | null;\n}): op is Option => {\n return op.isCorrect != null;\n};\n\n/**\n * Validate alternativa (single choice) question\n * Must select exactly one correct option\n */\nconst validateAlternativa = (\n selected: Set<string>,\n options: Option[]\n): ANSWER_STATUS => {\n if (selected.size !== 1) return ANSWER_STATUS.RESPOSTA_INCORRETA;\n\n const [selectedId] = selected;\n return options.find((o) => o.id === selectedId)?.isCorrect\n ? ANSWER_STATUS.RESPOSTA_CORRETA\n : ANSWER_STATUS.RESPOSTA_INCORRETA;\n};\n\n/**\n * Validate multipla escolha (multiple choice) question\n * Each option must match its correct state: selected if correct, not selected if incorrect\n */\nconst validateMultiplaEscolha = (\n selected: Set<string>,\n options: Option[]\n): ANSWER_STATUS => {\n const allMatch = options.every((op) => selected.has(op.id) === op.isCorrect);\n\n return allMatch\n ? ANSWER_STATUS.RESPOSTA_CORRETA\n : ANSWER_STATUS.RESPOSTA_INCORRETA;\n};\n\n/**\n * Validate verdadeiro/falso (true/false) question\n * Each statement is evaluated individually: if statement is true, must be selected;\n * if statement is false, must not be selected\n */\nconst validateVerdadeiroFalso = validateMultiplaEscolha;\n\nconst validators: Partial<\n Record<QUESTION_TYPE, (s: Set<string>, o: Option[]) => ANSWER_STATUS>\n> = {\n [QUESTION_TYPE.ALTERNATIVA]: validateAlternativa,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: validateMultiplaEscolha,\n [QUESTION_TYPE.VERDADEIRO_FALSO]: validateVerdadeiroFalso,\n};\n\n/**\n * Auto-validate question based on selected options vs correct options\n * @param questionData - Correction question data\n * @returns ANSWER_STATUS if can determine, null otherwise\n */\nexport const autoValidateQuestion = (\n questionData: CorrectionQuestionData\n): ANSWER_STATUS | null => {\n const { result } = questionData;\n\n if (!canAutoValidate(questionData) || !result.options) return null;\n\n // Filter options to only include those with isCorrect defined\n const validOptions = result.options.filter(hasIsCorrect);\n if (validOptions.length === 0) return null;\n\n const selected = new Set(\n result.selectedOptions?.map((o) => o.optionId) ?? []\n );\n\n if (selected.size === 0) return ANSWER_STATUS.NAO_RESPONDIDO;\n\n const validator = validators[result.questionType];\n if (!validator) return null;\n\n return validator(selected, validOptions);\n};\n\n/**\n * Get question status from CorrectionQuestionData\n * Maps the result's answerStatus to QuestionStatus\n * If status is PENDENTE_AVALIACAO but can auto-validate, calculates status automatically\n * @param questionData - Correction question data\n * @returns QuestionStatus for UI display\n */\nexport const getQuestionStatusFromData = (\n questionData: CorrectionQuestionData\n): QuestionStatus => {\n const { result } = questionData;\n\n // If pending evaluation, try to auto-validate\n if (\n result.answerStatus === ANSWER_STATUS.PENDENTE_AVALIACAO &&\n canAutoValidate(questionData)\n ) {\n const autoValidatedStatus = autoValidateQuestion(questionData);\n if (autoValidatedStatus !== null) {\n return mapAnswerStatusToQuestionStatus(autoValidatedStatus);\n }\n }\n\n return mapAnswerStatusToQuestionStatus(result.answerStatus);\n};\n","import type { Question } from '../../components/Quiz/useQuizStore';\nimport { QUESTION_TYPE } from '../../components/Quiz/useQuizStore';\nimport type {\n QuestionsAnswersByStudentResponse,\n StudentActivityCorrectionData,\n CorrectionQuestionData,\n EssayQuestionCorrection,\n} from './types';\nimport { getIsCorrect } from './utils';\n\n/**\n * Build Question object from answer data\n * @param answer - Answer data from QuestionResult\n * @returns Question object in Quiz format\n */\nconst buildQuestionFromAnswer = (\n answer: QuestionsAnswersByStudentResponse['data']['answers'][number]\n): Question => {\n return {\n id: answer.questionId,\n statement: answer.statement,\n questionType: answer.questionType,\n difficultyLevel: answer.difficultyLevel,\n description: '',\n examBoard: null,\n examYear: null,\n solutionExplanation: answer.solutionExplanation || null,\n answer: null,\n answerStatus: answer.answerStatus,\n options: answer.options || [],\n knowledgeMatrix: answer.knowledgeMatrix.map((matrix) => ({\n areaKnowledge: matrix.areaKnowledge || {\n id: '',\n name: '',\n },\n subject: matrix.subject || {\n id: '',\n name: '',\n color: '',\n icon: '',\n },\n topic: matrix.topic || {\n id: '',\n name: '',\n },\n subtopic: matrix.subtopic || {\n id: '',\n name: '',\n },\n content: matrix.content || {\n id: '',\n name: '',\n },\n })),\n correctOptionIds:\n answer.options?.filter((opt) => opt.isCorrect).map((opt) => opt.id) || [],\n };\n};\n\n/**\n * Build correction data for essay questions\n * @param answer - Answer data from QuestionResult\n * @returns EssayQuestionCorrection if question is DISSERTATIVA, undefined otherwise\n */\nconst buildEssayCorrection = (\n answer: QuestionsAnswersByStudentResponse['data']['answers'][number]\n): EssayQuestionCorrection | undefined => {\n if (answer.questionType === QUESTION_TYPE.DISSERTATIVA) {\n return {\n isCorrect: getIsCorrect(answer.answerStatus),\n teacherFeedback: answer.teacherFeedback || '',\n };\n }\n return undefined;\n};\n\n/**\n * Convert a single answer to CorrectionQuestionData format\n * @param answer - Answer data from QuestionResult\n * @param index - Index of the answer (0-based)\n * @returns CorrectionQuestionData formatted for the modal\n */\nconst convertAnswerToQuestionData = (\n answer: QuestionsAnswersByStudentResponse['data']['answers'][number],\n index: number\n): CorrectionQuestionData => {\n const question = buildQuestionFromAnswer(answer);\n const correction = buildEssayCorrection(answer);\n\n return {\n question,\n result: answer,\n questionNumber: index + 1,\n correction,\n };\n};\n\n/**\n * Convert QuestionResult from API to StudentActivityCorrectionData\n * This function transforms the API response into the format expected by CorrectActivityModal\n * @param apiResponse - API response with answers and statistics\n * @param studentId - Student ID\n * @param studentName - Student name\n * @param observation - Optional teacher observation\n * @param attachment - Optional attachment URL\n * @returns StudentActivityCorrectionData formatted for the modal\n */\nexport const convertApiResponseToCorrectionData = (\n apiResponse: QuestionsAnswersByStudentResponse,\n studentId: string,\n studentName: string,\n observation?: string,\n attachment?: string\n): StudentActivityCorrectionData => {\n const { answers, statistics } = apiResponse.data;\n\n // Calculate counts from statistics\n const correctCount = statistics.correctAnswers;\n const incorrectCount = statistics.incorrectAnswers;\n const blankCount = statistics.totalAnswered - correctCount - incorrectCount;\n\n // Convert answers to CorrectionQuestionData format\n const questions: CorrectionQuestionData[] = answers.map((answer, index) =>\n convertAnswerToQuestionData(answer, index)\n );\n\n return {\n studentId,\n studentName,\n score: statistics.score ?? null,\n correctCount,\n incorrectCount,\n blankCount,\n questions,\n observation,\n attachment,\n };\n};\n","import { CheckCircle, XCircle } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\nimport { RadioGroup, RadioGroupItem } from '../Radio/Radio';\nimport { forwardRef, HTMLAttributes, useId, useState } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Interface para definir uma alternativa\n */\nexport interface Alternative {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n description?: string;\n}\n\n/**\n * Props do componente AlternativesList\n */\nexport interface AlternativesListProps {\n /** Lista de alternativas */\n alternatives: Alternative[];\n /** Nome do grupo de radio */\n name?: string;\n /** Valor selecionado por padrão */\n defaultValue?: string;\n /** Valor controlado */\n value?: string;\n /** Callback quando uma alternativa é selecionada */\n onValueChange?: (value: string) => void;\n /** Se o componente está desabilitado */\n disabled?: boolean;\n /** Layout das alternativas */\n layout?: 'default' | 'compact' | 'detailed';\n /** Classes CSS adicionais */\n className?: string;\n /** Modo de exibição: interativo (com radios funcionais) ou readonly (apenas visual) */\n mode?: 'interactive' | 'readonly';\n /** Valor selecionado pelo usuário (apenas para modo readonly) */\n selectedValue?: string;\n}\n\n/**\n * Componente reutilizável para exibir lista de alternativas com RadioGroup\n *\n * Suporta dois modos:\n * - `interactive`: Permite interação com radios (padrão)\n * - `readonly`: Apenas exibição visual dos estados\n *\n * @example\n * ```tsx\n * // Modo interativo (padrão)\n * <AlternativesList\n * mode=\"interactive\"\n * alternatives={[\n * { value: \"a\", label: \"Alternativa A\", status: \"correct\" },\n * { value: \"b\", label: \"Alternativa B\", status: \"incorrect\" },\n * { value: \"c\", label: \"Alternativa C\" }\n * ]}\n * defaultValue=\"a\"\n * onValueChange={(value) => console.log(value)}\n * />\n *\n * // Modo readonly - mostra seleção do usuário\n * <AlternativesList\n * mode=\"readonly\"\n * selectedValue=\"b\" // O que o usuário selecionou\n * alternatives={[\n * { value: \"a\", label: \"Resposta A\", status: \"correct\" }, // Mostra como correta\n * { value: \"b\", label: \"Resposta B\" }, // Mostra radio selecionado + badge incorreto\n * { value: \"c\", label: \"Resposta C\" }\n * ]}\n * />\n * ```\n */\nconst AlternativesList = ({\n alternatives,\n name,\n defaultValue,\n value,\n onValueChange,\n disabled = false,\n layout = 'default',\n className = '',\n mode = 'interactive',\n selectedValue,\n}: AlternativesListProps) => {\n // Gerar um ID único para garantir que cada instância tenha seu próprio grupo\n const uniqueId = useId();\n const groupName = name || `alternatives-${uniqueId}`;\n const [actualValue, setActualValue] = useState(value);\n // No modo readonly, não precisamos de interação\n const isReadonly = mode === 'readonly';\n const getStatusStyles = (\n status?: Alternative['status'],\n isReadonly?: boolean\n ) => {\n const hoverClass = isReadonly ? '' : 'hover:bg-background-50';\n\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100 ${hoverClass}`;\n }\n };\n\n const getStatusBadge = (status?: Alternative['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getLayoutClasses = () => {\n switch (layout) {\n case 'compact':\n return 'gap-2';\n case 'detailed':\n return 'gap-4';\n default:\n return 'gap-3.5';\n }\n };\n\n // Componente para renderizar alternativa no modo readonly\n const renderReadonlyAlternative = (alternative: Alternative) => {\n const alternativeId = alternative.value;\n const isUserSelected = selectedValue === alternative.value;\n const isCorrectAnswer = alternative.status === 'correct';\n\n // Determinar o status da alternativa para visualização\n let displayStatus: Alternative['status'] = undefined;\n if (isUserSelected && !isCorrectAnswer) {\n // Usuário selecionou alternativa incorreta\n displayStatus = 'incorrect';\n } else if (isCorrectAnswer) {\n // Alternativa correta (independente se foi selecionada ou não)\n displayStatus = 'correct';\n }\n\n const statusStyles = getStatusStyles(displayStatus, true);\n const statusBadge = getStatusBadge(displayStatus);\n\n // Radio visual - apenas mostra selecionado se o usuário escolheu esta alternativa\n const renderRadio = () => {\n const radioClasses = `w-6 h-6 rounded-full border-2 cursor-default transition-all duration-200 flex items-center justify-center ${\n isUserSelected\n ? 'border-primary-950 bg-background'\n : 'border-border-400 bg-background'\n }`;\n\n const dotClasses =\n 'w-3 h-3 rounded-full bg-primary-950 transition-all duration-200';\n\n return (\n <div className={radioClasses}>\n {isUserSelected && <div className={dotClasses} />}\n </div>\n );\n };\n\n if (layout === 'detailed') {\n return (\n <div\n key={alternativeId}\n className={cn(\n 'border-2 rounded-lg p-4 w-full',\n statusStyles,\n alternative.disabled ? 'opacity-50' : ''\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1\">\n <div className=\"mt-1\">{renderRadio()}</div>\n <div className=\"flex-1\">\n <p\n className={cn(\n 'block font-medium',\n selectedValue === alternative.value || statusBadge\n ? 'text-text-950'\n : 'text-text-600'\n )}\n >\n {alternative.label}\n </p>\n {alternative.description && (\n <p className=\"text-sm text-text-600 mt-1\">\n {alternative.description}\n </p>\n )}\n </div>\n </div>\n {statusBadge && <div className=\"flex-shrink-0\">{statusBadge}</div>}\n </div>\n </div>\n );\n }\n\n return (\n <div\n key={alternativeId}\n className={cn(\n 'flex flex-row justify-between items-start gap-2 p-2 rounded-lg w-full',\n statusStyles,\n alternative.disabled ? 'opacity-50' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderRadio()}\n <span\n className={cn(\n 'flex-1',\n selectedValue === alternative.value || statusBadge\n ? 'text-text-950'\n : 'text-text-600'\n )}\n >\n {alternative.label}\n </span>\n </div>\n {statusBadge && <div className=\"flex-shrink-0\">{statusBadge}</div>}\n </div>\n );\n };\n\n // Se for modo readonly, renderizar sem RadioGroup\n if (isReadonly) {\n return (\n <div\n className={cn('flex flex-col', getLayoutClasses(), 'w-full', className)}\n >\n {alternatives.map((alternative) =>\n renderReadonlyAlternative(alternative)\n )}\n </div>\n );\n }\n\n return (\n <RadioGroup\n name={groupName}\n defaultValue={defaultValue}\n value={value}\n onValueChange={(value) => {\n setActualValue(value);\n onValueChange?.(value);\n }}\n disabled={disabled}\n className={cn('flex flex-col', getLayoutClasses(), className)}\n >\n {alternatives.map((alternative, index) => {\n const alternativeId = alternative.value || `alt-${index}`;\n const statusStyles = getStatusStyles(alternative.status, false);\n const statusBadge = getStatusBadge(alternative.status);\n\n if (layout === 'detailed') {\n return (\n <div\n key={alternativeId}\n className={cn(\n 'border-2 rounded-lg p-4 transition-all',\n statusStyles,\n alternative.disabled\n ? 'opacity-50 cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1\">\n <RadioGroupItem\n value={alternative.value}\n id={alternativeId}\n disabled={alternative.disabled}\n className=\"mt-1\"\n />\n <div className=\"flex-1\">\n <label\n htmlFor={alternativeId}\n className={cn(\n 'block font-medium',\n actualValue === alternative.value\n ? 'text-text-950'\n : 'text-text-600',\n alternative.disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {alternative.label}\n </label>\n {alternative.description && (\n <p className=\"text-sm text-text-600 mt-1\">\n {alternative.description}\n </p>\n )}\n </div>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div\n key={alternativeId}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n alternative.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n <RadioGroupItem\n value={alternative.value}\n id={alternativeId}\n disabled={alternative.disabled}\n />\n <label\n htmlFor={alternativeId}\n className={cn(\n 'flex-1',\n actualValue === alternative.value\n ? 'text-text-950'\n : 'text-text-600',\n alternative.disabled ? 'cursor-not-allowed' : 'cursor-pointer'\n )}\n >\n {alternative.label}\n </label>\n </div>\n {statusBadge && <div className=\"flex-shrink-0\">{statusBadge}</div>}\n </div>\n );\n })}\n </RadioGroup>\n );\n};\n\ninterface HeaderAlternativeProps extends HTMLAttributes<HTMLDivElement> {\n title: string;\n subTitle: string;\n content: string;\n}\n\nconst HeaderAlternative = forwardRef<HTMLDivElement, HeaderAlternativeProps>(\n ({ className, title, subTitle, content, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'bg-background p-4 flex flex-col gap-4 rounded-xl',\n className\n )}\n {...props}\n >\n <span className=\"flex flex-col\">\n <p className=\"text-text-950 font-bold text-lg\">{title}</p>\n <p className=\"text-text-700 text-sm \">{subTitle}</p>\n </span>\n\n <p className=\"text-text-950 text-md\">{content}</p>\n </div>\n );\n }\n);\n\nexport { AlternativesList, HeaderAlternative };\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport { AlternativesList } from '../../../components/Alternative/Alternative';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\nimport { Status } from '../types';\n\n/**\n * Render alternative question (single choice)\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionAlternative = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n // Check if options have isCorrect defined (can auto-validate even if pending)\n const hasAutoValidation = result?.options?.some(\n (op) => op.isCorrect !== undefined && op.isCorrect !== null\n );\n\n const alternatives = question.options?.map((option) => {\n const isCorrectOption =\n result?.options?.find((op) => op.id === option.id)?.isCorrect || false;\n\n const isSelected =\n result?.selectedOptions?.some(\n (selectedOption) => selectedOption.optionId === option.id\n ) || false;\n\n // Show correct answers if not pending, OR if we can auto-validate (has isCorrect)\n const shouldShowCorrectAnswers =\n result?.answerStatus !== ANSWER_STATUS.PENDENTE_AVALIACAO ||\n hasAutoValidation;\n\n let status: Status;\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation and no auto-validation, show all options as neutral\n status = Status.NEUTRAL;\n }\n\n return {\n label: option.option,\n value: option.id,\n status: status,\n };\n });\n\n if (!alternatives || alternatives.length === 0) {\n return (\n <div>\n <Text size=\"sm\" weight=\"normal\">\n Não há Alternativas\n </Text>\n </div>\n );\n }\n\n return (\n <div className=\"pt-2\">\n <AlternativesList\n mode=\"readonly\"\n key={`question-${question.id}`}\n name={`question-${question.id}`}\n layout=\"compact\"\n alternatives={alternatives}\n selectedValue={result?.selectedOptions?.[0]?.optionId || ''}\n />\n </div>\n );\n};\n","import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '../../utils/utils';\nimport { CheckCircle, XCircle, Check } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\n\ninterface Choice {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = 'interactive',\n}: MultipleChoiceListProps) => {\n const [actualValue, setActualValue] = useState(selectedValues);\n\n useEffect(() => {\n setActualValue(selectedValues);\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n <div className={checkboxClasses}>\n {isSelected && <Check size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, choice.disabled || disabled)}\n <span\n className={cn(\n 'flex-1',\n isSelected || (choice.status && choice.status != 'neutral')\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-default'\n )}\n >\n {choice.label}\n </span>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className=\"flex flex-row gap-2 items-center\"\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {choice.label}\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport { MultipleChoiceList } from '../../../components/MultipleChoice/MultipleChoice';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\nimport { Status } from '../types';\n\n/**\n * Render multiple choice question\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionMultipleChoice = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n // Check if options have isCorrect defined (can auto-validate even if pending)\n const hasAutoValidation = result?.options?.some(\n (op) => op.isCorrect !== undefined && op.isCorrect !== null\n );\n\n const choices = question.options?.map((option) => {\n const isCorrectOption =\n result?.options?.find((op) => op.id === option.id)?.isCorrect || false;\n\n const isSelected = result?.selectedOptions?.some(\n (op) => op.optionId === option.id\n );\n\n // Show correct/incorrect status if not pending/blank, OR if we can auto-validate (has isCorrect)\n const shouldShowCorrectAnswers =\n (result?.answerStatus !== ANSWER_STATUS.PENDENTE_AVALIACAO &&\n result?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO) ||\n hasAutoValidation;\n\n let status: Status;\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation and no auto-validation, show all options as neutral\n status = Status.NEUTRAL;\n }\n\n return {\n label: option.option,\n value: option.id,\n status,\n };\n });\n\n if (!choices || choices.length === 0) {\n return (\n <div>\n <Text size=\"sm\" weight=\"normal\">\n Não há Escolhas Múltiplas\n </Text>\n </div>\n );\n }\n\n const selectedValues =\n result?.selectedOptions?.map((op) => op.optionId) || [];\n\n return (\n <div className=\"pt-2\">\n <MultipleChoiceList\n mode=\"readonly\"\n key={`question-${question.id}`}\n name={`question-${question.id}`}\n choices={choices}\n selectedValues={selectedValues}\n />\n </div>\n );\n};\n","import {\n forwardRef,\n MouseEvent,\n ReactNode,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { ANSWER_STATUS, useQuizStore } from './useQuizStore';\nimport { cn } from '../../utils/utils';\nimport Select, {\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../Select/Select';\nimport TextArea from '../TextArea/TextArea';\nimport { AlternativesList } from '../Alternative/Alternative';\nimport { MultipleChoiceList } from '../MultipleChoice/MultipleChoice';\nimport Badge from '../Badge/Badge';\nimport { CheckCircle, XCircle } from 'phosphor-react';\nimport ImageQuestion from '../../assets/img/mock-image-question.png';\n\nexport const getStatusBadge = (status?: 'correct' | 'incorrect') => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n};\n\nexport const getStatusStyles = (variantCorrect?: string) => {\n switch (variantCorrect) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return '';\n }\n};\n\nenum Status {\n CORRECT = 'correct',\n INCORRECT = 'incorrect',\n NEUTRAL = 'neutral',\n}\n\ninterface QuizVariantInterface {\n paddingBottom?: string;\n}\n\nconst QuizSubTitle = forwardRef<HTMLDivElement, { subTitle: string }>(\n ({ subTitle, ...props }, ref) => {\n return (\n <div className=\"px-4 pb-2 pt-6\" {...props} ref={ref}>\n <p className=\"font-bold text-lg text-text-950\">{subTitle}</p>\n </div>\n );\n }\n);\n\nconst QuizContainer = forwardRef<\n HTMLDivElement,\n { children: ReactNode; className?: string }\n>(({ children, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'bg-background rounded-t-xl px-4 pt-4 pb-[80px] h-auto flex flex-col gap-4 mb-auto',\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n});\n\nconst QuizAlternative = ({ paddingBottom }: QuizVariantInterface) => {\n const {\n getCurrentQuestion,\n selectAnswer,\n getQuestionResultByQuestionId,\n getCurrentAnswer,\n variant,\n } = useQuizStore();\n const currentQuestion = getCurrentQuestion();\n const currentQuestionResult = getQuestionResultByQuestionId(\n currentQuestion?.id || ''\n );\n\n const currentAnswer = getCurrentAnswer();\n const alternatives = currentQuestion?.options?.map((option) => {\n let status: Status = Status.NEUTRAL;\n if (variant === 'result') {\n const isCorrectOption =\n currentQuestionResult?.options?.find((op) => op.id === option.id)\n ?.isCorrect || false;\n\n const isSelected = currentQuestionResult?.selectedOptions.some(\n (selectedOption) => selectedOption.optionId === option.id\n );\n\n // Only show correct/incorrect status if answer is not pending evaluation\n const shouldShowCorrectAnswers =\n currentQuestionResult?.answerStatus !==\n ANSWER_STATUS.PENDENTE_AVALIACAO &&\n currentQuestionResult?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO;\n\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation, show all options as neutral\n status = Status.NEUTRAL;\n }\n }\n\n return {\n label: option.option,\n value: option.id,\n status: status,\n };\n });\n\n if (!alternatives)\n return (\n <div>\n <p>Não há Alternativas</p>\n </div>\n );\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"space-y-4\">\n <AlternativesList\n mode={variant === 'default' ? 'interactive' : 'readonly'}\n key={`question-${currentQuestion?.id || '1'}`}\n name={`question-${currentQuestion?.id || '1'}`}\n layout=\"compact\"\n alternatives={alternatives}\n value={\n variant === 'result'\n ? currentQuestionResult?.selectedOptions[0]?.optionId || ''\n : currentAnswer?.optionId || ''\n }\n selectedValue={\n variant === 'result'\n ? currentQuestionResult?.selectedOptions[0]?.optionId || ''\n : currentAnswer?.optionId || ''\n }\n onValueChange={(value) => {\n if (currentQuestion) {\n selectAnswer(currentQuestion.id, value);\n }\n }}\n />\n </div>\n </QuizContainer>\n </>\n );\n};\n\nconst QuizMultipleChoice = ({ paddingBottom }: QuizVariantInterface) => {\n const {\n getCurrentQuestion,\n selectMultipleAnswer,\n getAllCurrentAnswer,\n getQuestionResultByQuestionId,\n variant,\n } = useQuizStore();\n const currentQuestion = getCurrentQuestion();\n const allCurrentAnswers = getAllCurrentAnswer();\n const currentQuestionResult = getQuestionResultByQuestionId(\n currentQuestion?.id || ''\n );\n // Use ref to track previous values and prevent unnecessary updates\n const prevSelectedValuesRef = useRef<string[]>([]);\n const prevQuestionIdRef = useRef<string>('');\n\n // Memoize the answer IDs to prevent unnecessary re-renders\n const allCurrentAnswerIds = useMemo(() => {\n return allCurrentAnswers?.map((answer) => answer.optionId) || [];\n }, [allCurrentAnswers]);\n\n // Memoize the selected values to prevent infinite loops\n const selectedValues = useMemo(() => {\n return allCurrentAnswerIds?.filter((id): id is string => id !== null) || [];\n }, [allCurrentAnswerIds]);\n\n // Only update selectedValues if they actually changed or question changed\n const stableSelectedValues = useMemo(() => {\n const currentQuestionId = currentQuestion?.id || '';\n const hasQuestionChanged = prevQuestionIdRef.current !== currentQuestionId;\n\n if (hasQuestionChanged) {\n prevQuestionIdRef.current = currentQuestionId;\n prevSelectedValuesRef.current = selectedValues;\n return selectedValues;\n }\n\n // Only update if values actually changed\n const hasValuesChanged =\n JSON.stringify(prevSelectedValuesRef.current) !==\n JSON.stringify(selectedValues);\n if (hasValuesChanged) {\n prevSelectedValuesRef.current = selectedValues;\n return selectedValues;\n }\n\n if (variant == 'result') {\n return (\n currentQuestionResult?.selectedOptions.map((op) => op.optionId) || []\n );\n } else {\n return prevSelectedValuesRef.current;\n }\n }, [\n selectedValues,\n currentQuestion?.id,\n variant,\n currentQuestionResult?.selectedOptions,\n ]);\n\n // Memoize the callback to prevent unnecessary re-renders\n const handleSelectedValues = useCallback(\n (values: string[]) => {\n if (currentQuestion) {\n selectMultipleAnswer(currentQuestion.id, values);\n }\n },\n [currentQuestion, selectMultipleAnswer]\n );\n\n // Create a stable key to force re-mount when question changes\n const questionKey = useMemo(\n () => `question-${currentQuestion?.id || '1'}`,\n [currentQuestion?.id]\n );\n const choices = currentQuestion?.options?.map((option) => {\n let status: Status = Status.NEUTRAL;\n\n if (variant === 'result') {\n const isCorrectOption =\n currentQuestionResult?.options?.find((op) => op.id === option.id)\n ?.isCorrect || false;\n\n const isSelected = currentQuestionResult?.selectedOptions?.some(\n (op) => op.optionId === option.id\n );\n\n // Only show correct/incorrect status if answer is not pending evaluation\n const shouldShowCorrectAnswers =\n currentQuestionResult?.answerStatus !==\n ANSWER_STATUS.PENDENTE_AVALIACAO &&\n currentQuestionResult?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO;\n\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation, show all options as neutral\n status = Status.NEUTRAL;\n }\n }\n\n return {\n label: option.option,\n value: option.id,\n status: status,\n };\n });\n\n if (!choices)\n return (\n <div>\n <p>Não há Escolhas Multiplas</p>\n </div>\n );\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"space-y-4\">\n <MultipleChoiceList\n choices={choices}\n key={questionKey}\n name={questionKey}\n selectedValues={stableSelectedValues}\n onHandleSelectedValues={handleSelectedValues}\n mode={variant === 'default' ? 'interactive' : 'readonly'}\n />\n </div>\n </QuizContainer>\n </>\n );\n};\n\nconst QuizDissertative = ({ paddingBottom }: QuizVariantInterface) => {\n const {\n getCurrentQuestion,\n getCurrentAnswer,\n selectDissertativeAnswer,\n getQuestionResultByQuestionId,\n variant,\n getDissertativeCharLimit,\n } = useQuizStore();\n\n const currentQuestion = getCurrentQuestion();\n const currentQuestionResult = getQuestionResultByQuestionId(\n currentQuestion?.id || ''\n );\n\n const currentAnswer = getCurrentAnswer();\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const charLimit = getDissertativeCharLimit();\n\n const handleAnswerChange = (value: string) => {\n if (currentQuestion) {\n selectDissertativeAnswer(currentQuestion.id, value);\n }\n };\n\n // Auto-resize function\n const adjustTextareaHeight = useCallback(() => {\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n const scrollHeight = textareaRef.current.scrollHeight;\n const minHeight = 120; // 120px minimum height\n const maxHeight = 400; // 400px maximum height\n const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight);\n textareaRef.current.style.height = `${newHeight}px`;\n }\n }, []);\n\n // Adjust height when currentAnswer changes\n useEffect(() => {\n adjustTextareaHeight();\n }, [currentAnswer, adjustTextareaHeight]);\n\n if (!currentQuestion) {\n return (\n <div className=\"space-y-4\">\n <p className=\"text-text-600 text-md\">Nenhuma questão disponível</p>\n </div>\n );\n }\n\n const localAnswer =\n (variant == 'result'\n ? currentQuestionResult?.answer\n : currentAnswer?.answer) || '';\n return (\n <>\n <QuizSubTitle subTitle=\"Resposta\" />\n\n <QuizContainer className={cn(variant != 'result' && paddingBottom)}>\n <div className=\"space-y-4 max-h-[600px] overflow-y-auto\">\n {variant === 'default' ? (\n <div className=\"space-y-4\">\n <TextArea\n ref={textareaRef}\n placeholder=\"Escreva sua resposta\"\n value={localAnswer}\n onChange={(e) => handleAnswerChange(e.target.value)}\n rows={4}\n className=\"min-h-[120px] max-h-[400px] resize-none overflow-y-auto\"\n maxLength={charLimit}\n showCharacterCount={!!charLimit}\n />\n </div>\n ) : (\n <div className=\"space-y-4\">\n <p className=\"text-text-600 text-md whitespace-pre-wrap\">\n {localAnswer || 'Nenhuma resposta fornecida'}\n </p>\n </div>\n )}\n </div>\n </QuizContainer>\n\n {variant === 'result' &&\n currentQuestionResult?.answerStatus ==\n ANSWER_STATUS.RESPOSTA_INCORRETA && (\n <>\n <QuizSubTitle subTitle=\"Observação do professor\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <p className=\"text-text-600 text-md whitespace-pre-wrap\">\n {currentQuestionResult?.teacherFeedback}\n </p>\n </QuizContainer>\n </>\n )}\n </>\n );\n};\n\nconst QuizTrueOrFalse = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const options = [\n {\n label: '25 metros',\n isCorrect: true,\n },\n {\n label: '30 metros',\n isCorrect: false,\n },\n {\n label: '40 metros',\n isCorrect: false,\n },\n {\n label: '50 metros',\n isCorrect: false,\n },\n ];\n\n const getLetterByIndex = (index: number) => String.fromCodePoint(97 + index); // 97 = 'a' in ASCII\n\n const isDefaultVariant = variant === 'default';\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"flex flex-col gap-3.5\">\n {options.map((option, index) => {\n const variantCorrect = option.isCorrect ? 'correct' : 'incorrect';\n return (\n <section\n key={option.label.concat(`-${index}`)}\n className=\"flex flex-col gap-2\"\n >\n <div\n className={cn(\n 'flex flex-row justify-between items-center gap-2 p-2 rounded-md',\n isDefaultVariant ? '' : getStatusStyles(variantCorrect)\n )}\n >\n <p className=\"text-text-900 text-sm\">\n {getLetterByIndex(index).concat(') ').concat(option.label)}\n </p>\n\n {isDefaultVariant ? (\n <Select size=\"medium\">\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue placeholder=\"Selecione opcão\" />\n </SelectTrigger>\n\n <SelectContent>\n <SelectItem value=\"V\">Verdadeiro</SelectItem>\n <SelectItem value=\"F\">Falso</SelectItem>\n </SelectContent>\n </Select>\n ) : (\n <div className=\"flex-shrink-0\">\n {getStatusBadge(variantCorrect)}\n </div>\n )}\n </div>\n\n {!isDefaultVariant && (\n <span className=\"flex flex-row gap-2 items-center\">\n <p className=\"text-text-800 text-2xs\">\n Resposta selecionada: V\n </p>\n {!option.isCorrect && (\n <p className=\"text-text-800 text-2xs\">\n Resposta correta: F\n </p>\n )}\n </span>\n )}\n </section>\n );\n })}\n </div>\n </QuizContainer>\n </>\n );\n};\n\ninterface UserAnswer {\n option: string;\n dotOption: string | null;\n correctOption: string;\n isCorrect: boolean | null;\n}\n\nconst QuizConnectDots = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const dotsOptions = [\n { label: 'Ração' },\n { label: 'Rato' },\n { label: 'Grama' },\n { label: 'Peixe' },\n ];\n\n const options = [\n {\n label: 'Cachorro',\n correctOption: 'Ração',\n },\n {\n label: 'Gato',\n correctOption: 'Rato',\n },\n {\n label: 'Cabra',\n correctOption: 'Grama',\n },\n {\n label: 'Baleia',\n correctOption: 'Peixe',\n },\n ];\n\n const mockUserAnswers = [\n {\n option: 'Cachorro',\n dotOption: 'Ração',\n correctOption: 'Ração',\n isCorrect: true,\n },\n {\n option: 'Gato',\n dotOption: 'Rato',\n correctOption: 'Rato',\n isCorrect: true,\n },\n {\n option: 'Cabra',\n dotOption: 'Peixe',\n correctOption: 'Grama',\n isCorrect: false,\n },\n {\n option: 'Baleia',\n dotOption: 'Grama',\n correctOption: 'Peixe',\n isCorrect: false,\n },\n ];\n\n const [userAnswers, setUserAnswers] = useState<UserAnswer[]>(() => {\n if (variant === 'result') {\n return mockUserAnswers;\n }\n return options.map((option) => ({\n option: option.label,\n dotOption: null,\n correctOption: option.correctOption,\n isCorrect: null,\n }));\n });\n\n const handleSelectDot = (optionIndex: number, dotValue: string) => {\n setUserAnswers((prev) => {\n const next = [...prev];\n const { label: optionLabel, correctOption } = options[optionIndex];\n next[optionIndex] = {\n option: optionLabel,\n dotOption: dotValue,\n correctOption,\n isCorrect: dotValue ? dotValue === correctOption : null,\n };\n return next;\n });\n };\n\n const getLetterByIndex = (index: number) => String.fromCodePoint(97 + index); // 'a', 'b', 'c'...\n\n const isDefaultVariant = variant === 'default';\n const assignedDots = new Set(\n userAnswers.map((a) => a.dotOption).filter(Boolean)\n );\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"flex flex-col gap-3.5\">\n {options.map((option, index) => {\n const answer = userAnswers[index];\n const variantCorrect = answer.isCorrect ? 'correct' : 'incorrect';\n return (\n <section key={option.label} className=\"flex flex-col gap-2\">\n <div\n className={cn(\n 'flex flex-row justify-between items-center gap-2 p-2 rounded-md',\n isDefaultVariant ? '' : getStatusStyles(variantCorrect)\n )}\n >\n <p className=\"text-text-900 text-sm\">\n {getLetterByIndex(index) + ') ' + option.label}\n </p>\n\n {isDefaultVariant ? (\n <Select\n size=\"medium\"\n value={answer.dotOption || undefined}\n onValueChange={(value) => handleSelectDot(index, value)}\n >\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue placeholder=\"Selecione opção\" />\n </SelectTrigger>\n\n <SelectContent>\n {dotsOptions\n .filter(\n (dot) =>\n !assignedDots.has(dot.label) ||\n answer.dotOption === dot.label\n )\n .map((dot) => (\n <SelectItem key={dot.label} value={dot.label}>\n {dot.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <div className=\"flex-shrink-0\">\n {answer.isCorrect === null\n ? null\n : getStatusBadge(variantCorrect)}\n </div>\n )}\n </div>\n\n {!isDefaultVariant && (\n <span className=\"flex flex-row gap-2 items-center\">\n <p className=\"text-text-800 text-2xs\">\n Resposta selecionada: {answer.dotOption || 'Nenhuma'}\n </p>\n {!answer.isCorrect && (\n <p className=\"text-text-800 text-2xs\">\n Resposta correta: {answer.correctOption}\n </p>\n )}\n </span>\n )}\n </section>\n );\n })}\n </div>\n </QuizContainer>\n </>\n );\n};\n\ninterface FillUserAnswer {\n selectId: string;\n userAnswer: string;\n correctAnswer: string;\n isCorrect: boolean;\n}\n\nconst QuizFill = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const options = [\n 'ciência',\n 'disciplina',\n 'área',\n 'especialidade',\n 'variações',\n ];\n\n const exampleText = `A meteorologia é a {{ciencia}} que estuda os fenômenos atmosféricos e suas {{variações}}. Esta disciplina científica tem como objetivo principal {{objetivo}} o comportamento da atmosfera terrestre.\n\n Os meteorologistas utilizam diversos {{instrumentos}} para coletar dados atmosféricos, incluindo termômetros, barômetros e {{equipamentos}} modernos como radares meteorológicos.`;\n\n // Mock data for result variant - simulating user answers\n const mockUserAnswers: FillUserAnswer[] = [\n {\n selectId: 'ciencia',\n userAnswer: 'tecnologia',\n correctAnswer: 'ciência',\n isCorrect: false,\n },\n {\n selectId: 'variações',\n userAnswer: 'variações',\n correctAnswer: 'variações',\n isCorrect: true,\n },\n {\n selectId: 'objetivo',\n userAnswer: 'estudar',\n correctAnswer: 'compreender',\n isCorrect: false,\n },\n {\n selectId: 'instrumentos',\n userAnswer: 'ferramentas',\n correctAnswer: 'instrumentos',\n isCorrect: false,\n },\n {\n selectId: 'equipamentos',\n userAnswer: 'equipamentos',\n correctAnswer: 'equipamentos',\n isCorrect: true,\n },\n ];\n\n const [answers, setAnswers] = useState<Record<string, string>>({});\n const baseId = useId(); // Generate base ID for this component instance\n\n // Get available options for a specific select\n const getAvailableOptionsForSelect = (selectId: string) => {\n const usedOptions = new Set(\n Object.entries(answers)\n .filter(([key]) => key !== selectId) // Exclude the current selection itself\n .map(([, value]) => value)\n );\n\n return options.filter((option) => !usedOptions.has(option));\n };\n\n const handleSelectChange = (selectId: string, value: string) => {\n const newAnswers = { ...answers, [selectId]: value };\n setAnswers(newAnswers);\n };\n\n const renderResolutionElement = (selectId: string) => {\n const mockAnswer = mockUserAnswers.find(\n (answer) => answer.selectId === selectId\n );\n\n return (\n <p className=\"inline-flex mb-2.5 text-success-600 font-semibold text-md border-b-2 border-success-600\">\n {mockAnswer?.correctAnswer}\n </p>\n );\n };\n\n const renderDefaultElement = (\n selectId: string,\n startIndex: number,\n selectedValue: string,\n availableOptionsForThisSelect: string[]\n ) => {\n return (\n <Select\n key={`${selectId}-${startIndex}`}\n value={selectedValue}\n onValueChange={(value) => handleSelectChange(selectId, value)}\n className=\"inline-flex mb-2.5\"\n >\n <SelectTrigger className=\"inline-flex w-auto min-w-[140px] h-8 mx-1 bg-background border-gray-300\">\n <SelectValue placeholder=\"Selecione opção\" />\n </SelectTrigger>\n <SelectContent>\n {availableOptionsForThisSelect.map((option, index) => (\n <SelectItem key={`${option}-${index}`} value={option}>\n {option}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n };\n\n const renderResultElement = (selectId: string) => {\n const mockAnswer = mockUserAnswers.find(\n (answer) => answer.selectId === selectId\n );\n\n if (!mockAnswer) return null;\n\n const action = mockAnswer.isCorrect ? 'success' : 'error';\n const icon = mockAnswer.isCorrect ? <CheckCircle /> : <XCircle />;\n\n return (\n <Badge\n key={selectId}\n variant=\"solid\"\n action={action}\n iconRight={icon}\n size=\"large\"\n className=\"py-3 w-[180px] justify-between mb-2.5\"\n >\n <span className=\"text-text-900\">{mockAnswer.userAnswer}</span>\n </Badge>\n );\n };\n\n const renderTextWithSelects = (text: string, isResolution?: boolean) => {\n const elements: Array<{ element: string | ReactNode; id: string }> = [];\n let lastIndex = 0;\n let elementCounter = 0;\n\n // Support Unicode letters/marks and digits: allows placeholders like {{variações}}\n const regex = /\\{\\{([\\p{L}\\p{M}\\d_]+)\\}\\}/gu;\n let match;\n\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, selectId] = match;\n const startIndex = match.index;\n\n if (startIndex > lastIndex) {\n elements.push({\n element: text.slice(lastIndex, startIndex),\n id: `${baseId}-text-${++elementCounter}`,\n });\n }\n\n const selectedValue = answers[selectId];\n const availableOptionsForThisSelect =\n getAvailableOptionsForSelect(selectId);\n\n if (isResolution) {\n elements.push({\n element: renderResolutionElement(selectId),\n id: `${baseId}-resolution-${++elementCounter}`,\n });\n } else if (variant === 'default') {\n elements.push({\n element: renderDefaultElement(\n selectId,\n startIndex,\n selectedValue,\n availableOptionsForThisSelect\n ),\n id: `${baseId}-select-${++elementCounter}`,\n });\n } else {\n const resultElement = renderResultElement(selectId);\n if (resultElement) {\n elements.push({\n element: resultElement,\n id: `${baseId}-result-${++elementCounter}`,\n });\n }\n }\n\n lastIndex = match.index + fullMatch.length;\n }\n\n if (lastIndex < text.length) {\n elements.push({\n element: text.slice(lastIndex),\n id: `${baseId}-text-${++elementCounter}`,\n });\n }\n\n return elements;\n };\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className=\"h-auto pb-0\">\n <div className=\"space-y-6 px-4 h-auto\">\n <div\n className={cn(\n 'text-lg text-text-900 leading-8 h-auto',\n variant != 'result' && paddingBottom\n )}\n >\n {renderTextWithSelects(exampleText).map((element) => (\n <span key={element.id}>{element.element}</span>\n ))}\n </div>\n </div>\n </QuizContainer>\n\n {variant === 'result' && (\n <>\n <QuizSubTitle subTitle=\"Resultado\" />\n\n <QuizContainer className=\"h-auto pb-0\">\n <div className=\"space-y-6 px-4\">\n <div\n className={cn('text-lg text-text-900 leading-8', paddingBottom)}\n >\n {renderTextWithSelects(exampleText, true).map((element) => (\n <span key={element.id}>{element.element}</span>\n ))}\n </div>\n </div>\n </QuizContainer>\n </>\n )}\n </>\n );\n};\n\nconst QuizImageQuestion = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const correctPositionRelative = { x: 0.48, y: 0.45 };\n\n // Calculate correctRadiusRelative automatically based on the circle dimensions\n const calculateCorrectRadiusRelative = (): number => {\n // The correct answer circle has width: 15% and height: 30%\n // We'll use the average of these as the radius\n const circleWidthRelative = 0.15; // 15%\n const circleHeightRelative = 0.3; // 30%\n\n // Calculate the average radius (half of the average of width and height)\n const averageRadius = (circleWidthRelative + circleHeightRelative) / 4;\n\n // Add a small tolerance for better user experience\n const tolerance = 0.02; // 2% tolerance\n\n return averageRadius + tolerance;\n };\n\n const correctRadiusRelative = calculateCorrectRadiusRelative();\n const mockUserAnswerRelative = { x: 0.72, y: 0.348 };\n\n const [clickPositionRelative, setClickPositionRelative] = useState<{\n x: number;\n y: number;\n } | null>(variant == 'result' ? mockUserAnswerRelative : null);\n\n // Helper function to safely convert click coordinates to relative coordinates\n const convertToRelativeCoordinates = (\n x: number,\n y: number,\n rect: DOMRect\n ): { x: number; y: number } => {\n // Guard against division by zero or extremely small dimensions\n const safeWidth = Math.max(rect.width, 0.001);\n const safeHeight = Math.max(rect.height, 0.001);\n\n // Convert to relative coordinates and clamp to [0, 1] range\n const xRelative = Math.max(0, Math.min(1, x / safeWidth));\n const yRelative = Math.max(0, Math.min(1, y / safeHeight));\n\n return { x: xRelative, y: yRelative };\n };\n\n const handleImageClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (variant === 'result') return;\n\n const rect = event.currentTarget.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n\n // Use helper function for safe conversion\n const positionRelative = convertToRelativeCoordinates(x, y, rect);\n setClickPositionRelative(positionRelative);\n };\n\n const handleKeyboardActivate = () => {\n if (variant === 'result') return;\n // Choose a deterministic position for keyboard activation; center is a reasonable default\n setClickPositionRelative({ x: 0.5, y: 0.5 });\n };\n\n const isCorrect = () => {\n if (!clickPositionRelative) return false;\n\n const distance = Math.sqrt(\n Math.pow(clickPositionRelative.x - correctPositionRelative.x, 2) +\n Math.pow(clickPositionRelative.y - correctPositionRelative.y, 2)\n );\n\n return distance <= correctRadiusRelative;\n };\n\n const getUserCircleColorClasses = () => {\n if (variant === 'default') {\n return 'bg-indicator-primary/70 border-[#F8CC2E]';\n }\n\n if (variant === 'result') {\n return isCorrect()\n ? 'bg-success-600/70 border-white' // Green for correct answer\n : 'bg-indicator-error/70 border-white'; // Red for incorrect answer\n }\n\n return 'bg-success-600/70 border-white';\n };\n\n return (\n <>\n <QuizSubTitle subTitle=\"Clique na área correta\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div\n data-testid=\"quiz-image-container\"\n className=\"space-y-6 p-3 relative inline-block\"\n >\n {variant == 'result' && (\n <div\n data-testid=\"quiz-legend\"\n className=\"flex items-center gap-4 text-xs\"\n >\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-primary/70 border border-[#F8CC2E]\"></div>\n <span className=\"text-text-600 font-medium text-sm\">\n Área correta\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-success-600/70 border border-white\"></div>\n <span className=\"text-text-600 font-medium text-sm\">\n Resposta correta\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-error/70 border border-white\"></div>\n <span className=\"text-text-600 font-medium text-sm\">\n Resposta incorreta\n </span>\n </div>\n </div>\n )}\n\n <button\n data-testid=\"quiz-image-button\"\n type=\"button\"\n className=\"relative cursor-pointer w-full h-full border-0 bg-transparent p-0\"\n onClick={handleImageClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleKeyboardActivate();\n }\n }}\n aria-label=\"Área da imagem interativa\"\n >\n <img\n data-testid=\"quiz-image\"\n src={ImageQuestion}\n alt=\"Question\"\n className=\"w-full h-auto rounded-md\"\n />\n\n {/* Correct answer circle - only show in result variant */}\n {variant === 'result' && (\n <div\n data-testid=\"quiz-correct-circle\"\n className=\"absolute rounded-full bg-indicator-primary/70 border-4 border-[#F8CC2E] pointer-events-none\"\n style={{\n minWidth: '50px',\n maxWidth: '160px',\n width: '15%',\n aspectRatio: '1 / 1',\n left: `calc(${correctPositionRelative.x * 100}% - 7.5%)`,\n top: `calc(${correctPositionRelative.y * 100}% - 15%)`,\n }}\n />\n )}\n\n {/* User's answer circle */}\n {clickPositionRelative && (\n <div\n data-testid=\"quiz-user-circle\"\n className={`absolute rounded-full border-4 pointer-events-none ${getUserCircleColorClasses()}`}\n style={{\n minWidth: '30px',\n maxWidth: '52px',\n width: '5%',\n aspectRatio: '1 / 1',\n left: `calc(${clickPositionRelative.x * 100}% - 2.5%)`,\n top: `calc(${clickPositionRelative.y * 100}% - 2.5%)`,\n }}\n />\n )}\n </button>\n </div>\n </QuizContainer>\n </>\n );\n};\n\nexport {\n QuizSubTitle,\n QuizContainer,\n QuizMultipleChoice,\n QuizDissertative,\n QuizTrueOrFalse,\n QuizConnectDots,\n QuizFill,\n QuizImageQuestion,\n QuizAlternative,\n};\n","import { useId, type ReactNode } from 'react';\nimport Badge from '../../../components/Badge/Badge';\nimport { CheckCircle, XCircle } from 'phosphor-react';\nimport { cn } from '../../utils';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\n\n/**\n * Get status badge component\n */\nexport const getStatusBadge = (status?: 'correct' | 'incorrect'): ReactNode => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n};\n\n/**\n * Container component for question content\n */\nexport const QuestionContainer = ({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) => {\n return (\n <div\n className={cn(\n 'bg-background rounded-t-xl px-4 pt-4 pb-[80px] h-auto flex flex-col gap-4 mb-auto',\n className\n )}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Subtitle component for question sections\n */\nexport const QuestionSubTitle = ({ subTitle }: { subTitle: string }) => {\n return (\n <div className=\"px-4 pb-2 pt-6\">\n <Text size=\"md\" weight=\"bold\" color=\"text-text-950\">\n {subTitle}\n </Text>\n </div>\n );\n};\n\n/**\n * Internal component for fill in the blanks question\n * Uses useId hook to generate unique IDs\n */\nexport const FillQuestionContent = ({\n question,\n result,\n}: QuestionRendererProps) => {\n // Extract text from statement - it should contain {{placeholders}}\n const text = question.statement || '';\n const baseId = useId();\n\n // Parse student answer - assuming it's stored in result.answer as JSON or structured data\n // For now, we'll need to extract from the answer field\n // The answer might be structured or we need to parse placeholders from the statement\n const studentAnswers: Record<\n string,\n { answer: string; isCorrect: boolean; correctAnswer: string }\n > = {};\n\n // Try to parse answer if it's JSON, otherwise use empty object\n try {\n if (result?.answer) {\n const parsed =\n typeof result.answer === 'string'\n ? JSON.parse(result.answer)\n : result.answer;\n if (typeof parsed === 'object') {\n Object.assign(studentAnswers, parsed);\n }\n }\n } catch (error) {\n console.error('Error parsing answer:', error);\n }\n\n // Extract placeholders from text\n const regex = /\\{\\{([\\p{L}\\p{M}\\d_]+)\\}\\}/gu;\n const placeholders: string[] = [];\n let match;\n while ((match = regex.exec(text)) !== null) {\n placeholders.push(match[1]);\n }\n\n // Build correct answers from studentAnswers - use the already-parsed correctAnswer field\n const correctAnswers: Record<string, string> = {};\n placeholders.forEach((placeholder) => {\n correctAnswers[placeholder] =\n studentAnswers[placeholder]?.correctAnswer || `[${placeholder}]`;\n });\n\n /**\n * Add text element to elements array\n */\n const addTextElement = (\n elements: Array<{ element: string | ReactNode; id: string }>,\n textContent: string,\n elementCounter: { current: number }\n ) => {\n if (textContent) {\n elements.push({\n element: textContent,\n id: `${baseId}-text-${++elementCounter.current}`,\n });\n }\n };\n\n /**\n * Render placeholder for gabarito (correct answer)\n */\n const renderGabaritoPlaceholder = (\n selectId: string,\n elementCounter: { current: number }\n ): { element: ReactNode; id: string } => {\n const correctAnswer = correctAnswers[selectId] || `[${selectId}]`;\n return {\n element: (\n <Text\n key={`${baseId}-gabarito-${selectId}`}\n size=\"md\"\n weight=\"semibold\"\n color=\"text-success-600\"\n className=\"inline-flex mb-2.5 border-b-2 border-success-600\"\n >\n {correctAnswer}\n </Text>\n ),\n id: `${baseId}-gabarito-${++elementCounter.current}`,\n };\n };\n\n /**\n * Render placeholder for student answer\n */\n const renderStudentPlaceholder = (\n selectId: string,\n elementCounter: { current: number }\n ): { element: ReactNode; id: string } => {\n const studentAnswer = studentAnswers[selectId];\n if (!studentAnswer) {\n return {\n element: (\n <Text\n key={`${baseId}-no-answer-${selectId}`}\n size=\"md\"\n weight=\"normal\"\n color=\"text-text-400\"\n className=\"inline-flex mb-2.5 border-b-2 border-text-300\"\n >\n [Não respondido]\n </Text>\n ),\n id: `${baseId}-no-answer-${++elementCounter.current}`,\n };\n }\n\n const isCorrect = studentAnswer.isCorrect;\n const colorClass = isCorrect\n ? 'text-success-600 border-success-600'\n : 'text-error-600 border-error-600';\n\n return {\n element: (\n <Badge\n key={`${baseId}-answer-${selectId}`}\n variant=\"solid\"\n action={isCorrect ? 'success' : 'error'}\n iconRight={isCorrect ? <CheckCircle /> : <XCircle />}\n size=\"large\"\n className={`py-3 w-[180px] justify-between mb-2.5 ${colorClass}`}\n >\n <span className=\"text-text-900\">{studentAnswer.answer}</span>\n </Badge>\n ),\n id: `${baseId}-answer-${++elementCounter.current}`,\n };\n };\n\n /**\n * Render text with answers or gabarito\n */\n const renderTextWithAnswers = (isGabarito = false) => {\n const elements: Array<{ element: string | ReactNode; id: string }> = [];\n let lastIndex = 0;\n const elementCounter = { current: 0 };\n\n regex.lastIndex = 0; // Reset regex\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, selectId] = match;\n const startIndex = match.index;\n\n // Add text before placeholder\n if (startIndex > lastIndex) {\n addTextElement(\n elements,\n text.slice(lastIndex, startIndex),\n elementCounter\n );\n }\n\n // Add placeholder element\n const placeholderElement = isGabarito\n ? renderGabaritoPlaceholder(selectId, elementCounter)\n : renderStudentPlaceholder(selectId, elementCounter);\n elements.push(placeholderElement);\n\n lastIndex = match.index + fullMatch.length;\n }\n\n // Add remaining text after last placeholder\n if (lastIndex < text.length) {\n addTextElement(elements, text.slice(lastIndex), elementCounter);\n }\n\n return elements;\n };\n\n return (\n <div className=\"pt-2 space-y-4\">\n <div className=\"space-y-2\">\n <Text size=\"xs\" weight=\"normal\" color=\"text-text-500\">\n Resposta do aluno:\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <div className=\"leading-8\">\n {renderTextWithAnswers(false).map((element) => (\n <Text\n key={element.id}\n size=\"md\"\n weight=\"normal\"\n color=\"text-text-900\"\n >\n {element.element}\n </Text>\n ))}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Text size=\"xs\" weight=\"normal\" color=\"text-text-500\">\n Gabarito:\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <div className=\"leading-8\">\n {renderTextWithAnswers(true).map((element) => (\n <Text\n key={element.id}\n size=\"md\"\n weight=\"normal\"\n color=\"text-text-900\"\n >\n {element.element}\n </Text>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport { getStatusStyles } from '../../../components/Quiz/QuizContent';\nimport Text from '../../../components/Text/Text';\nimport { cn } from '../../../utils/utils';\nimport type { QuestionRendererProps } from '../types';\nimport { getStatusBadge } from '../components';\n\n/**\n * Render true or false question\n * Each option has a statement, and student marks V or F for each\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionTrueOrFalse = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n const options = question.options || [];\n const getLetterByIndex = (index: number) => String.fromCodePoint(97 + index); // 97 = 'a' in ASCII\n\n const shouldShowStatus =\n result?.answerStatus !== ANSWER_STATUS.PENDENTE_AVALIACAO &&\n result?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO;\n\n return (\n <div className=\"pt-2\">\n <div className=\"flex flex-col gap-3.5\">\n {options.map((option, index) => {\n // In true/false, isCorrect indicates if the statement is TRUE\n const statementIsTrue =\n result?.options?.find((op) => op.id === option.id)?.isCorrect ||\n false;\n const isSelected = result?.selectedOptions?.some(\n (op) => op.optionId === option.id\n );\n\n // Determine if student's answer is correct\n // If statement is true and selected, or statement is false and not selected\n const isStudentCorrect = statementIsTrue === isSelected;\n\n const variantCorrect = statementIsTrue ? 'correct' : 'incorrect';\n const studentAnswer = isSelected ? 'V' : 'F';\n const correctAnswer = statementIsTrue ? 'V' : 'F';\n\n return (\n <section\n key={option.id || `option-${index}`}\n className=\"flex flex-col gap-2\"\n >\n <div\n className={cn(\n 'flex flex-row justify-between items-center gap-2 p-2 rounded-md border',\n shouldShowStatus ? getStatusStyles(variantCorrect) : ''\n )}\n >\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-900\">\n {getLetterByIndex(index).concat(') ').concat(option.option)}\n </Text>\n\n {shouldShowStatus && (\n <div className=\"flex-shrink-0\">\n {getStatusBadge(isStudentCorrect ? 'correct' : 'incorrect')}\n </div>\n )}\n </div>\n\n {shouldShowStatus && (\n <span className=\"flex flex-row gap-2 items-center\">\n <Text size=\"2xs\" weight=\"normal\" color=\"text-text-800\">\n Resposta selecionada: {studentAnswer}\n </Text>\n {!isStudentCorrect && (\n <Text size=\"2xs\" weight=\"normal\" color=\"text-text-800\">\n Resposta correta: {correctAnswer}\n </Text>\n )}\n </span>\n )}\n </section>\n );\n })}\n </div>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\n\n/**\n * Render essay/dissertative question (readonly mode for correction)\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionDissertative = ({\n result,\n}: Omit<QuestionRendererProps, 'question'>): ReactNode => {\n const localAnswer = result?.answer || '';\n\n return (\n <div className=\"pt-2 space-y-4\">\n <div className=\"space-y-2\">\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-950\">\n Resposta do aluno\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-700\">\n {localAnswer || 'Nenhuma resposta fornecida'}\n </Text>\n </div>\n </div>\n\n {result?.answerStatus === ANSWER_STATUS.RESPOSTA_INCORRETA &&\n result?.teacherFeedback && (\n <div className=\"space-y-2\">\n <Text size=\"xs\" weight=\"normal\" color=\"text-text-500\">\n Observação do professor:\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-700\">\n {result.teacherFeedback}\n </Text>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport type { QuestionRendererProps } from '../types';\nimport { FillQuestionContent } from '../components';\n\n/**\n * Render fill in the blanks question\n * Shows text with student answers highlighted (green if correct, red if wrong)\n * Also shows a \"gabarito\" section with correct answers\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionFill = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n return <FillQuestionContent question={question} result={result} />;\n};\n","import type { ReactNode } from 'react';\nimport ImageQuestion from '../../../assets/img/mock-image-question.png';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\n\n/**\n * Render image question\n * Shows image with clickable area, correct answer circle, and user's answer circle\n */\nexport const renderQuestionImage = ({\n result,\n}: Omit<QuestionRendererProps, 'question'>): ReactNode => {\n // Extract position data from result or question\n // Assuming correct position is stored in question metadata or result\n const correctPositionRelative = { x: 0.48, y: 0.45 }; // Default, should come from question data\n const correctRadiusRelative = 0.1; // Default radius\n\n // Get user's answer position from result\n // This would typically be stored in result.answer as coordinates\n let userPositionRelative: { x: number; y: number } | null = null;\n try {\n if (result?.answer) {\n const parsed =\n typeof result.answer === 'string'\n ? JSON.parse(result.answer)\n : result.answer;\n if (\n parsed &&\n typeof parsed.x === 'number' &&\n typeof parsed.y === 'number'\n ) {\n userPositionRelative = { x: parsed.x, y: parsed.y };\n }\n }\n } catch {\n userPositionRelative = null;\n }\n\n // Determine if answer is correct (within radius)\n const isCorrect = userPositionRelative\n ? Math.sqrt(\n Math.pow(userPositionRelative.x - correctPositionRelative.x, 2) +\n Math.pow(userPositionRelative.y - correctPositionRelative.y, 2)\n ) <= correctRadiusRelative\n : false;\n\n const getUserCircleColorClasses = () => {\n if (!userPositionRelative) return '';\n return isCorrect\n ? 'bg-success-600/70 border-white'\n : 'bg-indicator-error/70 border-white';\n };\n\n // Calculate position descriptions for accessibility\n const getPositionDescription = (x: number, y: number): string => {\n const xPercent = Math.round(x * 100);\n const yPercent = Math.round(y * 100);\n return `${xPercent}% da esquerda, ${yPercent}% do topo`;\n };\n\n const getSpatialRelationship = (): string => {\n if (!userPositionRelative) {\n return `Área correta localizada em ${getPositionDescription(\n correctPositionRelative.x,\n correctPositionRelative.y\n )}. Nenhuma resposta do aluno fornecida.`;\n }\n\n const deltaX = userPositionRelative.x - correctPositionRelative.x;\n const deltaY = userPositionRelative.y - correctPositionRelative.y;\n const distance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));\n const distancePercent = Math.round(distance * 100);\n\n let direction = '';\n if (Math.abs(deltaX) > Math.abs(deltaY)) {\n direction = deltaX > 0 ? 'à direita' : 'à esquerda';\n } else {\n direction = deltaY > 0 ? 'abaixo' : 'acima';\n }\n\n const correctPos = getPositionDescription(\n correctPositionRelative.x,\n correctPositionRelative.y\n );\n const userPos = getPositionDescription(\n userPositionRelative.x,\n userPositionRelative.y\n );\n\n return `Área correta localizada em ${correctPos}. Resposta do aluno em ${userPos}. A resposta do aluno está ${distancePercent}% de distância ${direction} da área correta. ${isCorrect ? 'A resposta está dentro da área de tolerância e é considerada correta.' : 'A resposta está fora da área de tolerância e é considerada incorreta.'}`;\n };\n\n const correctPositionDescription = getPositionDescription(\n correctPositionRelative.x,\n correctPositionRelative.y\n );\n const imageAltText = `Questão de imagem com área correta localizada em ${correctPositionDescription}`;\n\n return (\n <div className=\"pt-2 space-y-4\">\n {/* Legend */}\n <div className=\"flex items-center gap-4 text-xs\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-primary/70 border border-[#F8CC2E]\"></div>\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-600\">\n Área correta\n </Text>\n </div>\n {userPositionRelative && (\n <>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-success-600/70 border border-white\"></div>\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-600\">\n Resposta correta\n </Text>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-error/70 border border-white\"></div>\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-600\">\n Resposta incorreta\n </Text>\n </div>\n </>\n )}\n </div>\n\n {/* Image container */}\n <div className=\"relative w-full\">\n {/* Hidden text summary for screen readers */}\n <div className=\"sr-only\">{getSpatialRelationship()}</div>\n\n <img\n src={ImageQuestion}\n alt={imageAltText}\n className=\"w-full h-auto rounded-md\"\n />\n\n {/* Correct answer circle */}\n <div\n role=\"img\"\n aria-label={`Área correta marcada em ${correctPositionDescription}`}\n className=\"absolute rounded-full bg-indicator-primary/70 border-4 border-[#F8CC2E] pointer-events-none\"\n style={{\n minWidth: '50px',\n maxWidth: '160px',\n width: '15%',\n aspectRatio: '1 / 1',\n left: `calc(${correctPositionRelative.x * 100}% - 7.5%)`,\n top: `calc(${correctPositionRelative.y * 100}% - 15%)`,\n }}\n >\n <Text\n size=\"sm\"\n weight=\"normal\"\n color=\"text-text-600\"\n className=\"sr-only\"\n >\n Círculo amarelo indicando a área correta da resposta, posicionado em{' '}\n {correctPositionDescription}\n </Text>\n </div>\n\n {/* User's answer circle */}\n {userPositionRelative && (\n <div\n role=\"img\"\n aria-label={`Resposta do aluno marcada em ${getPositionDescription(\n userPositionRelative.x,\n userPositionRelative.y\n )}, ${isCorrect ? 'correta' : 'incorreta'}`}\n className={`absolute rounded-full border-4 pointer-events-none ${getUserCircleColorClasses()}`}\n style={{\n minWidth: '30px',\n maxWidth: '52px',\n width: '5%',\n aspectRatio: '1 / 1',\n left: `calc(${userPositionRelative.x * 100}% - 2.5%)`,\n top: `calc(${userPositionRelative.y * 100}% - 2.5%)`,\n }}\n >\n <Text\n size=\"sm\"\n weight=\"normal\"\n color=\"text-text-600\"\n className=\"sr-only\"\n >\n Círculo {isCorrect ? 'verde' : 'vermelho'} indicando a resposta do\n aluno, posicionado em{' '}\n {getPositionDescription(\n userPositionRelative.x,\n userPositionRelative.y\n )}\n . A resposta está{' '}\n {Math.round(\n Math.sqrt(\n Math.pow(\n userPositionRelative.x - correctPositionRelative.x,\n 2\n ) +\n Math.pow(\n userPositionRelative.y - correctPositionRelative.y,\n 2\n )\n ) * 100\n )}\n % de distância da área correta e é considerada{' '}\n {isCorrect ? 'correta' : 'incorreta'}.\n </Text>\n </div>\n )}\n </div>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport { cn } from '../../../utils/utils';\nimport Text from '../../../components/Text/Text';\nimport { QuestionSubTitle, QuestionContainer } from '../components';\n\n/**\n * Render connect dots question (not implemented)\n */\nexport const renderQuestionConnectDots = ({\n paddingBottom,\n}: {\n paddingBottom?: string;\n} = {}): ReactNode => {\n return (\n <>\n <QuestionSubTitle subTitle=\"Tipo de questão: Ligar Pontos\" />\n <QuestionContainer className={cn('', paddingBottom)}>\n <div className=\"space-y-4\">\n <Text size=\"md\" weight=\"normal\" color=\"text-text-600\">\n Tipo de questão: Ligar Pontos (não implementado)\n </Text>\n </div>\n </QuestionContainer>\n </>\n );\n};\n","import type { ReactNode } from 'react';\nimport { QUESTION_TYPE } from '../../components/Quiz/useQuizStore';\nimport { renderQuestionAlternative } from './alternative';\nimport { renderQuestionMultipleChoice } from './multipleChoice';\nimport { renderQuestionTrueOrFalse } from './trueOrFalse';\nimport { renderQuestionDissertative } from './dissertative';\nimport { renderQuestionFill } from './fill';\nimport { renderQuestionImage } from './image';\nimport { renderQuestionConnectDots } from './connectDots';\nimport type { QuestionRendererProps } from './types';\n\n// Re-export types\nexport type { QuestionRendererProps } from './types';\nexport { Status } from './types';\n\n// Re-export components\nexport {\n getStatusBadge,\n QuestionContainer,\n QuestionSubTitle,\n FillQuestionContent,\n} from './components';\n\n// Re-export individual renderers\nexport { renderQuestionAlternative } from './alternative';\nexport { renderQuestionMultipleChoice } from './multipleChoice';\nexport { renderQuestionTrueOrFalse } from './trueOrFalse';\nexport { renderQuestionDissertative } from './dissertative';\nexport { renderQuestionFill } from './fill';\nexport { renderQuestionImage } from './image';\nexport { renderQuestionConnectDots } from './connectDots';\n\n/**\n * Map question types to their render functions\n */\nconst questionRendererMap = {\n [QUESTION_TYPE.ALTERNATIVA]: renderQuestionAlternative,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: renderQuestionMultipleChoice,\n [QUESTION_TYPE.VERDADEIRO_FALSO]: renderQuestionTrueOrFalse,\n [QUESTION_TYPE.DISSERTATIVA]: renderQuestionDissertative,\n [QUESTION_TYPE.PREENCHER]: renderQuestionFill,\n [QUESTION_TYPE.IMAGEM]: renderQuestionImage,\n [QUESTION_TYPE.LIGAR_PONTOS]: renderQuestionConnectDots,\n};\n\n/**\n * Render question based on question type\n * @param props - Question renderer props\n * @returns Rendered question content\n */\nexport const renderQuestion = (props: QuestionRendererProps): ReactNode => {\n const { question } = props;\n const renderer = questionRendererMap[question.questionType];\n\n if (!renderer) {\n // Fallback: try to render based on options presence\n if (question.options && question.options.length > 0) {\n return renderQuestionAlternative(props);\n }\n return renderQuestionDissertative({ result: props.result });\n }\n\n // Handle renderers with different prop requirements\n switch (question.questionType) {\n case QUESTION_TYPE.DISSERTATIVA:\n return renderQuestionDissertative({ result: props.result });\n case QUESTION_TYPE.IMAGEM:\n return renderQuestionImage({ result: props.result });\n case QUESTION_TYPE.LIGAR_PONTOS:\n return renderQuestionConnectDots({ paddingBottom: '' });\n case QUESTION_TYPE.ALTERNATIVA:\n case QUESTION_TYPE.MULTIPLA_ESCOLHA:\n case QUESTION_TYPE.VERDADEIRO_FALSO:\n case QUESTION_TYPE.PREENCHER:\n return renderer(props);\n default:\n return null;\n }\n};\n\n/**\n * Type for question renderer map\n */\nexport type QuestionRendererMap = Record<QUESTION_TYPE, () => ReactNode>;\n\n/**\n * Render from a map of renderers\n * @param renderers - Map of question type to render function\n * @param questionType - Type of question to render\n * @returns Rendered content or null\n */\nexport const renderFromMap = (\n renderers: QuestionRendererMap,\n questionType?: QUESTION_TYPE\n) => {\n if (!questionType) return null;\n const renderer = renderers[questionType];\n return renderer ? renderer() : null;\n};\n","import { useState, useEffect } from 'react';\n\n// Mobile width in pixels\nconst MOBILE_WIDTH = 500;\n// Tablet width in pixels\nconst TABLET_WIDTH = 931;\n// Video responsive breakpoints\nconst SMALL_MOBILE_WIDTH = 425;\nconst EXTRA_SMALL_MOBILE_WIDTH = 375;\nconst ULTRA_SMALL_MOBILE_WIDTH = 375; // For video controls\nconst TINY_MOBILE_WIDTH = 320;\n// Default desktop width for SSR\nconst DEFAULT_WIDTH = 1200;\n\n/**\n * Device type based on screen width\n */\nexport type DeviceType = 'responsive' | 'desktop';\n\n/**\n * Gets the window width safely (SSR compatible)\n * @returns {number} window width or default value for SSR\n */\nconst getWindowWidth = (): number => {\n if (typeof window === 'undefined') {\n return DEFAULT_WIDTH;\n }\n return window.innerWidth;\n};\n\n/**\n * Gets the current device type based on screen width\n * @returns {DeviceType} 'responsive' for mobile/tablet (width < 931px), 'desktop' for larger screens\n */\nexport const getDeviceType = (): DeviceType => {\n const width = getWindowWidth();\n return width < TABLET_WIDTH ? 'responsive' : 'desktop';\n};\n\n/**\n * Hook to detect screen size and get responsive classes\n * @returns object with isMobile, isTablet, responsive class functions and getDeviceType\n */\nexport const useMobile = () => {\n const [isMobile, setIsMobile] = useState(false);\n const [isTablet, setIsTablet] = useState(false);\n const [isSmallMobile, setIsSmallMobile] = useState(false);\n const [isExtraSmallMobile, setIsExtraSmallMobile] = useState(false);\n const [isUltraSmallMobile, setIsUltraSmallMobile] = useState(false);\n const [isTinyMobile, setIsTinyMobile] = useState(false);\n\n useEffect(() => {\n const checkScreenSize = () => {\n const width = getWindowWidth();\n setIsMobile(width < MOBILE_WIDTH);\n setIsTablet(width < TABLET_WIDTH);\n setIsSmallMobile(width < SMALL_MOBILE_WIDTH);\n setIsExtraSmallMobile(width < EXTRA_SMALL_MOBILE_WIDTH);\n setIsUltraSmallMobile(width < ULTRA_SMALL_MOBILE_WIDTH);\n setIsTinyMobile(width < TINY_MOBILE_WIDTH);\n };\n\n checkScreenSize();\n\n window.addEventListener('resize', checkScreenSize);\n\n return () => window.removeEventListener('resize', checkScreenSize);\n }, []);\n\n /**\n * Get responsive classes for the form container\n * @returns className string for form container based on screen size\n */\n const getFormContainerClasses = (): string => {\n if (isMobile) {\n return 'w-full px-4';\n }\n if (isTablet) {\n return 'w-full px-6';\n }\n return 'w-full max-w-[992px] mx-auto px-0';\n };\n\n /**\n * Get mobile-specific classes for the header\n * @returns className string for mobile header layout\n */\n const getMobileHeaderClasses = (): string => {\n return 'flex flex-col items-start gap-4 mb-6';\n };\n\n /**\n * Get desktop-specific classes for the header\n * @returns className string for desktop header layout\n */\n const getDesktopHeaderClasses = (): string => {\n return 'flex flex-row justify-between items-center gap-6 mb-8';\n };\n\n /**\n * Get responsive classes for the header\n * @returns className string for header based on screen size\n */\n const getHeaderClasses = (): string => {\n return isMobile ? getMobileHeaderClasses() : getDesktopHeaderClasses();\n };\n\n /**\n * Get responsive classes for video container\n * @returns className string for video container aspect ratio based on screen size\n */\n const getVideoContainerClasses = (): string => {\n if (isTinyMobile) return 'aspect-square'; // 1:1 ratio for screens < 320px\n if (isExtraSmallMobile) return 'aspect-[4/3]'; // 4:3 ratio for screens < 375px\n if (isSmallMobile) return 'aspect-[16/12]'; // 16:12 ratio for screens < 425px\n return 'aspect-video'; // 16:9 ratio for larger screens\n };\n\n return {\n isMobile,\n isTablet,\n isSmallMobile,\n isExtraSmallMobile,\n isUltraSmallMobile,\n isTinyMobile,\n getFormContainerClasses,\n getHeaderClasses,\n getMobileHeaderClasses,\n getDesktopHeaderClasses,\n getVideoContainerClasses,\n getDeviceType,\n };\n};\n","export const BookOpenText = ({\n size,\n color,\n}: {\n size: number;\n color: string;\n}) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M29 6H20C19.2238 6 18.4582 6.18073 17.7639 6.52786C17.0697 6.875 16.4657 7.37902 16 8C15.5343 7.37902 14.9303 6.875 14.2361 6.52786C13.5418 6.18073 12.7762 6 12 6H3C2.73478 6 2.48043 6.10536 2.29289 6.29289C2.10536 6.48043 2 6.73478 2 7V25C2 25.2652 2.10536 25.5196 2.29289 25.7071C2.48043 25.8946 2.73478 26 3 26H12C12.7956 26 13.5587 26.3161 14.1213 26.8787C14.6839 27.4413 15 28.2044 15 29C15 29.2652 15.1054 29.5196 15.2929 29.7071C15.4804 29.8946 15.7348 30 16 30C16.2652 30 16.5196 29.8946 16.7071 29.7071C16.8946 29.5196 17 29.2652 17 29C17 28.2044 17.3161 27.4413 17.8787 26.8787C18.4413 26.3161 19.2044 26 20 26H29C29.2652 26 29.5196 25.8946 29.7071 25.7071C29.8946 25.5196 30 25.2652 30 25V7C30 6.73478 29.8946 6.48043 29.7071 6.29289C29.5196 6.10536 29.2652 6 29 6ZM12 24H4V8H12C12.7956 8 13.5587 8.31607 14.1213 8.87868C14.6839 9.44129 15 10.2044 15 11V25C14.1353 24.3493 13.0821 23.9983 12 24ZM28 24H20C18.9179 23.9983 17.8647 24.3493 17 25V11C17 10.2044 17.3161 9.44129 17.8787 8.87868C18.4413 8.31607 19.2044 8 20 8H28V24ZM20 11H25C25.2652 11 25.5196 11.1054 25.7071 11.2929C25.8946 11.4804 26 11.7348 26 12C26 12.2652 25.8946 12.5196 25.7071 12.7071C25.5196 12.8946 25.2652 13 25 13H20C19.7348 13 19.4804 12.8946 19.2929 12.7071C19.1054 12.5196 19 12.2652 19 12C19 11.7348 19.1054 11.4804 19.2929 11.2929C19.4804 11.1054 19.7348 11 20 11ZM26 16C26 16.2652 25.8946 16.5196 25.7071 16.7071C25.5196 16.8946 25.2652 17 25 17H20C19.7348 17 19.4804 16.8946 19.2929 16.7071C19.1054 16.5196 19 16.2652 19 16C19 15.7348 19.1054 15.4804 19.2929 15.2929C19.4804 15.1054 19.7348 15 20 15H25C25.2652 15 25.5196 15.1054 25.7071 15.2929C25.8946 15.4804 26 15.7348 26 16ZM26 20C26 20.2652 25.8946 20.5196 25.7071 20.7071C25.5196 20.8946 25.2652 21 25 21H20C19.7348 21 19.4804 20.8946 19.2929 20.7071C19.1054 20.5196 19 20.2652 19 20C19 19.7348 19.1054 19.4804 19.2929 19.2929C19.4804 19.1054 19.7348 19 20 19H25C25.2652 19 25.5196 19.1054 25.7071 19.2929C25.8946 19.4804 26 19.7348 26 20Z\"\n fill={color}\n />\n </svg>\n);\n","export const HeadCircuit = ({\n size,\n color,\n}: {\n size: number;\n color: string;\n}) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M24.0625 21.4338C25.327 20.3715 26.3372 19.0392 27.0187 17.5348C27.7001 16.0304 28.0354 14.3924 28 12.7413C27.875 7.02751 23.2987 2.31626 17.595 2.01626C16.1233 1.93616 14.6506 2.15261 13.2642 2.65277C11.8778 3.15293 10.6061 3.92659 9.52453 4.92781C8.44297 5.92903 7.57365 7.13739 6.96819 8.48112C6.36272 9.82485 6.03347 11.2766 5.99997 12.75L3.19372 18.1475C3.18247 18.17 3.17122 18.1925 3.16122 18.215C2.96003 18.6839 2.94569 19.212 3.12114 19.6912C3.29659 20.1704 3.64855 20.5644 4.10497 20.7925L4.13622 20.8063L6.99997 22.1175V26C6.99997 26.5304 7.21068 27.0392 7.58576 27.4142C7.96083 27.7893 8.46954 28 8.99997 28H15C15.2652 28 15.5195 27.8947 15.7071 27.7071C15.8946 27.5196 16 27.2652 16 27C16 26.7348 15.8946 26.4804 15.7071 26.2929C15.5195 26.1054 15.2652 26 15 26H8.99997V21.4763C9.00011 21.2846 8.94517 21.0969 8.84168 20.9356C8.73818 20.7742 8.5905 20.646 8.41622 20.5663L4.99997 19L7.88372 13.4575C7.95889 13.3166 7.99878 13.1597 7.99997 13C7.99968 10.9604 8.69216 8.98124 9.96395 7.38674C11.2357 5.79224 13.0114 4.677 15 4.22376V6.17251C14.3328 6.4084 13.7704 6.87258 13.4123 7.48299C13.0543 8.0934 12.9235 8.81075 13.0432 9.50824C13.1628 10.2057 13.5252 10.8385 14.0663 11.2946C14.6074 11.7508 15.2923 12.0009 16 12.0009C16.7077 12.0009 17.3926 11.7508 17.9336 11.2946C18.4747 10.8385 18.8371 10.2057 18.9568 9.50824C19.0764 8.81075 18.9457 8.0934 18.5876 7.48299C18.2295 6.87258 17.6672 6.4084 17 6.17251V4.00001C17.1625 4.00001 17.325 4.00001 17.4875 4.01251C19.2608 4.11409 20.9649 4.73627 22.3864 5.80124C23.808 6.86621 24.8841 8.32669 25.48 10H23C22.8533 9.99995 22.7084 10.0322 22.5755 10.0944C22.4426 10.1566 22.3251 10.2473 22.2312 10.36L19.0425 14.1875C18.3774 13.9397 17.6462 13.9351 16.9781 14.1744C16.3099 14.4138 15.748 14.8817 15.3916 15.4954C15.0352 16.1092 14.9073 16.8292 15.0306 17.5281C15.1538 18.227 15.5203 18.8598 16.0652 19.3146C16.61 19.7694 17.2981 20.0168 18.0078 20.0132C18.7175 20.0095 19.4031 19.755 19.9432 19.2947C20.4834 18.8343 20.8433 18.1977 20.9594 17.4976C21.0754 16.7974 20.9402 16.0788 20.5775 15.4688L23.4687 12H25.9425C25.9725 12.26 25.9908 12.5225 25.9975 12.7875C26.0286 14.2198 25.7187 15.639 25.0931 16.9278C24.4676 18.2167 23.5445 19.3383 22.4 20.2C22.2589 20.3057 22.1484 20.4469 22.0794 20.6091C22.0105 20.7713 21.9857 20.9489 22.0075 21.1238L23.0075 29.1238C23.0379 29.3653 23.1554 29.5874 23.3379 29.7485C23.5203 29.9095 23.7553 29.9985 23.9987 29.9988C24.0405 29.9988 24.0822 29.9962 24.1237 29.9913C24.2541 29.975 24.3799 29.9333 24.4942 29.8684C24.6084 29.8035 24.7087 29.7168 24.7893 29.6131C24.87 29.5094 24.9295 29.3909 24.9643 29.2643C24.9992 29.1376 25.0087 29.0054 24.9925 28.875L24.0625 21.4338ZM16 10C15.8022 10 15.6088 9.94136 15.4444 9.83148C15.28 9.7216 15.1518 9.56542 15.0761 9.38269C15.0004 9.19997 14.9806 8.9989 15.0192 8.80492C15.0578 8.61094 15.153 8.43275 15.2929 8.2929C15.4327 8.15305 15.6109 8.05781 15.8049 8.01922C15.9989 7.98064 16.1999 8.00044 16.3827 8.07613C16.5654 8.15182 16.7216 8.27999 16.8314 8.44444C16.9413 8.60889 17 8.80223 17 9.00001C17 9.26523 16.8946 9.51958 16.7071 9.70712C16.5195 9.89465 16.2652 10 16 10ZM18 18C17.8022 18 17.6088 17.9414 17.4444 17.8315C17.28 17.7216 17.1518 17.5654 17.0761 17.3827C17.0004 17.2 16.9806 16.9989 17.0192 16.8049C17.0578 16.6109 17.153 16.4328 17.2929 16.2929C17.4327 16.153 17.6109 16.0578 17.8049 16.0192C17.9989 15.9806 18.1999 16.0004 18.3827 16.0761C18.5654 16.1518 18.7216 16.28 18.8314 16.4444C18.9413 16.6089 19 16.8022 19 17C19 17.2652 18.8946 17.5196 18.7071 17.7071C18.5195 17.8947 18.2652 18 18 18Z\"\n fill={color}\n />\n </svg>\n);\n","export const Microscope = ({\n size,\n color,\n}: {\n size: number;\n color: string;\n}) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M28 26H25.4925C26.7637 24.4552 27.5898 22.5932 27.882 20.6142C28.1743 18.6351 27.9216 16.6138 27.1511 14.7676C26.3806 12.9213 25.1215 11.32 23.5092 10.1358C21.8968 8.95153 19.9922 8.22913 18 8.04625V4C18 3.46957 17.7893 2.96086 17.4142 2.58579C17.0391 2.21071 16.5304 2 16 2H10C9.46957 2 8.96086 2.21071 8.58579 2.58579C8.21071 2.96086 8 3.46957 8 4V17C8 17.5304 8.21071 18.0391 8.58579 18.4142C8.96086 18.7893 9.46957 19 10 19H16C16.5304 19 17.0391 18.7893 17.4142 18.4142C17.7893 18.0391 18 17.5304 18 17V10.0575C19.7643 10.2552 21.4306 10.9703 22.7895 12.1128C24.1483 13.2553 25.1389 14.7742 25.6366 16.4783C26.1343 18.1824 26.1169 19.9957 25.5866 21.69C25.0563 23.3842 24.0368 24.8838 22.6562 26H4C3.73478 26 3.48043 26.1054 3.29289 26.2929C3.10536 26.4804 3 26.7348 3 27C3 27.2652 3.10536 27.5196 3.29289 27.7071C3.48043 27.8946 3.73478 28 4 28H28C28.2652 28 28.5196 27.8946 28.7071 27.7071C28.8946 27.5196 29 27.2652 29 27C29 26.7348 28.8946 26.4804 28.7071 26.2929C28.5196 26.1054 28.2652 26 28 26ZM16 17H10V4H16V17ZM9 23C8.73478 23 8.48043 22.8946 8.29289 22.7071C8.10536 22.5196 8 22.2652 8 22C8 21.7348 8.10536 21.4804 8.29289 21.2929C8.48043 21.1054 8.73478 21 9 21H17C17.2652 21 17.5196 21.1054 17.7071 21.2929C17.8946 21.4804 18 21.7348 18 22C18 22.2652 17.8946 22.5196 17.7071 22.7071C17.5196 22.8946 17.2652 23 17 23H9Z\"\n fill={color}\n />\n </svg>\n);\n","import { BookOpenText } from '../../assets/icons/subjects/BookOpenText';\nimport { ChatEN } from '../../assets/icons/subjects/ChatEN';\nimport { ChatES } from '../../assets/icons/subjects/ChatES';\nimport { ChatPT } from '../../assets/icons/subjects/ChatPT';\nimport { HeadCircuit } from '../../assets/icons/subjects/HeadCircuit';\nimport { Microscope } from '../../assets/icons/subjects/Microscope';\nimport { SubjectEnum } from '../../enums/SubjectEnum';\nimport {\n ArticleNyTimes,\n Atom,\n Book,\n BookBookmark,\n DribbbleLogo,\n Flask,\n GlobeHemisphereWest,\n MathOperations,\n Palette,\n Person,\n Scroll,\n} from 'phosphor-react';\nimport { ReactElement } from 'react';\nexport interface IconProps {\n size?: number;\n color?: string;\n}\n\nexport interface SubjectData {\n icon: ReactElement<IconProps>;\n colorClass: string;\n name: string;\n}\n\nexport const SubjectInfo: Record<SubjectEnum, SubjectData> = {\n [SubjectEnum.FISICA]: {\n icon: <Atom size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-1',\n name: SubjectEnum.FISICA,\n },\n [SubjectEnum.HISTORIA]: {\n icon: <Scroll size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-2',\n name: SubjectEnum.HISTORIA,\n },\n [SubjectEnum.LITERATURA]: {\n icon: <BookOpenText size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-3',\n name: SubjectEnum.LITERATURA,\n },\n [SubjectEnum.GEOGRAFIA]: {\n icon: <GlobeHemisphereWest size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-4',\n name: SubjectEnum.GEOGRAFIA,\n },\n [SubjectEnum.BIOLOGIA]: {\n icon: <Microscope size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-5',\n name: SubjectEnum.BIOLOGIA,\n },\n [SubjectEnum.PORTUGUES]: {\n icon: <ChatPT size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-6',\n name: SubjectEnum.PORTUGUES,\n },\n [SubjectEnum.QUIMICA]: {\n icon: <Flask size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-7',\n name: SubjectEnum.QUIMICA,\n },\n [SubjectEnum.ARTES]: {\n icon: <Palette size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-8',\n name: SubjectEnum.ARTES,\n },\n [SubjectEnum.MATEMATICA]: {\n icon: <MathOperations size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-9',\n name: SubjectEnum.MATEMATICA,\n },\n [SubjectEnum.FILOSOFIA]: {\n icon: <HeadCircuit size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-10',\n name: SubjectEnum.FILOSOFIA,\n },\n [SubjectEnum.ESPANHOL]: {\n icon: <ChatES size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-11',\n name: SubjectEnum.ESPANHOL,\n },\n [SubjectEnum.REDACAO]: {\n icon: <ArticleNyTimes size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-12',\n name: SubjectEnum.REDACAO,\n },\n [SubjectEnum.SOCIOLOGIA]: {\n icon: <Person size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-13',\n name: SubjectEnum.SOCIOLOGIA,\n },\n [SubjectEnum.INGLES]: {\n icon: <ChatEN size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-14',\n name: SubjectEnum.INGLES,\n },\n [SubjectEnum.EDUCACAO_FISICA]: {\n icon: <DribbbleLogo size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-15',\n name: SubjectEnum.EDUCACAO_FISICA,\n },\n [SubjectEnum.TRILHAS]: {\n icon: <BookBookmark size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-16',\n name: SubjectEnum.TRILHAS,\n },\n};\n\nexport const getSubjectInfo = (subject: SubjectEnum): SubjectData => {\n return (\n SubjectInfo[subject] || {\n icon: <Book size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-16',\n name: subject,\n }\n );\n};\n\nexport const getSubjectIcon = (subject: SubjectEnum): ReactElement => {\n return SubjectInfo[subject].icon;\n};\n\nexport const getSubjectColorClass = (subject: SubjectEnum): string => {\n return SubjectInfo[subject].colorClass;\n};\n\nexport const getSubjectName = (subject: SubjectEnum): string => {\n return SubjectInfo[subject].name;\n};\n","import { useState, useCallback } from 'react';\nimport type { BaseApiClient } from '../types/api';\nimport type {\n QuestionsFilterBody,\n QuestionsListResponseActivity,\n QuestionsByIdsBody,\n QuestionsByIdsResponse,\n Question,\n Pagination,\n PaginationActivity,\n} from '../types/questions';\n\n// ============================================================================\n// Hook State Types\n// ============================================================================\n\n/**\n * Hook state interface\n */\ninterface UseQuestionsListState {\n questions: Question[];\n pagination: Pagination | null;\n loading: boolean;\n loadingMore: boolean;\n error: string | null;\n currentFilters: Partial<QuestionsFilterBody> | null;\n}\n\n// ============================================================================\n// Hook Return Type\n// ============================================================================\n\n/**\n * Hook return type\n */\nexport interface UseQuestionsListReturn extends UseQuestionsListState {\n fetchQuestions: (\n filters?: Partial<QuestionsFilterBody>,\n append?: boolean\n ) => Promise<void>;\n fetchRandomQuestions: (\n count: number,\n filters?: Partial<QuestionsFilterBody>\n ) => Promise<Question[]>;\n fetchQuestionsByIds: (questionIds: string[]) => Promise<Question[]>;\n loadMore: () => Promise<void>;\n reset: () => void;\n}\n\n// ============================================================================\n// Main Hook Implementation\n// ============================================================================\n\nconst useQuestionsListImpl = (\n apiClient: BaseApiClient\n): UseQuestionsListReturn => {\n const [state, setState] = useState<UseQuestionsListState>({\n questions: [],\n pagination: null,\n loading: false,\n loadingMore: false,\n error: null,\n currentFilters: null,\n });\n\n const updateState = useCallback((updates: Partial<UseQuestionsListState>) => {\n setState((prev) => ({ ...prev, ...updates }));\n }, []);\n\n const handleError = useCallback(\n (error: unknown) => {\n console.error('Erro ao carregar questões:', error);\n let errorMessage = 'Erro ao carregar questões';\n\n if (error && typeof error === 'object' && 'response' in error) {\n const axiosError = error as {\n response?: { data?: { message?: string } };\n message?: string;\n };\n errorMessage =\n axiosError?.response?.data?.message ||\n axiosError?.message ||\n errorMessage;\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n updateState({\n loading: false,\n loadingMore: false,\n error: errorMessage,\n });\n },\n [updateState]\n );\n\n /**\n * Convert PaginationActivity to Pagination format\n */\n const convertPagination = (\n pagination: PaginationActivity | undefined\n ): Pagination | null => {\n if (!pagination) return null;\n return {\n page: pagination.page,\n pageSize: pagination.limit,\n total: pagination.total,\n totalPages: pagination.totalPages,\n hasNext: pagination.hasNext,\n hasPrevious: pagination.hasPrev,\n };\n };\n\n /**\n * Fetch questions from API with filters\n * @param filters - Filters to apply\n * @param append - If true, appends results to existing questions; if false, replaces them\n */\n const fetchQuestions = useCallback(\n async (filters?: Partial<QuestionsFilterBody>, append: boolean = false) => {\n if (append) {\n setState((prev) => ({ ...prev, loadingMore: true, error: null }));\n } else {\n updateState({ loading: true, error: null, questions: [] });\n }\n\n try {\n const validatedFilters: QuestionsFilterBody = {\n ...filters,\n };\n\n const response = await apiClient.post<QuestionsListResponseActivity>(\n '/questions/list',\n validatedFilters\n );\n\n setState((prev) => ({\n loading: false,\n loadingMore: false,\n questions: append\n ? [...prev.questions, ...response.data.data.questions]\n : response.data.data.questions,\n pagination: convertPagination(response.data.data.pagination),\n error: null,\n currentFilters: validatedFilters,\n }));\n } catch (error) {\n setState((prev) => ({\n ...prev,\n loading: false,\n loadingMore: false,\n }));\n handleError(error);\n }\n },\n [apiClient, updateState, handleError]\n );\n\n /**\n * Fetch random questions from API\n * @param count - Number of random questions to fetch\n * @param filters - Optional filters to apply\n * @returns Promise with array of questions\n */\n const fetchRandomQuestions = useCallback(\n async (\n count: number,\n filters?: Partial<QuestionsFilterBody>\n ): Promise<Question[]> => {\n try {\n const validatedFilters: QuestionsFilterBody = {\n ...filters,\n randomQuestions: count,\n };\n\n const response = await apiClient.post<QuestionsListResponseActivity>(\n '/questions/list',\n validatedFilters\n );\n\n return response.data.data.questions;\n } catch (error) {\n handleError(error);\n return [];\n }\n },\n [apiClient, handleError]\n );\n\n /**\n * Fetch questions by their IDs\n * @param questionIds - Array of question IDs to fetch\n * @returns Promise with array of questions\n */\n const fetchQuestionsByIds = useCallback(\n async (questionIds: string[]): Promise<Question[]> => {\n try {\n const body: QuestionsByIdsBody & Record<string, unknown> = {\n questionsIds: questionIds,\n };\n\n const response = await apiClient.post<QuestionsByIdsResponse>(\n '/questions/by-ids',\n body\n );\n\n return response.data.data.questions;\n } catch (error) {\n handleError(error);\n return [];\n }\n },\n [apiClient, handleError]\n );\n\n const loadMore = useCallback(async () => {\n setState((prev) => {\n const { currentFilters, pagination, loadingMore: isLoadingMore } = prev;\n\n if (isLoadingMore || !currentFilters || !pagination?.hasNext) {\n return prev;\n }\n\n const nextPageFilters = {\n ...currentFilters,\n page: pagination.page + 1,\n };\n\n fetchQuestions(nextPageFilters, true).catch((error) => {\n console.error('Erro ao carregar mais questões:', error);\n });\n\n return {\n ...prev,\n loadingMore: true,\n };\n });\n }, [fetchQuestions]);\n\n /**\n * Reset questions list\n */\n const reset = useCallback(() => {\n setState({\n questions: [],\n pagination: null,\n loading: false,\n loadingMore: false,\n error: null,\n currentFilters: null,\n });\n }, []);\n\n return {\n ...state,\n fetchQuestions,\n fetchRandomQuestions,\n fetchQuestionsByIds,\n loadMore,\n reset,\n };\n};\n\n// ============================================================================\n// Hook Factory\n// ============================================================================\n\n/**\n * Create a questions list hook with API client injection.\n * @param apiClient - API client instance\n * @returns Pre-configured useQuestionsList hook\n *\n * @example\n * // In your app setup\n * import { createUseQuestionsList } from 'analytica-frontend-lib';\n * import api from './services/api';\n *\n * export const useQuestionsList = createUseQuestionsList(api);\n *\n * // Then use directly in components\n * const { questions, fetchQuestions, loadMore } = useQuestionsList();\n */\nexport const createUseQuestionsList = (apiClient: BaseApiClient) => {\n return (): UseQuestionsListReturn => useQuestionsListImpl(apiClient);\n};\n\n/**\n * Create a pre-configured questions list hook\n * This is a convenience function that returns a hook ready to use\n *\n * @param apiClient - API client instance\n * @returns Pre-configured useQuestionsList hook\n *\n * @example\n * // In your app setup\n * import { createQuestionsListHook } from 'analytica-frontend-lib';\n * import api from './services/api';\n *\n * export const useQuestionsList = createQuestionsListHook(api);\n *\n * // Then use directly in components\n * const { questions, fetchQuestions, loadMore } = useQuestionsList();\n */\nexport const createQuestionsListHook = (apiClient: BaseApiClient) => {\n return createUseQuestionsList(apiClient);\n};\n","import type {\n ActivityFiltersData,\n PreviewQuestion,\n QuestionActivity as Question,\n} from '../..';\nimport { QUESTION_TYPE } from '../Quiz/useQuizStore';\nimport type {\n BackendFiltersFormat,\n School,\n SchoolYear,\n Class,\n Student,\n} from './ActivityCreate.types';\nimport { ActivityType } from './ActivityCreate.types';\nimport type { BaseApiClient } from '../../types/api';\nimport type { CategoryConfig } from '../CheckBoxGroup/CheckBoxGroup';\n\n/**\n * Set of valid QUESTION_TYPE enum values for runtime validation\n */\nconst VALID_QUESTION_TYPES = new Set(Object.values(QUESTION_TYPE));\n\n/**\n * Type guard to validate if a string is a valid QUESTION_TYPE\n * @param type - String to validate\n * @returns True if type is a valid QUESTION_TYPE enum value\n */\nconst isValidQuestionType = (type: string): type is QUESTION_TYPE => {\n return VALID_QUESTION_TYPES.has(type as QUESTION_TYPE);\n};\n\n/**\n * Knowledge area interface for subject lookup\n */\nexport interface KnowledgeArea {\n id: string;\n name: string;\n}\n\n/**\n * Convert ActivityFiltersData to backend format\n *\n * @param filters - ActivityFiltersData to convert, can be null\n * @returns BackendFiltersFormat object with converted filter data\n *\n * @example\n * ```ts\n * const backendFilters = convertFiltersToBackendFormat({\n * types: ['ALTERNATIVA'],\n * subjectIds: ['math'],\n * // ...\n * });\n * ```\n */\nexport function convertFiltersToBackendFormat(\n filters: ActivityFiltersData | null\n): BackendFiltersFormat {\n if (!filters) {\n return {\n questionTypes: [],\n questionBanks: [],\n subjects: [],\n topics: [],\n subtopics: [],\n contents: [],\n };\n }\n\n return {\n questionTypes: filters.types,\n questionBanks: filters.bankIds,\n subjects: filters.subjectIds,\n topics: filters.topicIds,\n subtopics: filters.subtopicIds,\n contents: filters.contentIds,\n };\n}\n\n/**\n * Convert backend filters format to ActivityFiltersData\n *\n * @param backendFilters - BackendFiltersFormat to convert, can be null\n * @returns ActivityFiltersData object with converted filter data, or null if input is null\n *\n * @example\n * ```ts\n * const activityFilters = convertBackendFiltersToActivityFiltersData({\n * questionTypes: ['ALTERNATIVA'],\n * subjects: ['math'],\n * // ...\n * });\n * ```\n */\nexport function convertBackendFiltersToActivityFiltersData(\n backendFilters: BackendFiltersFormat | null\n): ActivityFiltersData | null {\n if (!backendFilters) {\n return null;\n }\n\n return {\n types: (backendFilters.questionTypes || []).filter(isValidQuestionType),\n bankIds: backendFilters.questionBanks || [],\n subjectIds: backendFilters.subjects || [],\n topicIds: backendFilters.topics || [],\n subtopicIds: backendFilters.subtopics || [],\n contentIds: backendFilters.contents || [],\n yearIds: [],\n };\n}\n\n/**\n * Get subject name from subjectId by searching in knowledge areas\n *\n * @param subjectId - The subject ID to look up\n * @param knowledgeAreas - Array of knowledge areas to search in\n * @returns The subject name if found, null otherwise\n *\n * @example\n * ```ts\n * const subjectName = getSubjectName('math', [\n * { id: 'math', name: 'Matemática' }\n * ]);\n * // Returns: 'Matemática'\n * ```\n */\nexport function getSubjectName(\n subjectId: string | null,\n knowledgeAreas: KnowledgeArea[]\n): string | null {\n if (!subjectId || !knowledgeAreas.length) {\n return null;\n }\n const subject = knowledgeAreas.find((area) => area.id === subjectId);\n return subject?.name || null;\n}\n\n/**\n * Get activity type label using object literal mapping\n *\n * @param type - Activity type (ActivityType enum)\n * @returns Label string for the activity type\n *\n * @example\n * ```ts\n * const label = getActivityTypeLabel(ActivityType.RASCUNHO);\n * // Returns: 'Rascunho'\n * ```\n */\nexport function getActivityTypeLabel(type: ActivityType): string {\n const activityTypeLabels: Record<ActivityType, string> = {\n [ActivityType.RASCUNHO]: 'Rascunho',\n [ActivityType.MODELO]: 'Modelo',\n [ActivityType.ATIVIDADE]: 'Atividade',\n };\n return activityTypeLabels[type];\n}\n\n/**\n * Generate activity title based on type and subject\n *\n * @param type - Activity type (ActivityType enum)\n * @param subjectId - Subject ID to get name from\n * @param knowledgeAreas - Array of knowledge areas for subject lookup\n * @returns Generated title string\n *\n * @example\n * ```ts\n * const title = generateTitle(ActivityType.RASCUNHO, 'math', [\n * { id: 'math', name: 'Matemática' }\n * ]);\n * // Returns: 'Rascunho - Matemática'\n * ```\n */\nexport function generateTitle(\n type: ActivityType,\n subjectId: string | null,\n knowledgeAreas: KnowledgeArea[]\n): string {\n const typeLabel = getActivityTypeLabel(type);\n const subjectName = getSubjectName(subjectId, knowledgeAreas);\n return subjectName ? `${typeLabel} - ${subjectName}` : typeLabel;\n}\n\n/**\n * Format time for display (HH:mm format)\n *\n * @param date - Date object to format\n * @returns Formatted time string in HH:mm format\n *\n * @example\n * ```ts\n * const time = formatTime(new Date('2025-01-01T14:30:00'));\n * // Returns: '14:30'\n * ```\n */\nexport function formatTime(date: Date): string {\n const hours = date.getHours().toString().padStart(2, '0');\n const minutes = date.getMinutes().toString().padStart(2, '0');\n return `${hours}:${minutes}`;\n}\n\n/**\n * Converte ActivityType para o formato usado na URL\n *\n * @param type - ActivityType enum value\n * @returns String representation for URL (rascunho or modelo)\n *\n * @example\n * ```ts\n * const urlType = getTypeFromUrl(ActivityType.RASCUNHO);\n * // Returns: 'rascunho'\n * ```\n */\nexport function getTypeFromUrl(type: ActivityType): string {\n switch (type) {\n case ActivityType.RASCUNHO:\n return 'rascunho';\n case ActivityType.MODELO:\n return 'modelo';\n default:\n return 'rascunho';\n }\n}\n\n/**\n * Converte string da URL para ActivityType\n *\n * @param type - String from URL (rascunho or modelo)\n * @returns ActivityType enum value\n *\n * @example\n * ```ts\n * const activityType = getTypeFromUrlString('rascunho');\n * // Returns: ActivityType.RASCUNHO\n * ```\n */\nexport function getTypeFromUrlString(type: string | undefined): ActivityType {\n switch (type) {\n case 'rascunho':\n return ActivityType.RASCUNHO;\n case 'modelo':\n return ActivityType.MODELO;\n default:\n return ActivityType.RASCUNHO;\n }\n}\n\n/**\n * Convert Question to PreviewQuestion format\n *\n * @param question - Question object to convert\n * @returns PreviewQuestion object with converted data\n *\n * @example\n * ```ts\n * const previewQuestion = convertQuestionToPreview({\n * id: 'q1',\n * statement: 'Test question',\n * questionType: 'ALTERNATIVA',\n * options: [{ id: 'opt1', option: 'Option 1' }],\n * knowledgeMatrix: [{\n * subject: { name: 'Math', color: '#000', icon: 'Math' }\n * }]\n * });\n * ```\n */\nexport function convertQuestionToPreview(question: Question): PreviewQuestion {\n const subjectInfo =\n question.knowledgeMatrix && question.knowledgeMatrix.length > 0\n ? {\n subjectName: question.knowledgeMatrix[0].subject?.name || undefined,\n subjectColor: question.knowledgeMatrix[0].subject?.color || undefined,\n iconName: question.knowledgeMatrix[0].subject?.icon || undefined,\n }\n : {};\n\n return {\n id: question.id,\n enunciado: question.statement,\n questionType: question.questionType,\n question: question.options\n ? {\n options: question.options.map(\n (opt: { id: string; option: string }) => ({\n id: opt.id,\n option: opt.option,\n })\n ),\n correctOptionIds: [],\n }\n : undefined,\n ...subjectInfo,\n };\n}\n\n/**\n * Fetch all students by paginating through all pages\n *\n * @param apiClient - API client instance\n * @returns Promise resolving to array of all students\n *\n * @example\n * ```ts\n * const students = await fetchAllStudents(apiClient);\n * ```\n */\nexport async function fetchAllStudents(\n apiClient: BaseApiClient\n): Promise<Student[]> {\n const allStudents: Student[] = [];\n let currentPage = 1;\n let totalPages = 1;\n const limit = 100;\n\n do {\n const response = await apiClient.get<{\n message: string;\n data: {\n students: Student[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n };\n }>(`/students?page=${currentPage}&limit=${limit}`);\n\n const { students, pagination } = response.data.data;\n allStudents.push(...students);\n totalPages = pagination.totalPages;\n currentPage++;\n } while (currentPage <= totalPages);\n\n return allStudents;\n}\n\n/**\n * Load categories data from API and transform to CategoryConfig format\n *\n * @param apiClient - API client instance\n * @param existingCategories - Current categories array to check if already loaded\n * @returns Promise resolving to array of CategoryConfig\n *\n * @example\n * ```ts\n * const categories = await loadCategoriesData(apiClient, []);\n * ```\n */\nexport async function loadCategoriesData(\n apiClient: BaseApiClient,\n existingCategories: CategoryConfig[]\n): Promise<CategoryConfig[]> {\n if (existingCategories.length > 0) {\n return existingCategories;\n }\n\n const [schoolsResponse, schoolYearsResponse, classesResponse, allStudents] =\n await Promise.all([\n apiClient.get<{ message: string; data: { schools: School[] } }>(\n '/school'\n ),\n apiClient.get<{\n message: string;\n data: { schoolYears: SchoolYear[] };\n }>('/schoolYear'),\n apiClient.get<{\n message: string;\n data: { classes: Class[] };\n }>('/classes'),\n fetchAllStudents(apiClient),\n ]);\n\n const schools = schoolsResponse.data.data.schools;\n const schoolYears = schoolYearsResponse.data.data.schoolYears;\n const classes = classesResponse.data.data.classes;\n const students = allStudents;\n\n const transformedCategories: CategoryConfig[] = [\n {\n key: 'escola',\n label: 'Escola',\n itens: schools.map((s) => ({ id: s.id, name: s.companyName })),\n selectedIds: [],\n },\n {\n key: 'serie',\n label: 'Série',\n dependsOn: ['escola'],\n filteredBy: [{ key: 'escola', internalField: 'schoolId' }],\n itens: schoolYears.map((sy) => ({\n id: sy.id,\n name: sy.name,\n schoolId: sy.schoolId,\n })),\n selectedIds: [],\n },\n {\n key: 'turma',\n label: 'Turma',\n dependsOn: ['serie'],\n filteredBy: [{ key: 'serie', internalField: 'schoolYearId' }],\n itens: classes.map((c) => ({\n id: c.id,\n name: c.name,\n schoolYearId: c.schoolYearId,\n })),\n selectedIds: [],\n },\n {\n key: 'alunos',\n label: 'Alunos',\n dependsOn: ['turma'],\n filteredBy: [{ key: 'turma', internalField: 'classId' }],\n itens: students.map((s) => ({\n id: s.id,\n name: s.name,\n classId: s.classId,\n studentId: s.id,\n userInstitutionId: s.userInstitutionId,\n })),\n selectedIds: [],\n },\n ];\n\n return transformedCategories;\n}\n","import React, { forwardRef, useRef, useCallback } from 'react';\nimport { QUESTION_TYPE } from '../Quiz/useQuizStore';\nimport LatexRenderer from '../LatexRenderer/LatexRenderer';\nimport type { PreviewQuestion } from '../ActivityPreview/ActivityPreview';\n\ninterface QuestionsPdfGeneratorProps {\n questions: PreviewQuestion[];\n onPrint?: () => void;\n onPrintError?: (error: Error) => void;\n /**\n * Optional render prop to access the handlePrint function.\n * If not provided, the component will render the hidden PDF content only.\n * Consumers can use the hook directly (useQuestionsPdfPrint) for more control.\n */\n children?: (handlePrint: () => void) => React.ReactNode;\n}\n\n/**\n * Component that renders questions in a format suitable for PDF printing\n * This component is hidden from view and only used for printing\n */\nexport const QuestionsPdfContent = forwardRef<\n HTMLDivElement,\n { questions: PreviewQuestion[] }\n>(({ questions }, ref) => {\n const getLetterByIndex = (index: number): string => {\n return String.fromCodePoint(97 + index);\n };\n\n const renderAlternative = (question: PreviewQuestion) => {\n if (!question.question?.options || question.question.options.length === 0) {\n return null;\n }\n\n return (\n <ol\n type=\"a\"\n style={{\n marginTop: '12px',\n marginBottom: '12px',\n paddingLeft: '24px',\n }}\n >\n {question.question.options.map((option) => (\n <li\n key={option.id}\n style={{\n marginBottom: '8px',\n lineHeight: '1.6',\n }}\n >\n <LatexRenderer content={option.option} />\n </li>\n ))}\n </ol>\n );\n };\n\n const renderMultipleChoice = (question: PreviewQuestion) => {\n if (!question.question?.options || question.question.options.length === 0) {\n return null;\n }\n\n return (\n <div\n style={{\n marginTop: '12px',\n marginBottom: '12px',\n }}\n >\n {question.question.options.map((option, index) => {\n const letter = getLetterByIndex(index);\n return (\n <div\n key={option.id}\n style={{\n marginBottom: '12px',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n lineHeight: '1.6',\n }}\n >\n <span\n style={{\n marginTop: '2px',\n minWidth: '20px',\n fontSize: '16px',\n }}\n >\n ☐\n </span>\n <span\n style={{\n fontWeight: 'bold',\n marginRight: '4px',\n }}\n >\n {letter})\n </span>\n <div style={{ flex: 1 }}>\n <LatexRenderer content={option.option} />\n </div>\n </div>\n );\n })}\n </div>\n );\n };\n\n const renderDissertative = () => {\n return (\n <div\n style={{\n marginTop: '12px',\n marginBottom: '12px',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n }}\n >\n <span\n style={{\n fontWeight: 'bold',\n marginTop: '2px',\n }}\n >\n R:\n </span>\n <div\n style={{\n minHeight: '150px',\n flex: 1,\n }}\n />\n </div>\n </div>\n );\n };\n\n const renderTrueOrFalse = (question: PreviewQuestion) => {\n if (!question.question?.options || question.question.options.length === 0) {\n return null;\n }\n\n return (\n <div style={{ marginTop: '12px', marginBottom: '12px' }}>\n {question.question.options.map((option, index) => (\n <div\n key={option.id}\n style={{\n marginBottom: '16px',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '12px',\n }}\n >\n <span\n style={{\n fontWeight: 'bold',\n minWidth: '20px',\n }}\n >\n {getLetterByIndex(index)})\n </span>\n <div style={{ flex: 1 }}>\n <LatexRenderer content={option.option} />\n </div>\n <span\n style={{\n marginLeft: '8px',\n whiteSpace: 'nowrap',\n fontSize: '14px',\n }}\n >\n ( ) V ( ) F\n </span>\n </div>\n ))}\n </div>\n );\n };\n\n const renderQuestionTypeContent = (question: PreviewQuestion) => {\n type RenderFunction = (\n question: PreviewQuestion\n ) => ReturnType<typeof renderAlternative> | null;\n\n const renderMap: Record<QUESTION_TYPE, RenderFunction> = {\n [QUESTION_TYPE.ALTERNATIVA]: renderAlternative,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: renderMultipleChoice,\n [QUESTION_TYPE.DISSERTATIVA]: () => renderDissertative(),\n [QUESTION_TYPE.VERDADEIRO_FALSO]: renderTrueOrFalse,\n [QUESTION_TYPE.LIGAR_PONTOS]: () => null,\n [QUESTION_TYPE.PREENCHER]: () => null,\n [QUESTION_TYPE.IMAGEM]: () => null,\n };\n\n if (!question.questionType) {\n return null;\n }\n\n const renderFunction = renderMap[question.questionType];\n return renderFunction ? renderFunction(question) : null;\n };\n\n const renderQuestionContent = (question: PreviewQuestion, index: number) => {\n const questionNumber = index + 1;\n\n return (\n <div\n key={question.id}\n style={{\n marginBottom: '32px',\n pageBreakInside: 'avoid',\n }}\n >\n <h3\n style={{\n fontSize: '16px',\n fontWeight: 'bold',\n marginBottom: '12px',\n color: '#000',\n }}\n >\n Questão {questionNumber}\n </h3>\n\n {question.enunciado && (\n <div\n style={{\n marginBottom: '12px',\n lineHeight: '1.6',\n color: '#000',\n }}\n >\n <LatexRenderer content={question.enunciado} />\n </div>\n )}\n\n {renderQuestionTypeContent(question)}\n </div>\n );\n };\n\n return (\n <div\n ref={ref}\n className=\"questions-pdf-container\"\n style={{\n position: 'fixed',\n left: 0,\n top: 0,\n width: '210mm',\n minHeight: '297mm',\n visibility: 'hidden',\n pointerEvents: 'none',\n zIndex: -1,\n }}\n >\n <style>\n {`\n @media print {\n @page {\n margin: 20mm;\n size: A4;\n }\n \n body {\n margin: 0;\n padding: 0;\n }\n \n .questions-pdf-container {\n position: static !important;\n left: auto !important;\n top: auto !important;\n visibility: visible !important;\n pointer-events: auto !important;\n z-index: auto !important;\n padding: 0;\n margin: 0;\n font-family: Arial, sans-serif;\n font-size: 14px;\n line-height: 1.6;\n color: #000;\n width: auto;\n min-height: auto;\n }\n \n .questions-pdf-container h3 {\n page-break-after: avoid;\n }\n \n .questions-pdf-container > div {\n page-break-inside: avoid;\n }\n }\n `}\n </style>\n <div style={{ padding: '20px' }}>\n {questions.map((question, index) =>\n renderQuestionContent(question, index)\n )}\n </div>\n </div>\n );\n});\n\nQuestionsPdfContent.displayName = 'QuestionsPdfContent';\n\n/**\n * Collects relevant CSS styles from document stylesheets\n */\nconst collectRelevantStyles = (): string[] => {\n const styles: string[] = [];\n const styleSheets = Array.from(document.styleSheets);\n\n styleSheets.forEach((styleSheet) => {\n try {\n const cssRules = styleSheet.cssRules || [];\n Array.from(cssRules).forEach((rule) => {\n const ruleText = rule.cssText;\n if (ruleText.includes('katex') || ruleText.includes('questions-pdf')) {\n styles.push(ruleText);\n }\n });\n } catch (error) {\n if (typeof console !== 'undefined' && console.debug) {\n console.debug('Could not access stylesheet (likely CORS):', error);\n }\n }\n });\n\n return styles;\n};\n\n/**\n * Generates the HTML content for the print window\n *\n * Security note: contentHTML is already sanitized via DOMPurify in LatexRenderer\n * before reaching this function, so it's safe to inject into the template string.\n *\n * CSP note: This function loads KaTeX CSS from CDN. Ensure your Content Security Policy\n * allows: style-src 'self' https://cdn.jsdelivr.net;\n * Or consider serving KaTeX CSS locally for stricter CSP compliance.\n */\nconst generatePrintHTML = (contentHTML: string, styles: string[]): string => {\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Questões</title>\n <meta charset=\"utf-8\">\n <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/katex@0.16.27/dist/katex.min.css\">\n <style>\n @page {\n margin: 20mm;\n size: A4;\n }\n \n * {\n box-sizing: border-box;\n }\n \n body {\n margin: 0;\n padding: 0;\n font-family: Arial, sans-serif;\n font-size: 14px;\n line-height: 1.6;\n color: #000;\n }\n \n .questions-pdf-container {\n position: static !important;\n visibility: visible !important;\n pointer-events: auto !important;\n z-index: auto !important;\n left: auto !important;\n top: auto !important;\n width: auto !important;\n min-height: auto !important;\n padding: 0;\n margin: 0;\n }\n \n .questions-pdf-container h3 {\n page-break-after: avoid;\n font-size: 16px;\n font-weight: bold;\n margin-bottom: 12px;\n color: #000;\n }\n \n .questions-pdf-container > div {\n page-break-inside: avoid;\n }\n \n ol {\n margin-top: 12px;\n margin-bottom: 12px;\n padding-left: 24px;\n }\n \n li {\n margin-bottom: 8px;\n line-height: 1.6;\n }\n \n ${styles.join('\\n')}\n </style>\n </head>\n <body>\n <div class=\"questions-pdf-container\">\n ${contentHTML}\n </div>\n </body>\n </html>\n `;\n};\n\n/**\n * Sets up the print window onload handler with improved timing and cleanup\n */\nconst setupPrintWindowHandler = (printWindow: Window): void => {\n printWindow.onload = () => {\n const printAndCleanup = () => {\n try {\n printWindow.print();\n } finally {\n setTimeout(() => {\n if (printWindow && !printWindow.closed) {\n printWindow.close();\n }\n }, 1000);\n }\n };\n\n const fonts = printWindow.document.fonts;\n if (fonts && 'ready' in fonts) {\n fonts.ready\n .then(() => {\n setTimeout(printAndCleanup, 100);\n })\n .catch(() => {\n setTimeout(printAndCleanup, 500);\n });\n } else {\n setTimeout(printAndCleanup, 500);\n }\n };\n};\n\n/**\n * Hook to generate PDF from questions using native browser print API\n * Returns the content ref and print handler\n *\n * Security: Content is sanitized via DOMPurify in LatexRenderer before rendering.\n * CSP: Ensure your Content Security Policy allows loading KaTeX CSS from cdn.jsdelivr.net\n * or serve KaTeX CSS locally for stricter CSP compliance.\n */\nexport const useQuestionsPdfPrint = (\n questions: PreviewQuestion[],\n onPrint?: () => void,\n onPrintError?: (error: Error) => void\n) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n const handlePrint = useCallback(() => {\n try {\n onPrint?.();\n\n if (!contentRef.current) {\n throw new Error('Elemento de PDF não encontrado no DOM');\n }\n\n const printWindow = window.open('', '_blank');\n if (!printWindow) {\n throw new Error(\n 'Não foi possível abrir a janela de impressão. Verifique se os pop-ups estão bloqueados.'\n );\n }\n printWindow.opener = null;\n\n const contentHTML = contentRef.current.innerHTML;\n const styles = collectRelevantStyles();\n const htmlContent = generatePrintHTML(contentHTML, styles);\n\n const doc = printWindow.document;\n doc.open();\n doc.write(htmlContent);\n doc.close();\n\n setupPrintWindowHandler(printWindow);\n } catch (error) {\n const errorObj =\n error instanceof Error ? error : new Error(String(error));\n onPrintError?.(errorObj);\n console.error('Erro ao gerar PDF:', errorObj);\n }\n }, [onPrint, onPrintError]);\n\n return {\n contentRef,\n handlePrint,\n };\n};\n\n/**\n * QuestionsPdfGenerator Component\n *\n * Isolated and reusable component for generating PDFs of questions without answers.\n * Formats questions for school printing with specific layouts for each question type.\n *\n * This component renders hidden content and optionally exposes handlePrint via render prop.\n * For more control, consumers can use the hook directly (useQuestionsPdfPrint).\n *\n * @param questions - Array of questions to render in PDF\n * @param onPrint - Optional callback when print is triggered\n * @param onPrintError - Optional callback when print error occurs\n * @param children - Optional render prop function that receives handlePrint\n * @returns Component with hidden PDF content and optionally rendered children\n *\n * @example\n * // Without render prop (hidden content only)\n * <QuestionsPdfGenerator questions={questions} />\n *\n * @example\n * // With render prop (expose handlePrint)\n * <QuestionsPdfGenerator questions={questions}>\n * {(handlePrint) => <button onClick={handlePrint}>Print</button>}\n * </QuestionsPdfGenerator>\n */\nexport const QuestionsPdfGenerator = ({\n questions,\n onPrint,\n onPrintError,\n children,\n}: QuestionsPdfGeneratorProps) => {\n const { contentRef, handlePrint } = useQuestionsPdfPrint(\n questions,\n onPrint,\n onPrintError\n );\n\n return (\n <>\n {children?.(handlePrint)}\n <div style={{ display: 'none' }}>\n <QuestionsPdfContent ref={contentRef} questions={questions} />\n </div>\n </>\n );\n};\n\nexport type { QuestionsPdfGeneratorProps };\n","import { useCallback } from 'react';\nimport type { BaseApiClient } from '../types/api';\nimport type {\n ActivityDetailsData,\n ActivityDetailsQueryParams,\n ActivityDetailsApiResponse,\n QuizResponse,\n PresignedUrlResponse,\n} from '../types/activityDetails';\nimport type {\n QuestionsAnswersByStudentResponse,\n SaveQuestionCorrectionPayload,\n} from '../utils/studentActivityCorrection';\n\n/**\n * Hook return type for activity details\n */\nexport interface UseActivityDetailsReturn {\n /**\n * Fetch activity details from API\n * @param id - Activity ID\n * @param params - Query parameters for pagination\n * @returns Activity details data\n */\n fetchActivityDetails: (\n id: string,\n params?: ActivityDetailsQueryParams\n ) => Promise<ActivityDetailsData>;\n /**\n * Fetch student correction data from API\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @returns Student answers response data\n */\n fetchStudentCorrection: (\n activityId: string,\n studentId: string\n ) => Promise<QuestionsAnswersByStudentResponse>;\n /**\n * Submit observation for student activity\n * @param actId - Activity ID\n * @param studentId - Student ID\n * @param observation - Observation text\n * @param file - Attached file (optional)\n */\n submitObservation: (\n actId: string,\n studentId: string,\n observation: string,\n file: File | null\n ) => Promise<void>;\n /**\n * Submit question correction for student activity\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @param payload - Question correction payload\n */\n submitQuestionCorrection: (\n activityId: string,\n studentId: string,\n payload: SaveQuestionCorrectionPayload\n ) => Promise<void>;\n}\n\n/**\n * Build query parameters for API request\n */\nconst buildQueryParams = (\n params?: ActivityDetailsQueryParams\n): Record<string, unknown> => {\n const paramsObj: Record<string, unknown> = {};\n if (params?.page) paramsObj.page = params.page;\n if (params?.limit) paramsObj.limit = params.limit;\n if (params?.sortBy) paramsObj.sortBy = params.sortBy;\n if (params?.sortOrder) paramsObj.sortOrder = params.sortOrder;\n if (params?.status) paramsObj.status = params.status;\n return paramsObj;\n};\n\n/**\n * Hook for managing activity details API calls\n * Provides functions to fetch activity details, student corrections, and submit observations/corrections\n *\n * @param apiClient - API client instance for making requests\n * @returns Hook return object with API functions\n *\n * @example\n * ```tsx\n * import { useActivityDetails } from 'analytica-frontend-lib';\n * import { useApi } from './services/apiService';\n *\n * function ActivityDetailsPage() {\n * const api = useApi();\n * const { fetchActivityDetails, fetchStudentCorrection } = useActivityDetails(api);\n *\n * // Use functions...\n * }\n * ```\n */\nexport const useActivityDetails = (\n apiClient: BaseApiClient\n): UseActivityDetailsReturn => {\n /**\n * Fetch activity details from API\n * @param id - Activity ID\n * @param params - Query parameters for pagination\n * @returns Activity details data\n */\n const fetchActivityDetails = useCallback(\n async (\n id: string,\n params?: ActivityDetailsQueryParams\n ): Promise<ActivityDetailsData> => {\n const queryParams = buildQueryParams(params);\n\n const [detailsResponse, quizResponse] = await Promise.all([\n apiClient.get<ActivityDetailsApiResponse>(`/activities/${id}/details`, {\n params: queryParams,\n }),\n apiClient.get<QuizResponse>(`/activities/${id}/quiz`).catch(() => null),\n ]);\n\n return {\n ...detailsResponse.data.data,\n activity: quizResponse?.data?.data,\n };\n },\n [apiClient]\n );\n\n /**\n * Fetch student correction data from API\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @returns Student answers response data\n */\n const fetchStudentCorrection = useCallback(\n async (\n activityId: string,\n studentId: string\n ): Promise<QuestionsAnswersByStudentResponse> => {\n const response = await apiClient.get<QuestionsAnswersByStudentResponse>(\n `/questions/activity/${activityId}/user/${studentId}/answers`\n );\n return response.data;\n },\n [apiClient]\n );\n\n /**\n * Submit observation for student activity\n * @param actId - Activity ID\n * @param studentId - Student ID\n * @param observation - Observation text\n * @param file - Attached file (optional)\n */\n const submitObservation = useCallback(\n async (\n actId: string,\n studentId: string,\n observation: string,\n file: File | null\n ): Promise<void> => {\n let attachmentUrl: string | null = null;\n\n if (file) {\n const presignedRes = await apiClient.post<PresignedUrlResponse>(\n '/user/get-pre-signed-url',\n {\n fileName: file.name,\n fileType: file.type,\n fileSize: file.size,\n }\n );\n\n const { url, fields } = presignedRes.data.data;\n const formData = new FormData();\n\n for (const [key, value] of Object.entries(fields)) {\n formData.append(key, value);\n }\n formData.append('file', file);\n\n await fetch(url, {\n method: 'POST',\n body: formData,\n }).then((response) => {\n if (!response.ok) {\n throw new Error('Falha ao fazer upload do arquivo');\n }\n });\n\n // Ensure proper URL construction\n const baseUrl = url.endsWith('/') ? url.slice(0, -1) : url;\n const key = fields.key.startsWith('/')\n ? fields.key.slice(1)\n : fields.key;\n attachmentUrl = `${baseUrl}/${key}`;\n }\n\n await apiClient.post(\n `/activities/${actId}/students/${studentId}/feedback/observation`,\n {\n observation,\n attachmentUrl,\n }\n );\n },\n [apiClient]\n );\n\n /**\n * Submit question correction for student activity\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @param payload - Question correction payload\n */\n const submitQuestionCorrection = useCallback(\n async (\n activityId: string,\n studentId: string,\n payload: SaveQuestionCorrectionPayload\n ): Promise<void> => {\n await apiClient.post(\n `/activities/${activityId}/students/${studentId}/questions/correction`,\n payload\n );\n },\n [apiClient]\n );\n\n return {\n fetchActivityDetails,\n fetchStudentCorrection,\n submitObservation,\n submitQuestionCorrection,\n };\n};\n","import type { CategoryConfig, Item } from './CheckBoxGroup';\n\n/**\n * Helper function to efficiently compare selectedIds arrays\n */\nexport const areSelectedIdsEqual = (\n ids1?: string[],\n ids2?: string[]\n): boolean => {\n if (ids1 === ids2) return true;\n if (!ids1 || !ids2) return ids1 === ids2;\n if (ids1.length !== ids2.length) return false;\n\n for (let i = 0; i < ids1.length; i++) {\n if (ids1[i] !== ids2[i]) return false;\n }\n return true;\n};\n\n/**\n * Helper function to check if category is enabled based on dependencies\n */\nexport const isCategoryEnabled = (\n category: CategoryConfig,\n allCategories: CategoryConfig[]\n): boolean => {\n if (!category.dependsOn || category.dependsOn.length === 0) {\n return true;\n }\n return category.dependsOn.every((depKey) => {\n const depCat = allCategories.find((c) => c.key === depKey);\n return depCat?.selectedIds && depCat.selectedIds.length > 0;\n });\n};\n\n/**\n * Helper function to check if an item matches a filter\n */\nexport const isItemMatchingFilter = (\n item: Item,\n filter: { key: string; internalField: string },\n allCategories: CategoryConfig[]\n): boolean => {\n const parentCat = allCategories.find((c) => c.key === filter.key);\n const parentSelectedIds = parentCat?.selectedIds || [];\n const itemFieldValue = item[filter.internalField];\n return parentSelectedIds.includes(String(itemFieldValue));\n};\n\n/**\n * Helper function to get badge text for category\n */\nexport const getBadgeText = (\n category: CategoryConfig,\n formattedItems: { groupLabel?: string; itens: Item[] }[]\n): string => {\n const visibleIds = formattedItems\n .flatMap((group) => group.itens || [])\n .map((i) => i.id);\n const selectedVisibleCount = visibleIds.filter((id) =>\n category.selectedIds?.includes(id)\n ).length;\n const totalVisible = visibleIds.length;\n return `${selectedVisibleCount} de ${totalVisible} ${\n selectedVisibleCount === 1 ? 'selecionado' : 'selecionados'\n }`;\n};\n\n/**\n * Helper function to handle accordion value change logic\n * Returns the new accordion value or null if should not change\n */\nexport const handleAccordionValueChange = (\n value: string | string[] | undefined,\n categories: CategoryConfig[],\n isCategoryEnabledFn: (category: CategoryConfig) => boolean\n): string | null => {\n if (typeof value !== 'string') {\n if (!value) {\n return '';\n }\n return null; // Don't change for array values\n }\n\n if (!value) {\n return '';\n }\n\n // Prevent opening disabled categories\n const category = categories.find((c) => c.key === value);\n if (!category) {\n return null; // Category not found, don't change\n }\n\n const isEnabled = isCategoryEnabledFn(category);\n if (!isEnabled) {\n return null; // Don't allow opening disabled accordions\n }\n\n return value;\n};\n\n/**\n * Helper function to calculate filtered items for auto-selection\n * This function determines which items are visible/filtered for a category\n */\nexport const calculateFormattedItemsForAutoSelection = (\n category: CategoryConfig,\n allCategories: CategoryConfig[]\n): Item[] => {\n if (!category?.dependsOn || category.dependsOn.length === 0) {\n return category?.itens || [];\n }\n\n // Check if category is enabled based on dependencies\n const isEnabled = isCategoryEnabled(category, allCategories);\n\n // If category is disabled, return empty items array\n if (!isEnabled) {\n return [];\n }\n\n const filters =\n (category.filteredBy as {\n key: string;\n internalField: string;\n label?: string;\n }[]) || [];\n\n if (filters.length === 0) {\n return category?.itens || [];\n }\n\n const selectedIdsArr = filters.map((f) => {\n const parentCat = allCategories.find((c) => c.key === f.key);\n if (!parentCat?.selectedIds?.length) {\n return [];\n }\n return parentCat.selectedIds;\n });\n\n if (selectedIdsArr.some((arr) => arr.length === 0)) {\n return [];\n }\n\n // Filter items based on selected parent IDs\n const filteredItems = (category.itens || []).filter((item) =>\n filters.every((filter) => isItemMatchingFilter(item, filter, allCategories))\n );\n\n return filteredItems;\n};\n","import Modal from '../Modal/Modal';\nimport { CheckboxGroup } from '../CheckBoxGroup/CheckBoxGroup';\nimport Button from '../Button/Button';\nimport type { FilterConfig } from './useTableFilter';\n\nexport type FilterModalProps = {\n /**\n * Controls modal visibility\n */\n isOpen: boolean;\n\n /**\n * Callback when modal should close\n */\n onClose: () => void;\n\n /**\n * Filter configurations with categories\n */\n filterConfigs: FilterConfig[];\n\n /**\n * Callback when filters change (temporary, before applying)\n */\n onFiltersChange: (configs: FilterConfig[]) => void;\n\n /**\n * Callback when \"Aplicar\" button is clicked\n */\n onApply: () => void;\n\n /**\n * Callback when \"Limpar filtros\" button is clicked\n */\n onClear: () => void;\n\n /**\n * Modal title\n * @default \"Filtros\"\n */\n title?: string;\n\n /**\n * Modal size\n * @default \"md\"\n */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n /**\n * Apply button label\n * @default \"Aplicar\"\n */\n applyLabel?: string;\n\n /**\n * Clear button label\n * @default \"Limpar filtros\"\n */\n clearLabel?: string;\n};\n\n/**\n * FilterModal component - A modal for table filtering with CheckboxGroup\n *\n * Integrates Modal, CheckboxGroup, and Button components to create a\n * complete filtering interface. Works with useTableFilter hook for URL synchronization.\n *\n * @example\n * ```tsx\n * const { filterConfigs, updateFilters, applyFilters, clearFilters } = useTableFilter(\n * initialConfigs,\n * { syncWithUrl: true }\n * );\n *\n * <FilterModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * filterConfigs={filterConfigs}\n * onFiltersChange={updateFilters}\n * onApply={() => {\n * applyFilters();\n * setIsOpen(false);\n * }}\n * onClear={clearFilters}\n * />\n * ```\n */\nexport const FilterModal = ({\n isOpen,\n onClose,\n filterConfigs,\n onFiltersChange,\n onApply,\n onClear,\n title = 'Filtros',\n size = 'md',\n applyLabel = 'Aplicar',\n clearLabel = 'Limpar filtros',\n}: FilterModalProps) => {\n const handleCategoryChange = (\n configIndex: number,\n updatedCategories: (typeof filterConfigs)[0]['categories']\n ) => {\n const newConfigs = [...filterConfigs];\n newConfigs[configIndex] = {\n ...newConfigs[configIndex],\n categories: updatedCategories,\n };\n onFiltersChange(newConfigs);\n };\n\n const handleApply = () => {\n onApply();\n onClose();\n };\n\n const handleClear = () => {\n onClear();\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size={size}\n footer={\n <div className=\"flex gap-3 justify-end w-full\">\n <Button variant=\"outline\" onClick={handleClear}>\n {clearLabel}\n </Button>\n <Button onClick={handleApply}>{applyLabel}</Button>\n </div>\n }\n >\n <div className=\"flex flex-col gap-6\">\n {filterConfigs.map((config, index) => (\n <div key={config.key} className=\"flex flex-col gap-4\">\n {/* Section Header */}\n <div className=\"flex items-center gap-2 text-text-400 text-sm font-medium uppercase\">\n {config.key === 'academic' && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-text-400\"\n >\n <path\n d=\"M8 2L2 5.33333L8 8.66667L14 5.33333L8 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M2 10.6667L8 14L14 10.6667\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M2 8L8 11.3333L14 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n {config.key === 'content' && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-text-400\"\n >\n <path\n d=\"M3.33333 2H12.6667C13.403 2 14 2.59695 14 3.33333V12.6667C14 13.403 13.403 14 12.6667 14H3.33333C2.59695 14 2 13.403 2 12.6667V3.33333C2 2.59695 2.59695 2 3.33333 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M2 6H14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M6 2V14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n <span>{config.label}</span>\n </div>\n\n {/* CheckboxGroup */}\n <CheckboxGroup\n categories={config.categories}\n onCategoriesChange={(updatedCategories) =>\n handleCategoryChange(index, updatedCategories)\n }\n />\n </div>\n ))}\n </div>\n </Modal>\n );\n};\n"],"mappings":";AAAA,SAAS,YAAAA,YAAU,WAAAC,UAAS,eAAAC,cAAa,aAAAC,aAAW,UAAAC,gBAAc;AAClE;AAAA,EACE,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,OACK;;;ACPP,SAAS,YAA6B;AACtC,SAAS,eAAe;;;ACDxB,SAAS,cAAc;AACvB,SAAS,gBAAgB;AAelB,IAAK,gBAAL,kBAAKC,mBAAL;AACL,EAAAA,eAAA,iBAAc;AACd,EAAAA,eAAA,kBAAe;AACf,EAAAA,eAAA,sBAAmB;AACnB,EAAAA,eAAA,sBAAmB;AACnB,EAAAA,eAAA,kBAAe;AACf,EAAAA,eAAA,eAAY;AACZ,EAAAA,eAAA,YAAS;AAPC,SAAAA;AAAA,GAAA;AAkQL,IAAM,qBAAqB;AAE3B,IAAM,eAAe,OAAkB;AAAA,EAC5C;AAAA,IACE,CAAC,KAAK,QAAQ;AACZ,UAAI,gBAAuD;AAC3D,UAAI,yBAAgE;AAEpE,YAAM,aAAa,MAAM;AACvB,YAAI,IAAI,EAAE,YAAY;AACpB;AAAA,QACF;AAEA,YAAI,eAAe;AACjB,wBAAc,aAAa;AAAA,QAC7B;AAEA,wBAAgB,YAAY,MAAM;AAChC,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,cAAI,EAAE,aAAa,cAAc,EAAE,CAAC;AAAA,QACtC,GAAG,GAAI;AAAA,MACT;AAEA,YAAM,YAAY,MAAM;AACtB,YAAI,eAAe;AACjB,wBAAc,aAAa;AAC3B,0BAAgB;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,oBAAoB,CAAC,aAAkC;AAC3D,YAAI,EAAE,gBAAgB,SAAS,CAAC;AAAA,MAClC;AAEA,YAAM,sBAAsB,MAAM;AAChC,cAAM,EAAE,gBAAgB,WAAW,IAAI,IAAI;AAE3C,YAAI,cAAc,CAAC,gBAAgB;AACjC;AAAA,QACF;AAEA,YAAI,wBAAwB;AAC1B,wBAAc,sBAAsB;AAAA,QACtC;AAEA,iCAAyB,YAAY,MAAM;AACzC,gBAAM;AAAA,YACJ,gBAAgB;AAAA,YAChB,YAAY;AAAA,UACd,IAAI,IAAI;AAER,cAAI,qBAAqB,CAAC,iBAAiB;AACzC,+BAAmB;AACnB;AAAA,UACF;AAEA,0BAAgB;AAAA,QAClB,GAAG,kBAAkB;AAAA,MACvB;AAEA,YAAM,qBAAqB,MAAM;AAC/B,YAAI,wBAAwB;AAC1B,wBAAc,sBAAsB;AACpC,mCAAyB;AAAA,QAC3B;AAAA,MACF;AAEA,aAAO;AAAA;AAAA,QAEL,MAAM;AAAA,QACN,sBAAsB;AAAA,QACtB,iBAAiB,CAAC;AAAA,QAClB,aAAa,CAAC;AAAA,QACd,aAAa;AAAA,QACb,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,uBAAuB;AAAA,QACvB,iBAAiB;AAAA,QACjB,uBAAuB;AAAA;AAAA,QAEvB,SAAS,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC;AAAA,QAC/B,WAAW,CAAC,WAAW,IAAI,EAAE,OAAO,CAAC;AAAA,QACrC,gBAAgB,CAAC,gBAAgB,IAAI,EAAE,YAAY,CAAC;AAAA,QACpD,WAAW,MAAM,IAAI,EAAE;AAAA,QACvB,YAAY,CAAC,YAAY,IAAI,EAAE,QAAQ,CAAC;AAAA,QACxC,mBAAmB,CAAC,oBAAoB,IAAI,EAAE,gBAAgB,CAAC;AAAA,QAC/D,0BAA0B,CAAC,UACzB,IAAI,EAAE,uBAAuB,MAAM,CAAC;AAAA,QACtC,0BAA0B,MAAM,IAAI,EAAE;AAAA;AAAA,QAEtC,kBAAkB,MAAM;AACtB,gBAAM,EAAE,sBAAsB,kBAAkB,IAAI,IAAI;AACxD,gBAAM,iBAAiB,kBAAkB;AAEzC,cAAI,uBAAuB,iBAAiB,GAAG;AAC7C,gBAAI,EAAE,sBAAsB,uBAAuB,EAAE,CAAC;AAAA,UACxD;AAAA,QACF;AAAA,QAEA,sBAAsB,MAAM;AAC1B,gBAAM,EAAE,qBAAqB,IAAI,IAAI;AAErC,cAAI,uBAAuB,GAAG;AAC5B,gBAAI,EAAE,sBAAsB,uBAAuB,EAAE,CAAC;AAAA,UACxD;AAAA,QACF;AAAA,QAEA,cAAc,CAAC,UAAU;AACvB,gBAAM,EAAE,kBAAkB,IAAI,IAAI;AAClC,gBAAM,iBAAiB,kBAAkB;AAEzC,cAAI,SAAS,KAAK,QAAQ,gBAAgB;AACxC,gBAAI,EAAE,sBAAsB,MAAM,CAAC;AAAA,UACrC;AAAA,QACF;AAAA,QAEA,cAAc,CAAC,YAAY,aAAa;AACtC,gBAAM,EAAE,MAAM,YAAY,IAAI,IAAI;AAElC,cAAI,CAAC,KAAM;AAEX,gBAAM,aAAa,KAAK;AACxB,gBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,cAAI,CAAC,UAAU,WAAW,IAAI;AAE5B;AAAA,UACF;AAEA,gBAAM,WAAW,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAC/D,cAAI,CAAC,SAAU;AAEf,gBAAM,sBAAsB,YAAY;AAAA,YACtC,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AAEA,gBAAM,gBAAgC;AAAA,YACpC;AAAA,YACA;AAAA,YACA;AAAA,YACA,QACE,SAAS,iBAAiB,oCACtB,WACA;AAAA,YACN,UACE,SAAS,iBAAiB,oCACtB,OACA;AAAA,YACN,cAAc,SAAS;AAAA,YACvB,cAAc;AAAA,UAChB;AAEA,cAAI;AACJ,cAAI,wBAAwB,IAAI;AAC9B,iCAAqB,CAAC,GAAG,WAAW;AACpC,+BAAmB,mBAAmB,IAAI;AAAA,UAC5C,OAAO;AACL,iCAAqB,CAAC,GAAG,aAAa,aAAa;AAAA,UACrD;AAEA,cAAI;AAAA,YACF,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,QAEA,sBAAsB,CAAC,YAAY,cAAc;AAC/C,gBAAM,EAAE,MAAM,YAAY,IAAI,IAAI;AAElC,cAAI,CAAC,KAAM;AAEX,gBAAM,aAAa,KAAK;AACxB,gBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,cAAI,CAAC,UAAU,WAAW,IAAI;AAE5B;AAAA,UACF;AAEA,gBAAM,WAAW,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAC/D,cAAI,CAAC,SAAU;AAGf,gBAAM,sBAAsB,YAAY;AAAA,YACtC,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AAGA,gBAAM,iBAAmC,UAAU;AAAA,YACjD,CAAC,cAAc;AAAA,cACb;AAAA,cACA;AAAA,cACA;AAAA,cACA,QAAQ;AAAA;AAAA,cACR,UAAU;AAAA;AAAA,cACV,cAAc,SAAS;AAAA,cACvB,cAAc;AAAA,YAChB;AAAA,UACF;AAGA,gBAAM,qBAAqB;AAAA,YACzB,GAAG;AAAA,YACH,GAAG;AAAA,UACL;AAEA,cAAI;AAAA,YACF,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,QAEA,0BAA0B,CAAC,YAAY,WAAW;AAChD,gBAAM,EAAE,MAAM,aAAa,sBAAsB,IAAI,IAAI;AAEzD,cAAI,CAAC,KAAM;AAEX,gBAAM,aAAa,KAAK;AACxB,gBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,cAAI,CAAC,UAAU,WAAW,IAAI;AAE5B;AAAA,UACF;AAEA,gBAAM,WAAW,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAC/D,cACE,CAAC,YACD,SAAS,iBAAiB,mCAC1B;AAEA;AAAA,UACF;AAGA,cAAI,kBAAkB;AACtB,cACE,0BAA0B,UAC1B,OAAO,SAAS,uBAChB;AACA,8BAAkB,OAAO,UAAU,GAAG,qBAAqB;AAAA,UAC7D;AAEA,gBAAM,sBAAsB,YAAY;AAAA,YACtC,CAAC,eAAe,WAAW,eAAe;AAAA,UAC5C;AAEA,gBAAM,gBAAgC;AAAA,YACpC;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR,UAAU;AAAA,YACV,cAAc;AAAA,YACd,cAAc;AAAA,UAChB;AAEA,cAAI;AACJ,cAAI,wBAAwB,IAAI;AAC9B,iCAAqB,CAAC,GAAG,WAAW;AACpC,+BAAmB,mBAAmB,IAAI;AAAA,UAC5C,OAAO;AACL,iCAAqB,CAAC,GAAG,aAAa,aAAa;AAAA,UACrD;AAEA,cAAI;AAAA,YACF,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,QAEA,cAAc,MAAM;AAClB,gBAAM,EAAE,oBAAoB,aAAa,KAAK,IAAI,IAAI;AACtD,gBAAM,kBAAkB,mBAAmB;AAE3C,cAAI,CAAC,KAAM;AAEX,cAAI,iBAAiB;AACnB,kBAAM,aAAa,KAAK;AACxB,kBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,gBAAI,CAAC,UAAU,WAAW,IAAI;AAE5B;AAAA,YACF;AAEA,kBAAM,sBAAsB,YAAY;AAAA,cACtC,CAAC,WAAW,OAAO,eAAe,gBAAgB;AAAA,YACpD;AAEA,kBAAM,gBAAgC;AAAA,cACpC,YAAY,gBAAgB;AAAA,cAC5B;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,cAAc,gBAAgB;AAAA,cAC9B,cAAc;AAAA,YAChB;AAEA,gBAAI;AACJ,gBAAI,wBAAwB,IAAI;AAE9B,mCAAqB,CAAC,GAAG,WAAW;AACpC,iCAAmB,mBAAmB,IAAI;AAAA,YAC5C,OAAO;AAEL,mCAAqB,CAAC,GAAG,aAAa,aAAa;AAAA,YACrD;AAEA,gBAAI;AAAA,cACF,aAAa;AAAA,YACf,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QAEA,iCAAiC,MAAM;AACrC,gBAAM,EAAE,oBAAoB,kBAAkB,aAAa,IAAI,IAAI;AACnE,gBAAM,kBAAkB,mBAAmB;AAC3C,gBAAM,gBAAgB,iBAAiB;AAGvC,cAAI,CAAC,gBAAiB;AAGtB,cACE,CAAC,iBACA,cAAc,aAAa,QAAQ,cAAc,WAAW,MAC7D;AACA,yBAAa;AAAA,UACf;AAAA,QACF;AAAA,QAEA,eAAe,CAAC,YAAY,aAAa;AACvC,gBAAM,EAAE,MAAM,YAAY,IAAI,IAAI;AAElC,cAAI,CAAC,KAAM;AAGX,gBAAM,aAAa,KAAK;AACxB,gBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,cAAI,CAAC,UAAU,WAAW,IAAI;AAE5B;AAAA,UACF;AAEA,gBAAM,WAAW,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAC/D,cAAI,CAAC,SAAU;AAEf,gBAAM,sBAAsB,YAAY;AAAA,YACtC,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AAEA,gBAAM,gBAAgC;AAAA,YACpC;AAAA,YACA;AAAA,YACA;AAAA,YACA,QACE,SAAS,iBAAiB,oCACtB,YAAY,OACZ;AAAA,YACN,UACE,SAAS,iBAAiB,oCACtB,YAAY,OACZ;AAAA,YACN,cAAc,SAAS;AAAA,YACvB,cAAc;AAAA,UAChB;AAEA,cAAI,wBAAwB,IAAI;AAE9B,kBAAM,qBAAqB,CAAC,GAAG,WAAW;AAC1C,+BAAmB,mBAAmB,IAAI;AAC1C,gBAAI,EAAE,aAAa,mBAAmB,CAAC;AAAA,UACzC,OAAO;AAEL,gBAAI,EAAE,aAAa,CAAC,GAAG,aAAa,aAAa,EAAE,CAAC;AAAA,UACtD;AAAA,QACF;AAAA,QAEA,WAAW,MAAM;AACf,cAAI,EAAE,WAAW,MAAM,aAAa,EAAE,CAAC;AACvC,qBAAW;AACX,8BAAoB;AAAA,QACtB;AAAA,QAEA,YAAY,MAAM;AAChB,cAAI,EAAE,YAAY,KAAK,CAAC;AACxB,oBAAU;AACV,6BAAmB;AAAA,QACrB;AAAA,QAEA,WAAW,MAAM;AACf,oBAAU;AACV,6BAAmB;AACnB,cAAI;AAAA,YACF,MAAM;AAAA,YACN,sBAAsB;AAAA,YACtB,iBAAiB,CAAC;AAAA,YAClB,aAAa,CAAC;AAAA,YACd,aAAa;AAAA,YACb,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,gBAAgB;AAAA,YAChB,uBAAuB;AAAA,YACvB,iBAAiB;AAAA,YACjB,uBAAuB;AAAA,UACzB,CAAC;AAAA,QACH;AAAA;AAAA,QAGA,YAAY,CAAC,SAAS,IAAI,EAAE,aAAa,KAAK,CAAC;AAAA,QAC/C;AAAA,QACA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAGA,oBAAoB,MAAM;AACxB,gBAAM,EAAE,sBAAsB,KAAK,IAAI,IAAI;AAE3C,cAAI,CAAC,MAAM;AACT,mBAAO;AAAA,UACT;AAEA,iBAAO,KAAK,UAAU,oBAAoB;AAAA,QAC5C;AAAA,QAEA,mBAAmB,MAAM;AACvB,gBAAM,EAAE,KAAK,IAAI,IAAI;AAErB,iBAAO,MAAM,WAAW,UAAU;AAAA,QACpC;AAAA,QAEA,sBAAsB,MAAM;AAC1B,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,iBAAO,YAAY;AAAA,YACjB,CAAC,WAAW,OAAO,aAAa,QAAQ,OAAO,WAAW;AAAA,UAC5D,EAAE;AAAA,QACJ;AAAA,QAEA,wBAAwB,MAAM;AAC5B,gBAAM,EAAE,MAAM,YAAY,IAAI,IAAI;AAClC,cAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,gBAAM,sBAAgC,CAAC;AAEvC,eAAK,UAAU,QAAQ,CAAC,UAAU,UAAU;AAC1C,kBAAM,aAAa,YAAY;AAAA,cAC7B,CAAC,WAAW,OAAO,eAAe,SAAS;AAAA,YAC7C;AACA,kBAAM,aACJ,eACC,WAAW,aAAa,QAAQ,WAAW,WAAW;AACzD,kBAAM,YACJ,cACA,WAAW,aAAa,QACxB,WAAW,WAAW;AAExB,gBAAI,CAAC,cAAc,CAAC,WAAW;AAC7B,kCAAoB,KAAK,QAAQ,CAAC;AAAA,YACpC;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,QAEA,qBAAqB,MAAM;AACzB,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,iBAAO,YAAY;AAAA,YACjB,CAAC,WAAW,OAAO,aAAa,QAAQ,OAAO,WAAW;AAAA,UAC5D,EAAE;AAAA,QACJ;AAAA,QAEA,aAAa,MAAM;AACjB,gBAAM,EAAE,mBAAmB,qBAAqB,IAAI,IAAI;AACxD,gBAAM,QAAQ,kBAAkB;AAChC,gBAAM,WAAW,qBAAqB;AAEtC,iBAAO,QAAQ,IAAK,WAAW,QAAS,MAAM;AAAA,QAChD;AAAA,QAEA,oBAAoB,CAAC,eAAe;AAClC,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,gBAAM,aAAa,YAAY;AAAA,YAC7B,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AACA,iBAAO,aACH,WAAW,aAAa,QAAQ,WAAW,WAAW,OACtD;AAAA,QACN;AAAA,QAEA,mBAAmB,CAAC,eAAe;AACjC,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,gBAAM,aAAa,YAAY;AAAA,YAC7B,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AACA,iBAAO,aACH,WAAW,aAAa,QAAQ,WAAW,WAAW,OACtD;AAAA,QACN;AAAA,QAEA,kBAAkB,MAAM;AACtB,gBAAM,EAAE,oBAAoB,YAAY,IAAI,IAAI;AAChD,gBAAM,kBAAkB,mBAAmB;AAE3C,cAAI,CAAC,gBAAiB,QAAO;AAE7B,gBAAM,aAAa,YAAY;AAAA,YAC7B,CAAC,WAAW,OAAO,eAAe,gBAAgB;AAAA,UACpD;AAGA,gBAAM,mBAAmB,CAAC,OACxB,CAAC,CAAC,OACA,GAAG,aAAa,QAAQ,GAAG,aAAa,MACvC,GAAG,WAAW,QAAQ,GAAG,WAAW;AAEzC,cAAI,CAAC,iBAAiB,UAAU,GAAG;AACjC,mBAAO;AAAA,UACT;AAEA,iBAAO;AAAA,QACT;AAAA,QAEA,qBAAqB,MAAM;AACzB,gBAAM,EAAE,oBAAoB,YAAY,IAAI,IAAI;AAChD,gBAAM,kBAAkB,mBAAmB;AAE3C,cAAI,CAAC,gBAAiB,QAAO;AAE7B,gBAAM,aAAa,YAAY;AAAA,YAC7B,CAAC,WAAW,OAAO,eAAe,gBAAgB;AAAA,UACpD;AAEA,iBAAO;AAAA,QACT;AAAA,QAEA,cAAc,MAAM;AAClB,gBAAM,EAAE,KAAK,IAAI,IAAI;AAErB,iBAAO,MAAM,SAAS;AAAA,QACxB;AAAA,QAEA,YAAY,CAAC,YAAoB;AAC/B,gBAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AACvC,gBAAM,mBAAmB,UAAU;AACnC,iBAAO,GAAG,QAAQ,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,iBAAiB,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,QAC/F;AAAA,QAEA,gBAAgB,MAAM;AACpB,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,iBAAO;AAAA,QACT;AAAA,QAEA,uCAAuC,MAAM;AAC3C,gBAAM,EAAE,MAAM,YAAY,IAAI,IAAI;AAClC,cAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,gBAAM,sBAAgC,CAAC;AAEvC,eAAK,UAAU,QAAQ,CAAC,UAAU,UAAU;AAC1C,kBAAM,aAAa,YAAY;AAAA,cAC7B,CAAC,WAAW,OAAO,eAAe,SAAS;AAAA,YAC7C;AACA,kBAAM,YACJ,eACC,WAAW,aAAa,QAAQ,WAAW,WAAW;AACzD,kBAAM,YACJ,cACA,WAAW,aAAa,QACxB,WAAW,WAAW;AAGxB,gBAAI,CAAC,aAAa,WAAW;AAC3B,kCAAoB,KAAK,QAAQ,CAAC;AAAA,YACpC;AAAA,UACF,CAAC;AAED,iBAAO;AAAA,QACT;AAAA,QAEA,8BAA8B,MAAM;AAClC,gBAAM,EAAE,mBAAmB,MAAM,QAAQ,IAAI,IAAI;AACjD,gBAAM,YACJ,WAAW,WACP,kBAAkB,GAAG,UACrB,MAAM;AACZ,cAAI,CAAC,UAAW,QAAO,CAAC;AACxB,gBAAM,mBAEF,CAAC;AACL,oBAAU,QAAQ,CAAC,aAAa;AAC9B,kBAAM,YACJ,SAAS,kBAAkB,CAAC,GAAG,SAAS,MAAM;AAEhD,gBAAI,CAAC,iBAAiB,SAAS,GAAG;AAChC,+BAAiB,SAAS,IAAI,CAAC;AAAA,YACjC;AAEA,6BAAiB,SAAS,EAAE,KAAK,QAAQ;AAAA,UAC3C,CAAC;AAED,iBAAO;AAAA,QACT;AAAA;AAAA,QAGA,2BAA2B,CAAC,eAAe;AACzC,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,iBACE,YAAY,KAAK,CAAC,WAAW,OAAO,eAAe,UAAU,KAC7D;AAAA,QAEJ;AAAA,QACA,iCAAiC,CAAC,eAAe;AAC/C,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,gBAAM,SAAS,YAAY;AAAA,YACzB,CAACC,YAAWA,QAAO,eAAe;AAAA,UACpC;AACA,iBAAO,SACH,OAAO,aAAa,QAAQ,OAAO,WAAW,OAC9C;AAAA,QACN;AAAA,QACA,kCAAkC,CAAC,eAAe;AAChD,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,gBAAM,SAAS,YAAY;AAAA,YACzB,CAACA,YAAWA,QAAO,eAAe;AAAA,UACpC;AACA,cAAI,CAAC,OAAQ,QAAO;AACpB,cAAI,OAAO,aAAa,KAAM,QAAO;AACrC,iBAAO;AAAA,QACT;AAAA,QACA,2BAA2B,MAAM;AAC/B,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,iBAAO;AAAA,QACT;AAAA,QACA,oBAAoB,CAAC,aAAa;AAChC,gBAAM,EAAE,MAAM,SAAS,gBAAgB,IAAI,IAAI;AAC/C,cAAI,CAAC,KAAM;AACX,cAAI,gBAAgB;AACpB,cAAI,WAAW,UAAU;AACvB,gBAAI,CAAC,gBAAiB;AACtB,kBAAM,iBACJ,gBAAgB,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,KACxD,gBAAgB,QAAQ,KAAK,CAAC,MAAM,EAAE,eAAe,SAAS,EAAE;AAClE,gBAAI,CAAC,eAAgB;AACrB,4BAAgB,KAAK,UAAU;AAAA,cAC7B,CAAC,MAAM,EAAE,OAAO,eAAe;AAAA,YACjC;AAAA,UACF,OAAO;AACL,4BAAgB,KAAK,UAAU;AAAA,cAC7B,CAAC,MAAM,EAAE,OAAO,SAAS;AAAA,YAC3B;AAAA,UACF;AAGA,cAAI,kBAAkB,IAAI;AAExB;AAAA,UACF;AAEA,cAAI,EAAE,sBAAsB,cAAc,CAAC;AAAA,QAC7C;AAAA,QAEA,iBAAiB,CAAC,YAAY,WAAW;AACvC,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,gBAAM,sBAAsB,YAAY;AAAA,YACtC,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AAEA,cAAI,wBAAwB,IAAI;AAC9B,kBAAM,qBAAqB,CAAC,GAAG,WAAW;AAC1C,+BAAmB,mBAAmB,IAAI;AAAA,cACxC,GAAG,mBAAmB,mBAAmB;AAAA,cACzC,cAAc;AAAA,YAChB;AACA,gBAAI,EAAE,aAAa,mBAAmB,CAAC;AAAA,UACzC;AAAA,QACF;AAAA,QAEA,iBAAiB,CAAC,eAAe;AAC/B,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,gBAAM,aAAa,YAAY;AAAA,YAC7B,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AACA,iBAAO,aAAa,WAAW,eAAe;AAAA,QAChD;AAAA,QACA,kBAAkB,CAAC,eAAe;AAChC,gBAAM,EAAE,iBAAiB,SAAS,KAAK,IAAI,IAAI;AAC/C,cAAI,WAAW,UAAU;AACvB,gBAAI,CAAC,gBAAiB,QAAO;AAE7B,gBAAI,MAAM,gBAAgB,QAAQ;AAAA,cAChC,CAAC,MAAM,EAAE,eAAe;AAAA,YAC1B;AACA,gBAAI,QAAQ,IAAI;AACd,oBAAM,gBAAgB,QAAQ;AAAA,gBAC5B,CAAC,MAAM,EAAE,OAAO;AAAA,cAClB;AAAA,YACF;AACA,mBAAO,QAAQ,KAAK,MAAM,IAAI;AAAA,UAChC,OAAO;AACL,gBAAI,CAAC,KAAM,QAAO;AAClB,kBAAM,MAAM,KAAK,UAAU,UAAU,CAAC,MAAM,EAAE,OAAO,UAAU;AAC/D,mBAAO,QAAQ,KAAK,MAAM,IAAI;AAAA,UAChC;AAAA,QACF;AAAA;AAAA,QAGA,+BAA+B,CAAC,eAAe;AAC7C,gBAAM,EAAE,gBAAgB,IAAI,IAAI;AAChC,gBAAM,WAAW,iBAAiB,QAAQ;AAAA,YACxC,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AAEA,iBAAO,YAAY;AAAA,QACrB;AAAA,QACA,6BAA6B,MAAM;AACjC,gBAAM,EAAE,gBAAgB,IAAI,IAAI;AAChC,iBAAO,iBAAiB,cAAc;AAAA,QACxC;AAAA,QACA,mBAAmB,MAAM;AACvB,gBAAM,EAAE,gBAAgB,IAAI,IAAI;AAChC,iBAAO;AAAA,QACT;AAAA,QACA,oBAAoB,CAAC,oBAAoB;AACvC,cAAI,EAAE,gBAAgB,CAAC;AAAA,QACzB;AAAA,QACA,0BAA0B,CAAC,0BAA0B;AACnD,cAAI,EAAE,sBAAsB,CAAC;AAAA,QAC/B;AAAA,QACA,0BAA0B,MAAM;AAC9B,gBAAM,EAAE,sBAAsB,IAAI,IAAI;AACtC,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;ACv/BA,SAAS,SAAS;AAKX,IAAM,0BAA0B;AAAA,EACrC,WAAW;AAAA,EACX,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,cAAc;AAChB;AAQO,IAAM,8BAA8B,EAAE,KAAK;AAAA,EAChD,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,wBAAwB;AAC1B,CAAC;;;ACZM,IAAM,uBAAuB,CAClC,WACsB;AACtB,QAAM,UAA4D;AAAA,IAChE,CAAC,wBAAwB,SAAS,GAAG;AAAA,MACnC,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,CAAC,wBAAwB,mBAAmB,GAAG;AAAA,MAC7C,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,CAAC,wBAAwB,mBAAmB,GAAG;AAAA,MAC7C,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,CAAC,wBAAwB,YAAY,GAAG;AAAA,MACtC,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO,QAAQ,MAAM;AACvB;AAOO,IAAM,kBAAkB,CAAC,YAA4B;AAC1D,QAAM,eAAe,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC;AACjD,QAAM,QAAQ,KAAK,MAAM,eAAe,IAAI;AAC5C,QAAM,UAAU,KAAK,MAAO,eAAe,OAAQ,EAAE;AACrD,QAAM,OAAO,eAAe;AAE5B,SAAO,GAAG,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,IAAI,EAAE,SAAS,GAAG,GAAG,CAAC;AAC/G;AAOO,IAAM,wBAAwB,CAAC,YAA8B;AAClE,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,SAAO,QAAQ,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,IAAI;AACrE;AAOO,IAAM,wBAAwB,CAAC,eAA+B;AACnE,QAAM,OAAO,IAAI,KAAK,UAAU;AAChC,QAAM,MAAM,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACrD,QAAM,QAAQ,OAAO,KAAK,YAAY,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AAC5D,QAAM,OAAO,KAAK,eAAe;AACjC,SAAO,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI;AAChC;;;AH9EO,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;AIsHI;AA/CJ,IAAM,OAAO,CAA8B;AAAA,EACzC;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,MAAI,cAAc;AAClB,MAAI,gBAAgB;AAGpB,QAAM,eAAe;AAAA,IACnB,OAAO;AAAA,IACP,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAEA,gBAAc,aAAa,IAAI,KAAK,aAAa;AAGjD,QAAM,iBAAiB;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AAEA,kBAAgB,eAAe,MAAM,KAAK,eAAe;AAEzD,QAAM,cAAc;AACpB,QAAM,YAAY,MAAO;AAEzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,aAAa,eAAe,OAAO,SAAS;AAAA,MACtE,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,eAAQ;;;ACtBX,SAMe,OAAAC,MANf;AAxGJ,IAAM,yBAAyB;AAAA,EAC7B,OAAO;AAAA,IACL,SACE;AAAA,IACF,WACE;AAAA,IACF,UACE;AAAA,IACF,UACE;AAAA,EACJ;AAAA,EACA,SAAS;AAAA,IACP,SACE;AAAA,IACF,WACE;AAAA,IACF,UACE;AAAA,IACF,UACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,SACE;AAAA,IACF,WACE;AAAA,IACF,UACE;AAAA,IACF,UACE;AAAA,EACJ;AACF;AAKA,IAAM,eAAe;AAAA,EACnB,eAAe;AAAA,EACf,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,eAAe;AACjB;AA0CA,IAAM,SAAS,CAAC;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,MAAmB;AAEjB,QAAM,cAAc,aAAa,IAAI;AACrC,QAAM,iBAAiB,uBAAuB,OAAO,EAAE,MAAM;AAE7D,QAAM,cACJ;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,gBAAgB,aAAa,SAAS;AAAA,MACjE;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,oBAAY,gBAAAA,KAAC,UAAK,WAAU,0BAA0B,oBAAS;AAAA,QAC/D;AAAA,QACA,aAAa,gBAAAA,KAAC,UAAK,WAAU,0BAA0B,qBAAU;AAAA;AAAA;AAAA,EACpE;AAEJ;AAEA,IAAO,iBAAQ;;;AC1Hf,SAAS,YAAY;AAqJf,SAIE,OAAAC,MAJF,QAAAC,aAAA;AA/IN,IAAMC,0BAAyB;AAAA,EAC7B,OAAO;AAAA,IACL,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA,UAAU;AAAA,IACR,OACE;AAAA,IACF,SACE;AAAA,IACF,SACE;AAAA,IACF,MAAM;AAAA,IACN,OACE;AAAA,EACJ;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,eAAe;AAAA,IACb,OACE;AAAA,IACF,OACE;AAAA,IACF,OACE;AAAA,IACF,OACE;AAAA,EACJ;AAAA,EACA,cAAc;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,cAAc;AAChB;AAKA,IAAMC,gBAAe;AAAA,EACnB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAEA,IAAM,oBAAoB;AAAA,EACxB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AA4DA,IAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,GAAG;AACL,MAAkB;AAEhB,QAAM,cAAcA,cAAa,IAAI;AACrC,QAAM,kBAAkB,kBAAkB,IAAI;AAC9C,QAAM,mBAAmBD,wBAAuB,OAAO,KAAK,CAAC;AAC7D,QAAM,iBACJ,OAAO,qBAAqB,WACxB,mBACE,iBAA4C,MAAM,KACnD,iBAA4C,SAC7C;AAEN,QAAM,cACJ;AAEF,QAAM,kBAAkB;AACxB,MAAI,YAAY,gBAAgB;AAC9B,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,aAAa,gBAAgB,aAAa,SAAS;AAAA,QAChE,GAAG;AAAA,QAEJ;AAAA,0BAAAD,KAAC,QAAK,MAAM,IAAI,WAAU,gBAAe,eAAY,QAAO;AAAA,UAE3D,sBACC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,eAAY;AAAA,cACZ,WAAU;AAAA;AAAA,UACZ;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACA,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,gBAAgB,aAAa,SAAS;AAAA,MAChE,GAAG;AAAA,MAEH;AAAA,oBACC,gBAAAD,KAAC,UAAK,WAAW,GAAG,iBAAiB,eAAe,GAAI,oBAAS;AAAA,QAElE;AAAA,QACA,aACC,gBAAAA,KAAC,UAAK,WAAW,GAAG,iBAAiB,eAAe,GACjD,qBACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,IAAO,gBAAQ;;;ACrGP,gBAAAI,MAIF,QAAAC,aAJE;AAlBR,IAAM,aAAa,CAAC;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,eAAe;AACjB,MAAuB;AACrB,QAAM,eAAe,SAAS;AAC9B,QAAM,qBACJ,eAAe;AAEjB,SACE,gBAAAA,MAAC,SAAI,WAAU,qGAEZ;AAAA,aACC,gBAAAD,KAAC,SAAI,KAAK,OAAO,KAAK,cAAc,WAAU,uBAAsB;AAAA,IAItE,gBAAAC,MAAC,SAAI,WAAU,8DAEb;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,WAAU;AAAA,UAET;AAAA;AAAA,MACH;AAAA,MAGA,gBAAAA,KAAC,gBAAK,WAAU,oEACb,8BACH;AAAA,OACF;AAAA,IAGC,cAAc,iBACb,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAU;AAAA,QAET;AAAA;AAAA,IACH;AAAA,KAEJ;AAEJ;AAEA,IAAO,qBAAQ;;;ACtHf,SAAS,kBAAiD;AAgE9C,gBAAAE,MA8EF,QAAAC,aA9EE;AApDZ,IAAM,6BAA6B;AAAA,EACjC,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,2BAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AACX;AAEA,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAEA,IAAM,WAAW;AAAA,EACf,CACE;AAAA,IACE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,iBAAiB,2BAA2B,SAAS;AAC3D,UAAM,eAAe,yBAAyB,OAAO;AACrD,UAAM,eAAe,gBAAgB,OAAO;AAE5C,UAAM,QAAuB;AAAA,MAC3B,OAAO,OAAO,UAAU,WAAW,GAAG,KAAK,OAAO;AAAA,MAClD,QAAQ,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,IACvD;AAGA,QAAI,YAAY,UAAU,QAAQ,GAAG;AACnC,aACE,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAW,GAAG,iBAAiB,cAAc,SAAS;AAAA,UACrD,GAAG;AAAA,UAEH,gBAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UACjC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,GAAG,cAAc,cAAc;AAAA,cAC1C,OAAO,UAAU,QAAQ,IAAI,EAAE,OAAO,MAAM,IAAI;AAAA;AAAA,YAF3C;AAAA,UAGP,CACD;AAAA;AAAA,MACH;AAAA,IAEJ;AAGA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,cAAc,gBAAgB,SAAS;AAAA,QACrD;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAGA,IAAM,eAAe;AAAA,EACnB,CAAC,OAAO,QAAQ,gBAAAA,KAAC,YAAS,KAAU,SAAQ,QAAQ,GAAG,OAAO;AAChE;AAEA,IAAM,iBAAiB,WAGrB,CAAC,OAAO,QAAQ,gBAAAA,KAAC,YAAS,KAAU,SAAQ,YAAY,GAAG,OAAO,CAAE;AAEtE,IAAM,oBAAoB,WAGxB,CAAC,OAAO,QAAQ,gBAAAA,KAAC,YAAS,KAAU,SAAQ,eAAe,GAAG,OAAO,CAAE;AAEzE,IAAM,kBAAkB,WAGtB,CAAC,OAAO,QAAQ,gBAAAA,KAAC,YAAS,KAAU,SAAQ,WAAW,GAAG,OAAO,CAAE;AAWrE,IAAM,eAAe;AAAA,EACnB,CACE;AAAA,IACE,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,0BAAAA,MAAC,SAAI,WAAU,8BACZ;AAAA,0BAAc,gBAAAD,KAAC,kBAAe,OAAO,IAAI,QAAQ,IAAI;AAAA,YAEtD,gBAAAC,MAAC,SAAI,WAAU,oBACZ;AAAA,2BAAa,gBAAAD,KAAC,gBAAa,OAAM,OAAM,QAAQ,IAAI;AAAA,cAEnD,mBAAmB,gBAAAA,KAAC,gBAAa,OAAc,SAAQ,SAAQ;AAAA,eAClE;AAAA,aACF;AAAA,UAEC,eACC,gBAAAC,MAAC,SAAI,WAAU,mCACb;AAAA,4BAAAD,KAAC,qBAAkB,OAAO,IAAI,QAAQ,IAAI;AAAA,YAC1C,gBAAAA,KAAC,qBAAkB,OAAO,IAAI,QAAQ,IAAI;AAAA,aAC5C;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAWA,IAAM,eAAe;AAAA,EACnB,CACE;AAAA,IACE,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,gBAAAA,KAAC,SAAI,KAAU,WAAW,GAAG,aAAa,SAAS,GAAI,GAAG,OACvD,gBAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UACjC,gBAAAC,MAAC,SAAgB,WAAU,kCACxB;AAAA,oBAAc,gBAAAD,KAAC,kBAAe,OAAO,IAAI,QAAQ,IAAI;AAAA,MAEtD,gBAAAC,MAAC,SAAI,WAAU,oBACZ;AAAA,qBAAa,gBAAAD,KAAC,gBAAa,OAAM,OAAM,QAAQ,IAAI;AAAA,QAEnD,mBACC,gBAAAA,KAAC,gBAAa,OAAc,SAAQ,SAAQ;AAAA,SAEhD;AAAA,SATQ,KAUV,CACD,GACH;AAAA,EAEJ;AACF;AASA,IAAM,gBAAgB;AAAA,EACpB,CACE,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,MAAM,YAAY,IAAI,GAAG,MAAM,GACrE,QACG;AACH,WACE,gBAAAC,MAAC,SAAI,KAAU,WAAW,GAAG,UAAU,SAAS,GAAI,GAAG,OACpD;AAAA,oBACC,gBAAAD,KAAC,SAAI,WAAU,uBACZ,gBAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAAC,GAAG,UACnC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,GAAG,MAAM,OAAO;AAAA,UACvB,QAAQ;AAAA;AAAA,QAFH;AAAA,MAGP,CACD,GACH;AAAA,MAGF,gBAAAA,KAAC,SAAI,WAAU,aACZ,gBAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,aAChC,gBAAAA,KAAC,SAAmB,WAAU,kBAC3B,gBAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAACE,IAAG,aACnC,gBAAAF;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,GAAG,MAAM,OAAO;AAAA,UACvB,QAAQ;AAAA;AAAA,QAFH;AAAA,MAGP,CACD,KAPO,QAQV,CACD,GACH;AAAA,OACF;AAAA,EAEJ;AACF;;;ACpPA,SAAS,YAAAG,YAAU,aAAAC,aAAW,WAAAC,UAAS,eAAAC,oBAA8B;;;ACArE;AAAA,EACE,cAAAC;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,SAAS,aAAAC,kBAAiB;;;ACgC3B,gBAAAC,MAQF,QAAAC,aARE;AAVR,IAAM,iBAAiB,CAAC,EAAE,OAAO,OAAO,YAAY,MAA2B;AAC7E,QAAM,eAAe,SAAS;AAC9B,QAAM,qBACJ,eACA;AAEF,SACE,gBAAAA,MAAC,SAAI,WAAU,6EAEb;AAAA,oBAAAD,KAAC,SAAI,WAAU,oCACb,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,KAAI;AAAA,QACJ,WAAU;AAAA;AAAA,IACZ,GACF;AAAA,IAGA,gBAAAC,MAAC,SAAI,WAAU,6CAEb;AAAA,sBAAAD,KAAC,SAAI,WAAU,8EAEb,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,WAAU;AAAA,UAET;AAAA;AAAA,MACH,GACF;AAAA,MAGA,gBAAAA,KAAC,SAAI,WAAU,+DAEb,0BAAAA,KAAC,gBAAK,WAAU,yEACb,8BACH,GACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,IAAO,yBAAQ;;;AC5Ef,SAAS,WAAW,YAAY,iBAAiB;AAwG3C,SASM,OAAAE,MATN,QAAAC,aAAA;AA7CN,IAAM,kBAAkB,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB,CAAC,IAAI,IAAI,IAAI,GAAG;AAAA,EACtC;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,MAA4B;AAC1B,QAAM,aAAa,cAAc,KAAK,eAAe;AAErD,QAAM,iBAAiB,MAAM;AAC3B,QAAI,cAAc,GAAG;AACnB,mBAAa,cAAc,CAAC;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,aAAa,MAAM;AACvB,QAAI,cAAc,YAAY;AAC5B,mBAAa,cAAc,CAAC;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,2BAA2B,CAAC,MAAsC;AACtE,QAAI,sBAAsB;AACxB,2BAAqB,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,cAAc,gBAAgB;AACpC,QAAM,aAAa,gBAAgB;AAEnC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAGJ;AAAA,wBAAAA,MAAC,UAAK,WAAU,oDACb;AAAA;AAAA,UAAU;AAAA,UAAK;AAAA,UAAW;AAAA,UAAE;AAAA,WAC/B;AAAA,QAGA,gBAAAA,MAAC,SAAI,WAAU,6FAEZ;AAAA,kCACC,gBAAAA,MAAC,SAAI,WAAU,YACb;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU;AAAA,gBACV,WAAU;AAAA,gBACV,cAAW;AAAA,gBAEV,8BAAoB,IAAI,CAAC,WACxB,gBAAAC,MAAC,YAAoB,OAAO,QACzB;AAAA;AAAA,kBAAO;AAAA,qBADG,MAEb,CACD;AAAA;AAAA,YACH;AAAA,YACA,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM;AAAA,gBACN,QAAO;AAAA,gBACP,WAAU;AAAA;AAAA,YACZ;AAAA,aACF;AAAA,UAIF,gBAAAC,MAAC,UAAK,WAAU,oDAAmD;AAAA;AAAA,YACzD;AAAA,YAAY;AAAA,YAAK;AAAA,aAC3B;AAAA,UAGA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,UAAU;AAAA,cACV,WAAW;AAAA,gBACT;AAAA,gBACA,cACI,kCACA;AAAA,cACN;AAAA,cACA,cAAW;AAAA,cAEX;AAAA,gCAAAD,KAAC,aAAU,MAAM,IAAI,QAAO,QAAO,WAAU,oBAAmB;AAAA,gBAChE,gBAAAA,KAAC,UAAK,WAAU,uDAAsD,sBAEtE;AAAA;AAAA;AAAA,UACF;AAAA,UAGA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,UAAU;AAAA,cACV,WAAW;AAAA,gBACT;AAAA,gBACA,aACI,kCACA;AAAA,cACN;AAAA,cACA,cAAW;AAAA,cAEX;AAAA,gCAAAD,KAAC,UAAK,WAAU,uDAAsD,wBAEtE;AAAA,gBACA,gBAAAA,KAAC,cAAW,MAAM,IAAI,QAAO,QAAO,WAAU,oBAAmB;AAAA;AAAA;AAAA,UACnE;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;;;AFuBT,gBAAAE,MASF,QAAAC,aATE;AAhJC,SAAS,aACd,MACA,UAA+B,CAAC,GAChC;AACA,QAAM,EAAE,cAAc,MAAM,IAAI;AAGhC,QAAM,kBAAkB,MAAM;AAC5B,QAAI,CAAC,eAAe,WAAW,WAAW,QAAW;AACnD,aAAO,EAAE,QAAQ,MAAM,WAAW,KAAK;AAAA,IACzC;AAEA,UAAM,SAAS,IAAI,gBAAgB,WAAW,SAAS,MAAM;AAC7D,UAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,UAAM,OAAO,OAAO,IAAI,MAAM;AAE9B,QAAI,UAAU,SAAS,SAAS,SAAS,SAAS,SAAS;AACzD,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,WAAW,KAAK,YAAY;AAAA,MAC9B;AAAA,IACF;AAEA,WAAO,EAAE,QAAQ,MAAM,WAAW,KAAK;AAAA,EACzC;AAEA,QAAM,eAAe,gBAAgB;AACrC,QAAM,CAAC,YAAY,aAAa,IAAI;AAAA,IAClC,aAAa;AAAA,EACf;AACA,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC,aAAa;AAAA,EACf;AAGA,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,WAAW,OAAW;AAErD,UAAM,MAAM,IAAI,IAAI,WAAW,SAAS,IAAI;AAC5C,UAAM,SAAS,IAAI;AAEnB,QAAI,cAAc,eAAe;AAC/B,aAAO,IAAI,UAAU,UAAU;AAC/B,aAAO,IAAI,QAAQ,cAAc,YAAY,CAAC;AAAA,IAChD,OAAO;AACL,aAAO,OAAO,QAAQ;AACtB,aAAO,OAAO,MAAM;AAAA,IACtB;AAGA,eAAW,QAAQ,aAAa,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AAAA,EACxD,GAAG,CAAC,YAAY,eAAe,WAAW,CAAC;AAE3C,QAAM,aAAa,CAAC,WAAmB;AACrC,QAAI,eAAe,QAAQ;AACzB,UAAI,kBAAkB,OAAO;AAC3B,yBAAiB,MAAM;AAAA,MACzB,WAAW,kBAAkB,QAAQ;AACnC,sBAAc,IAAI;AAClB,yBAAiB,IAAI;AAAA,MACvB;AAAA,IACF,OAAO;AACL,oBAAc,MAAM;AACpB,uBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,aAAa,QAAQ,MAAM;AAC/B,QAAI,CAAC,cAAc,CAAC,eAAe;AACjC,aAAO;AAAA,IACT;AAEA,WAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9B,YAAM,SAAS,EAAE,UAAqB;AACtC,YAAM,SAAS,EAAE,UAAqB;AAEtC,UAAI,OAAO,WAAW,YAAY,OAAO,WAAW,UAAU;AAC5D,cAAM,aAAa,OAAO,cAAc,MAAM;AAC9C,eAAO,kBAAkB,QAAQ,aAAa,CAAC;AAAA,MACjD;AAEA,UAAI,OAAO,WAAW,YAAY,OAAO,WAAW,UAAU;AAC5D,eAAO,kBAAkB,QAAQ,SAAS,SAAS,SAAS;AAAA,MAC9D;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,YAAY,aAAa,CAAC;AAEpC,SAAO,EAAE,YAAY,YAAY,eAAe,WAAW;AAC7D;AA4BA,IAAM,uBAAuB,CAAC,aAAwB;AACpD,SAAO,SAAS,IAAI,UAAU,CAAC,UAAU;AACvC,QACE,eAAe,KAAK,MACnB,MAAM,SAAS,gBAAgB,MAAM,SAAS,cAC/C;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAKA,IAAM,2BAA2B,CAC/B,QACA,cACA,uBACG;AACH,MAAI,OAAO,WAAW;AACpB,WAAO,OAAO;AAAA,EAChB;AAEA,MAAI,OAAO,OAAO;AAChB,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO,SAAS;AAAA,QACvB,aAAa,OAAO,eAAe;AAAA;AAAA,IACrC;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAU,eACb;AAAA,oBAAAD,KAAC,OAAE,WAAU,4CACV,iBAAO,SAAS,cACnB;AAAA,IACA,gBAAAA,KAAC,OAAE,WAAU,yBACV,iBAAO,eAAe,oBACzB;AAAA,KACF;AAEJ;AAKA,IAAM,uBAAuB,CAC3B,QACA,cACA,uBACG;AACH,MAAI,QAAQ,WAAW;AACrB,WAAO,OAAO;AAAA,EAChB;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ,SAAS;AAAA,MACxB,aAAa,QAAQ,eAAe;AAAA,MACpC,YAAY,QAAQ;AAAA,MACpB,YAAY,QAAQ;AAAA,MACpB,eAAe,QAAQ;AAAA,MACvB,eAAe,QAAQ;AAAA,MACvB,cAAc,QAAQ;AAAA;AAAA,EACxB;AAEJ;AAKA,IAAM,qBAAqB,CACzB,SACA,UACA,WACA,UACA,cACA,eACG;AACH,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,YAAY,aAAa;AAAA,MAC3B;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,WAAW;AAAA,cACT;AAAA,cACA;AAAA,YACF;AAAA,YACC,GAAG;AAAA,YAEH,+BAAqB,QAAQ;AAAA;AAAA,QAChC;AAAA,QACA,gBAAAA,KAAC,SAAI,WAAU,4BAA4B,wBAAa;AAAA;AAAA;AAAA,EAC1D;AAEJ;AAEA,IAAM,QAAQE;AAAA,EACZ,CACE;AAAA,IACE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA,qBAAqB;AAAA,IACrB;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,6BAAmD;AAAA,MACvD,OAAO;AAAA,MACP,aACE;AAAA,IACJ;AAEA,UAAM,oBAAsC;AAAA,MAC1C,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAEA,UAAM,2BACJ,uBAAuB;AACzB,UAAM,kBAAkB,cAAc;AAGtC,QAAI,aAAa;AACf,YAAM,iBAAiB,cAAc,aACnC,gBAAAF,KAAC,iBAAc,MAAM,GAAG,SAAS,GAAG,YAAY,OAAO;AAEzD,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI,oBAAoB;AACtB,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,2BAA2B,SAAS;AAAA,QACpC,2BAA2B,eAAe;AAAA,MAC5C;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,QAAI,WAAW;AACb,YAAM,eAAe;AAAA,QACnB;AAAA,QACA,kBAAkB,SAAS;AAAA,QAC3B,kBAAkB,eAAe;AAAA,MACnC;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,YAAY,aAAa;AAAA,QAC3B;AAAA,QAEA,0BAAAC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,WAAW;AAAA,cACT,YAAY,aAAa;AAAA,cACzB,YAAY,aAAa;AAAA,cACzB;AAAA,cACA;AAAA,YACF;AAAA,YACC,GAAG;AAAA,YAGH;AAAA,eAAC,SAAS,QAAQ,QAAQ,EAAE;AAAA,gBAC3B,CAAC,UAAU,eAAe,KAAK,KAAK,MAAM,SAAS;AAAA,cACrD,KAAK,gBAAAD,KAAC,aAAQ,WAAU,WAAU,sBAAQ;AAAA,cACzC;AAAA;AAAA;AAAA,QACH;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,MAAM,cAAc;AAEpB,IAAM,cAAcE,YAGlB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B,gBAAAF;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW,GAAG,+BAA+B,SAAS;AAAA,IACrD,GAAG;AAAA;AACN,CACD;AACD,YAAY,cAAc;AAM1B,IAAM,YAAYE;AAAA,EAChB,CAAC,EAAE,WAAW,UAAU,WAAW,GAAG,MAAM,GAAG,QAC7C,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,YAAY,aAAa;AAAA,QACzB;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AACA,UAAU,cAAc;AAMxB,IAAM,cAAcE;AAAA,EAClB,CAAC,EAAE,UAAU,WAAW,WAAW,GAAG,MAAM,GAAG,QAC7C,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,YAAY,aAAa;AAAA,QACzB;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AACA,YAAY,cAAc;AAE1B,IAAM,qBAAqB;AAAA,EACzB,SAAS;AAAA,IACP,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,SACE;AAAA,IACF,mBACE;AAAA,IACF,YAAY;AAAA,EACd;AACF;AAOA,IAAM,WAAWE;AAAA,EACf,CACE;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,UAAU,aAAa,KAAK;AAAA,UAC5B,UAAU,cAAc,CAAC,YAAY,KAAK;AAAA,UAC1C,mBAAmB,KAAK,EAAE,OAAO;AAAA,UACjC;AAAA,QACF;AAAA,QACA,iBAAe,UAAU;AAAA,QACxB,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,SAAS,cAAc;AAWvB,IAAM,YAAYE;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,cAAc,MAAM;AACxB,UAAI,YAAY,QAAQ;AACtB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,UACZ;AAAA,QACF;AAAA,QACA,SAAS;AAAA,QACR,GAAG;AAAA,QAEJ,0BAAAC,MAAC,SAAI,WAAU,2BACZ;AAAA;AAAA,UACA,YACC,gBAAAA,MAAC,SAAI,WAAU,iBACZ;AAAA,8BAAkB,SACjB,gBAAAD,KAAC,WAAQ,MAAM,IAAI,QAAO,QAAO,WAAU,iBAAgB;AAAA,YAE5D,kBAAkB,UACjB,gBAAAA,KAACG,YAAA,EAAU,MAAM,IAAI,QAAO,QAAO,WAAU,iBAAgB;AAAA,aAEjE;AAAA,WAEJ;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AACA,UAAU,cAAc;AAExB,IAAM,YAAYD,YAGhB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B,gBAAAF;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,UAAU,cAAc;AAExB,IAAM,eAAeE,YAGnB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B,gBAAAF;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,aAAa,cAAc;AAK3B,IAAO,gBAAQ;;;AGjlBf,SAAS,aAAAI,YAAW,YAAAC,WAAU,aAAa,WAAAC,gBAAe;AA2CnD,IAAM,iBAAiB,CAC5B,gBACA,UAAiC,CAAC,MACT;AACzB,QAAM,EAAE,cAAc,MAAM,IAAI;AAGhC,QAAM,kBAAkB,YAAY,MAAsB;AACxD,QAAI,CAAC,eAAe,WAAW,WAAW,QAAW;AACnD,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,IAAI,gBAAgB,WAAW,OAAO,SAAS,MAAM;AACpE,UAAM,sBAAsB,eAAe,IAAI,CAAC,YAAY;AAAA,MAC1D,GAAG;AAAA,MACH,YAAY,OAAO,WAAW,IAAI,CAAC,aAAa;AAC9C,cAAM,WAAW,OAAO,IAAI,UAAU,SAAS,GAAG,EAAE;AACpD,cAAM,cAAc,WAAW,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO,IAAI,CAAC;AACtE,eAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,EAAE;AAEF,WAAO;AAAA,EACT,GAAG,CAAC,gBAAgB,WAAW,CAAC;AAEhC,QAAM,CAAC,eAAe,gBAAgB,IACpCD,UAAyB,eAAe;AAI1C,QAAM,gBAAgBC,SAAQ,MAAM;AAClC,UAAM,UAAoC,CAAC;AAE3C,eAAW,UAAU,eAAe;AAClC,iBAAW,YAAY,OAAO,YAAY;AACxC,YAAI,SAAS,eAAe,SAAS,YAAY,SAAS,GAAG;AAC3D,kBAAQ,SAAS,GAAG,IAAI,SAAS;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,aAAa,CAAC;AAElB,QAAM,mBAAmB,OAAO,KAAK,aAAa,EAAE,SAAS;AAK7D,QAAM,gBAAgB,YAAY,CAAC,YAA4B;AAC7D,qBAAiB,OAAO;AAAA,EAC1B,GAAG,CAAC,CAAC;AAKL,QAAM,eAAe,YAAY,MAAM;AACrC,QAAI,CAAC,eAAe,WAAW,WAAW,QAAW;AACnD;AAAA,IACF;AAEA,UAAM,MAAM,IAAI,IAAI,WAAW,OAAO,SAAS,IAAI;AACnD,UAAM,SAAS,IAAI;AAGnB,eAAW,UAAU,eAAe;AAClC,iBAAW,YAAY,OAAO,YAAY;AACxC,cAAM,WAAW,UAAU,SAAS,GAAG;AAEvC,YAAI,SAAS,eAAe,SAAS,YAAY,SAAS,GAAG;AAC3D,iBAAO,IAAI,UAAU,SAAS,YAAY,KAAK,GAAG,CAAC;AAAA,QACrD,OAAO;AACL,iBAAO,OAAO,QAAQ;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAGA,eAAW,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AAAA,EAC/D,GAAG,CAAC,eAAe,WAAW,CAAC;AAK/B,QAAM,eAAe,YAAY,MAAM;AACrC,UAAM,iBAAiB,cAAc,IAAI,CAAC,YAAY;AAAA,MACpD,GAAG;AAAA,MACH,YAAY,OAAO,WAAW,IAAI,CAAC,cAAc;AAAA,QAC/C,GAAG;AAAA,QACH,aAAa,CAAC;AAAA,MAChB,EAAE;AAAA,IACJ,EAAE;AAEF,qBAAiB,cAAc;AAG/B,QAAI,eAAe,WAAW,WAAW,QAAW;AAClD,YAAM,MAAM,IAAI,IAAI,WAAW,OAAO,SAAS,IAAI;AACnD,YAAM,SAAS,IAAI;AAEnB,iBAAW,UAAU,eAAe;AAClC,mBAAW,YAAY,OAAO,YAAY;AACxC,iBAAO,OAAO,UAAU,SAAS,GAAG,EAAE;AAAA,QACxC;AAAA,MACF;AAEA,iBAAW,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AAAA,IAC/D;AAAA,EACF,GAAG,CAAC,eAAe,WAAW,CAAC;AAG/B,EAAAF,WAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,WAAW,QAAW;AACnD;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM;AAC3B,uBAAiB,gBAAgB,CAAC;AAAA,IACpC;AAEA,eAAW,OAAO,iBAAiB,YAAY,cAAc;AAC7D,WAAO,MACL,WAAW,OAAO,oBAAoB,YAAY,cAAc;AAAA,EACpE,GAAG,CAAC,aAAa,eAAe,CAAC;AAEjC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACnLA,SAAS,KAAAG,IAAG,uBAAuB;AACnC;AAAA,EAEE,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,OAIK;;;ACZP,SAAS,cAAAC,aAAY,SAAS,YAAY;AAC1C;AAAA,EACE,cAAAC;AAAA,EAGA,aAAAC;AAAA,EACA;AAAA,EACA;AAAA,EAIA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA;AAAA,EAEA,YAAAC;AAAA,OAGK;AACP,SAAS,oBAAoB;AAC7B,SAAS,UAAAC,SAAkB,gBAAgB;;;ACpB3C,SAAoB,aAAAC,YAAW,aAAa;AAC5C,SAAS,SAAS;;;ACWX,IAAM,eAAe,CAAC,QAAyB;AACpD,QAAM,eACJ;AACF,SAAO,aAAa,KAAK,GAAG;AAC9B;AAQA,IAAM,qBAAqB,CACzB,SAC+C;AAC/C,MAAI,SAAS,WAAY,QAAO;AAEhC,QAAM,oBACJ,SAAS,iBACR,KAAK,SAAS,cAAc,KAC3B,gCAAgC,KAAK,IAAI;AAE7C,MAAI,kBAAmB,QAAO;AAE9B,QAAM,kBACJ,SAAS,0BACR,KAAK,SAAS,uBAAuB,KACpC,yCAAyC,KAAK,IAAI;AAEtD,MAAI,gBAAiB,QAAO;AAE5B,SAAO;AACT;AAQA,IAAM,mBAAmB,CAAC,aAAoC;AAC5D,QAAM,WAAW,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,CAAC;AACtD,SAAO,YAAY;AACrB;AASA,IAAM,mBAAmB,CACvB,UACA,iBACkB;AAClB,QAAM,QAAQ,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAChD,QAAM,CAAC,OAAO,MAAM,IAAI;AAExB,MAAI,UAAU,WAAW,OAAQ,QAAO;AACxC,MAAI,UAAU,YAAY,OAAQ,QAAO;AACzC,MAAI,UAAU,UAAU,OAAQ,QAAO;AAEvC,QAAM,IAAI,aAAa,IAAI,GAAG;AAC9B,MAAI,EAAG,QAAO;AAEd,SAAO;AACT;AAQO,IAAM,oBAAoB,CAAC,QAA+B;AAC/D,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,GAAG;AACrB,UAAM,WAAW,mBAAmB,EAAE,SAAS,YAAY,CAAC;AAE5D,QAAI,CAAC,SAAU,QAAO;AAEtB,QAAI,aAAa,YAAY;AAC3B,aAAO,iBAAiB,EAAE,QAAQ;AAAA,IACpC;AAEA,WAAO,iBAAiB,EAAE,UAAU,EAAE,YAAY;AAAA,EACpD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,IAAM,qBAAqB,CAAC,YAA4B;AAC7D,SAAO,0CAA0C,OAAO;AAC1D;;;AD0GgB,gBAAAC,MAmCF,QAAAC,aAnCE;AA7MhB,IAAMC,gBAAe;AAAA,EACnB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAyEA,IAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB;AAAA,EACA,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AACrB,MAAkB;AAChB,QAAM,UAAU,MAAM;AAGtB,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,cAAe;AAE/B,UAAM,eAAe,CAAC,UAAoC;AACxD,UAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,aAAS,iBAAiB,WAAW,YAAY;AACjD,WAAO,MAAM,SAAS,oBAAoB,WAAW,YAAY;AAAA,EACnE,GAAG,CAAC,QAAQ,eAAe,OAAO,CAAC;AAGnC,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAGb,UAAM,iBACJ,OAAO,aAAa,SAAS,gBAAgB;AAG/C,UAAM,mBAAmB,SAAS,KAAK,MAAM;AAC7C,UAAM,uBAAuB,SAAS,KAAK,MAAM;AAGjD,aAAS,KAAK,MAAM,WAAW;AAG/B,QAAI,iBAAiB,GAAG;AACtB,eAAS,KAAK,MAAM,eAAe,GAAG,cAAc;AAGpD,YAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,cAAQ,KAAK;AACb,cAAQ,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,iBAIb,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAMzB,eAAS,KAAK,YAAY,OAAO;AAAA,IACnC;AAEA,WAAO,MAAM;AAEX,eAAS,KAAK,MAAM,WAAW;AAC/B,eAAS,KAAK,MAAM,eAAe;AAGnC,YAAM,UAAU,SAAS,eAAe,yBAAyB;AACjE,UAAI,SAAS;AACX,gBAAQ,OAAO;AAAA,MACjB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,cAAcD,cAAa,IAAI;AACrC,QAAM,cACJ;AAEF,QAAM,qBACJ;AACF,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,eAAe,CAAC,SACpB,gBAAgB,KAAK,IAAI,IAAI,OAAO,WAAW,IAAI;AAGrD,QAAM,oBAAoB,MAAM;AAC9B,QAAI,YAAY;AACd,aAAO,KAAK,aAAa,UAAU,GAAG,UAAU,qBAAqB;AAAA,IACvE;AAAA,EACF;AAGA,MAAI,YAAY,YAAY;AAC1B,WACE,gBAAAF,KAAC,SAAI,WAAU,8HACb,0BAAAC;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,QACX,mBAAiB;AAAA,QACjB,cAAW;AAAA,QACX,MAAI;AAAA,QAGJ;AAAA,0BAAAD,KAAC,SAAI,WAAU,6BACZ,WAAC,mBACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,WAAU;AAAA,cACV,cAAW;AAAA,cAEX,0BAAAA,KAAC,KAAE,MAAM,IAAI;AAAA;AAAA,UACf,GAEJ;AAAA,UAGA,gBAAAC,MAAC,SAAI,WAAU,8CAEZ;AAAA,qBACC,gBAAAD,KAAC,SAAI,WAAU,uBACb,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK;AAAA,gBACL,KAAK,YAAY;AAAA,gBACjB,WAAU;AAAA;AAAA,YACZ,GACF;AAAA,YAIF,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI;AAAA,gBACJ,WAAU;AAAA,gBAET;AAAA;AAAA,YACH;AAAA,YAGC,eACC,gBAAAA,KAAC,OAAE,WAAU,yEACV,uBACH;AAAA,YAID,cACC,gBAAAC,MAAC,SAAI,WAAU,UACX;AAAA,qBAAM;AACN,sBAAM,aAAa,aAAa,UAAU;AAC1C,sBAAM,OAAO,aAAa,UAAU;AACpC,oBAAI,CAAC,KAAM,QAAO;AAClB,sBAAM,KAAK,kBAAkB,UAAU;AACvC,oBAAI,CAAC,IAAI;AACP,yBACE,gBAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,SAAQ;AAAA,sBACR,QAAO;AAAA,sBACP,MAAK;AAAA,sBACL,WAAU;AAAA,sBACV,SAAS;AAAA,sBAER,yBAAe;AAAA;AAAA,kBAClB;AAAA,gBAEJ;AACA,uBACE,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,KAAK,mBAAmB,EAAE;AAAA,oBAC1B,WAAU;AAAA,oBACV,iBAAe;AAAA,oBACf,OAAM;AAAA,oBACN,OAAM;AAAA;AAAA,gBACR;AAAA,cAEJ,GAAG;AAAA,cACF,CAAC,aAAa,aAAa,UAAU,CAAC,KACrC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,QAAO;AAAA,kBACP,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS;AAAA,kBAER,yBAAe;AAAA;AAAA,cAClB;AAAA,eAEJ;AAAA,aAEJ;AAAA;AAAA;AAAA,IACF,GACF;AAAA,EAEJ;AAGA,SACE,gBAAAA,KAAC,SAAI,WAAU,8HACb,0BAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,MACX,mBAAiB;AAAA,MACjB,cAAW;AAAA,MACX,MAAI;AAAA,MAGJ;AAAA,wBAAAA,MAAC,SAAI,WAAU,+CACb;AAAA,0BAAAD,KAAC,QAAG,IAAI,SAAS,WAAU,uCACxB,iBACH;AAAA,UACC,CAAC,mBACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,WAAU;AAAA,cACV,cAAW;AAAA,cAEX,0BAAAA,KAAC,KAAE,MAAM,IAAI;AAAA;AAAA,UACf;AAAA,WAEJ;AAAA,QAGC,YACC,gBAAAA,KAAC,SAAI,WAAW,GAAG,aAAa,gBAAgB,GAC9C,0BAAAA,KAAC,SAAI,WAAU,+CACZ,UACH,GACF;AAAA,QAID,UACC,gBAAAA,KAAC,SAAI,WAAU,oCAAoC,kBAAO;AAAA;AAAA;AAAA,EAE9D,GACF;AAEJ;AAEA,IAAO,gBAAQ;;;AExVf,SAAS,MAAM,WAAW;AAC1B,SAAS,YAAAI,WAAU,aAAAC,kBAAiB;;;ACDpC,SAA0C,cAAAC,mBAAkB;AAqGtD,SAQE,OAAAC,OARF,QAAAC,aAAA;AA1CN,IAAM,kBAAkBC;AAAA,EACtB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WACjB,CAAC,oBAAoB,UAAU,iBAAiB,aAAa,IAC7D,CAAC;AAEL,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,YAAY,SAAS;AAAA,QACnC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,0BAAAD,MAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,gBAAAA,MAAC,UAAM,iBAAM;AAAA;AAAA;AAAA,IACf;AAAA,EAEJ;AACF;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;;;ACtHf,SAAS,aAAAG,kBAAiB;;;ACA1B,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,WAAU,eAAe;AAiDlC,IAAM,kBAAkB,CAAC,SAA6B;AACpD,QAAM,cAAc,SAAS;AAC7B,QAAM,gBAAgB,YAAY,aAAa,qBAAqB;AAEpE,MAAI,SAAS,QAAQ;AACnB,gBAAY,aAAa,cAAc,MAAM;AAC7C,WAAO;AAAA,EACT,WAAW,SAAS,SAAS;AAC3B,QAAI,eAAe;AACjB,kBAAY,aAAa,cAAc,aAAa;AAAA,IACtD;AACA,WAAO;AAAA,EACT,WAAW,SAAS,UAAU;AAC5B,UAAM,eAAe,OAAO;AAAA,MAC1B;AAAA,IACF,EAAE;AACF,QAAI,cAAc;AAChB,kBAAY,aAAa,cAAc,MAAM;AAC7C,aAAO;AAAA,IACT,WAAW,eAAe;AACxB,kBAAY,aAAa,cAAc,aAAa;AACpD,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKA,IAAM,oBAAoB,MAAM;AAC9B,QAAM,cAAc,SAAS;AAC7B,QAAM,eAAe,YAAY,aAAa,YAAY;AAC1D,MAAI,gBAAgB,CAAC,YAAY,aAAa,qBAAqB,GAAG;AACpE,gBAAY,aAAa,uBAAuB,YAAY;AAAA,EAC9D;AACF;AAKO,IAAM,gBAAgBD,QAAmB;AAAA,EAC9CC;AAAA,IACE;AAAA,MACE,CAAC,KAAK,SAAS;AAAA;AAAA,QAEb,WAAW;AAAA,QACX,QAAQ;AAAA;AAAA,QAGR,YAAY,CAAC,SAAoB;AAC/B,gBAAM,SAAS,gBAAgB,IAAI;AACnC,cAAI,EAAE,OAAO,CAAC;AAAA,QAChB;AAAA,QAEA,aAAa,MAAM;AACjB,gBAAM,EAAE,WAAW,WAAW,IAAI,IAAI;AACtC,cAAI;AAEJ,cAAI,cAAc,SAAS;AACzB,sBAAU;AAAA,UACZ,WAAW,cAAc,QAAQ;AAC/B,sBAAU;AAAA,UACZ,OAAO;AAEL,sBAAU;AAAA,UACZ;AAEA,cAAI,EAAE,WAAW,QAAQ,CAAC;AAC1B,qBAAW,OAAO;AAAA,QACpB;AAAA,QAEA,UAAU,CAAC,SAAoB;AAC7B,gBAAM,EAAE,WAAW,IAAI,IAAI;AAC3B,cAAI,EAAE,WAAW,KAAK,CAAC;AACvB,qBAAW,IAAI;AAAA,QACjB;AAAA,QAEA,iBAAiB,MAAM;AACrB,gBAAM,EAAE,WAAW,WAAW,IAAI,IAAI;AAGtC,4BAAkB;AAGlB,qBAAW,SAAS;AAAA,QACtB;AAAA,QAEA,yBAAyB,MAAM;AAC7B,gBAAM,EAAE,WAAW,WAAW,IAAI,IAAI;AAEtC,cAAI,cAAc,UAAU;AAC1B,uBAAW,QAAQ;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA;AAAA,QACN,YAAY,CAAC,WAAW;AAAA,UACtB,WAAW,MAAM;AAAA,QACnB;AAAA;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;ADnJO,IAAM,WAAW,MAAM;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,cAAc;AAElB,EAAAC,WAAU,MAAM;AAEd,oBAAgB;AAGhB,UAAM,aAAa,OAAO,WAAW,8BAA8B;AAEnE,eAAW,iBAAiB,UAAU,uBAAuB;AAE7D,WAAO,MAAM;AACX,iBAAW,oBAAoB,UAAU,uBAAuB;AAAA,IAClE;AAAA,EACF,GAAG,CAAC,iBAAiB,uBAAuB,CAAC;AAE7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AFbY,gBAAAC,aAAA;AAhBL,IAAM,cAAc,CAAC;AAAA,EAC1B,UAAU;AAAA,EACV;AACF,MAAwB;AACtB,QAAM,EAAE,WAAW,SAAS,IAAI,SAAS;AACzC,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAoB,SAAS;AAG/D,EAAAC,WAAU,MAAM;AACd,iBAAa,SAAS;AAAA,EACxB,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,eAAe;AAAA,IACnB;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM,gBAAAF,MAAC,OAAI,MAAM,IAAI;AAAA,IACvB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM,gBAAAA,MAAC,QAAK,MAAM,IAAI;AAAA,IACxB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAM;AAAA,UACN,QAAO;AAAA,UACP,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,OAAM;AAAA,UAEN,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAK;AAAA;AAAA,UACP;AAAA;AAAA,MACF;AAAA,IAEJ;AAAA,EACF;AAEA,QAAM,oBAAoB,CAAC,kBAA6B;AACtD,QAAI,YAAY,aAAa;AAC3B,mBAAa,aAAa;AAAA,IAC5B,OAAO;AACL,eAAS,aAAa;AAAA,IACxB;AAEA,QAAI,UAAU;AACZ,eAAS,aAAa;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,eAAe,YAAY,cAAc,YAAY;AAE3D,SACE,gBAAAA,MAAC,SAAI,WAAU,qCACZ,uBAAa,IAAI,CAAC,SACjB,gBAAAA;AAAA,IAAC;AAAA;AAAA,MAEC,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,UAAU,iBAAiB,KAAK;AAAA,MAChC,SAAS,MAAM,kBAAkB,KAAK,EAAE;AAAA,MACxC,WAAU;AAAA;AAAA,IALL,KAAK;AAAA,EAMZ,CACD,GACH;AAEJ;;;AH0HI,SAufA,UAvfA,OAAAG,OAsSE,QAAAC,cAtSF;AAxKG,SAAS,sBAAwC;AACtD,SAAOC,QAAsB,CAAC,SAAS;AAAA,IACrC,MAAM;AAAA,IACN,SAAS,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC;AAAA,EACjC,EAAE;AACJ;AAEO,IAAM,mBAAmB,CAAC,kBAAqC;AACpE,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,cAAc,CAClB,UACA,UACc;AACd,SAAOC,UAAS,IAAI,UAAU,CAAC,UAAU;AACvC,QAAIC,gBAAe,KAAK,GAAG;AACzB,YAAM,aAAa;AAMnB,YAAM,cACJ,WAAW,KACX;AAGF,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,WAGC,CAAC;AAEN,UAAI,QAAQ,SAAS,WAAW,GAAG;AACjC,iBAAS,QAAQ;AAAA,MACnB;AAEA,UAAI,WAAW,MAAM,UAAU;AAC7B,iBAAS,WAAW,YAAY,WAAW,MAAM,UAAU,KAAK;AAAA,MAClE;AAEA,aAAO,aAAa,YAAY,QAAQ;AAAA,IAC1C;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAQA,IAAM,eAAe,CAAC;AAAA,EACpB;AAAA,EACA,MAAM;AAAA,EACN;AACF,MAAyB;AACvB,QAAM,WAAW,OAAgC,IAAI;AACrD,WAAS,YAAY,oBAAoB;AACzC,QAAM,QAAQ,SAAS;AACvB,QAAM,EAAE,MAAM,SAAS,aAAa,IAAI,SAAS,OAAO,CAAC,MAAM,CAAC;AAEhE,QAAM,UAAU,CAAC,YAAqB;AACpC,iBAAa,OAAO;AAAA,EACtB;AAEA,QAAM,UAAU,OAA8B,IAAI;AAElD,QAAM,2BAA2B,CAAC,UAAoC;AACpE,UAAM,cAAc,QAAQ,SAAS,cAAc,eAAe;AAClE,QAAI,aAAa;AACf,YAAM,eAAe;AAErB,YAAM,QAAQ,MAAM;AAAA,QAClB,YAAY;AAAA,UACV;AAAA,QACF;AAAA,MACF,EAAE,OAAO,CAAC,OAA0B,cAAc,WAAW;AAE7D,UAAI,MAAM,WAAW,EAAG;AAExB,YAAM,cAAc,SAAS;AAC7B,YAAM,eAAe,MAAM,QAAQ,WAAW;AAE9C,UAAI;AACJ,UAAI,MAAM,QAAQ,aAAa;AAC7B,oBAAY,iBAAiB,KAAK,KAAK,eAAe,KAAK,MAAM;AAAA,MACnE,OAAO;AAEL,oBACE,iBAAiB,KACb,MAAM,SAAS,KACd,eAAe,IAAI,MAAM,UAAU,MAAM;AAAA,MAClD;AAEA,YAAM,SAAS,GAAG,MAAM;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,UAAoC;AACzD,QAAI,MAAM,QAAQ,UAAU;AAC1B,cAAQ,KAAK;AAAA,IACf,WAAW,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;AAC/D,+BAAyB,KAAK;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,qBAAqB,CAAC,UAAiB;AAC3C,UAAM,SAAS,MAAM;AAErB,QAAI,QAAQ,SAAS,SAAS,MAAM,GAAG;AACrC;AAAA,IACF;AAEA,QACE,kBAAkB,WAClB,OAAO,QAAQ,gCAAgC,GAC/C;AACA;AAAA,IACF;AAEA,YAAQ,KAAK;AAAA,EACf;AAEA,EAAAC,WAAU,MAAM;AACd,QAAI,MAAM;AACR,eAAS,iBAAiB,eAAe,kBAAkB;AAC3D,eAAS,iBAAiB,WAAW,aAAa;AAAA,IACpD;AAEA,WAAO,MAAM;AACX,eAAS,oBAAoB,eAAe,kBAAkB;AAC9D,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,EAAAA,WAAU,MAAM;AACd,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,MAAM,YAAY,CAAC;AAEvB,EAAAA,WAAU,MAAM;AACd,QAAI,aAAa,QAAW;AAC1B,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,SACE,gBAAAL,MAAC,SAAI,WAAU,YAAW,KAAK,SAC5B,sBAAY,UAAU,KAAK,GAC9B;AAEJ;AAGA,IAAM,sBAAsBM,YAM1B,CAAC,EAAE,WAAW,UAAU,SAAS,OAAO,eAAe,GAAG,MAAM,GAAG,QAAQ;AAC3E,QAAM,QAAQ,iBAAiB,aAAa;AAE5C,QAAM,OAAO,SAAS,OAAO,CAAC,MAAM,EAAE,IAAI;AAC1C,QAAM,aAAa,MAAM,MAAM,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;AAEvD,SACE,gBAAAN;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,SAAS,CAAC,MAAM;AACd,UAAE,gBAAgB;AAClB,mBAAW;AACX,kBAAU,CAAC;AAAA,MACb;AAAA,MACA,iBAAe;AAAA,MACf,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ,CAAC;AACD,oBAAoB,cAAc;AAElC,IAAM,oBAAoB;AAAA,EACxB,OAAO;AAAA,EACP,QAAQ;AACV;AAEA,IAAM,eAAe;AAAA,EACnB,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AAEA,IAAM,gBAAgB;AAAA,EACpB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AACP;AAEA,IAAM,8BAA8B;AAAA,EAClC,MAAM;AAAA,EACN,SAAS;AACX;AAEA,IAAM,YAAYM,YAMhB,CAAC,EAAE,WAAW,OAAO,OAAO,QAAQ,GAAG,MAAM,GAAG,QAAQ;AACxD,SACE,gBAAAN;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,GAAG,kBAAkB,QAAQ,SAAS,IAAI,SAAS;AAAA,MAC7D,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AACD,UAAU,cAAc;AAExB,IAAM,sBAAsBM;AAAA,EAY1B,CACE;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb;AAAA,IACA,OAAO;AAAA,IACP,SAAS;AAAA,IACT;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,QAAQ,iBAAiB,aAAa;AAC5C,UAAM,OAAO,SAAS,OAAO,CAAC,MAAM,EAAE,IAAI;AAC1C,UAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,IAAI;AAC/C,UAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AACxE,UAAM,aAAa,OAAuB,IAAI;AAE9C,IAAAF,WAAU,MAAM;AACd,UAAI,MAAM;AACR,qBAAa,IAAI;AAAA,MACnB,OAAO;AACL,cAAM,QAAQ,WAAW,MAAM,aAAa,KAAK,GAAG,GAAG;AACvD,eAAO,MAAM,aAAa,KAAK;AAAA,MACjC;AAAA,IACF,GAAG,CAAC,IAAI,CAAC;AAET,oBAAgB,MAAM;AACpB,UAAI,UAAU,QAAQ,YAAY,SAAS;AACzC,cAAM,OAAO,WAAW,QAAQ,sBAAsB;AACtD,YAAI,MAAM,KAAK,SAAS;AACxB,YAAI,OAAO,KAAK;AAGhB,YAAI,SAAS,QAAQ;AACnB,iBAAO,KAAK,OAAO;AACnB,gBAAM,KAAK;AAAA,QACb,WAAW,SAAS,SAAS;AAC3B,iBAAO,KAAK,QAAQ;AACpB,gBAAM,KAAK;AAAA,QACb,OAAO;AAEL,cAAI,UAAU,OAAO;AACnB,mBAAO,KAAK;AAAA,UACd,WAAW,UAAU,UAAU;AAC7B,mBAAO,KAAK,OAAO,KAAK,QAAQ;AAAA,UAClC;AAEA,cAAI,SAAS,OAAO;AAClB,kBAAM,KAAK,MAAM;AAAA,UACnB;AAAA,QACF;AAEA,0BAAkB,EAAE,KAAK,KAAK,CAAC;AAAA,MACjC;AAAA,IACF,GAAG,CAAC,QAAQ,MAAM,YAAY,OAAO,MAAM,UAAU,CAAC;AAEtD,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,qBAAqB,MAAM;AAC/B,UAAI,QAAQ;AACV,eAAO;AAAA,MACT;AACA,YAAM,WAAW,aAAa,IAAI;AAClC,YAAM,aAAa,cAAc,KAAK;AAEtC,aAAO,YAAY,QAAQ,IAAI,UAAU;AAAA,IAC3C;AAEA,UAAM,sBAAsB,MAAM;AAChC,UAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,YAAM,YAA2B;AAAA,QAC/B,KAAK,eAAe;AAAA,MACtB;AAEA,UAAI,UAAU,OAAO;AACnB,kBAAU,QAAQ,OAAO,aAAa,eAAe;AAAA,MACvD,WAAW,UAAU,UAAU;AAC7B,kBAAU,OAAO,eAAe;AAChC,kBAAU,YAAY;AAAA,MACxB,OAAO;AACL,kBAAU,OAAO,eAAe;AAAA,MAClC;AAEA,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,4BAA4B,OAAO;AAE1D,UAAM,UACJ,gBAAAL;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,SAAS,aAAa;AAAA,QAC3B,MAAK;AAAA,QACL,yBAAsB;AAAA,QACtB,WAAW;AAAA;AAAA,UAET,OAAO,oCAAoC,oCAAoC;AAAA,UAC/E,mBAAmB,CAAC;AAAA,UACpB,cAAc;AAAA,UACd,SAAS;AAAA;AAAA,QAEX,OAAO;AAAA,UACL,GAAI,SACA,oBAAoB,IACpB;AAAA,YACE,WAAW,SAAS,WAAW,aAAa;AAAA,YAC5C,cAAc,SAAS,QAAQ,aAAa;AAAA,YAC5C,YAAY,SAAS,UAAU,aAAa;AAAA,YAC5C,aAAa,SAAS,SAAS,aAAa;AAAA,UAC9C;AAAA,QACN;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAGF,QAAI,UAAU,OAAO,aAAa,aAAa;AAC7C,aAAO,aAAa,SAAS,SAAS,IAAI;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AACF;AACA,oBAAoB,cAAc;AAElC,IAAM,mBAAmBM;AAAA,EAavB,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,UAAU;AAAA,IACV,OAAO;AAAA,IACP,eAAe;AAAA,IACf,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,QAAQ,iBAAiB,aAAa;AAC5C,UAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO;AAChD,UAAM,cAAc,kBAAkB,IAAI;AAE1C,UAAM,cAAc,CAClB,MACG;AACH,UAAI,UAAU;AACZ,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB;AAAA,MACF;AACA,UAAI,EAAE,SAAS,SAAS;AACtB,kBAAU,CAA+B;AAAA,MAC3C,WAAW,EAAE,SAAS,WAAW;AAE/B,YACG,EAAoC,QAAQ,WAC5C,EAAoC,QAAQ,KAC7C;AACA,oBAAU,CAA0C;AAAA,QACtD;AAEA,cAAM,YAAY,CAAkC;AAAA,MACtD;AACA,UAAI,CAAC,cAAc;AACjB,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAEA,UAAM,oBAAoB,MAAM;AAC9B,UAAI,YAAY,WAAW;AACzB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,MAAM;AAC5B,aAAO,YAAY,YAAY,EAAE,gBAAgB,UAAU,IAAI,CAAC;AAAA,IAClE;AAEA,WACE,gBAAAL;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACJ,GAAG,gBAAgB;AAAA,QACpB,iBAAe;AAAA,QACf,WAAW;AAAA;AAAA,aAEN,kBAAkB,CAAC;AAAA,YACpB,WAAW;AAAA,YACX,SAAS;AAAA,YAET,WACI,qCACA,+IACN;AAAA;AAAA,QAEF,SAAS;AAAA,QACT,WAAW,CAAC,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,cAAE,eAAe;AACjB,cAAE,gBAAgB;AAClB,wBAAY,CAAC;AAAA,UACf;AAAA,QACF;AAAA,QACA,UAAU,WAAW,KAAK;AAAA,QACzB,GAAG;AAAA,QAEH;AAAA;AAAA,UACD,gBAAAD,MAAC,SAAI,WAAU,UAAU,UAAS;AAAA,UACjC;AAAA;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,iBAAiB,cAAc;AAE/B,IAAM,wBAAwBM,YAG5B,CAAC,EAAE,WAAW,OAAO,QAAQ,GAAG,MAAM,GAAG,QACzC,gBAAAN;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW,GAAG,2BAA2B,SAAS;AAAA,IACjD,GAAG;AAAA;AACN,CACD;AACD,sBAAsB,cAAc;AAGpC,IAAM,qBAAqBM,YAGzB,CAAC,EAAE,WAAW,SAAS,OAAO,eAAe,GAAG,MAAM,GAAG,QAAQ;AACjE,QAAM,QAAQ,iBAAiB,aAAa;AAC5C,QAAM,OAAO,SAAS,OAAO,CAAC,MAAM,EAAE,IAAI;AAC1C,QAAM,aAAa,MAAM,MAAM,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;AAEvD,SACE,gBAAAN;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS,CAAC,MAAM;AACd,UAAE,gBAAgB;AAClB,mBAAW;AACX,kBAAU,CAAC;AAAA,MACb;AAAA,MACA,iBAAe;AAAA,MACd,GAAG;AAAA,MAEJ,0BAAAA,MAAC,UAAK,WAAU,uEACd,0BAAAA,MAAC,QAAK,WAAU,oBAAmB,MAAM,IAAI,GAC/C;AAAA;AAAA,EACF;AAEJ,CAAC;AACD,mBAAmB,cAAc;AAEjC,IAAM,oBAAoBM,YAQxB,CAAC,EAAE,WAAW,MAAM,OAAO,UAAU,OAAO,QAAQ,GAAG,MAAM,GAAG,QAAQ;AACxE,SACE,gBAAAL;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,kBAAe;AAAA,MACf,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,wBAAAD,MAAC,UAAK,WAAU,wGACb,qBACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,WAAU;AAAA;AAAA,QACZ,IAEA,gBAAAA,MAAC,QAAK,MAAM,IAAI,WAAU,oBAAmB,GAEjD;AAAA,QACA,gBAAAC,OAAC,SAAI,WAAU,yBACb;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAO;AAAA,cACP,OAAM;AAAA,cACN,WAAU;AAAA,cAET;AAAA;AAAA,UACH;AAAA,UACA,gBAAAA,MAAC,gBAAK,MAAK,MAAK,OAAM,iBAAgB,WAAU,YAC7C,iBACH;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AACD,kBAAkB,cAAc;AAEhC,IAAM,kBAAkBM;AAAA,EAStB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,gBAAAL;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,kBAAe;AAAA,QACf,WAAW,GAAG,oCAAoC,SAAS;AAAA,QAC1D,GAAG;AAAA,QAEJ;AAAA,0BAAAD,MAAC,UAAK,WAAU,aAAY;AAAA,UAC5B,gBAAAC,OAAC,SAAI,WAAU,kBACb;AAAA,4BAAAD,MAAC,gBAAK,MAAK,MAAK,OAAM,iBACnB,sBACH;AAAA,YAEA,gBAAAC,OAAC,UAAK,WAAU,oCACd;AAAA,8BAAAD,MAAC,gBAAK,MAAK,MAAK,OAAM,iBACnB,yBACH;AAAA,cACA,gBAAAA,MAAC,OAAE,WAAU,sCAAqC,oBAAC;AAAA,cACnD,gBAAAA,MAAC,gBAAK,MAAK,MAAK,OAAM,iBACnB,0BACH;AAAA,eACF;AAAA,aACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AACA,gBAAgB,cAAc;AAE9B,IAAM,qBAAqB,CAAC;AAAA,EAC1B,OAAO;AAAA,EACP,GAAG;AACL,MAAqE;AACnE,QAAM,EAAE,WAAW,SAAS,IAAI,SAAS;AACzC,QAAM,CAAC,kBAAkB,mBAAmB,IAAIO,UAAS,KAAK;AAC9D,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAoB,SAAS;AAEvE,QAAM,mBAAmB,OAAgC,IAAI;AAC7D,mBAAiB,YAAY,oBAAoB;AACjD,QAAM,QAAQ,iBAAiB,iBAAiB;AAChD,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO;AAEhD,QAAM,cAAc,CAAC,MAAkC;AACrD,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,wBAAoB,IAAI;AAAA,EAC1B;AAEA,QAAM,aAAa,MAAM;AACvB,aAAS,aAAa;AACtB,wBAAoB,KAAK;AACzB,YAAQ,KAAK;AAAA,EACf;AAEA,QAAM,eAAe,MAAM;AACzB,qBAAiB,SAAS;AAC1B,wBAAoB,KAAK;AACzB,YAAQ,KAAK;AAAA,EACf;AAEA,SACE,gBAAAN,OAAA,YACE;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,cAAc;AAAA,QACd;AAAA,QACA,UACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,QAAO;AAAA,YACP,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,OAAM;AAAA,YAEN,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,GAAE;AAAA,gBACF,MAAK;AAAA;AAAA,YACP;AAAA;AAAA,QACF;AAAA,QAEF,WAAW,gBAAAA,MAACQ,aAAA,EAAW;AAAA,QACvB,SAAS;AAAA,QACT,WAAW,CAAC,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,cAAE,eAAe;AACjB,cAAE,gBAAgB;AAClB,gCAAoB,IAAI;AAAA,UAC1B;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ,0BAAAR,MAAC,gBAAK,MAAK,MAAK,OAAM,iBAAgB,0BAEtC;AAAA;AAAA,IACF;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,OAAM;AAAA,QACN,MAAK;AAAA,QACL,QACE,gBAAAC,OAAC,SAAI,WAAU,cACb;AAAA,0BAAAD,MAAC,kBAAO,SAAQ,WAAU,SAAS,cAAc,sBAEjD;AAAA,UACA,gBAAAA,MAAC,kBAAO,SAAQ,SAAQ,SAAS,YAAY,oBAE7C;AAAA,WACF;AAAA,QAGF,0BAAAC,OAAC,SAAI,WAAU,iBACb;AAAA,0BAAAD,MAAC,OAAE,WAAU,yBAAwB,6BAAe;AAAA,UACpD,gBAAAA,MAAC,eAAY,SAAQ,aAAY,UAAU,kBAAkB;AAAA,WAC/D;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AACA,mBAAmB,cAAc;AAEjC,IAAM,qBAAqBM,YAGzB,CAAC,EAAE,WAAW,UAAU,OAAO,QAAQ,GAAG,MAAM,GAAG,QAAQ;AAC3D,SACE,gBAAAN,MAAC,SAAI,KAAU,WAAW,GAAG,qBAAqB,SAAS,GAAI,GAAG,OAC/D,UACH;AAEJ,CAAC;AACD,mBAAmB,cAAc;AAEjC,IAAM,oBAAoB,CAAC;AAAA,EACzB;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,MAGM;AACJ,QAAM,QAAQ,iBAAiB,aAAa;AAC5C,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO;AAEhD,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,WAAW,GAAG,UAAU,SAAS;AAAA,MACjC;AAAA,MACA,SAAS,CAAC,MAAM;AACd,gBAAQ,KAAK;AACb,kBAAU,CAAC;AAAA,MACb;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,wBAAAD,MAAC,UAAK,WAAU,0BACd,0BAAAA,MAAC,WAAQ,WAAU,gBAAe,GACpC;AAAA,QACA,gBAAAA,MAAC,gBAAK,OAAM,WAAU,kBAAI;AAAA;AAAA;AAAA,EAC5B;AAEJ;AACA,kBAAkB,cAAc;AAGhC,IAAO,uBAAQ;;;ADlgBP,SAEE,OAAAS,OAFF,QAAAC,cAAA;AAzNR,IAAM,gBAAgB,CAAC,SAAmB,UAA4B;AACpE,MAAI,CAAC,SAAS,MAAM,SAAS,EAAG,QAAO,CAAC;AAExC,SAAO,QAAQ;AAAA,IAAO,CAAC,WACrB,OAAO,YAAY,EAAE,SAAS,MAAM,YAAY,CAAC;AAAA,EACnD;AACF;AAKA,IAAM,mBAAmB,CACvB,OACA,KAIA,aACG;AACH,MAAI,CAAC,SAAU;AAEf,MAAI,OAAO,aAAa,OAAO,IAAI,SAAS;AAC1C,QAAI,QAAQ,QAAQ;AACpB,UAAM,QAAQ,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC;AAClD,WAAO,eAAe,OAAO,UAAU;AAAA,MACrC,UAAU;AAAA,MACV,OAAO,IAAI;AAAA,IACb,CAAC;AACD,aAAS,KAAiD;AAAA,EAC5D,OAAO;AAEL,UAAM,QAAQ;AAAA,MACZ,QAAQ,EAAE,MAAM;AAAA,MAChB,eAAe,EAAE,MAAM;AAAA,IACzB;AACA,aAAS,KAAK;AAAA,EAChB;AACF;AAEA,IAAM,SAASC;AAAA,EACb,CACE;AAAA,IACE,UAAU,CAAC;AAAA,IACX;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,qBAAqB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,WAAW;AAAA,IACX,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,CAAC,cAAc,eAAe,IAAIC,UAAS,KAAK;AACtD,UAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,UAAM,kBAAkBC,QAAO,KAAK;AACpC,UAAM,gBAAgBA,QAAO,oBAAoB,CAAC,EAAE;AACpD,UAAM,cAAcA,QAAuB,IAAI;AAC/C,UAAM,aAAaA,QAAyB,IAAI;AAGhD,UAAM,kBAAkBC,SAAQ,MAAM;AACpC,UAAI,CAAC,QAAQ,QAAQ;AACnB,eAAO,CAAC;AAAA,MACV;AACA,YAAM,WAAW,cAAc,SAAU,SAAoB,EAAE;AAC/D,aAAO;AAAA,IACT,GAAG,CAAC,SAAS,KAAK,CAAC;AAGnB,UAAM,eACJ,CAAC,eACA,2BACE,gBAAgB,SAAS,OAAO,KAAK,EAAE,SAAS;AAGrD,UAAM,mBAAmB,CAAC,SAAkB;AAC1C,sBAAgB,IAAI;AACpB,oBAAc,SAAS,EAAE,KAAK,CAAC;AAC/B,yBAAmB,IAAI;AAAA,IACzB;AAGA,IAAAC,WAAU,MAAM;AAEd,UAAI,gBAAgB,SAAS;AAC3B,wBAAgB,UAAU;AAC1B;AAAA,MACF;AAEA,UAAI,YAAY;AACd,yBAAiB,KAAK;AACtB;AAAA,MACF;AAEA,YAAM,aAAa,QAAQ,SAAS,OAAO,KAAK,EAAE,SAAS,CAAC;AAC5D,uBAAiB,UAAU;AAAA,IAC7B,GAAG,CAAC,OAAO,YAAY,kBAAkB,aAAa,CAAC;AAGvD,UAAM,qBAAqB,CAAC,WAAmB;AAC7C,sBAAgB,UAAU;AAC1B,oBAAc,IAAI;AAClB,iBAAW,MAAM;AACjB,uBAAiB,KAAK;AAGtB,uBAAiB,QAAQ,KAAK,QAAQ;AAAA,IACxC;AAGA,IAAAA,WAAU,MAAM;AACd,YAAM,qBAAqB,CAAC,UAAiC;AAC3D,YACE,YAAY,WACZ,CAAC,YAAY,QAAQ,SAAS,MAAM,MAAc,GAClD;AACA,2BAAiB,KAAK;AAAA,QACxB;AAAA,MACF;AAEA,UAAI,cAAc;AAChB,iBAAS,iBAAiB,aAAa,kBAAkB;AAAA,MAC3D;AAEA,aAAO,MAAM;AACX,iBAAS,oBAAoB,aAAa,kBAAkB;AAAA,MAC9D;AAAA,IACF,GAAG,CAAC,cAAc,eAAe,gBAAgB,CAAC;AAGlD,UAAM,cAAcC,OAAM;AAC1B,UAAM,UAAU,MAAM,UAAU,WAAW;AAC3C,UAAM,aAAa,GAAG,OAAO;AAG7B,UAAM,cAAc,MAAM;AACxB,UAAI,SAAS;AACX,gBAAQ;AAAA,MACV,OAAO;AACL,yBAAiB,IAAI,KAAK,QAAQ;AAAA,MACpC;AAAA,IACF;AAGA,UAAM,mBAAmB,CAAC,MAAkB;AAC1C,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAClB,kBAAY;AAAA,IACd;AAGA,UAAM,wBAAwB,CAAC,MAAkB;AAC/C,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAClB,iBAAW,MAAM;AACf,mBAAW,SAAS,MAAM;AAAA,MAC5B,GAAG,CAAC;AAAA,IACN;AAGA,UAAM,oBAAoB,CAAC,MAAqC;AAC9D,oBAAc,KAAK;AACnB,iBAAW,CAAC;AACZ,iBAAW,EAAE,OAAO,KAAK;AAAA,IAC3B;AAGA,UAAM,gBAAgB,CAAC,MAAuC;AAE5D,sBAAgB,CAAC;AACjB,UAAI,EAAE,iBAAkB;AAExB,UAAI,EAAE,QAAQ,SAAS;AACrB,UAAE,eAAe;AAGjB,YAAI,gBAAgB,gBAAgB,SAAS,GAAG;AAC9C,6BAAmB,gBAAgB,CAAC,CAAC;AAAA,QACvC,WAAW,OAAO;AAEhB,qBAAW,OAAO,KAAK,CAAC;AACxB,wBAAc,IAAI;AAClB,2BAAiB,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,uBAAuB,CAACC,WAAoBC,cAAuB;AACvE,UAAID,UAAU,QAAO;AACrB,UAAIC,UAAU,QAAO;AACrB,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,OAAO,SAAS,EAAE,EAAE,SAAS;AAC9C,UAAM,kBAAkB,YAAY,CAAC,YAAY,CAAC;AAClD,UAAM,iBAAiB,CAAC,YAAY,CAAC,YAAY,CAAC;AAElD,WACE,gBAAAR;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAW,gCAAgC,kBAAkB;AAAA,QAG7D;AAAA,0BAAAA,OAAC,SAAI,WAAU,8BAEb;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK,CAAC,SAAS;AAEb,sBAAI,KAAK;AACP,wBAAI,OAAO,QAAQ,WAAY,KAAI,IAAI;AAAA;AAErC,sBAAC,IAA6C,UAAU;AAAA,kBAC5D;AAEA,6BAAW,UAAU;AAAA,gBACvB;AAAA,gBACA,IAAI;AAAA,gBACJ,MAAK;AAAA,gBACL,WAAW,6NAA6N,qBAAqB,UAAU,QAAQ,CAAC,IAAI,SAAS;AAAA,gBAC7R;AAAA,gBACA,UAAU;AAAA,gBACV,WAAW;AAAA,gBACX;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,iBAAe,eAAe,SAAS;AAAA,gBACvC,iBAAe,QAAQ,SAAS,IAAI,YAAY;AAAA,gBAChD,iBAAe,eAAe,aAAa;AAAA,gBAC3C,qBAAkB;AAAA,gBAClB,MAAM,QAAQ,SAAS,IAAI,aAAa;AAAA,gBACvC,GAAG;AAAA;AAAA,YACN;AAAA,YAGC,mBACC,gBAAAA,MAAC,SAAI,WAAU,uDACb,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,aAAa;AAAA,gBACb,cAAW;AAAA,gBAEX,0BAAAA,MAAC,UAAK,WAAU,gGACd,0BAAAA,MAACU,IAAA,EAAE,GACL;AAAA;AAAA,YACF,GACF;AAAA,YAID,kBACC,gBAAAV,MAAC,SAAI,WAAU,uDACb,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,aAAa;AAAA,gBACb,cAAW;AAAA,gBAEX,0BAAAA,MAAC,UAAK,WAAU,gGACd,0BAAAA,MAAC,mBAAgB,GACnB;AAAA;AAAA,YACF,GACF;AAAA,aAEJ;AAAA,UAGC,gBACC,gBAAAA,MAAC,wBAAa,MAAM,cAAc,cAAc,iBAC9C,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,WAAU;AAAA,cACV,OAAO,EAAE,WAAW,kBAAkB;AAAA,cACtC,OAAM;AAAA,cAEL,0BAAgB,SAAS,IACxB,gBAAgB,IAAI,CAAC,WACnB,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBAEC,SAAS,MAAM,mBAAmB,MAAM;AAAA,kBACxC,WAAU;AAAA,kBAET;AAAA;AAAA,gBAJI;AAAA,cAKP,CACD,IAED,gBAAAA,MAAC,SAAI,WAAU,qCACZ,yBACH;AAAA;AAAA,UAEJ,GACF;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;AAErB,IAAO,iBAAQ;;;AQ7Yf,SAAS,aAAAW,aAAW,WAAAC,UAAS,UAAAC,UAAQ,YAAAC,kBAAgB;;;ACCrD,OAAO;AACP,SAAS,YAAY,iBAAiB;AACtC,OAAO,eAAe;AACtB,OAAO;AAAA,EAEL,WAAAC;AAAA,OAEK;AA0EG,SA0KC,YAAAC,WA1KD,OAAAC,OAgKJ,QAAAC,cAhKI;AAtDV,IAAM,eAAe,CAAC,UAA0B;AAC9C,SAAO,UAAU,SAAS,OAAO;AAAA,IAC/B,UAAU,CAAC,cAAc,qBAAqB,aAAa,cAAc;AAAA,EAC3E,CAAC;AACH;AAMA,IAAM,qBAAqB,CAAC,QAAwB;AAClD,QAAM,WAAW,SAAS,cAAc,UAAU;AAClD,WAAS,YAAY;AACrB,SAAO,SAAS;AAClB;AAKA,IAAM,aAAa,CAAC,QAAwB;AAE1C,SAAO,IAAI,WAAW,0BAA0B,EAAE,EAAE,KAAK;AAC3D;AAeA,IAAM,qBAAqB,CACzB,WACA,kBACG;AACH,SAAO,CAAC,YAAqB;AAC3B,QACE,mBAAmBC,YACnB,QAAQ,SAAS,UACjB,QAAQ,QAAQ,cAAc,GAC9B;AACA,YAAM,SAAS,OAAO,SAAS,QAAQ,QAAQ,cAAc,GAAG,EAAE;AAClE,YAAM,WAAW,UAAU,MAAM;AAEjC,UAAI,CAAC,SAAU,QAAO;AAEtB,UAAI,SAAS,SAAS,UAAU;AAC9B,eACE,gBAAAF;AAAA,UAAC;AAAA;AAAA,YAEC,MAAM,SAAS;AAAA,YACf,aAAa,MAAM,cAAc,SAAS,KAAK;AAAA;AAAA,UAF1C,QAAQ,MAAM;AAAA,QAGrB;AAAA,MAEJ,OAAO;AACL,eACE,gBAAAA,MAAC,SAA2B,WAAU,sBACpC,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,SAAS;AAAA,YACf,aAAa,MAAM,cAAc,SAAS,KAAK;AAAA;AAAA,QACjD,KAJQ,QAAQ,MAAM,EAKxB;AAAA,MAEJ;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAiCA,IAAM,gBAAgB,CAAC;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA0B;AACxB,QAAM,wBAAwB,CAAC,gBAAwB;AACrD,QAAI,CAAC,YAAa,QAAO;AAEzB,QAAI,mBAAmB;AACvB,UAAM,YAAwB,CAAC;AAG/B,UAAM,qBACJ;AACF,uBAAmB,iBAAiB;AAAA,MAClC;AAAA,MACA,CAAC,OAAO,UAAU;AAChB,cAAM,gBAAgB,MAAM,SAAS,0BAA0B;AAC/D,cAAM,KAAK,UAAU;AACrB,kBAAU,KAAK;AAAA,UACb;AAAA,UACA,MAAM,gBAAgB,UAAU;AAAA,UAChC,OAAO,WAAW,mBAAmB,KAAK,CAAC;AAAA,QAC7C,CAAC;AACD,eAAO,uBAAuB,EAAE;AAAA,MAClC;AAAA,IACF;AAGA,UAAM,qBACJ;AACF,uBAAmB,iBAAiB;AAAA,MAClC;AAAA,MACA,CAAC,OAAO,UAAU;AAChB,cAAM,KAAK,UAAU;AACrB,kBAAU,KAAK;AAAA,UACb;AAAA,UACA,MAAM;AAAA,UACN,OAAO,WAAW,mBAAmB,KAAK,CAAC;AAAA,QAC7C,CAAC;AACD,eAAO,uBAAuB,EAAE;AAAA,MAClC;AAAA,IACF;AAGA,UAAM,sBAAsB;AAC5B,uBAAmB,iBAAiB;AAAA,MAClC;AAAA,MACA,CAAC,OAAO,UAAU;AAChB,cAAM,KAAK,UAAU;AACrB,kBAAU,KAAK;AAAA,UACb;AAAA,UACA,MAAM;AAAA,UACN,OAAO,WAAW,KAAK;AAAA,QACzB,CAAC;AACD,eAAO,uBAAuB,EAAE;AAAA,MAClC;AAAA,IACF;AAGA,UAAM,sBAAsB;AAC5B,uBAAmB,iBAAiB;AAAA,MAClC;AAAA,MACA,CAAC,OAAO,UAAU;AAChB,cAAM,KAAK,UAAU;AACrB,kBAAU,KAAK;AAAA,UACb;AAAA,UACA,MAAM;AAAA,UACN,OAAO,WAAW,KAAK;AAAA,QACzB,CAAC;AACD,eAAO,uBAAuB,EAAE;AAAA,MAClC;AAAA,IACF;AAGA,UAAM,kBACJ;AACF,uBAAmB,iBAAiB;AAAA,MAClC;AAAA,MACA,CAAC,OAAO,UAAU;AAChB,cAAM,KAAK,UAAU;AACrB,kBAAU,KAAK;AAAA,UACb;AAAA,UACA,MAAM;AAAA,UACN,OAAO,WAAW,KAAK;AAAA,QACzB,CAAC;AACD,eAAO,uBAAuB,EAAE;AAAA,MAClC;AAAA,IACF;AAGA,UAAM,kBAAkB;AACxB,uBAAmB,iBAAiB,WAAW,iBAAiB,CAAC,UAAU;AACzE,YAAM,KAAK,UAAU;AACrB,gBAAU,KAAK;AAAA,QACb;AAAA,QACA,MAAM;AAAA,QACN,OAAO,WAAW,KAAK;AAAA,MACzB,CAAC;AACD,aAAO,uBAAuB,EAAE;AAAA,IAClC,CAAC;AAGD,UAAM,mBAAmB,aAAa,gBAAgB;AAGtD,UAAM,uBAAuB,CAAC,UAC5B,gBAAAC,OAAC,UAAK,WAAU,gBAAe;AAAA;AAAA,MAAa;AAAA,OAAM;AAGpD,UAAM,gBAAgB,WAAW;AAGjC,UAAM,UAAkC;AAAA,MACtC,SAAS,mBAAmB,WAAW,aAAa;AAAA,IACtD;AAEA,WAAO,gBAAAD,MAAAD,WAAA,EAAG,gBAAM,kBAAkB,OAAO,GAAE;AAAA,EAC7C;AAEA,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,uCAAuC,SAAS;AAAA,MAC9D;AAAA,MAEC,gCAAsB,OAAO;AAAA;AAAA,EAChC;AAEJ;AAEA,IAAO,wBAAQ;;;ACzQf;AAAA,EAGE,cAAAG;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,OAEK;AAEP,SAAS,OAAO,aAAa;AA8LnB,gBAAAC,OAuBF,QAAAC,cAvBE;AA9KV,IAAMC,gBAAe;AAAA,EACnB,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IACT,aAAa;AAAA;AAAA,IACb,UAAU;AAAA;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAKA,IAAM,wBACJ;AAKF,IAAM,gBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SACE;AAAA,EACJ;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,WACE;AAAA,IACF,SACE;AAAA,EACJ;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,UAAU;AAAA,IACR,WAAW;AAAA,IACX,SACE;AAAA,EACJ;AACF;AA8CA,IAAM,WAAWC;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,cAAcC,OAAM;AAC1B,UAAM,UAAU,MAAM,YAAY,WAAW;AAG7C,UAAM,CAAC,iBAAiB,kBAAkB,IAAIC,UAAS,KAAK;AAC5D,UAAM,eAAe,gBAAgB;AACrC,UAAM,UAAU,eAAe,cAAc;AAG7C,UAAM,eAAe,CAAC,UAAyC;AAC7D,UAAI,CAAC,cAAc;AACjB,2BAAmB,MAAM,OAAO,OAAO;AAAA,MACzC;AACA,iBAAW,KAAK;AAAA,IAClB;AAGA,UAAM,eAAe,WAAW,aAAa;AAG7C,UAAM,cAAcH,cAAa,IAAI;AAGrC,UAAM,eAAe,WAAW,gBAAgB,YAAY;AAG5D,UAAM,iBAAiB,cAAc,YAAY,EAAE,YAAY;AAG/D,UAAM,mBACJ,UAAU,aAAc,UAAU,aAAa,SAAS,UACpD,iBACA,YAAY;AAGlB,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,aAAa,MAAM;AACvB,UAAI,eAAe;AACjB,eACE,gBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,YAAY;AAAA,YAClB,QAAO;AAAA,YACP,OAAM;AAAA;AAAA,QACR;AAAA,MAEJ;AAEA,UAAI,SAAS;AACX,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,YAAY;AAAA,YAClB,QAAO;AAAA,YACP,OAAM;AAAA;AAAA,QACR;AAAA,MAEJ;AAEA,aAAO;AAAA,IACT;AAEA,WACE,gBAAAC,OAAC,SAAI,WAAU,iBACb;AAAA,sBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,YAAY;AAAA,YACZ,WAAW,eAAe;AAAA,UAC5B;AAAA,UAGA;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA,MAAK;AAAA,gBACL,IAAI;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA,UAAU;AAAA,gBACV,WAAU;AAAA,gBACT,GAAG;AAAA;AAAA,YACN;AAAA,YAGA,gBAAAA,MAAC,WAAM,SAAS,SAAS,WAAW,iBAEjC,qBAAW,GACd;AAAA,YAGC,SACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,YAAY;AAAA,gBACd;AAAA,gBAEA,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,IAAG;AAAA,oBACH,SAAS;AAAA,oBACT,MAAM,YAAY;AAAA,oBAClB,QAAO;AAAA,oBACP,WAAW;AAAA,sBACT;AAAA,sBACA;AAAA,oBACF;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MAEJ;AAAA,MAGC,gBACC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,MAID,cAAc,CAAC,gBACd,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,OAEJ;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEvB,IAAO,mBAAQ;;;AC7Sf;AAAA,EAIE,cAAAM;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,kBAAAC;AAAA,OAEK;AACP,SAAS,UAAAC,SAAkB,YAAAC,iBAAgB;AA0LrC,gBAAAC,aAAA;AAtJN,IAAM,0BAA0B,CAC9B,MACA,eACA,UACA,mBAEAC,QAA0B,CAAC,KAAK,SAAS;AAAA,EACvC,QAAQ;AAAA,EACR,WAAW,CAAC,WAAW;AACrB,QAAI,CAAC,IAAI,EAAE,UAAU;AACnB,UAAI,EAAE,OAAO,CAAC;AACd,UAAI,EAAE,iBAAiB,MAAM;AAAA,IAC/B;AAAA,EACF;AAAA,EACA,aAAa,CAAC,UAAU;AACtB,QAAI,CAAC,IAAI,EAAE,UAAU;AACnB,YAAM,gBAAgB,IAAI,EAAE;AAC5B,YAAM,YAAY,cAAc,SAAS,KAAK,IAC1C,cAAc,OAAO,CAAC,MAAM,MAAM,KAAK,IACvC,CAAC,GAAG,eAAe,KAAK;AAC5B,UAAI,EAAE,QAAQ,UAAU,CAAC;AACzB,UAAI,EAAE,iBAAiB,SAAS;AAAA,IAClC;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE;AAKG,IAAM,uBAAuB,CAAC,kBAAyC;AAC5E,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;AAKA,IAAMC,eAAc,CAClB,UACA,UAEAC,UAAS,IAAI,UAAU,CAAC,UAAU;AAChC,MAAI,CAACC,gBAAe,KAAK,EAAG,QAAO;AACnC,QAAM,aAAa;AACnB,QAAM,eAAe,WAAW,SAAS;AACzC,SAAOC,cAAa,YAAY;AAAA,IAC9B,GAAI,eAAe,EAAE,MAAM,IAAI,CAAC;AAAA,IAChC,GAAI,WAAW,MAAM,WACjB,EAAE,UAAUH,aAAY,WAAW,MAAM,UAAU,KAAK,EAAE,IAC1D,CAAC;AAAA,EACP,CAAC;AACH,CAAC;AA0CH,IAAM,eAAeI;AAAA,EACnB,CACE;AAAA,IACE,QAAQ;AAAA,IACR,gBAAgB,CAAC;AAAA,IACjB;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,cAAcC,OAAM;AAC1B,UAAM,OAAO,YAAY,iBAAiB,WAAW;AAGrD,UAAM,WAAWC,QAA6B,IAAI;AAClD,aAAS,YAAY;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,SAAS;AAGvB,UAAM,EAAE,UAAU,IAAIC,UAAS,OAAO,CAAC,MAAM,CAAC;AAG9C,IAAAC,WAAU,MAAM;AACd,YAAM,gBAAgB,MAAM,SAAS,EAAE;AACvC,UAAI,cAAc,SAAS,KAAK,gBAAgB;AAC9C,uBAAe,aAAa;AAAA,MAC9B;AAAA,IACF,GAAG,CAAC,CAAC;AAGL,IAAAA,WAAU,MAAM;AACd,UAAI,eAAe,QAAW;AAC5B,kBAAU,UAAU;AAAA,MACtB;AAAA,IACF,GAAG,CAAC,YAAY,SAAS,CAAC;AAG1B,IAAAA,WAAU,MAAM;AACd,YAAM,SAAS,EAAE,SAAS,CAAC;AAAA,IAC7B,GAAG,CAAC,UAAU,KAAK,CAAC;AAEpB,WACE,gBAAAV;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,8BAA8B,SAAS;AAAA,QACrD,cAAY;AAAA,QACX,GAAG;AAAA,QAEH,UAAAE,aAAY,UAAU,KAAK;AAAA;AAAA,IAC9B;AAAA,EAEJ;AACF;AAEA,aAAa,cAAc;AAuC3B,IAAM,mBAAmBI;AAAA,EACvB,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,QAAQ,qBAAqB,aAAa;AAChD,UAAM;AAAA,MACJ,QAAQ;AAAA,MACR;AAAA,MACA,UAAU;AAAA,MACV;AAAA,IACF,IAAIG,UAAS,KAAK;AAGlB,UAAM,cAAcF,OAAM;AAC1B,UAAM,UAAU,MAAM,iBAAiB,WAAW;AAGlD,UAAM,YAAY,YAAY,SAAS,KAAK;AAC5C,UAAM,aAAa,iBAAiB;AACpC,UAAM,eAAe,aAAa,aAAa;AAG/C,WACE,gBAAAP;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,UAAU;AAAA,QACV;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA,UAAU,MAAM;AACd,cAAI,CAAC,YAAY;AACf,wBAAY,KAAK;AAAA,UACnB;AAAA,QACF;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEA,iBAAiB,cAAc;AAE/B,IAAO,uBAAQ;;;ACnTf;AAAA,EAGE,cAAAW;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,OAGK;AACP,SAAS,qBAAqB;AAuMpB,SASe,OAAAC,OATf,QAAAC,cAAA;AAtLV,IAAMC,gBAAe;AAAA,EACnB,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,IACL,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,YAAY;AAAA,IACV,UAAU;AAAA;AAAA,IACV,UAAU;AAAA,EACZ;AACF;AAKA,IAAM,wBACJ;AAKF,IAAMC,iBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;AA8CA,IAAM,WAAWC;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,IACrB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,cAAcC,OAAM;AAC1B,UAAM,UAAU,MAAM,YAAY,WAAW;AAG7C,UAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAGhD,UAAM,gBAAgB,OAAO,UAAU,WAAW,MAAM,SAAS;AACjE,UAAM,cAAc,aAAa,iBAAiB,YAAY;AAG9D,UAAM,eAAe,CAAC,UAA4C;AAChE,iBAAW,KAAK;AAAA,IAClB;AAGA,UAAM,cAAc,CAAC,UAA2C;AAC9D,mBAAa,IAAI;AACjB,YAAM,UAAU,KAAK;AAAA,IACvB;AAGA,UAAM,aAAa,CAAC,UAA2C;AAC7D,mBAAa,KAAK;AAClB,YAAM,SAAS,KAAK;AAAA,IACtB;AAGA,QAAI,eAAe,WAAW,aAAa;AAG3C,QACE,aACA,iBAAiB,aACjB,iBAAiB,YACjB;AACA,qBAAe;AAAA,IACjB;AAGA,UAAM,cAAcJ,cAAa,IAAI;AAGrC,UAAM,eAAeC,eAAc,YAAY;AAG/C,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,MACb;AAAA,IACF;AAEA,WACE,gBAAAF,OAAC,SAAI,WAAW,iBAEb;AAAA,eACC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,SAAS;AAAA,UACT,MAAM,YAAY;AAAA,UAClB,QAAO;AAAA,UACP,OAAM;AAAA,UACN,WAAW,GAAG,UAAU,cAAc;AAAA,UAErC;AAAA;AAAA,YAAO;AAAA,YACP,YAAY,gBAAAD,MAAC,UAAK,WAAU,wBAAuB,eAAC;AAAA;AAAA;AAAA,MACvD;AAAA,MAIF,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,IAAI;AAAA,UACJ;AAAA,UACA,UAAU;AAAA,UACV,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACC,GAAG;AAAA;AAAA,MACN;AAAA,MAGC,gBACC,gBAAAC,OAAC,OAAE,WAAU,+DACX;AAAA,wBAAAD,MAAC,iBAAc,MAAM,IAAI;AAAA,QAAE;AAAA,QAAE;AAAA,SAC/B;AAAA,MAID,CAAC,gBAAgB,sBAAsB,aACtC,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAW,UAAU,cAAc,2BAA2B,eAAe;AAAA,UAE5E;AAAA;AAAA,YAAc;AAAA,YAAE;AAAA,YAAU;AAAA;AAAA;AAAA,MAC7B;AAAA,MAED,CAAC,gBACA,iBACA,EAAE,sBAAsB,cACtB,gBAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,WAAU,wBACvC,yBACH;AAAA,OAEN;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEvB,IAAO,mBAAQ;;;ACjOX,gBAAAO,aAAA;AAbJ,IAAM,UAAU,CAAC;AAAA,EACf,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,GAAG;AACL,MAAoB;AAClB,QAAM,cAAc;AAEpB,QAAM,qBAAqB;AAAA,IACzB,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,aAAa,mBAAmB,WAAW,GAAG,SAAS;AAAA,MACrE,oBAAkB;AAAA,MACjB,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAO,kBAAQ;;;ACnDf;AAAA,EAIE,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,EAEA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,kBAAAC;AAAA,OAEK;AACP,SAAS,UAAAC,SAAkB,YAAAC,iBAAgB;AAkRnC,SAUE,OAAAC,OAVF,QAAAC,cAAA;AAjQR,IAAMC,gBAAe;AAAA,EACnB,OAAO;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,aAAa;AAAA,IACb,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,aAAa;AAAA,IACb,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,aAAa;AAAA,IACb,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA,YAAY;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,aAAa;AAAA,IACb,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AACF;AAUA,IAAM,qBACJ;AAKF,IAAMC,iBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA,EACA,UAAU;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF;AAKA,IAAM,cAAc;AAAA,EAClB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AACZ;AAwDA,IAAM,QAAQC;AAAA,EACZ,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,cAAcC,OAAM;AAC1B,UAAM,UAAU,MAAM,SAAS,WAAW;AAC1C,UAAM,WAAWC,QAAyB,IAAI;AAG9C,UAAM,CAAC,iBAAiB,kBAAkB,IAAIC,UAAS,cAAc;AACrE,UAAM,eAAe,gBAAgB;AACrC,UAAM,UAAU,eAAe,cAAc;AAG7C,UAAM,eAAe,CAAC,UAAyC;AAC7D,YAAM,aAAa,MAAM,OAAO;AAEhC,UAAI,CAAC,cAAc;AACjB,2BAAmB,UAAU;AAAA,MAC/B;AAGA,UAAI,MAAM,QAAQ;AAChB,cAAM,OAAO,KAAK;AAAA,MACpB;AAEA,iBAAW,KAAK;AAAA,IAClB;AAGA,UAAM,eAAe,WAAW,aAAa;AAG7C,UAAM,cAAcL,cAAa,IAAI;AAGrC,UAAM,kBAAkB,YAAY;AACpC,UAAM,gBAAgB,YAAY;AAGlC,UAAM,eAAe,UAAU,YAAY;AAG3C,UAAM,iBAAiBC,eAAc,YAAY,EAAE,YAAY;AAG/D,UAAM,iBAAiB,MAAM;AAC3B,UAAI,iBAAiB,WAAW;AAC9B,eAAO;AAAA,MACT;AACA,aAAO,YAAY;AAAA,IACrB;AAEA,UAAM,mBAAmB,eAAe;AAGxC,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA,YAAY,YAAY;AAAA,MACxB;AAAA,IACF;AAGA,UAAM,kBACJ,iBAAiB,aAAa,iBAAiB;AACjD,UAAM,qBACJ,iBAAiB,YACb,0BACA;AAGN,UAAM,eAAe,MAAM;AACzB,UAAI,iBAAiB,YAAY;AAC/B,eAAO,UAAU,kBAAkB;AAAA,MACrC;AAEA,UAAI,iBAAiB,WAAW;AAC9B,eAAO;AAAA,MACT;AAEA,aAAO,UAAU,kBAAkB;AAAA,IACrC;AAGA,UAAM,iBAAiB,MAAM;AAC3B,aAAO,iBAAiB,aACpB,uBACA;AAAA,IACN;AAEA,WACE,gBAAAF,OAAC,SAAI,WAAU,iBACb;AAAA,sBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,kBACI,GAAG,gBAAgB,oBAAoB,oBAAoB,IAC3D,YAAY;AAAA,YAChB,WAAW,eAAe;AAAA,UAC5B;AAAA,UAGA;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK,CAAC,SAAS;AACb,2BAAS,UAAU;AACnB,sBAAI,OAAO,QAAQ,WAAY,KAAI,IAAI;AAAA,2BAC9B,IAAK,KAAI,UAAU;AAAA,gBAC9B;AAAA,gBACA,MAAK;AAAA,gBACL,IAAI;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,UAAU;AAAA,gBACV,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,UAAU;AAAA,kBACV,MAAM;AAAA,kBACN,YAAY;AAAA,gBACd;AAAA,gBACC,GAAG;AAAA;AAAA,YACN;AAAA,YAGA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAW;AAAA,gBACX;AAAA,gBACA,gBAAc;AAAA,gBACd,SAAS,CAAC,MAAM;AAEd,oBAAE,eAAe;AACjB,sBAAI,CAAC,UAAU;AAEb,wBAAI,SAAS,SAAS;AACpB,+BAAS,QAAQ,MAAM;AAEvB,+BAAS,QAAQ,KAAK;AAAA,oBACxB;AAAA,kBACF;AAAA,gBACF;AAAA,gBACA,WAAW,CAAC,MAAM;AAEhB,uBAAK,EAAE,QAAQ,WAAW,EAAE,QAAQ,QAAQ,CAAC,UAAU;AACrD,sBAAE,eAAe;AACjB,wBAAI,SAAS,SAAS;AACpB,+BAAS,QAAQ,MAAM;AACvB,+BAAS,QAAQ,KAAK;AAAA,oBACxB;AAAA,kBACF;AAAA,gBACF;AAAA,gBAGC,qBAAW,gBAAAA,MAAC,SAAI,WAAW,YAAY;AAAA;AAAA,YAC1C;AAAA,YAGC,SACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,YAAY;AAAA,kBACZ;AAAA,gBACF;AAAA,gBAEA,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,IAAG;AAAA,oBACH,SAAS;AAAA,oBACT,MAAM,YAAY;AAAA,oBAClB,QAAO;AAAA,oBACP,WAAW;AAAA,sBACT,eAAe;AAAA,sBACf;AAAA,sBACA;AAAA,oBACF;AAAA,oBACA,OAAO,aAAa;AAAA,oBAEnB;AAAA;AAAA,gBACH;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MAEJ;AAAA,MAGC,gBACC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,MAID,cAAc,CAAC,gBACd,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAU;AAAA,UACV,OAAM;AAAA,UAEL;AAAA;AAAA,MACH;AAAA,OAEJ;AAAA,EAEJ;AACF;AAEA,MAAM,cAAc;AAkBpB,IAAM,wBAAwB,CAC5B,MACA,cACA,UACA,kBAEAQ,QAAwB,CAAC,KAAK,SAAS;AAAA,EACrC,OAAO;AAAA,EACP,UAAU,CAAC,UAAU;AACnB,QAAI,CAAC,IAAI,EAAE,UAAU;AACnB,UAAI,EAAE,MAAM,CAAC;AACb,UAAI,EAAE,gBAAgB,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE;AAKG,IAAM,qBAAqB,CAAC,kBAAuC;AACxE,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AACA,SAAO;AACT;AAKA,IAAMC,eAAc,CAClB,UACA,UAEAC,UAAS,IAAI,UAAU,CAAC,UAAU;AAChC,MAAI,CAACC,gBAAe,KAAK,EAAG,QAAO;AAEnC,QAAM,aAAa;AACnB,QAAM,eAAe,WAAW,SAAS;AACzC,SAAOC,cAAa,YAAY;AAAA,IAC9B,GAAI,eAAe,EAAE,MAAM,IAAI,CAAC;AAAA,IAChC,GAAI,WAAW,MAAM,WACjB,EAAE,UAAUH,aAAY,WAAW,MAAM,UAAU,KAAK,EAAE,IAC1D,CAAC;AAAA,EACP,CAAC;AACH,CAAC;AA0CH,IAAM,aAAaL;AAAA,EACjB,CACE;AAAA,IACE,OAAO;AAAA,IACP,eAAe;AAAA,IACf;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,cAAcC,OAAM;AAC1B,UAAM,OAAO,YAAY,eAAe,WAAW;AAGnD,UAAM,WAAWC,QAA2B,IAAI;AAChD,aAAS,YAAY;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,QAAQ,SAAS;AAGvB,UAAM,EAAE,SAAS,IAAIO,UAAS,OAAO,CAAC,MAAM,CAAC;AAG7C,IAAAC,WAAU,MAAM;AACd,YAAM,eAAe,MAAM,SAAS,EAAE;AACtC,UAAI,gBAAgB,eAAe;AACjC,sBAAc,YAAY;AAAA,MAC5B;AAAA,IACF,GAAG,CAAC,CAAC;AAGL,IAAAA,WAAU,MAAM;AACd,UAAI,cAAc,QAAW;AAC3B,iBAAS,SAAS;AAAA,MACpB;AAAA,IACF,GAAG,CAAC,WAAW,QAAQ,CAAC;AAGxB,IAAAA,WAAU,MAAM;AACd,YAAM,SAAS,EAAE,SAAS,CAAC;AAAA,IAC7B,GAAG,CAAC,UAAU,KAAK,CAAC;AAEpB,WACE,gBAAAd;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,MAAK;AAAA,QACL,cAAY;AAAA,QACX,GAAG;AAAA,QAEH,UAAAS,aAAY,UAAU,KAAK;AAAA;AAAA,IAC9B;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;AAuCzB,IAAM,iBAAiBL;AAAA,EACrB,CACE;AAAA,IACE;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AAEH,UAAM,QAAQ,mBAAmB,aAAa;AAC9C,UAAM;AAAA,MACJ,OAAO;AAAA,MACP;AAAA,MACA,UAAU;AAAA,MACV;AAAA,IACF,IAAIS,UAAS,KAAK;AAGlB,UAAM,cAAcR,OAAM;AAC1B,UAAM,UAAU,MAAM,cAAc,WAAW;AAG/C,UAAM,YAAY,eAAe;AACjC,UAAM,aAAa,iBAAiB;AACpC,UAAM,eAAe,aAAa,aAAa;AAG/C,WACE,gBAAAL;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,UAAU;AAAA,QACV;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA,UAAU,CAAC,MAAM;AACf,cAAI,EAAE,OAAO,WAAW,CAAC,YAAY;AACnC,qBAAS,KAAK;AAAA,UAChB;AAAA,QACF;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEA,eAAe,cAAc;AAE7B,IAAO,gBAAQ;;;ACrqBf,SAAS,UAAAe,eAAc;AA0BvB,IAAM,gBAAgBA,QAAmB,CAAC,SAAS;AAAA,EACjD,QAAQ,CAAC;AAAA,EACT,UAAU,CAAC,UAAU;AACnB,UAAM,KAAK,OAAO,WAAW;AAE7B,QAAI,CAAC,WAAW;AAAA,MACd,QAAQ,CAAC,GAAG,MAAM,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC;AAAA,IAC5C,EAAE;AAAA,EACJ;AAAA,EACA,aAAa,CAAC,OAAO;AACnB,QAAI,CAAC,WAAW;AAAA,MACd,QAAQ,MAAM,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,IAChD,EAAE;AAAA,EACJ;AACF,EAAE;AAEF,IAAO,qBAAQ;;;ACwSP,qBAAAC,WACE,OAAAC,OACA,QAAAC,cAFF;AA5TR,IAAMC,gBAAe;AAAA,EACnB,OAAO;AAAA,IACL,WAAW;AAAA;AAAA,IACX,KAAK;AAAA;AAAA,IACL,SAAS;AAAA;AAAA,IACT,QAAQ;AAAA;AAAA,IACR,cAAc;AAAA;AAAA,EAChB;AAAA,EACA,QAAQ;AAAA,IACN,WAAW;AAAA;AAAA,IACX,KAAK;AAAA;AAAA,IACL,SAAS;AAAA;AAAA,IACT,QAAQ;AAAA;AAAA,IACR,cAAc;AAAA;AAAA,EAChB;AACF;AAKA,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,IACJ,YAAY;AAAA;AAAA,IACZ,MAAM;AAAA;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,YAAY;AAAA;AAAA,IACZ,MAAM;AAAA;AAAA,EACR;AACF;AAgHA,IAAM,0BAA0B,CAAC,OAAe,QAAgB;AAC9D,QAAM,YAAY,MAAM,KAAK,IAAI,IAAI;AACrC,QAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,GAAG,CAAC;AACzD,QAAM,aAAa,QAAQ,IAAI,IAAK,eAAe,MAAO;AAE1D,SAAO,EAAE,cAAc,WAAW;AACpC;AAKA,IAAM,mBAAmB,CACvB,OACA,gBACA,iBACY;AACZ,SAAO,CAAC,EAAE,SAAS,kBAAkB;AACvC;AAkBA,IAAM,qBAAqB,CACzB,cACA,gBACA,OACA,cACA,KACA,eACG;AACH,MAAI,cAAc;AAChB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,GAAG,KAAK,MAAM,YAAY,CAAC,OAAO,GAAG;AAAA,MAC9C,YAAY;AAAA,IACd;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,GAAG,KAAK,MAAM,UAAU,CAAC;AAAA,MAClC,YAAY;AAAA,IACd;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AACF;AA0BA,IAAM,yBAAyB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAiC;AAE/B,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,gBAAgB,aAAa,qBAAqB;AAAA,IACzD,WAAW,gBAAgB,aACvB,sBACA;AAAA,IACJ,SAAS,gBAAgB;AAAA,EAC3B;AACF;AAWA,IAAM,gCAAgC,CACpC,MACA,OACA,oBACI;AAAA,EACJ,YAAY,SAAS,WAAW,CAAC,EAAE,SAAS;AAAA,EAC5C,gBAAgB,SAAS,YAAY;AAAA,EACrC,WAAW,SAAS,YAAY,CAAC,CAAC,SAAS,CAAC;AAAA;AAC9C;AAWA,IAAM,+BAA+B,CACnC,cACA,gBACA,cACA,KACA,YACA,wBACc;AACd,MAAI,CAAC,gBAAgB,CAAC,eAAgB,QAAO;AAG7C,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEC,0BAAgB,SAAS,aACxB,gBAAAC,OAAAF,WAAA,EACE;AAAA,wBAAAC,MAAC,UAAK,WAAU,oBAAoB,eAAK,MAAM,YAAY,GAAE;AAAA,QAC7D,gBAAAC,OAAC,UAAK,WAAU,iBAAgB;AAAA;AAAA,UAAK;AAAA,WAAI;AAAA,SAC3C,IAEA,gBAAAA,OAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,WAAU,oBACvC;AAAA,aAAK,MAAM,UAAU;AAAA,QAAE;AAAA,SAC1B;AAAA;AAAA,EAEJ;AAEJ;AAKA,IAAM,kBAAkB,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MASE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,WAAW;AAAA,MACT;AAAA,MACA,eAAe;AAAA,MACf;AAAA,IACF;AAAA,IAEA;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP;AAAA,UACA,cACE,OAAO,UAAU,WACb,GAAG,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC,eACnC,aAAa,KAAK,MAAM,UAAU,CAAC,QAAQ,GAAG;AAAA,UAEpD,WAAU;AAAA;AAAA,MACZ;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,eAAe;AAAA,YACf;AAAA,UACF;AAAA,UACA,OAAO,EAAE,OAAO,GAAG,UAAU,IAAI;AAAA;AAAA,MACnC;AAAA;AAAA;AACF;AAMF,IAAM,gBAAgB,CAAC;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MACE,gBAAAC;AAAA,EAAC;AAAA;AAAA,IACC,WAAW;AAAA,MACT;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,MACX;AAAA,IACF;AAAA,IAEC;AAAA,uBAAiB,OAAO,gBAAgB,YAAY,KACnD,gBAAAA,OAAC,SAAI,WAAU,8DACZ;AAAA,iBACC,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,QAAO;AAAA,YACP,WAAW,GAAG,gCAAgC,cAAc;AAAA,YAE3D;AAAA;AAAA,QACH;AAAA,QAGD;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,SACF;AAAA,MAGF,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,oBAAmB;AAAA,UACnB,eAAc;AAAA;AAAA,MAChB;AAAA;AAAA;AACF;AAMF,IAAM,gBAAgB,CAAC;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA0B;AACxB,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX;AAAA,EACF,IAAI,uBAAuB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MAEC;AAAA,yBAAiB,OAAO,gBAAgB,YAAY,KACnD,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,QAAO;AAAA,YACP;AAAA,YACA,WAAW,GAAG,oBAAoB,gBAAgB;AAAA,YAEjD;AAAA;AAAA,QACH;AAAA,QAGF,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,oBAAmB;AAAA,YACnB,eAAc;AAAA;AAAA,QAChB;AAAA;AAAA;AAAA,EACF;AAEJ;AAKA,IAAM,gBAAgB,CAAC;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA0B;AACxB,QAAM,WAAW,SAAS,WAAW,UAAU,YAAY;AAC3D,QAAM,mBAAmB,SAAS,WAAW,cAAc;AAC3D,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SACE,gBAAAC,OAAC,SAAI,WAAW,GAAG,QAAQ,YAAY,QAAQ,UAAU,SAAS,GAC/D;AAAA,kBAAc,cACb,gBAAAA,OAAC,SAAI,WAAU,qDACZ;AAAA,eACC,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UAEC;AAAA;AAAA,MACH;AAAA,MAGD,kBACC,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UAEC;AAAA,iBAAK,MAAM,UAAU;AAAA,YAAE;AAAA;AAAA;AAAA,MAC1B;AAAA,OAEJ;AAAA,IAGF,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,UAClB;AAAA,UACA,YAAY;AAAA,UACZ,YAAY;AAAA,QACd;AAAA,QACA,eAAe;AAAA,UACb,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IAEC,cAAc,kBACb,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,QAAO;AAAA,QACP,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QAEC;AAAA,eAAK,MAAM,UAAU;AAAA,UAAE;AAAA;AAAA;AAAA,IAC1B;AAAA,IAGD,cAAc,aACb,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,MAAK;AAAA,QACL,QAAO;AAAA,QACP,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,KAEJ;AAEJ;AAsCA,IAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT;AAAA,EACA,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAwB;AACtB,QAAM,EAAE,cAAc,WAAW,IAAI,wBAAwB,OAAO,GAAG;AACvE,QAAM,cAAcE,cAAa,IAAI;AACrC,QAAM,iBAAiB,gBAAgB,OAAO;AAE9C,MAAI,WAAW,WAAW;AACxB,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,UACV,OAAO,gBAAgB;AAAA,UACvB,QAAQ,iBAAiB;AAAA,QAC3B;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,WAAW,WAAW;AACxB,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,UACV,OAAO,gBAAgB;AAAA,UACvB,QAAQ,iBAAiB;AAAA,QAC3B;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,sBAAQ;;;ACzuBf;AAAA,EACE,YAAAG;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA,aAAAC;AAAA,EACA,KAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,OACK;;;ACdP;AAAA,EACE,cAAAC;AAAA,EAIA,SAAAC;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,OACK;;;ACRP;AAAA,EACE,cAAAC;AAAA,EACA,YAAAC;AAAA,EAGA,YAAAC;AAAA,EACA,UAAAC;AAAA,EAKA,aAAAC;AAAA,OACK;AAIP;AAAA,EACE,cAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;AC3BP,SAAS,gBAAAC,qBAAsD;AAC/D,YAAY,mBAAmB;;;ACA7B,SAOE,OAAAC,OAPF,QAAAC,cAAA;AADK,IAAM,SAAS,CAAC,EAAE,MAAM,MAAM,MACnC,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA;AAAA;AACF;;;ACnBA,SAOE,OAAAE,OAPF,QAAAC,cAAA;AADK,IAAM,SAAS,CAAC,EAAE,MAAM,MAAM,MACnC,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA;AAAA;AACF;;;ACnBA,SAOE,OAAAE,OAPF,QAAAC,cAAA;AADK,IAAM,SAAS,CAAC,EAAE,MAAM,MAAM,MACnC,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,GAAE;AAAA,UACF,MAAM;AAAA;AAAA,MACR;AAAA;AAAA;AACF;;;AHkCa,gBAAAE,aAAA;AATR,IAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX,MAAoC;AAClC,MAAI,OAAO,aAAa,UAAU;AAChC,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO,gBAAAA,MAAC,UAAO,MAAY,OAAc;AAAA,MAC3C,KAAK;AACH,eAAO,gBAAAA,MAAC,UAAO,MAAY,OAAc;AAAA,MAC3C,KAAK;AACH,eAAO,gBAAAA,MAAC,UAAO,MAAY,OAAc;AAAA,MAC3C,SAAS;AACP,cAAM,gBAAiB,cAAc,QAA4B,KACjD;AAEhB,eAAO,gBAAAA,MAAC,iBAAc,MAAY,OAAc,QAAgB;AAAA,MAClE;AAAA,IACF;AAAA,EACF,OAAO;AAEL,WAAOC,cAAa,UAAU;AAAA,MAC5B;AAAA,MACA,OAAO;AAAA,IACT,CAGE;AAAA,EACJ;AACF;AAEA,IAAO,qBAAQ;;;ADeT,SAyOE,YAAAC,WAzOF,OAAAC,OAwFE,QAAAC,cAxFF;AAnDN,IAAM,oBAAoB;AAAA,EACxB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAEA,IAAM,uBAAuB;AAAA,EAC3B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAEA,IAAM,0BAA0B;AAAA,EAC9B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAEA,IAAM,sBAAsB;AAAA,EAC1B,YAAY;AAAA,EACZ,UAAU;AACZ;AAEA,IAAM,sBAAsB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AACX;AAEA,IAAM,WAAWC;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,cAAc,kBAAkB,OAAO;AAC7C,UAAM,iBAAiB,qBAAqB,OAAO;AACnD,UAAM,mBAAmB,wBAAwB,SAAS;AAC1D,UAAM,gBAAgB,oBAAoB,MAAM;AAChD,UAAM,gBAAgB,oBAAoB,MAAM;AAEhD,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAYA,IAAM,sBAAsB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,sBAAsB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,0BAA0B;AAAA,EAC9B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,wBAAwB;AAAA,EAC5B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,wBAAwBE;AAAA,EAI5B,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,oBAAoB,oBAAoB,MAAM;AACpD,UAAM,oBAAoB,oBAAoB,MAAM;AACpD,UAAM,wBAAwB,wBAAwB,MAAM;AAC5D,UAAM,sBAAsB,sBAAsB,MAAM;AAExD,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA,WAAW,iBAAiB;AAAA,cAC9B;AAAA,cAEA;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW;AAAA,sBACT;AAAA,sBACA;AAAA,oBACF;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA,gBAEA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,QAAO;AAAA,oBACP,WAAU;AAAA,oBAET;AAAA;AAAA,gBACH;AAAA,gBAEA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,GAAG,8BAA8B,qBAAqB;AAAA,oBAEhE;AAAA;AAAA,gBACH;AAAA;AAAA;AAAA,UACF;AAAA,UAEC,YACC,gBAAAC,OAAC,SAAI,WAAU,oDACb;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA;AAAA,gBACF;AAAA,gBAEC;AAAA;AAAA,YACH;AAAA,YACA,gBAAAA,MAAC,iBAAM,MAAK,SAAQ,QAAO,QACxB,uBACH;AAAA,aACF;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AASA,IAAM,gBAAgBE;AAAA,EACpB,CACE;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,SAAS,UAAU;AACzB,UAAM,aAAa,SAAS,cAAc;AAC1C,UAAM,cAAc,SAAS,kBAAkB;AAE/C,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW,GAAG,yBAAyB,SAAS;AAAA,QAC/C,GAAG;AAAA,QAEJ;AAAA,0BAAAA,OAAC,aAAQ,WAAU,sCACjB;AAAA,4BAAAD,MAAC,OAAE,WAAU,4CAA4C,kBAAO;AAAA,YAEhE,gBAAAA,MAAC,SAAI,WAAU,oCACb,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,QAAQ,SAAS,YAAY;AAAA,gBAE5B;AAAA;AAAA,YACH,GACF;AAAA,aACF;AAAA,UAEA,gBAAAA,MAAC,UAAK,WAAU,iBACd,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,gBAAgB,WAAW;AAAA,cAC1C,WAAU;AAAA,cAET;AAAA;AAAA,UACH,GACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAeA,IAAM,eAAeE;AAAA,EACnB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,YAAY;AAAA,IACZ;AAAA,IACA,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,eAAe,cAAc;AACnC,UAAM,mBAAmB;AAAA,MACvB,YACE,gBAAAD,OAAAF,WAAA,EACG;AAAA,qBACC,gBAAAE,OAAC,SAAI,WAAU,oCACZ;AAAA,yBACC,gBAAAA,OAAC,UAAK,WAAU,6CACd;AAAA,4BAAAD,MAAC,OAAE,WAAU,+BAA8B,uBAAM;AAAA,YACjD,gBAAAA,MAAC,OAAE,WAAU,iBAAiB,uBAAY;AAAA,aAC5C;AAAA,UAED,WACC,gBAAAC,OAAC,UAAK,WAAU,6CACd;AAAA,4BAAAD,MAAC,OAAE,WAAU,+BAA8B,iBAAG;AAAA,YAC9C,gBAAAA,MAAC,OAAE,WAAU,iBAAiB,mBAAQ;AAAA,aACxC;AAAA,WAEJ;AAAA,QAEF,gBAAAC,OAAC,UAAK,WAAU,gDACd;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO;AAAA,cACP,SAAS;AAAA,cACT,eAAY;AAAA;AAAA,UACd;AAAA,UAEA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAO;AAAA,cACP,WAAW;AAAA,gBACT;AAAA,cACF;AAAA,cAEC;AAAA,qBAAK,MAAM,QAAQ;AAAA,gBAAE;AAAA;AAAA;AAAA,UACxB;AAAA,WACF;AAAA,SACF;AAAA,MAEF,UAAU,gBAAAD,MAAC,OAAE,WAAU,yBAAyB,mBAAQ;AAAA,IAC1D;AAEA,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAQ,eAAe,eAAe;AAAA,QACtC,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,QAAO;AAAA,QACP,WAAW,GAAG,eAAe,SAAS,IAAI,SAAS;AAAA,QAClD,GAAG;AAAA,QAEJ;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,eACI,2CACA;AAAA,gBACJ,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,KAAK,KAAK;AAAA,cACxC;AAAA,cACA,OAAO,MAAM,WAAW,GAAG,IAAI,EAAE,iBAAiB,MAAM,IAAI;AAAA,cAC5D,eAAY;AAAA,cAEX;AAAA;AAAA,UACH;AAAA,UAEA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,CAAC,gBAAgB;AAAA,cACnB;AAAA,cAEA;AAAA,gCAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,QAAO,WAAU,0BACrC,kBACH;AAAA,gBACC,iBAAiB,SAAS;AAAA;AAAA;AAAA,UAC7B;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAUA,IAAM,YAAYE;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,QAAO;AAAA,QACP,WAAW,GAAG,mCAAmC,SAAS;AAAA,QACzD,GAAG;AAAA,QAEH;AAAA,qBACC,gBAAAD,MAAC,UAAK,WAAU,8CACb,kBAAQ,IAAI,CAAC,MAAM,UAClB,gBAAAC,OAACF,WAAA,EACC;AAAA,4BAAAC,MAAC,OAAG,gBAAK;AAAA,YACR,QAAQ,QAAQ,SAAS,KAAK,gBAAAA,MAAC,OAAE,oBAAC;AAAA,eAFtB,GAAG,IAAI,MAAM,KAAK,EAGjC,CACD,GACH;AAAA,UAGF,gBAAAA,MAAC,OAAE,WAAU,4CAA4C,kBAAO;AAAA,UAEhE,gBAAAC,OAAC,UAAK,WAAU,gDACd;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,eAAY;AAAA;AAAA,YACd;AAAA,YACC,kBACC,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,WAAW;AAAA,kBACT;AAAA,gBACF;AAAA,gBAEC;AAAA,uBAAK,MAAM,QAAQ;AAAA,kBAAE;AAAA;AAAA;AAAA,YACxB;AAAA,aAEJ;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAaA,IAAM,kBAAkBC;AAAA,EACtB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,cAAc,aAAa;AAEjC,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW;AAAA,UACT,iBAAiB,UAAU,mBAAmB;AAAA,UAC9C;AAAA,QACF;AAAA,QACA,SAAS,MAAM,iBAAiB,WAAW,gBAAgB,WAAW;AAAA,QACrE,GAAG;AAAA,QAEJ;AAAA,0BAAAA,OAAC,SAAI,WAAU,8CACb;AAAA,4BAAAA,OAAC,SAAI,WAAU,oDACb;AAAA,8BAAAD,MAAC,OAAE,WAAU,2DACV,kBACH;AAAA,cACC,kBAAkB,YACjB,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,SAAS,MAAM,gBAAgB,WAAW;AAAA,kBAC1C,WAAU;AAAA,kBACX;AAAA;AAAA,cAED;AAAA,eAEJ;AAAA,YAEA,gBAAAA,MAAC,SAAI,WAAU,UACZ,wBACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,OAAO,GAAG,QAAQ,KAAK,aAAa;AAAA,gBACpC,SAAS;AAAA;AAAA,YACX,IAEA,gBAAAA,MAAC,OAAE,WAAU,kCAAkC,uBAAY,GAE/D;AAAA,aACF;AAAA,UAEC,iBAAiB,WAChB,gBAAAA;AAAA,YAACG;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAY;AAAA;AAAA,UACd;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAWA,IAAM,cAAcD;AAAA,EAClB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,QAAQ,aAAa;AAE3B,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW,GAAG,qCAAqC,SAAS;AAAA,QAC3D,GAAG;AAAA,QAEJ;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,cACF;AAAA,cACA,OAAO;AAAA,gBACL,iBAAiB;AAAA,cACnB;AAAA,cAEA,0BAAAA,MAAC,sBAAW,UAAU,MAAM,OAAM,gBAAe,MAAM,IAAI;AAAA;AAAA,UAC7D;AAAA,UAEA,gBAAAC,OAAC,SAAI,WAAU,qDACb;AAAA,4BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,QAAQ,gCAAgC;AAAA,gBAC1C;AAAA,gBAEA;AAAA,kCAAAD,MAAC,OAAE,WAAU,0CAA0C,kBAAO;AAAA,kBAC9D,gBAAAC,OAAC,UAAK,WAAU,8CACd;AAAA,oCAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,QAAO;AAAA,wBACP,SAAQ;AAAA,wBACR,MAAK;AAAA,wBACL,UAAU,gBAAAD,MAAC,eAAY;AAAA,wBAEtB;AAAA;AAAA,0BAAgB;AAAA;AAAA;AAAA,oBACnB;AAAA,oBAEA,gBAAAC;AAAA,sBAAC;AAAA;AAAA,wBACC,QAAO;AAAA,wBACP,SAAQ;AAAA,wBACR,MAAK;AAAA,wBACL,UAAU,gBAAAD,MAAC,WAAQ;AAAA,wBAElB;AAAA;AAAA,0BAAkB;AAAA;AAAA;AAAA,oBACrB;AAAA,qBACF;AAAA;AAAA;AAAA,YACF;AAAA,YAEA,gBAAAA,MAACG,aAAA,EAAW,WAAU,iCAAgC;AAAA,aACxD;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAQA,IAAM,aAAaD;AAAA,EACjB,CAAC,EAAE,QAAQ,WAAW,QAAQ,OAAO,GAAG,MAAM,GAAG,QAAQ;AACvD,UAAM,gBAAgB,CAACE,YAAsC;AAC3D,cAAQA,SAAQ;AAAA,QACd,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACX;AAAA,IACF;AAEA,UAAM,eAAe,CAACA,YAAsC;AAC1D,cAAQA,SAAQ;AAAA,QACd,KAAK;AACH,iBAAO,gBAAAJ,MAAC,eAAY;AAAA,QACtB,KAAK;AACH,iBAAO,gBAAAA,MAAC,WAAQ;AAAA,QAClB,KAAK;AACH,iBAAO,gBAAAA,MAAC,SAAM;AAAA,QAChB;AACE,iBAAO,gBAAAA,MAAC,WAAQ;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,iBAAiB,CAACI,YAAsC;AAC5D,cAAQA,SAAQ;AAAA,QACd,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACX;AAAA,IACF;AAEA,WACE,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW,GAAG,+BAA+B,SAAS;AAAA,QACrD,GAAG;AAAA,QAEJ,0BAAAC,OAAC,SAAI,WAAU,kEACb;AAAA,0BAAAD,MAAC,OAAE,WAAU,2DACV,kBACH;AAAA,UACA,gBAAAC,OAAC,UAAK,WAAU,kDACb;AAAA,sBACC,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,QAAQ,eAAe,MAAM;AAAA,gBAC7B,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,UAAU,aAAa,MAAM;AAAA,gBAE5B,wBAAc,MAAM;AAAA;AAAA,YACvB;AAAA,YAED,SAAS,gBAAAA,MAAC,OAAE,WAAU,yBAAyB,iBAAM;AAAA,aACxD;AAAA,UACA,gBAAAA,MAACG,aAAA,EAAW,WAAU,mEAAkE;AAAA,WAC1F;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAOA,IAAM,eAAeD;AAAA,EACnB,CAAC,EAAE,QAAQ,WAAW,MAAM,GAAG,MAAM,GAAG,QAAQ;AAC9C,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,0BAAAD,MAAC,UAAK,WAAU,kBAAkB,gBAAK;AAAA,UAEvC,gBAAAA,MAAC,OAAE,WAAU,2BAA2B,kBAAO;AAAA,UAE/C,gBAAAA,MAACG,aAAA,EAAW,MAAM,IAAI,WAAU,kBAAiB;AAAA;AAAA;AAAA,IACnD;AAAA,EAEJ;AACF;AAQA,IAAM,cAAcD;AAAA,EAClB,CAAC,EAAE,QAAQ,WAAW,YAAY,OAAO,UAAU,GAAG,MAAM,GAAG,QAAQ;AACrE,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,aAAa,QAAQ,aAAa;AAAA,cACpC;AAAA,cAEA;AAAA,gCAAAD,MAAC,UAAK,WAAU,kBACd,0BAAAA,MAAC,OAAE,WAAU,4CAA4C,kBAAO,GAClE;AAAA,gBACA,gBAAAA,MAAC,UAAK,WAAU,uBAAuB,UAAS;AAAA;AAAA;AAAA,UAClD;AAAA,UAEA,gBAAAA,MAACG,aAAA,EAAW,WAAU,gCAA+B,MAAM,IAAI;AAAA;AAAA;AAAA,IACjE;AAAA,EAEJ;AACF;AAcA,IAAM,YAAYD;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,SAAQ;AAAA,QACR,WAAW,GAAG,uBAAuB,SAAS;AAAA,QAC7C,GAAG;AAAA,QAEJ;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,SAAS,MAAM,iBAAiB,YAAY;AAAA,cAC5C,WAAU;AAAA;AAAA,UACZ;AAAA,UAEA,gBAAAC,OAAC,SAAI,WAAU,sCACb;AAAA,4BAAAA,OAAC,SAAI,WAAU,8CACb;AAAA,8BAAAD,MAAC,OAAE,WAAU,mDACV,iBACH;AAAA,cACA,gBAAAC,OAAC,OAAE,WAAU,yBAAwB;AAAA;AAAA,gBAChC;AAAA,gBAAK;AAAA,gBAAI;AAAA,iBACd;AAAA,eACF;AAAA,YAEA,gBAAAD,MAAC,OAAE,WAAU,+CACV,mBACH;AAAA,YAEA,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,cAAW;AAAA,gBACX,SAAS,MAAM,kBAAkB,aAAa;AAAA,gBAC9C,WAAU;AAAA,gBAEV;AAAA,kCAAAD,MAAC,kBAAe,eAAY,QAAO,MAAM,IAAI;AAAA,kBAC7C,gBAAAC,OAAC,OAAE,WAAU,WAAW;AAAA;AAAA,oBAAS;AAAA,qBAAU;AAAA;AAAA;AAAA,YAC7C;AAAA,aACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAoBA,IAAM,YAAYC;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,CAAC,WAAW,YAAY,IAAIG,UAAS,KAAK;AAChD,UAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,CAAC;AAChD,UAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,CAAC;AAC1C,UAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,CAAC;AACtC,UAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAAS,KAAK;AAChE,UAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,KAAK;AACxD,UAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,CAAC;AAClD,UAAM,WAAWC,QAAyB,IAAI;AAC9C,UAAM,mBAAmBA,QAAuB,IAAI;AACpD,UAAM,eAAeA,QAAuB,IAAI;AAEhD,UAAM,aAAa,CAAC,SAAiB;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,EAAE;AACpC,YAAM,UAAU,KAAK,MAAM,OAAO,EAAE;AACpC,aAAO,GAAG,OAAO,IAAI,QAAQ,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,IAC1D;AAEA,UAAM,kBAAkB,MAAM;AAC5B,UAAI,WAAW;AACb,iBAAS,SAAS,MAAM;AACxB,qBAAa,KAAK;AAClB,kBAAU;AAAA,MACZ,OAAO;AACL,iBAAS,SAAS,KAAK;AACvB,qBAAa,IAAI;AACjB,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,mBAAmB,MAAM;AAC7B,YAAM,UAAU,SAAS,SAAS,eAAe;AACjD,YAAM,QAAQ,SAAS,SAAS,YAAY;AAE5C,qBAAe,OAAO;AACtB,kBAAY,KAAK;AACjB,0BAAoB,SAAS,KAAK;AAAA,IACpC;AAEA,UAAM,uBAAuB,MAAM;AACjC,kBAAY,SAAS,SAAS,YAAY,CAAC;AAAA,IAC7C;AAEA,UAAM,cAAc,MAAM;AACxB,mBAAa,KAAK;AAClB,qBAAe,CAAC;AAChB,gBAAU;AAAA,IACZ;AAEA,UAAM,sBAAsB,CAAC,MAAqC;AAChE,YAAM,OAAO,EAAE,cAAc,sBAAsB;AACnD,YAAM,SAAS,EAAE,UAAU,KAAK;AAChC,YAAM,QAAQ,KAAK;AACnB,YAAM,aAAa,SAAS;AAC5B,YAAM,UAAU,aAAa;AAE7B,UAAI,SAAS,SAAS;AACpB,iBAAS,QAAQ,cAAc;AAAA,MACjC;AACA,qBAAe,OAAO;AAAA,IACxB;AAEA,UAAM,qBAAqB,CAAC,MAAqC;AAC/D,YAAM,YAAY,WAAW,EAAE,OAAO,KAAK;AAC3C,gBAAU,SAAS;AACnB,UAAI,SAAS,SAAS;AACpB,iBAAS,QAAQ,SAAS;AAAA,MAC5B;AAAA,IACF;AAEA,UAAM,sBAAsB,MAAM;AAChC,2BAAqB,CAAC,iBAAiB;AACvC,uBAAiB,KAAK;AAAA,IACxB;AAEA,UAAM,kBAAkB,MAAM;AAC5B,uBAAiB,CAAC,aAAa;AAC/B,2BAAqB,KAAK;AAAA,IAC5B;AAEA,UAAM,oBAAoB,CAAC,UAAkB;AAC3C,sBAAgB,KAAK;AACrB,UAAI,SAAS,SAAS;AACpB,iBAAS,QAAQ,eAAe;AAAA,MAClC;AACA,uBAAiB,KAAK;AAAA,IACxB;AAEA,UAAM,gBAAgB,MAAM;AAC1B,UAAI,WAAW,GAAG;AAChB,eAAO,gBAAAN,MAAC,kBAAe,MAAM,IAAI;AAAA,MACnC;AACA,UAAI,SAAS,KAAK;AAChB,eAAO,gBAAAA,MAAC,cAAW,MAAM,IAAI;AAAA,MAC/B;AACA,aAAO,gBAAAA,MAAC,eAAY,MAAM,IAAI;AAAA,IAChC;AAEA,IAAAO,YAAU,MAAM;AACd,YAAM,qBAAqB,CAAC,UAAiB;AAC3C,YACE,iBAAiB,WACjB,CAAC,iBAAiB,QAAQ,SAAS,MAAM,MAAc,GACvD;AACA,+BAAqB,KAAK;AAAA,QAC5B;AACA,YACE,aAAa,WACb,CAAC,aAAa,QAAQ,SAAS,MAAM,MAAc,GACnD;AACA,2BAAiB,KAAK;AAAA,QACxB;AAAA,MACF;AAEA,eAAS,iBAAiB,aAAa,kBAAkB;AACzD,aAAO,MAAM;AACX,iBAAS,oBAAoB,aAAa,kBAAkB;AAAA,MAC9D;AAAA,IACF,GAAG,CAAC,CAAC;AAEL,WACE,gBAAAN;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAGJ;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL;AAAA,cACA;AAAA,cACA;AAAA,cACA,cAAc;AAAA,cACd,kBAAkB;AAAA,cAClB,SAAS;AAAA,cACT,eAAY;AAAA,cACZ,cAAY;AAAA,cAEX,mBACC,OAAO,IAAI,CAAC,UACV,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBAEC,MAAM,MAAM;AAAA,kBACZ,KAAK,MAAM;AAAA,kBACX,SAAS,MAAM;AAAA,kBACf,OAAO,MAAM;AAAA,kBACb,SAAS,MAAM;AAAA;AAAA,gBALV,MAAM;AAAA,cAMb,CACD,IAED,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,KAAI;AAAA,kBACJ,SAAQ;AAAA,kBACR,OAAM;AAAA;AAAA,cACR;AAAA;AAAA,UAEJ;AAAA,UAGA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS;AAAA,cACT,UAAU,CAAC;AAAA,cACX,WAAU;AAAA,cACV,cAAY,YAAY,WAAW;AAAA,cAElC,sBACC,gBAAAA,MAAC,SAAI,WAAU,4CACb,0BAAAC,OAAC,SAAI,WAAU,gBACb;AAAA,gCAAAD,MAAC,SAAI,WAAU,iCAAgC;AAAA,gBAC/C,gBAAAA,MAAC,SAAI,WAAU,iCAAgC;AAAA,iBACjD,GACF,IAEA,gBAAAA,MAAC,QAAK,MAAM,IAAI;AAAA;AAAA,UAEpB;AAAA,UAGA,gBAAAA,MAAC,OAAE,WAAU,oDACV,qBAAW,WAAW,GACzB;AAAA,UAGA,gBAAAA,MAAC,SAAI,WAAU,mBAAkB,eAAY,gBAC3C,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cACT,WAAW,CAAC,MAAM;AAChB,oBAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,oBAAE,eAAe;AACjB;AAAA,oBACE;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,cACA,cAAW;AAAA,cAEX,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,OACE,WAAW,IAAI,GAAI,cAAc,WAAY,GAAG,MAAM;AAAA,kBAC1D;AAAA;AAAA,cACF;AAAA;AAAA,UACF,GACF;AAAA,UAGA,gBAAAA,MAAC,OAAE,WAAU,oDACV,qBAAW,QAAQ,GACtB;AAAA,UAGA,gBAAAC,OAAC,SAAI,WAAU,gBAAe,KAAK,kBACjC;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,WAAU;AAAA,gBACV,cAAW;AAAA,gBAEX,0BAAAA,MAAC,SAAI,WAAU,4CACZ,wBAAc,GACjB;AAAA;AAAA,YACF;AAAA,YAEC,qBACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,WAAW,CAAC,MAAM;AAChB,sBAAI,EAAE,QAAQ,UAAU;AACtB,yCAAqB,KAAK;AAAA,kBAC5B;AAAA,gBACF;AAAA,gBAEA,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,KAAI;AAAA,oBACJ,KAAI;AAAA,oBACJ,MAAK;AAAA,oBACL,OAAO;AAAA,oBACP,UAAU;AAAA,oBACV,WAAW,CAAC,MAAM;AAChB,0BAAI,EAAE,QAAQ,aAAa,EAAE,QAAQ,cAAc;AACjD,0BAAE,eAAe;AACjB,8BAAM,YAAY,KAAK;AAAA,0BACrB;AAAA,0BACA,KAAK,OAAO,SAAS,OAAO,EAAE,IAAI;AAAA,wBACpC;AACA,kCAAU,SAAS;AACnB,4BAAI,SAAS,QAAS,UAAS,QAAQ,SAAS;AAAA,sBAClD,WAAW,EAAE,QAAQ,eAAe,EAAE,QAAQ,aAAa;AACzD,0BAAE,eAAe;AACjB,8BAAM,YAAY,KAAK;AAAA,0BACrB;AAAA,0BACA,KAAK,OAAO,SAAS,OAAO,EAAE,IAAI;AAAA,wBACpC;AACA,kCAAU,SAAS;AACnB,4BAAI,SAAS,QAAS,UAAS,QAAQ,SAAS;AAAA,sBAClD;AAAA,oBACF;AAAA,oBACA,WAAU;AAAA,oBACV,OAAO;AAAA,sBACL,YAAY,iDAAiD,SAAS,GAAG,cAAc,SAAS,GAAG;AAAA,oBACrG;AAAA,oBACA,cAAW;AAAA,oBACX,iBAAe,KAAK,MAAM,SAAS,GAAG;AAAA,oBACtC,iBAAe;AAAA,oBACf,iBAAe;AAAA;AAAA,gBACjB;AAAA;AAAA,YACF;AAAA,aAEJ;AAAA,UAGA,gBAAAC,OAAC,SAAI,WAAU,gBAAe,KAAK,cACjC;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,WAAU;AAAA,gBACV,cAAW;AAAA,gBAEX,0BAAAA,MAAC,qBAAkB,MAAM,IAAI;AAAA;AAAA,YAC/B;AAAA,YAEC,iBACC,gBAAAA,MAAC,SAAI,WAAU,mHACb,0BAAAA,MAAC,SAAI,WAAU,uBACZ;AAAA,cACC,EAAE,OAAO,GAAG,OAAO,KAAK;AAAA,cACxB,EAAE,OAAO,KAAK,OAAO,OAAO;AAAA,cAC5B,EAAE,OAAO,GAAG,OAAO,KAAK;AAAA,YAC1B,EAAE,IAAI,CAAC,EAAE,OAAO,MAAM,MACpB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,SAAS,MAAM,kBAAkB,KAAK;AAAA,gBACtC,WAAW;AAAA,kBACT;AAAA,kBACA,iBAAiB,QACb,kDACA;AAAA,gBACN;AAAA,gBAEC;AAAA;AAAA,cAVI;AAAA,YAWP,CACD,GACH,GACF;AAAA,aAEJ;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AASA,IAAM,8BAA8B;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW;AAAA,EACX,YAAY;AACd;AAEA,IAAM,eAAeE;AAAA,EACnB,CAAC,EAAE,OAAO,UAAU,MAAM,iBAAiB,WAAW,GAAG,MAAM,GAAG,QAAQ;AACxE,UAAM,kBAAkB,4BAA4B,eAAe;AAEnE,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,QAAO;AAAA,QACP,WAAW;AAAA,UACT,GAAG,eAAe;AAAA,UAClB;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ,0BAAAC,OAAC,SAAI,WAAU,kDACb;AAAA,0BAAAA,OAAC,SAAI,WAAU,sCACb;AAAA,4BAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,QAAO,WAAU,0BACrC,iBACH;AAAA,YAEA,gBAAAC,OAAC,SAAI,WAAU,yCACZ;AAAA,0BACC,gBAAAA,OAAC,SAAI,WAAU,2BACb;AAAA,gCAAAD,MAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB;AAAA,gBAC3C,gBAAAA,MAAC,gBAAK,MAAK,MAAM,oBAAS;AAAA,iBAC5B;AAAA,cAGF,gBAAAA,MAAC,gBAAK,MAAK,MAAK,WAAU,YACvB,gBACH;AAAA,eACF;AAAA,aACF;AAAA,UAEA,gBAAAA;AAAA,YAACG;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,WAAU;AAAA,cACV,eAAY;AAAA;AAAA,UACd;AAAA,WACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAWA,IAAM,WAAWD;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,cAAc,MAAM;AACxB,UAAI,UAAU;AACZ,iBAAS,CAAC,QAAQ;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,UAAsC;AAC3D,WAAK,MAAM,QAAQ,WAAW,MAAM,QAAQ,QAAQ,UAAU;AAC5D,cAAM,eAAe;AACrB,iBAAS,CAAC,QAAQ;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,eAAe,CAAC,CAAC;AACvB,UAAM,mBAAmB,CAAC,UAAkB;AAC1C,YAAM,WAAW,UAAU,IAAI,eAAY;AAC3C,aAAO,GAAG,KAAK,IAAI,QAAQ;AAAA,IAC7B;AAEA,UAAM,cAAc,iBAChB,iBAAiB,cAAc,IAC/B,kBAAkB;AACtB,UAAM,cACJ;AACF,UAAM,qBAAqB,eACvB,8FACA;AACJ,UAAM,kBAAkB,WACpB,0CACA;AAEJ,QAAI,cAAc;AAChB,aACE,gBAAAF;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,MAAK;AAAA,UACL,WAAW;AAAA,YACT,GAAG,WAAW,IAAI,kBAAkB,IAAI,eAAe,IAAI,SAAS,GAAG,KAAK;AAAA,UAC9E;AAAA,UACA,SAAS;AAAA,UACT,WAAW;AAAA,UACX,gBAAc;AAAA,UACb,GAAI;AAAA,UAEL,0BAAAC,OAAC,SAAI,WAAU,kFACb;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,WAAU;AAAA,gBAET;AAAA;AAAA,YACH;AAAA,YAEA,gBAAAC,OAAC,SAAI,WAAU,sDACZ;AAAA,0BACC,gBAAAA,OAAC,SAAI,WAAU,kDACb;AAAA,gCAAAD,MAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB;AAAA,gBAC3C,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBAET;AAAA;AAAA,gBACH;AAAA,iBACF;AAAA,cAGF,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBAET;AAAA;AAAA,cACH;AAAA,eACF;AAAA,aACF;AAAA;AAAA,MACF;AAAA,IAEJ;AAEA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,GAAG,WAAW,IAAI,SAAS,GAAG,KAAK,CAAC;AAAA,QACjD,GAAI;AAAA,QAEL,0BAAAC,OAAC,SAAI,WAAU,kFACb;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAO;AAAA,cACP,WAAU;AAAA,cAET;AAAA;AAAA,UACH;AAAA,UAEA,gBAAAC,OAAC,SAAI,WAAU,sDACZ;AAAA,wBACC,gBAAAA,OAAC,SAAI,WAAU,kDACb;AAAA,8BAAAD,MAAC,SAAM,MAAM,IAAI,WAAU,iBAAgB;AAAA,cAC3C,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBAET;AAAA;AAAA,cACH;AAAA,eACF;AAAA,YAGF,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBAET;AAAA;AAAA,YACH;AAAA,aACF;AAAA,WACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAmBA,IAAM,yBAAyB;AAAA,EAC7B,MAAM;AAAA,IACJ,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AACF;AAEA,IAAM,wBAAwBE,aAG5B,CAAC,EAAE,MAAM,mBAAmB,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC3D,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,GAAG,+BAA+B,SAAS;AAAA,MACrD,GAAG;AAAA,MAGJ,0BAAAC,OAAC,SAAI,WAAU,uBACZ;AAAA,aAAK,IAAI,CAAC,SAAS,iBAClB,gBAAAD,MAAC,SAAuB,WAAU,iBAEhC,0BAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,iBAAiB,IAAI,kBAAkB;AAAA,YACzC;AAAA,YAEA;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,QAAO;AAAA,kBACP,WAAU;AAAA,kBAET,kBAAQ;AAAA;AAAA,cACX;AAAA,cAEA,gBAAAA,MAAC,SAAI,WAAU,8BACZ,kBAAQ,YAAY,IAAI,CAAC,eAAe;AACvC,sBAAM,aAAa,uBAAuB,WAAW,IAAI;AAEzD,uBACE,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBAEC,QAAO;AAAA,oBACP,SAAQ;AAAA,oBACR,WAAU;AAAA,oBACV,QAAO;AAAA,oBACP,WAAW;AAAA,sBACT,GAAG,WAAW,UAAU;AAAA;AAAA,oBAE1B;AAAA,oBACA,SAAS,MAAM,oBAAoB,UAAU;AAAA,oBAE7C,0BAAAC,OAAC,SAAI,WAAU,kDACb;AAAA,sCAAAA,OAAC,SAAI,WAAU,4EACb;AAAA,wCAAAD;AAAA,0BAAC;AAAA;AAAA,4BACC,MAAK;AAAA,4BACL,QAAO;AAAA,4BACP,WAAU;AAAA,4BAET,qBAAW;AAAA;AAAA,wBACd;AAAA,wBAEA,gBAAAC,OAAC,SAAI,WAAU,2BACb;AAAA,0CAAAD;AAAA,4BAAC;AAAA;AAAA,8BACC,SAAQ;AAAA,8BACR,QAAQ,WAAW;AAAA,8BACnB,MAAK;AAAA,8BAEJ,qBAAW;AAAA;AAAA,0BACd;AAAA,0BAEA,gBAAAA,MAAC,gBAAK,MAAK,MAAK,WAAU,0BACvB,qBAAW,MACd;AAAA,2BACF;AAAA,yBACF;AAAA,sBAEA,gBAAAA;AAAA,wBAACG;AAAA,wBAAA;AAAA,0BACC,MAAM;AAAA,0BACN,WAAU;AAAA,0BACV,eAAY;AAAA;AAAA,sBACd;AAAA,uBACF;AAAA;AAAA,kBAzCK,WAAW;AAAA,gBA0ClB;AAAA,cAEJ,CAAC,GACH;AAAA;AAAA;AAAA,QACF,KApEQ,QAAQ,IAqElB,CACD;AAAA,QAGA,KAAK,SAAS,KACb,gBAAAH,MAAC,SAAI,WAAU,0CAAyC;AAAA,SAE5D;AAAA;AAAA,EACF;AAEJ,CAAC;;;AD3gDD,SAAS,cAAAQ,mBAAkB;AAqFnB,SAkBE,OAAAC,OAlBF,QAAAC,cAAA;AApER,IAAM,kBAAkBC;AAAA,EACtB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,CAAC,kBAAkB,mBAAmB,IAAIC,WAAS,eAAe;AACxE,UAAM,cAAcC,OAAM;AAG1B,UAAM,YAAY,QAAQ,qBAAqB,KAAK,KAAK;AACzD,UAAM,WAAW,QACb,oBAAoB,KAAK,KACzB,GAAG,WAAW;AAGlB,UAAM,eAAe,uBAAuB;AAC5C,UAAM,aAAa,eAAe,qBAAqB;AAGvD,IAAAC,YAAU,MAAM;AACd,UAAI,cAAc;AAChB,4BAAoB,kBAAkB;AAAA,MACxC;AAAA,IACF,GAAG,CAAC,cAAc,kBAAkB,CAAC;AAErC,UAAM,eAAe,MAAM;AACzB,UAAI,SAAU;AAEd,YAAM,cAAc,CAAC;AAErB,UAAI,CAAC,cAAc;AACjB,4BAAoB,WAAW;AAAA,MACjC;AAEA,yBAAmB,WAAW;AAAA,IAChC;AAEA,UAAM,gBAAgB,CAAC,UAA4C;AACjE,UAAI,SAAU;AAEd,UAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,cAAM,eAAe;AACrB,qBAAa;AAAA,MACf;AAAA,IACF;AAEA,WACE,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,WAAW,GAAG,mBAAmB,SAAS;AAAA,QACzC,GAAG;AAAA,QAGJ;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,SAAS;AAAA,cACT,WAAW;AAAA,cACX;AAAA,cACA,WAAW;AAAA,gBACT;AAAA,gBACA,YAAY;AAAA,gBACZ;AAAA,cACF;AAAA,cACA,iBAAe;AAAA,cACf,iBAAe;AAAA,cACf,iBAAe;AAAA,cACf,cAAY;AAAA,cAEX;AAAA;AAAA,gBAED,gBAAAD;AAAA,kBAACM;AAAA,kBAAA;AAAA,oBACC,MAAM;AAAA,oBACN,WAAW;AAAA,sBACT;AAAA,sBACA,WAAW,kBAAkB;AAAA,sBAC7B,aAAa,cAAc;AAAA,oBAC7B;AAAA,oBACA,eAAY;AAAA;AAAA,gBACd;AAAA;AAAA;AAAA,UACF;AAAA,UAGA,gBAAAN;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,mBAAiB;AAAA,cACjB,eAAa,CAAC;AAAA,cACd,WAAW;AAAA,gBACT;AAAA,gBACA,aAAa,6BAA6B;AAAA,cAC5C;AAAA,cACA,eAAY;AAAA,cACZ,cAAY;AAAA,cAEZ,0BAAAA,MAAC,SAAI,WAAW,GAAG,YAAY,gBAAgB,GAAI,UAAS;AAAA;AAAA,UAC9D;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,gBAAgB,cAAc;;;AM/I9B;AAAA,EACE,YAAAO;AAAA,EACA,gBAAAC;AAAA,EACA,cAAAC;AAAA,EAEA,kBAAAC;AAAA,EAGA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AACP,SAAS,UAAAC,eAAwB;AAkO3B,gBAAAC,aAAA;AArNN,SAAS,0BACP,MACA,cACA,aACwB;AACxB,SAAOD,QAA4B,CAAC,KAAK,SAAS;AAAA,IAChD;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,UAAU,CAAC,UAAU,IAAI,EAAE,MAAM,CAAC;AAAA,IAClC,gBAAgB,CAAC,cAA+B;AAC9C,YAAM,QAAQ,IAAI;AAClB,UAAI,MAAM,SAAS,UAAU;AAC3B,eAAO,MAAM,UAAU;AAAA,MACzB,OAAO;AACL,eAAO,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM,SAAS,SAAS;AAAA,MACrE;AAAA,IACF;AAAA,EACF,EAAE;AACJ;AAYA,IAAME,eAAc,CAClB,UACA,OACA,UACA,iBACc;AACd,SAAOT,UAAS,IAAI,UAAU,CAAC,UAAU;AACvC,QAAI,CAACG,gBAAe,KAAK,GAAG;AAC1B,aAAO;AAAA,IACT;AAEA,UAAM,aAAa;AAOnB,UAAM,cAAe,WAAW,MAC5B;AAEJ,QAAI,WAKC,CAAC;AAEN,QAAI,gBAAgB,mBAAmB;AAErC,YAAM,YACJ,WAAW,MAAM,SAAS,kBAAkB,SAAS,SAAS;AAGhE,YAAM,aAAa,MAAM,SAAS;AAClC,YAAM,WAAW,WAAW,eAAe,SAAS;AAEpD,eAAS,QAAQ;AACjB,eAAS,WAAW;AACpB,eAAS,mBAAmB,CAAC,eAAwB;AACnD,qBAAa,WAAW,UAAU;AAClC,mBAAW,MAAM,mBAAmB,UAAU;AAAA,MAChD;AAAA,IACF;AAGA,QAAI,WAAW,MAAM,UAAU;AAC7B,YAAM,oBAAoBM;AAAA,QACxB,WAAW,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAGA,UAAI,gBAAgB,mBAAmB;AACrC,iBAAS,WAAW;AAAA,MACtB,WAAW,sBAAsB,WAAW,MAAM,UAAU;AAE1D,eAAOR,cAAa,YAAY,EAAE,UAAU,kBAAkB,CAAC;AAAA,MACjE;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,QAAQ,EAAE,SAAS,GAAG;AACpC,aAAOA,cAAa,YAAY,QAAQ;AAAA,IAC1C;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,IAAM,iBAAiBC;AAAA,EACrB,CACE;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,CAAC,eAAe,gBAAgB,IAAII;AAAA,MACxC,iBAAiB,SAAS,WAAW,KAAK,CAAC;AAAA,IAC7C;AAEA,UAAM,eAAe,oBAAoB;AACzC,UAAM,eAAe,eAAe,kBAAkB;AAGtD,UAAM,WAAWD,QAAsC,IAAI;AAC3D,QAAI,SAAS,SAAS;AAEpB,eAAS,QAAQ,SAAS,CAAC,SAAS;AAClC,cAAM,YAA0C,CAAC;AACjD,YAAI,KAAK,SAAS,MAAM;AACtB,oBAAU,OAAO;AAAA,QACnB;AACA,YAAI,KAAK,gBAAgB,aAAa;AACpC,oBAAU,cAAc;AAAA,QAC1B;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH,OAAO;AAEL,eAAS,UAAU;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,QAAQ,SAAS;AAGvB,IAAAD,YAAU,MAAM;AACd,YAAM,SAAS,EAAE,OAAO,aAAa,CAAC;AAAA,IACxC,GAAG,CAAC,cAAc,KAAK,CAAC;AAGxB,IAAAA,YAAU,MAAM;AACd,UAAI,CAAC,cAAc;AACjB,yBAAiB,CAAC,SAAS;AACzB,cAAI,SAAS,UAAU;AACrB,gBAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,qBAAO,KAAK,CAAC,KAAK;AAAA,YACpB;AACA,mBAAO,OAAO,SAAS,WAAW,OAAO;AAAA,UAC3C;AACA,cAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,mBAAO;AAAA,UACT;AACA,iBAAO,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,cAAc,IAAI,CAAC;AAEvB,UAAM,mBAAmB,CAAC,WAAmB,eAAwB;AACnE,YAAM,aAAa,MAAM,SAAS;AAClC,UAAI;AAEJ,UAAI,SAAS,UAAU;AAErB,YAAI,YAAY;AACd,qBAAW;AAAA,QACb,OAAO;AAEL,qBAAW,cAAc,KAAM,WAAW;AAAA,QAC5C;AAAA,MACF,OAAO;AAEL,cAAM,eAAe,MAAM,QAAQ,WAAW,KAAK,IAC/C,WAAW,QACX,CAAC;AAEL,YAAI,YAAY;AACd,qBAAW,CAAC,GAAG,cAAc,SAAS;AAAA,QACxC,OAAO;AACL,qBAAW,aAAa,OAAO,CAAC,MAAM,MAAM,SAAS;AAAA,QACvD;AAAA,MACF;AAEA,UAAI,CAAC,cAAc;AACjB,yBAAiB,QAAQ;AAAA,MAC3B;AACA,YAAM,SAAS,EAAE,OAAO,SAAS,CAAC;AAClC,sBAAgB,QAAQ;AAAA,IAC1B;AAGA,UAAM,WAAW,EAAE,SAAS,EAAE;AAC9B,UAAM,mBAAmBK;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WACE,gBAAAD,MAAC,SAAI,KAAU,WAAuB,GAAG,OACtC,4BACH;AAAA,EAEJ;AACF;AAEA,eAAe,cAAc;;;ACrP7B,SAAgB,UAAAE,eAAc;AAC9B,SAAS,WAAW,UAAU,KAAAC,UAAS;AA2HjC,gBAAAC,OAWE,QAAAC,cAXF;AArEN,IAAM,iBAAiB,MAAc;AACnC,SAAO,OAAO,WAAW;AAC3B;;;ACrDO,IAAM,kBAAkB;AAAA,EAC7B,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA;AAAA,EAEX,UAAU;AACZ;;;ACGO,IAAM,eAAe,CAAC,iBAAgD;AAC3E,MAAI,2DAAiD,QAAO;AAC5D,MAAI,+DAAmD,QAAO;AAC9D,SAAO;AACT;AAOO,IAAM,kCAAkC,CAC7C,iBACmB;AACnB,UAAQ,cAAc;AAAA,IACpB;AACE,aAAO,gBAAgB;AAAA,IACzB;AACE,aAAO,gBAAgB;AAAA,IACzB;AACE,aAAO,gBAAgB;AAAA,IACzB;AACE,aAAO,gBAAgB;AAAA,IACzB;AACE,aAAO,gBAAgB;AAAA,EAC3B;AACF;AAOO,IAAM,+BAA+B,CAAC,WAA2B;AACtE,QAAM,UAA8D;AAAA,IAClE,CAAC,gBAAgB,OAAO,GAAG;AAAA,MACzB,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,CAAC,gBAAgB,SAAS,GAAG;AAAA,MAC3B,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,CAAC,gBAAgB,SAAS,GAAG;AAAA,MAC3B,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,CAAC,gBAAgB,QAAQ,GAAG;AAAA,MAC1B,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AAEA,SAAO,QAAQ,MAAM,KAAK;AAC5B;AAQO,IAAM,kBAAkB,CAC7B,iBACY;AACZ,QAAM,EAAE,OAAO,IAAI;AAGnB,MAAI,OAAO,oDAA6C;AACtD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAWA,IAAM,eAAe,CAAC,OAIF;AAClB,SAAO,GAAG,aAAa;AACzB;AAMA,IAAM,sBAAsB,CAC1B,UACA,YACkB;AAClB,MAAI,SAAS,SAAS,EAAG;AAEzB,QAAM,CAAC,UAAU,IAAI;AACrB,SAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,GAAG;AAGnD;AAMA,IAAM,0BAA0B,CAC9B,UACA,YACkB;AAClB,QAAM,WAAW,QAAQ,MAAM,CAAC,OAAO,SAAS,IAAI,GAAG,EAAE,MAAM,GAAG,SAAS;AAE3E,SAAO;AAGT;AAOA,IAAM,0BAA0B;AAEhC,IAAM,aAEF;AAAA,EACF,gCAA0B,GAAG;AAAA,EAC7B,0CAA+B,GAAG;AAAA,EAClC,0CAA+B,GAAG;AACpC;AAOO,IAAM,uBAAuB,CAClC,iBACyB;AACzB,QAAM,EAAE,OAAO,IAAI;AAEnB,MAAI,CAAC,gBAAgB,YAAY,KAAK,CAAC,OAAO,QAAS,QAAO;AAG9D,QAAM,eAAe,OAAO,QAAQ,OAAO,YAAY;AACvD,MAAI,aAAa,WAAW,EAAG,QAAO;AAEtC,QAAM,WAAW,IAAI;AAAA,IACnB,OAAO,iBAAiB,IAAI,CAAC,MAAM,EAAE,QAAQ,KAAK,CAAC;AAAA,EACrD;AAEA,MAAI,SAAS,SAAS,EAAG;AAEzB,QAAM,YAAY,WAAW,OAAO,YAAY;AAChD,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAO,UAAU,UAAU,YAAY;AACzC;AASO,IAAM,4BAA4B,CACvC,iBACmB;AACnB,QAAM,EAAE,OAAO,IAAI;AAGnB,MACE,OAAO,kEACP,gBAAgB,YAAY,GAC5B;AACA,UAAM,sBAAsB,qBAAqB,YAAY;AAC7D,QAAI,wBAAwB,MAAM;AAChC,aAAO,gCAAgC,mBAAmB;AAAA,IAC5D;AAAA,EACF;AAEA,SAAO,gCAAgC,OAAO,YAAY;AAC5D;;;ACtMA,IAAM,0BAA0B,CAC9B,WACa;AACb,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX,WAAW,OAAO;AAAA,IAClB,cAAc,OAAO;AAAA,IACrB,iBAAiB,OAAO;AAAA,IACxB,aAAa;AAAA,IACb,WAAW;AAAA,IACX,UAAU;AAAA,IACV,qBAAqB,OAAO,uBAAuB;AAAA,IACnD,QAAQ;AAAA,IACR,cAAc,OAAO;AAAA,IACrB,SAAS,OAAO,WAAW,CAAC;AAAA,IAC5B,iBAAiB,OAAO,gBAAgB,IAAI,CAAC,YAAY;AAAA,MACvD,eAAe,OAAO,iBAAiB;AAAA,QACrC,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,MACA,SAAS,OAAO,WAAW;AAAA,QACzB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,MACA,OAAO,OAAO,SAAS;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,MACA,UAAU,OAAO,YAAY;AAAA,QAC3B,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,MACA,SAAS,OAAO,WAAW;AAAA,QACzB,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,IACF,EAAE;AAAA,IACF,kBACE,OAAO,SAAS,OAAO,CAAC,QAAQ,IAAI,SAAS,EAAE,IAAI,CAAC,QAAQ,IAAI,EAAE,KAAK,CAAC;AAAA,EAC5E;AACF;AAOA,IAAM,uBAAuB,CAC3B,WACwC;AACxC,MAAI,OAAO,oDAA6C;AACtD,WAAO;AAAA,MACL,WAAW,aAAa,OAAO,YAAY;AAAA,MAC3C,iBAAiB,OAAO,mBAAmB;AAAA,IAC7C;AAAA,EACF;AACA,SAAO;AACT;AAQA,IAAM,8BAA8B,CAClC,QACA,UAC2B;AAC3B,QAAM,WAAW,wBAAwB,MAAM;AAC/C,QAAM,aAAa,qBAAqB,MAAM;AAE9C,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,gBAAgB,QAAQ;AAAA,IACxB;AAAA,EACF;AACF;AAYO,IAAM,qCAAqC,CAChD,aACA,WACA,aACA,aACA,eACkC;AAClC,QAAM,EAAE,SAAS,WAAW,IAAI,YAAY;AAG5C,QAAM,eAAe,WAAW;AAChC,QAAM,iBAAiB,WAAW;AAClC,QAAM,aAAa,WAAW,gBAAgB,eAAe;AAG7D,QAAM,YAAsC,QAAQ;AAAA,IAAI,CAAC,QAAQ,UAC/D,4BAA4B,QAAQ,KAAK;AAAA,EAC3C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,WAAW,SAAS;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACzIA,SAAS,eAAAC,cAAa,WAAAC,gBAAe;AAGrC,SAAS,cAAAC,cAA4B,SAAAC,QAAO,YAAAC,kBAAgB;AA+GA,gBAAAC,OA4E9C,QAAAC,cA5E8C;AAtC5D,IAAM,mBAAmB,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,OAAO;AAAA,EACP;AACF,MAA6B;AAE3B,QAAM,WAAWC,OAAM;AACvB,QAAM,YAAY,QAAQ,gBAAgB,QAAQ;AAClD,QAAM,CAAC,aAAa,cAAc,IAAIC,WAAS,KAAK;AAEpD,QAAM,aAAa,SAAS;AAC5B,QAAMC,mBAAkB,CACtB,QACAC,gBACG;AACH,UAAM,aAAaA,cAAa,KAAK;AAErC,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO,mCAAmC,UAAU;AAAA,IACxD;AAAA,EACF;AAEA,QAAMC,kBAAiB,CAAC,WAAmC;AACzD,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eACE,gBAAAN,MAAC,iBAAM,SAAQ,SAAQ,QAAO,WAAU,UAAU,gBAAAA,MAACO,cAAA,EAAY,GAAI,8BAEnE;AAAA,MAEJ,KAAK;AACH,eACE,gBAAAP,MAAC,iBAAM,SAAQ,SAAQ,QAAO,SAAQ,UAAU,gBAAAA,MAACQ,UAAA,EAAQ,GAAI,gCAE7D;AAAA,MAEJ;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,QAAM,mBAAmB,MAAM;AAC7B,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAGA,QAAM,4BAA4B,CAAC,gBAA6B;AAC9D,UAAM,gBAAgB,YAAY;AAClC,UAAM,iBAAiB,kBAAkB,YAAY;AACrD,UAAM,kBAAkB,YAAY,WAAW;AAG/C,QAAI,gBAAuC;AAC3C,QAAI,kBAAkB,CAAC,iBAAiB;AAEtC,sBAAgB;AAAA,IAClB,WAAW,iBAAiB;AAE1B,sBAAgB;AAAA,IAClB;AAEA,UAAM,eAAeJ,iBAAgB,eAAe,IAAI;AACxD,UAAM,cAAcE,gBAAe,aAAa;AAGhD,UAAM,cAAc,MAAM;AACxB,YAAM,eAAe,6GACnB,iBACI,qCACA,iCACN;AAEA,YAAM,aACJ;AAEF,aACE,gBAAAN,MAAC,SAAI,WAAW,cACb,4BAAkB,gBAAAA,MAAC,SAAI,WAAW,YAAY,GACjD;AAAA,IAEJ;AAEA,QAAI,WAAW,YAAY;AACzB,aACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA,YAAY,WAAW,eAAe;AAAA,UACxC;AAAA,UAEA,0BAAAC,OAAC,SAAI,WAAU,0CACb;AAAA,4BAAAA,OAAC,SAAI,WAAU,iCACb;AAAA,8BAAAD,MAAC,SAAI,WAAU,QAAQ,sBAAY,GAAE;AAAA,cACrC,gBAAAC,OAAC,SAAI,WAAU,UACb;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW;AAAA,sBACT;AAAA,sBACA,kBAAkB,YAAY,SAAS,cACnC,kBACA;AAAA,oBACN;AAAA,oBAEC,sBAAY;AAAA;AAAA,gBACf;AAAA,gBACC,YAAY,eACX,gBAAAA,MAAC,OAAE,WAAU,8BACV,sBAAY,aACf;AAAA,iBAEJ;AAAA,eACF;AAAA,YACC,eAAe,gBAAAA,MAAC,SAAI,WAAU,iBAAiB,uBAAY;AAAA,aAC9D;AAAA;AAAA,QA7BK;AAAA,MA8BP;AAAA,IAEJ;AAEA,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA,YAAY,WAAW,eAAe;AAAA,QACxC;AAAA,QAEA;AAAA,0BAAAA,OAAC,SAAI,WAAU,kCACZ;AAAA,wBAAY;AAAA,YACb,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,kBAAkB,YAAY,SAAS,cACnC,kBACA;AAAA,gBACN;AAAA,gBAEC,sBAAY;AAAA;AAAA,YACf;AAAA,aACF;AAAA,UACC,eAAe,gBAAAA,MAAC,SAAI,WAAU,iBAAiB,uBAAY;AAAA;AAAA;AAAA,MApBvD;AAAA,IAqBP;AAAA,EAEJ;AAGA,MAAI,YAAY;AACd,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,iBAAiB,iBAAiB,GAAG,UAAU,SAAS;AAAA,QAErE,uBAAa;AAAA,UAAI,CAAC,gBACjB,0BAA0B,WAAW;AAAA,QACvC;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,eAAe,CAACS,WAAU;AACxB,uBAAeA,MAAK;AACpB,wBAAgBA,MAAK;AAAA,MACvB;AAAA,MACA;AAAA,MACA,WAAW,GAAG,iBAAiB,iBAAiB,GAAG,SAAS;AAAA,MAE3D,uBAAa,IAAI,CAAC,aAAa,UAAU;AACxC,cAAM,gBAAgB,YAAY,SAAS,OAAO,KAAK;AACvD,cAAM,eAAeL,iBAAgB,YAAY,QAAQ,KAAK;AAC9D,cAAM,cAAcE,gBAAe,YAAY,MAAM;AAErD,YAAI,WAAW,YAAY;AACzB,iBACE,gBAAAN;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA,YAAY,WACR,kCACA;AAAA,cACN;AAAA,cAEA,0BAAAC,OAAC,SAAI,WAAU,0CACb;AAAA,gCAAAA,OAAC,SAAI,WAAU,iCACb;AAAA,kCAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO,YAAY;AAAA,sBACnB,IAAI;AAAA,sBACJ,UAAU,YAAY;AAAA,sBACtB,WAAU;AAAA;AAAA,kBACZ;AAAA,kBACA,gBAAAC,OAAC,SAAI,WAAU,UACb;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS;AAAA,wBACT,WAAW;AAAA,0BACT;AAAA,0BACA,gBAAgB,YAAY,QACxB,kBACA;AAAA,0BACJ,YAAY,WACR,uBACA;AAAA,wBACN;AAAA,wBAEC,sBAAY;AAAA;AAAA,oBACf;AAAA,oBACC,YAAY,eACX,gBAAAA,MAAC,OAAE,WAAU,8BACV,sBAAY,aACf;AAAA,qBAEJ;AAAA,mBACF;AAAA,gBACC,eACC,gBAAAA,MAAC,SAAI,WAAU,iBAAiB,uBAAY;AAAA,iBAEhD;AAAA;AAAA,YA1CK;AAAA,UA2CP;AAAA,QAEJ;AAEA,eACE,gBAAAC;AAAA,UAAC;AAAA;AAAA,YAEC,WAAW;AAAA,cACT;AAAA,cACA;AAAA,cACA,YAAY,WAAW,kCAAkC;AAAA,YAC3D;AAAA,YAEA;AAAA,8BAAAA,OAAC,SAAI,WAAU,kCACb;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO,YAAY;AAAA,oBACnB,IAAI;AAAA,oBACJ,UAAU,YAAY;AAAA;AAAA,gBACxB;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS;AAAA,oBACT,WAAW;AAAA,sBACT;AAAA,sBACA,gBAAgB,YAAY,QACxB,kBACA;AAAA,sBACJ,YAAY,WAAW,uBAAuB;AAAA,oBAChD;AAAA,oBAEC,sBAAY;AAAA;AAAA,gBACf;AAAA,iBACF;AAAA,cACC,eAAe,gBAAAA,MAAC,SAAI,WAAU,iBAAiB,uBAAY;AAAA;AAAA;AAAA,UA1BvD;AAAA,QA2BP;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;AAQA,IAAM,oBAAoBU;AAAA,EACxB,CAAC,EAAE,WAAW,OAAO,UAAU,SAAS,GAAG,MAAM,GAAG,QAAQ;AAC1D,WACE,gBAAAT;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,0BAAAA,OAAC,UAAK,WAAU,iBACd;AAAA,4BAAAD,MAAC,OAAE,WAAU,mCAAmC,iBAAM;AAAA,YACtD,gBAAAA,MAAC,OAAE,WAAU,0BAA0B,oBAAS;AAAA,aAClD;AAAA,UAEA,gBAAAA,MAAC,OAAE,WAAU,yBAAyB,mBAAQ;AAAA;AAAA;AAAA,IAChD;AAAA,EAEJ;AACF;;;ACrUQ,gBAAAW,aAAA;AA/CD,IAAM,4BAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AACF,MAAwC;AAEtC,QAAM,oBAAoB,QAAQ,SAAS;AAAA,IACzC,CAAC,OAAO,GAAG,cAAc,UAAa,GAAG,cAAc;AAAA,EACzD;AAEA,QAAM,eAAe,SAAS,SAAS,IAAI,CAAC,WAAW;AACrD,UAAM,kBACJ,QAAQ,SAAS,KAAK,CAAC,OAAO,GAAG,OAAO,OAAO,EAAE,GAAG,aAAa;AAEnE,UAAM,aACJ,QAAQ,iBAAiB;AAAA,MACvB,CAAC,mBAAmB,eAAe,aAAa,OAAO;AAAA,IACzD,KAAK;AAGP,UAAM,2BACJ,QAAQ,kEACR;AAEF,QAAI;AACJ,QAAI,0BAA0B;AAC5B,UAAI,iBAAiB;AACnB;AAAA,MACF,WAAW,cAAc,CAAC,iBAAiB;AACzC;AAAA,MACF,OAAO;AACL;AAAA,MACF;AAAA,IACF,OAAO;AAEL;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,OAAO,OAAO;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI,CAAC,gBAAgB,aAAa,WAAW,GAAG;AAC9C,WACE,gBAAAA,MAAC,SACC,0BAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,uCAEhC,GACF;AAAA,EAEJ;AAEA,SACE,gBAAAA,MAAC,SAAI,WAAU,QACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MAEL,MAAM,YAAY,SAAS,EAAE;AAAA,MAC7B,QAAO;AAAA,MACP;AAAA,MACA,eAAe,QAAQ,kBAAkB,CAAC,GAAG,YAAY;AAAA;AAAA,IAJpD,YAAY,SAAS,EAAE;AAAA,EAK9B,GACF;AAEJ;;;AC7EA,SAA6B,aAAAC,aAAW,YAAAC,kBAAgB;AAGxD,SAAS,eAAAC,cAAa,WAAAC,UAAS,SAAAC,cAAa;AAqCgB,gBAAAC,OA2D9C,QAAAC,cA3D8C;AAlB5D,IAAM,qBAAqB,CAAC;AAAA,EAC1B,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AACT,MAA+B;AAC7B,QAAM,CAAC,aAAa,cAAc,IAAIC,WAAS,cAAc;AAE7D,EAAAC,YAAU,MAAM;AACd,mBAAe,cAAc;AAAA,EAC/B,GAAG,CAAC,cAAc,CAAC;AACnB,QAAMC,kBAAiB,CAAC,WAA6B;AACnD,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eACE,gBAAAJ,MAAC,iBAAM,SAAQ,SAAQ,QAAO,WAAU,UAAU,gBAAAA,MAACK,cAAA,EAAY,GAAI,8BAEnE;AAAA,MAEJ,KAAK;AACH,eACE,gBAAAL,MAAC,iBAAM,SAAQ,SAAQ,QAAO,SAAQ,UAAU,gBAAAA,MAACM,UAAA,EAAQ,GAAI,gCAE7D;AAAA,MAEJ;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,QAAMC,mBAAkB,CAAC,WAA6B;AACpD,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,QAAM,uBAAuB,CAAC,YAAqB,eAAwB;AACzE,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA,aACI,gDACA;AAAA,MACJ,cAAc;AAAA,IAChB;AAEA,WACE,gBAAAP,MAAC,SAAI,WAAW,iBACb,wBAAc,gBAAAA,MAACQ,QAAA,EAAM,MAAM,IAAI,QAAO,QAAO,GAChD;AAAA,EAEJ;AAEA,MAAI,SAAS,YAAY;AACvB,WACE,gBAAAR,MAAC,SAAI,WAAW,GAAG,uBAAuB,SAAS,GAChD,kBAAQ,IAAI,CAAC,QAAQ,MAAM;AAC1B,YAAM,aAAa,aAAa,SAAS,OAAO,KAAK,KAAK;AAC1D,YAAM,eAAeO,iBAAgB,OAAO,MAAM;AAClD,YAAM,cAAcH,gBAAe,OAAO,MAAM;AAEhD,aACE,gBAAAH;AAAA,QAAC;AAAA;AAAA,UAEC,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA,OAAO,WAAW,kCAAkC;AAAA,UACtD;AAAA,UAEA;AAAA,4BAAAA,OAAC,SAAI,WAAU,kCACZ;AAAA,mCAAqB,YAAY,OAAO,YAAY,QAAQ;AAAA,cAC7D,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW;AAAA,oBACT;AAAA,oBACA,cAAe,OAAO,UAAU,OAAO,UAAU,YAC7C,kBACA;AAAA,oBACJ,OAAO,YAAY,WACf,uBACA;AAAA,kBACN;AAAA,kBAEC,iBAAO;AAAA;AAAA,cACV;AAAA,eACF;AAAA,YACC,eACC,gBAAAA,MAAC,SAAI,WAAU,iBAAiB,uBAAY;AAAA;AAAA;AAAA,QAxBzC,YAAY,OAAO,KAAK,IAAI,CAAC;AAAA,MA0BpC;AAAA,IAEJ,CAAC,GACH;AAAA,EAEJ;AACA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,WAAW,kCAAkC;AAAA,QAC7C;AAAA,MACF;AAAA,MAEA,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR,gBAAgB,CAAC,MAAM;AACrB,2BAAe,CAAC;AAChB,qCAAyB,CAAC;AAAA,UAC5B;AAAA,UACA;AAAA,UAEC,kBAAQ,IAAI,CAAC,QAAQ,MACpB,gBAAAC;AAAA,YAAC;AAAA;AAAA,cAEC,WAAU;AAAA,cAEV;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO,OAAO;AAAA,oBACd,IAAI,eAAe,OAAO,KAAK,IAAI,CAAC;AAAA,oBACpC,UAAU,OAAO,YAAY;AAAA;AAAA,gBAC/B;AAAA,gBAEA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS,eAAe,OAAO,KAAK,IAAI,CAAC;AAAA,oBACzC,WAAW;AAAA,sBACT;AAAA,sBACA,aAAa,SAAS,OAAO,KAAK,IAC9B,kBACA;AAAA,sBACJ,OAAO,YAAY,WACf,uBACA;AAAA,oBACN;AAAA,oBAEC,iBAAO;AAAA;AAAA,gBACV;AAAA;AAAA;AAAA,YAtBK,eAAe,OAAO,KAAK,IAAI,CAAC;AAAA,UAuBvC,CACD;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;;;ACjHQ,gBAAAS,aAAA;AA/CD,IAAM,+BAA+B,CAAC;AAAA,EAC3C;AAAA,EACA;AACF,MAAwC;AAEtC,QAAM,oBAAoB,QAAQ,SAAS;AAAA,IACzC,CAAC,OAAO,GAAG,cAAc,UAAa,GAAG,cAAc;AAAA,EACzD;AAEA,QAAM,UAAU,SAAS,SAAS,IAAI,CAAC,WAAW;AAChD,UAAM,kBACJ,QAAQ,SAAS,KAAK,CAAC,OAAO,GAAG,OAAO,OAAO,EAAE,GAAG,aAAa;AAEnE,UAAM,aAAa,QAAQ,iBAAiB;AAAA,MAC1C,CAAC,OAAO,GAAG,aAAa,OAAO;AAAA,IACjC;AAGA,UAAM,2BACH,QAAQ,kEACP,QAAQ,0DACV;AAEF,QAAI;AACJ,QAAI,0BAA0B;AAC5B,UAAI,iBAAiB;AACnB;AAAA,MACF,WAAW,cAAc,CAAC,iBAAiB;AACzC;AAAA,MACF,OAAO;AACL;AAAA,MACF;AAAA,IACF,OAAO;AAEL;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,OAAO,OAAO;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WACE,gBAAAA,MAAC,SACC,0BAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,gDAEhC,GACF;AAAA,EAEJ;AAEA,QAAM,iBACJ,QAAQ,iBAAiB,IAAI,CAAC,OAAO,GAAG,QAAQ,KAAK,CAAC;AAExD,SACE,gBAAAA,MAAC,SAAI,WAAU,QACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MAEL,MAAM,YAAY,SAAS,EAAE;AAAA,MAC7B;AAAA,MACA;AAAA;AAAA,IAHK,YAAY,SAAS,EAAE;AAAA,EAI9B,GACF;AAEJ;;;AC/EA;AAAA,EACE,cAAAC;AAAA,EAGA,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AAaP,SAAS,eAAAC,cAAa,WAAAC,gBAAe;A;;;;;AAOqB,SA4HtD,YAAAC,WA5HsD,OAAAC,OA4HtD,QAAAC,cA5HsD;AAenD,IAAM,kBAAkB,CAAC,mBAA4B;AAC1D,UAAQ,gBAAgB;AAAA,IACtB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAYA,IAAM,eAAeC;AAAA,EACnB,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ;AAC/B,WACE,gBAAAC,MAAC,SAAI,WAAU,kBAAkB,GAAG,OAAO,KACzC,0BAAAA,MAAC,OAAE,WAAU,mCAAmC,oBAAS,GAC3D;AAAA,EAEJ;AACF;AAEA,IAAM,gBAAgBD,aAGpB,CAAC,EAAE,UAAU,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC5C,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ,CAAC;;;AC5FD,SAAS,SAAAC,eAA6B;AAEtC,SAAS,eAAAC,cAAa,WAAAC,gBAAe;AAYqB,gBAAAC,OAoOpD,QAAAC,cApOoD;AAJnD,IAAM,iBAAiB,CAAC,WAAgD;AAC7E,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aACE,gBAAAD,MAAC,iBAAM,SAAQ,SAAQ,QAAO,WAAU,UAAU,gBAAAA,MAACE,cAAA,EAAY,GAAI,8BAEnE;AAAA,IAEJ,KAAK;AACH,aACE,gBAAAF,MAAC,iBAAM,SAAQ,SAAQ,QAAO,SAAQ,UAAU,gBAAAA,MAACG,UAAA,EAAQ,GAAI,gCAE7D;AAAA,IAEJ;AACE,aAAO;AAAA,EACX;AACF;AAKO,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AACF,MAGM;AACJ,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAKO,IAAM,mBAAmB,CAAC,EAAE,SAAS,MAA4B;AACtE,SACE,gBAAAA,MAAC,SAAI,WAAU,kBACb,0BAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,QAAO,OAAM,iBACjC,oBACH,GACF;AAEJ;AAMO,IAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AACF,MAA6B;AAE3B,QAAM,OAAO,SAAS,aAAa;AACnC,QAAM,SAASI,QAAM;AAKrB,QAAM,iBAGF,CAAC;AAGL,MAAI;AACF,QAAI,QAAQ,QAAQ;AAClB,YAAM,SACJ,OAAO,OAAO,WAAW,WACrB,KAAK,MAAM,OAAO,MAAM,IACxB,OAAO;AACb,UAAI,OAAO,WAAW,UAAU;AAC9B,eAAO,OAAO,gBAAgB,MAAM;AAAA,MACtC;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,yBAAyB,KAAK;AAAA,EAC9C;AAGA,QAAM,QAAQ;AACd,QAAM,eAAyB,CAAC;AAChC,MAAI;AACJ,UAAQ,QAAQ,MAAM,KAAK,IAAI,OAAO,MAAM;AAC1C,iBAAa,KAAK,MAAM,CAAC,CAAC;AAAA,EAC5B;AAGA,QAAM,iBAAyC,CAAC;AAChD,eAAa,QAAQ,CAAC,gBAAgB;AACpC,mBAAe,WAAW,IACxB,eAAe,WAAW,GAAG,iBAAiB,IAAI,WAAW;AAAA,EACjE,CAAC;AAKD,QAAM,iBAAiB,CACrB,UACA,aACA,mBACG;AACH,QAAI,aAAa;AACf,eAAS,KAAK;AAAA,QACZ,SAAS;AAAA,QACT,IAAI,GAAG,MAAM,SAAS,EAAE,eAAe,OAAO;AAAA,MAChD,CAAC;AAAA,IACH;AAAA,EACF;AAKA,QAAM,4BAA4B,CAChC,UACA,mBACuC;AACvC,UAAM,gBAAgB,eAAe,QAAQ,KAAK,IAAI,QAAQ;AAC9D,WAAO;AAAA,MACL,SACE,gBAAAJ;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,OAAM;AAAA,UACN,WAAU;AAAA,UAET;AAAA;AAAA,QANI,GAAG,MAAM,aAAa,QAAQ;AAAA,MAOrC;AAAA,MAEF,IAAI,GAAG,MAAM,aAAa,EAAE,eAAe,OAAO;AAAA,IACpD;AAAA,EACF;AAKA,QAAM,2BAA2B,CAC/B,UACA,mBACuC;AACvC,UAAM,gBAAgB,eAAe,QAAQ;AAC7C,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,QACL,SACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,QAAO;AAAA,YACP,OAAM;AAAA,YACN,WAAU;AAAA,YACX;AAAA;AAAA,UALM,GAAG,MAAM,cAAc,QAAQ;AAAA,QAOtC;AAAA,QAEF,IAAI,GAAG,MAAM,cAAc,EAAE,eAAe,OAAO;AAAA,MACrD;AAAA,IACF;AAEA,UAAM,YAAY,cAAc;AAChC,UAAM,aAAa,YACf,wCACA;AAEJ,WAAO;AAAA,MACL,SACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,SAAQ;AAAA,UACR,QAAQ,YAAY,YAAY;AAAA,UAChC,WAAW,YAAY,gBAAAA,MAACE,cAAA,EAAY,IAAK,gBAAAF,MAACG,UAAA,EAAQ;AAAA,UAClD,MAAK;AAAA,UACL,WAAW,yCAAyC,UAAU;AAAA,UAE9D,0BAAAH,MAAC,UAAK,WAAU,iBAAiB,wBAAc,QAAO;AAAA;AAAA,QAPjD,GAAG,MAAM,WAAW,QAAQ;AAAA,MAQnC;AAAA,MAEF,IAAI,GAAG,MAAM,WAAW,EAAE,eAAe,OAAO;AAAA,IAClD;AAAA,EACF;AAKA,QAAM,wBAAwB,CAAC,aAAa,UAAU;AACpD,UAAM,WAA+D,CAAC;AACtE,QAAI,YAAY;AAChB,UAAM,iBAAiB,EAAE,SAAS,EAAE;AAEpC,UAAM,YAAY;AAClB,YAAQ,QAAQ,MAAM,KAAK,IAAI,OAAO,MAAM;AAC1C,YAAM,CAAC,WAAW,QAAQ,IAAI;AAC9B,YAAM,aAAa,MAAM;AAGzB,UAAI,aAAa,WAAW;AAC1B;AAAA,UACE;AAAA,UACA,KAAK,MAAM,WAAW,UAAU;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAGA,YAAM,qBAAqB,aACvB,0BAA0B,UAAU,cAAc,IAClD,yBAAyB,UAAU,cAAc;AACrD,eAAS,KAAK,kBAAkB;AAEhC,kBAAY,MAAM,QAAQ,UAAU;AAAA,IACtC;AAGA,QAAI,YAAY,KAAK,QAAQ;AAC3B,qBAAe,UAAU,KAAK,MAAM,SAAS,GAAG,cAAc;AAAA,IAChE;AAEA,WAAO;AAAA,EACT;AAEA,SACE,gBAAAC,OAAC,SAAI,WAAU,kBACb;AAAA,oBAAAA,OAAC,SAAI,WAAU,aACb;AAAA,sBAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,gCAEtD;AAAA,MACA,gBAAAA,MAAC,SAAI,WAAU,4DACb,0BAAAA,MAAC,SAAI,WAAU,aACZ,gCAAsB,KAAK,EAAE,IAAI,CAAC,YACjC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,OAAM;AAAA,UAEL,kBAAQ;AAAA;AAAA,QALJ,QAAQ;AAAA,MAMf,CACD,GACH,GACF;AAAA,OACF;AAAA,IAEA,gBAAAC,OAAC,SAAI,WAAU,aACb;AAAA,sBAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,uBAEtD;AAAA,MACA,gBAAAA,MAAC,SAAI,WAAU,4DACb,0BAAAA,MAAC,SAAI,WAAU,aACZ,gCAAsB,IAAI,EAAE,IAAI,CAAC,YAChC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,OAAM;AAAA,UAEL,kBAAQ;AAAA;AAAA,QALJ,QAAQ;AAAA,MAMf,CACD,GACH,GACF;AAAA,OACF;AAAA,KACF;AAEJ;;;AC1Oc,SAME,OAAAK,OANF,QAAAC,cAAA;AApCP,IAAM,4BAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AACF,MAAwC;AACtC,QAAM,UAAU,SAAS,WAAW,CAAC;AACrC,QAAM,mBAAmB,CAAC,UAAkB,OAAO,cAAc,KAAK,KAAK;AAE3E,QAAM,mBACJ,QAAQ,kEACR,QAAQ;AAEV,SACE,gBAAAD,MAAC,SAAI,WAAU,QACb,0BAAAA,MAAC,SAAI,WAAU,yBACZ,kBAAQ,IAAI,CAAC,QAAQ,UAAU;AAE9B,UAAM,kBACJ,QAAQ,SAAS,KAAK,CAAC,OAAO,GAAG,OAAO,OAAO,EAAE,GAAG,aACpD;AACF,UAAM,aAAa,QAAQ,iBAAiB;AAAA,MAC1C,CAAC,OAAO,GAAG,aAAa,OAAO;AAAA,IACjC;AAIA,UAAM,mBAAmB,oBAAoB;AAE7C,UAAM,iBAAiB,kBAAkB,YAAY;AACrD,UAAM,gBAAgB,aAAa,MAAM;AACzC,UAAM,gBAAgB,kBAAkB,MAAM;AAE9C,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QAEV;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,mBAAmB,gBAAgB,cAAc,IAAI;AAAA,cACvD;AAAA,cAEA;AAAA,gCAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBACnC,2BAAiB,KAAK,EAAE,OAAO,IAAI,EAAE,OAAO,OAAO,MAAM,GAC5D;AAAA,gBAEC,oBACC,gBAAAA,MAAC,SAAI,WAAU,iBACZ,yBAAe,mBAAmB,YAAY,WAAW,GAC5D;AAAA;AAAA;AAAA,UAEJ;AAAA,UAEC,oBACC,gBAAAC,OAAC,UAAK,WAAU,oCACd;AAAA,4BAAAA,OAAC,gBAAK,MAAK,OAAM,QAAO,UAAS,OAAM,iBAAgB;AAAA;AAAA,cAC9B;AAAA,eACzB;AAAA,YACC,CAAC,oBACA,gBAAAA,OAAC,gBAAK,MAAK,OAAM,QAAO,UAAS,OAAM,iBAAgB;AAAA;AAAA,cAClC;AAAA,eACrB;AAAA,aAEJ;AAAA;AAAA;AAAA,MA9BG,OAAO,MAAM,UAAU,KAAK;AAAA,IAgCnC;AAAA,EAEJ,CAAC,GACH,GACF;AAEJ;;;ACpEM,SACE,OAAAC,OADF,QAAAC,cAAA;AAPC,IAAM,6BAA6B,CAAC;AAAA,EACzC;AACF,MAA0D;AACxD,QAAM,cAAc,QAAQ,UAAU;AAEtC,SACE,gBAAAA,OAAC,SAAI,WAAU,kBACb;AAAA,oBAAAA,OAAC,SAAI,WAAU,aACb;AAAA,sBAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,+BAEtD;AAAA,MACA,gBAAAA,MAAC,SAAI,WAAU,4DACb,0BAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBACnC,yBAAe,8BAClB,GACF;AAAA,OACF;AAAA,IAEC,QAAQ,kEACP,QAAQ,mBACN,gBAAAC,OAAC,SAAI,WAAU,aACb;AAAA,sBAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,4CAEtD;AAAA,MACA,gBAAAA,MAAC,SAAI,WAAU,4DACb,0BAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBACnC,iBAAO,iBACV,GACF;AAAA,OACF;AAAA,KAEN;AAEJ;;;AC5BS,gBAAAE,aAAA;AAJF,IAAM,qBAAqB,CAAC;AAAA,EACjC;AAAA,EACA;AACF,MAAwC;AACtC,SAAO,gBAAAA,MAAC,uBAAoB,UAAoB,QAAgB;AAClE;;;ACuFQ,SAOE,YAAAC,WANA,OAAAC,OADF,QAAAC,cAAA;AA7FD,IAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,MAA0D;AAGxD,QAAM,0BAA0B,EAAE,GAAG,MAAM,GAAG,KAAK;AACnD,QAAM,wBAAwB;AAI9B,MAAI,uBAAwD;AAC5D,MAAI;AACF,QAAI,QAAQ,QAAQ;AAClB,YAAM,SACJ,OAAO,OAAO,WAAW,WACrB,KAAK,MAAM,OAAO,MAAM,IACxB,OAAO;AACb,UACE,UACA,OAAO,OAAO,MAAM,YACpB,OAAO,OAAO,MAAM,UACpB;AACA,+BAAuB,EAAE,GAAG,OAAO,GAAG,GAAG,OAAO,EAAE;AAAA,MACpD;AAAA,IACF;AAAA,EACF,QAAQ;AACN,2BAAuB;AAAA,EACzB;AAGA,QAAM,YAAY,uBACd,KAAK;AAAA,IACH,KAAK,IAAI,qBAAqB,IAAI,wBAAwB,GAAG,CAAC,IAC5D,KAAK,IAAI,qBAAqB,IAAI,wBAAwB,GAAG,CAAC;AAAA,EAClE,KAAK,wBACL;AAEJ,QAAM,4BAA4B,MAAM;AACtC,QAAI,CAAC,qBAAsB,QAAO;AAClC,WAAO,YACH,mCACA;AAAA,EACN;AAGA,QAAM,yBAAyB,CAAC,GAAW,MAAsB;AAC/D,UAAM,WAAW,KAAK,MAAM,IAAI,GAAG;AACnC,UAAM,WAAW,KAAK,MAAM,IAAI,GAAG;AACnC,WAAO,GAAG,QAAQ,kBAAkB,QAAQ;AAAA,EAC9C;AAEA,QAAM,yBAAyB,MAAc;AAC3C,QAAI,CAAC,sBAAsB;AACzB,aAAO,iCAA8B;AAAA,QACnC,wBAAwB;AAAA,QACxB,wBAAwB;AAAA,MAC1B,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,qBAAqB,IAAI,wBAAwB;AAChE,UAAM,SAAS,qBAAqB,IAAI,wBAAwB;AAChE,UAAM,WAAW,KAAK,KAAK,KAAK,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,CAAC;AACpE,UAAM,kBAAkB,KAAK,MAAM,WAAW,GAAG;AAEjD,QAAI,YAAY;AAChB,QAAI,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,GAAG;AACvC,kBAAY,SAAS,IAAI,iBAAc;AAAA,IACzC,OAAO;AACL,kBAAY,SAAS,IAAI,WAAW;AAAA,IACtC;AAEA,UAAM,aAAa;AAAA,MACjB,wBAAwB;AAAA,MACxB,wBAAwB;AAAA,IAC1B;AACA,UAAM,UAAU;AAAA,MACd,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,IACvB;AAEA,WAAO,iCAA8B,UAAU,0BAA0B,OAAO,iCAA8B,eAAe,qBAAkB,SAAS,wBAAqB,YAAY,sFAA0E,mFAAuE;AAAA,EAC5U;AAEA,QAAM,6BAA6B;AAAA,IACjC,wBAAwB;AAAA,IACxB,wBAAwB;AAAA,EAC1B;AACA,QAAM,eAAe,0DAAoD,0BAA0B;AAEnG,SACE,gBAAAA,OAAC,SAAI,WAAU,kBAEb;AAAA,oBAAAA,OAAC,SAAI,WAAU,mCACb;AAAA,sBAAAA,OAAC,SAAI,WAAU,2BACb;AAAA,wBAAAD,MAAC,SAAI,WAAU,wEAAuE;AAAA,QACtF,gBAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,6BAEtD;AAAA,SACF;AAAA,MACC,wBACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,wBAAAE,OAAC,SAAI,WAAU,2BACb;AAAA,0BAAAD,MAAC,SAAI,WAAU,8DAA6D;AAAA,UAC5E,gBAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,8BAEtD;AAAA,WACF;AAAA,QACA,gBAAAC,OAAC,SAAI,WAAU,2BACb;AAAA,0BAAAD,MAAC,SAAI,WAAU,kEAAiE;AAAA,UAChF,gBAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,gCAEtD;AAAA,WACF;AAAA,SACF;AAAA,OAEJ;AAAA,IAGA,gBAAAC,OAAC,SAAI,WAAU,mBAEb;AAAA,sBAAAD,MAAC,SAAI,WAAU,WAAW,iCAAuB,GAAE;AAAA,MAEnD,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK;AAAA,UACL,WAAU;AAAA;AAAA,MACZ;AAAA,MAGA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,cAAY,8BAA2B,0BAA0B;AAAA,UACjE,WAAU;AAAA,UACV,OAAO;AAAA,YACL,UAAU;AAAA,YACV,UAAU;AAAA,YACV,OAAO;AAAA,YACP,aAAa;AAAA,YACb,MAAM,QAAQ,wBAAwB,IAAI,GAAG;AAAA,YAC7C,KAAK,QAAQ,wBAAwB,IAAI,GAAG;AAAA,UAC9C;AAAA,UAEA,0BAAAC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAO;AAAA,cACP,OAAM;AAAA,cACN,WAAU;AAAA,cACX;AAAA;AAAA,gBACsE;AAAA,gBACpE;AAAA;AAAA;AAAA,UACH;AAAA;AAAA,MACF;AAAA,MAGC,wBACC,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,cAAY,gCAAgC;AAAA,YAC1C,qBAAqB;AAAA,YACrB,qBAAqB;AAAA,UACvB,CAAC,KAAK,YAAY,YAAY,WAAW;AAAA,UACzC,WAAW,sDAAsD,0BAA0B,CAAC;AAAA,UAC5F,OAAO;AAAA,YACL,UAAU;AAAA,YACV,UAAU;AAAA,YACV,OAAO;AAAA,YACP,aAAa;AAAA,YACb,MAAM,QAAQ,qBAAqB,IAAI,GAAG;AAAA,YAC1C,KAAK,QAAQ,qBAAqB,IAAI,GAAG;AAAA,UAC3C;AAAA,UAEA,0BAAAC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,QAAO;AAAA,cACP,OAAM;AAAA,cACN,WAAU;AAAA,cACX;AAAA;AAAA,gBACU,YAAY,UAAU;AAAA,gBAAW;AAAA,gBACpB;AAAA,gBACrB;AAAA,kBACC,qBAAqB;AAAA,kBACrB,qBAAqB;AAAA,gBACvB;AAAA,gBAAE;AAAA,gBACgB;AAAA,gBACjB,KAAK;AAAA,kBACJ,KAAK;AAAA,oBACH,KAAK;AAAA,sBACH,qBAAqB,IAAI,wBAAwB;AAAA,sBACjD;AAAA,oBACF,IACE,KAAK;AAAA,sBACH,qBAAqB,IAAI,wBAAwB;AAAA,sBACjD;AAAA,oBACF;AAAA,kBACJ,IAAI;AAAA,gBACN;AAAA,gBAAE;AAAA,gBAC6C;AAAA,gBAC9C,YAAY,YAAY;AAAA,gBAAY;AAAA;AAAA;AAAA,UACvC;AAAA;AAAA,MACF;AAAA,OAEJ;AAAA,KACF;AAEJ;;;ACvMI,qBAAAC,WACE,OAAAC,OADF,QAAAC,cAAA;AANG,IAAM,4BAA4B,CAAC;AAAA,EACxC;AACF,IAEI,CAAC,MAAiB;AACpB,SACE,gBAAAA,OAAAF,WAAA,EACE;AAAA,oBAAAC,MAAC,oBAAiB,UAAS,oCAAgC;AAAA,IAC3D,gBAAAA,MAAC,qBAAkB,WAAW,GAAG,IAAI,aAAa,GAChD,0BAAAA,MAAC,SAAI,WAAU,aACb,0BAAAA,MAAC,gBAAK,MAAK,MAAK,QAAO,UAAS,OAAM,iBAAgB,oEAEtD,GACF,GACF;AAAA,KACF;AAEJ;;;ACUA,IAAM,sBAAsB;AAAA,EAC1B,gCAA0B,GAAG;AAAA,EAC7B,0CAA+B,GAAG;AAAA,EAClC,0CAA+B,GAAG;AAAA,EAClC,kCAA2B,GAAG;AAAA,EAC9B,4BAAwB,GAAG;AAAA,EAC3B,sBAAqB,GAAG;AAAA,EACxB,kCAA2B,GAAG;AAChC;;;AvBgFI,SAwTM,YAAAE,WA5SF,OAAAC,OAZJ,QAAAC,cAAA;AA3CJ,IAAM,gBASF;AAAA,EACF,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,eAAe;AAAA,EACjB;AAAA,EACA,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,eAAe;AAAA,EACjB;AAAA,EACA,WAAW;AAAA,IACT,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,eAAeC;AAAA,EACjB;AACF;AAOA,IAAM,WAAW,CAAC,EAAE,OAAO,OAAO,QAAQ,MAAqB;AAC7D,QAAM,SAAS,cAAc,OAAO;AACpC,QAAM,gBAAgB,OAAO;AAE7B,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,OAAO;AAAA,MACT;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,OAAO;AAAA,YACT;AAAA,YAEA,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM;AAAA,gBACN,WAAW,OAAO;AAAA,gBAClB,QAAO;AAAA;AAAA,YACT;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,GAAG,4CAA4C,OAAO,IAAI;AAAA,YAEpE;AAAA;AAAA,QACH;AAAA,QACA,gBAAAA,MAAC,gBAAK,WAAW,GAAG,qBAAqB,OAAO,IAAI,GAAI,iBAAM;AAAA;AAAA;AAAA,EAChE;AAEJ;AAsBA,IAAM,uBAAuB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AACF,MAAiC;AAC/B,QAAM,CAAC,aAAa,cAAc,IAAIG,WAAS,EAAE;AACjD,QAAM,CAAC,uBAAuB,wBAAwB,IAAIA,WAAS,KAAK;AACxE,QAAM,CAAC,oBAAoB,qBAAqB,IAAIA,WAAS,KAAK;AAClE,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,WAAS,EAAE;AAC3D,QAAM,CAAC,eAAe,gBAAgB,IAAIA,WAAyB,CAAC,CAAC;AACrE,QAAM,CAAC,YAAY,aAAa,IAAIA,WAAyB,CAAC,CAAC;AAC/D,QAAM,CAAC,oBAAoB,qBAAqB,IAAIA;AAAA,IAClD;AAAA,EACF;AACA,QAAM,eAAeC,QAAyB,IAAI;AAGlD,QAAM,CAAC,kBAAkB,mBAAmB,IAAID,WAS9C,CAAC,CAAC;AAMJ,EAAAE,YAAU,MAAM;AACd,QAAI,QAAQ;AACV,qBAAe,EAAE;AACjB,+BAAyB,KAAK;AAC9B,uBAAiB,CAAC,CAAC;AACnB,oBAAc,CAAC,CAAC;AAChB,4BAAsB,MAAM,cAAc,IAAI;AAG9C,UAAI,MAAM,eAAe,MAAM,YAAY;AACzC,8BAAsB,IAAI;AAC1B,4BAAoB,KAAK,eAAe,EAAE;AAAA,MAC5C,OAAO;AACL,8BAAsB,KAAK;AAC3B,4BAAoB,EAAE;AAAA,MACxB;AAGA,YAAM,qBAOF,CAAC;AACL,YAAM,WAAW,QAAQ,CAAC,iBAAiB;AACzC,YAAI,aAAa,SAAS,oDAA6C;AACrE,6BAAmB,aAAa,cAAc,IAAI;AAAA,YAChD,WAAW,aAAa,YAAY,aAAa;AAAA,YACjD,iBAAiB,aAAa,YAAY,mBAAmB;AAAA,YAC7D,UAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF,CAAC;AACD,0BAAoB,kBAAkB;AAAA,IACxC;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR,CAAC;AAKD,QAAM,wBAAwB,MAAM;AAClC,6BAAyB,IAAI;AAAA,EAC/B;AAMA,QAAM,iBAAiB,CAAC,UAAkB;AACxC,UAAM,UAAU,MAAM,CAAC;AACvB,QAAI,SAAS;AACX,uBAAiB,CAAC,EAAE,MAAM,SAAS,IAAI,eAAe,EAAE,CAAC,CAAC;AAAA,IAC5D;AAAA,EACF;AAMA,QAAM,mBAAmB,CAAC,OAAe;AACvC,qBAAiB,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EAC5D;AAKA,QAAM,wBAAwB,MAAM;AAClC,QAAI,YAAY,KAAK,KAAK,cAAc,SAAS,KAAK,oBAAoB;AAExE,UAAI,CAAC,MAAM,WAAW;AACpB;AAAA,MACF;AAEA,0BAAoB,WAAW;AAC/B,oBAAc,CAAC,GAAG,aAAa,CAAC;AAChC,4BAAsB,IAAI;AAC1B,+BAAyB,KAAK;AAG9B;AAAA,QACE,KAAK;AAAA,QACL;AAAA,QACA,cAAc,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAKA,QAAM,wBAAwB,MAAM;AAClC,mBAAe,gBAAgB;AAC/B,qBAAiB,CAAC,GAAG,UAAU,CAAC;AAChC,0BAAsB,KAAK;AAC3B,6BAAyB,IAAI;AAAA,EAC/B;AAKA,QAAM,4BAA4BC;AAAA,IAChC,OAAO,mBAA2B;AAChC,UAAI,CAAC,MAAM,aAAa,CAAC,2BAA4B;AAErD,YAAM,aAAa,iBAAiB,cAAc;AAClD,UAAI,YAAY,aAAa,MAAM;AACjC;AAAA,MACF;AAEA,0BAAoB,CAAC,UAAU;AAAA,QAC7B,GAAG;AAAA,QACH,CAAC,cAAc,GAAG,EAAE,GAAG,KAAK,cAAc,GAAG,UAAU,KAAK;AAAA,MAC9D,EAAE;AAEF,UAAI;AAEF,cAAM,eAAe,MAAM,UAAU;AAAA,UACnC,CAAC,MAAM,EAAE,mBAAmB;AAAA,QAC9B;AACA,YAAI,CAAC,cAAc;AACjB,kBAAQ,MAAM,iCAA2B,cAAc;AACvD;AAAA,QACF;AAEA,cAAM,2BAA2B,KAAK,WAAW;AAAA,UAC/C,YAAY,aAAa,SAAS;AAAA,UAClC,WAAW,WAAW;AAAA,UACtB,iBAAiB,WAAW;AAAA,QAC9B,CAAC;AAAA,MACH,SAAS,OAAO;AACd,gBAAQ,MAAM,gDAAuC,KAAK;AAAA,MAC5D,UAAE;AACA,4BAAoB,CAAC,UAAU;AAAA,UAC7B,GAAG;AAAA,UACH,CAAC,cAAc,GAAG,EAAE,GAAG,KAAK,cAAc,GAAG,UAAU,MAAM;AAAA,QAC/D,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAKA,QAAM,wBAAwBA;AAAA,IAC5B,CACE,gBACA,OACA,UACG;AACH,0BAAoB,CAAC,UAAU;AAAA,QAC7B,GAAG;AAAA,QACH,CAAC,cAAc,GAAG;AAAA,UAChB,GAAG,KAAK,cAAc;AAAA,UACtB,CAAC,KAAK,GAAG;AAAA,QACX;AAAA,MACF,EAAE;AAAA,IACJ;AAAA,IACA,CAAC;AAAA,EACH;AAKA,QAAM,oBAAoB,CAAC,iBAAwC;AACjE,YAAQ,cAAc;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AACE,eAAO;AAAA,MACT;AACE,eAAO;AAAA,MACT;AACE,eAAO;AAAA,MACT;AACE,eAAO;AAAA,MACT;AACE,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAKA,QAAM,wBAAwB,CAC5B,iBACG;AACH,UAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,UAAM,eAAe,SAAS;AAC9B,UAAM,iBAAiB,kBAAkB,YAAY;AAErD,QAAI;AAEJ,YAAQ,cAAc;AAAA,MACpB;AACE,kBAAU,0BAA0B;AAAA,UAClC;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACE,kBAAU,6BAA6B;AAAA,UACrC;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACE,kBAAU,0BAA0B;AAAA,UAClC;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACE,kBACE,gBAAAL,OAAAF,WAAA,EACG;AAAA,qCAA2B;AAAA,YAC1B;AAAA,UACF,CAAC;AAAA,UACA,8BACC,gBAAAC,MAAC,SAAI,WAAU,kDACZ,sCAA4B,YAAY,GAC3C;AAAA,WAEJ;AAEF;AAAA,MACF;AACE,kBAAU,mBAAmB;AAAA,UAC3B;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACE,kBAAU,oBAAoB;AAAA,UAC5B;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACE,kBAAU,0BAA0B,EAAE,eAAe,GAAG,CAAC;AACzD;AAAA,MACF;AAEE,YAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAAG;AACnD,oBAAU,0BAA0B;AAAA,YAClC;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH,OAAO;AACL,oBAAU,2BAA2B;AAAA,YACnC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,IACJ;AAEA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,aAAa,aAAa,cAAc;AAAA,QAC/C,WAAU;AAAA,QACV,SACE,gBAAAA,MAAC,SAAI,WAAU,oBACb,0BAAAA,MAAC,gBAAK,WAAU,mCACb,0BACH,GACF;AAAA,QAGD;AAAA;AAAA,IACH;AAAA,EAEJ;AAKA,QAAM,8BAA8B,CAClC,iBACG;AACH,UAAM,aAAa,iBAAiB,aAAa,cAAc,KAAK;AAAA,MAClE,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,UAAU;AAAA,IACZ;AAEA,QAAI;AACJ,QAAI,WAAW,cAAc,MAAM;AACjC,mBAAa;AAAA,IACf,WAAW,WAAW,WAAW;AAC/B,mBAAa;AAAA,IACf,OAAO;AACL,mBAAa;AAAA,IACf;AAEA,WACE,gBAAAC,OAAAF,WAAA,EAEE;AAAA,sBAAAE,OAAC,SAAI,WAAU,aACb;AAAA,wBAAAD,MAAC,gBAAK,WAAU,uCAAsC,uCAEtD;AAAA,QACA,gBAAAC,OAAC,SAAI,WAAU,cACb;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,aAAa,aAAa,cAAc;AAAA,cAC9C,OAAM;AAAA,cACN,IAAI,eAAe,aAAa,cAAc;AAAA,cAC9C,OAAM;AAAA,cACN,MAAK;AAAA,cACL,SAAS,eAAe;AAAA,cACxB,UAAU,CAAC,MAAM;AACf,oBAAI,EAAE,OAAO,SAAS;AACpB;AAAA,oBACE,aAAa;AAAA,oBACb;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA;AAAA,UACF;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,aAAa,aAAa,cAAc;AAAA,cAC9C,OAAM;AAAA,cACN,IAAI,cAAc,aAAa,cAAc;AAAA,cAC7C,OAAM;AAAA,cACN,MAAK;AAAA,cACL,SAAS,eAAe;AAAA,cACxB,UAAU,CAAC,MAAM;AACf,oBAAI,EAAE,OAAO,SAAS;AACpB;AAAA,oBACE,aAAa;AAAA,oBACb;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA;AAAA,UACF;AAAA,WACF;AAAA,SACF;AAAA,MAGA,gBAAAC,OAAC,SAAI,WAAU,aACb;AAAA,wBAAAD,MAAC,gBAAK,WAAU,uCAAsC,sCAEtD;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW;AAAA,YAClB,UAAU,CAAC,MAAM;AACf;AAAA,gBACE,aAAa;AAAA,gBACb;AAAA,gBACA,EAAE,OAAO;AAAA,cACX;AAAA,YACF;AAAA,YACA,aAAY;AAAA,YACZ,MAAM;AAAA,YACN,MAAK;AAAA;AAAA,QACP;AAAA,SACF;AAAA,MAGA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,0BAA0B,aAAa,cAAc;AAAA,UACpE,UACE,WAAW,cAAc,QACzB,WAAW,YACX,CAAC;AAAA,UAGF,qBAAW,WAAW,gBAAgB;AAAA;AAAA,MACzC;AAAA,OACF;AAAA,EAEJ;AAEA,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,QAAQ,aAAa,0BAA0B;AACrD,QAAM,iBAAiB,KAAK,SAAS,OAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;AAOtE,QAAM,2BAA2B,MAAM;AAMrC,UAAM,qBAAqB,CAAC,QAAwB;AAClD,UAAI;AACF,cAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,cAAM,UAAU,OAAO;AACvB,eAAO,QAAQ,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,MACrC,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAMA,UAAM,wBAAwB,MAAM;AAClC,UAAI,cAAc,SAAS,GAAG;AAC5B,eACE,gBAAAC,OAAC,SAAI,WAAU,wGACb;AAAA,0BAAAD,MAACO,YAAA,EAAU,MAAM,IAAI,WAAU,+BAA8B;AAAA,UAC7D,gBAAAP,MAAC,UAAK,WAAU,gDACb,wBAAc,CAAC,EAAE,KAAK,MACzB;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,iBAAiB,cAAc,CAAC,EAAE,EAAE;AAAA,cACnD,WAAU;AAAA,cACV,cAAY,WAAW,cAAc,CAAC,EAAE,KAAK,IAAI;AAAA,cAEjD,0BAAAA,MAACQ,IAAA,EAAE,MAAM,IAAI;AAAA;AAAA,UACf;AAAA,WACF;AAAA,MAEJ;AAEA,UAAI,oBAAoB;AACtB,eACE,gBAAAP,OAAC,SAAI,WAAU,2BACb;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAM;AAAA,cACN,QAAO;AAAA,cACP,KAAI;AAAA,cACJ,WAAU;AAAA,cAEV;AAAA,gCAAAD,MAACO,YAAA,EAAU,MAAM,IAAI,WAAU,+BAA8B;AAAA,gBAC7D,gBAAAP,MAAC,UAAK,WAAU,gDACb,6BAAmB,kBAAkB,GACxC;AAAA;AAAA;AAAA,UACF;AAAA,UACA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM,aAAa,SAAS,MAAM;AAAA,cAC3C,WAAU;AAAA,cAEV;AAAA,gCAAAD,MAACO,YAAA,EAAU,MAAM,IAAI;AAAA,gBAAE;AAAA;AAAA;AAAA,UAEzB;AAAA,WACF;AAAA,MAEJ;AAEA,aACE,gBAAAN;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM,aAAa,SAAS,MAAM;AAAA,UAC3C,WAAU;AAAA,UAEV;AAAA,4BAAAD,MAACO,YAAA,EAAU,MAAM,IAAI;AAAA,YAAE;AAAA;AAAA;AAAA,MAEzB;AAAA,IAEJ;AAGA,QAAI,oBAAoB;AACtB,aACE,gBAAAN,OAAC,SAAI,WAAU,mEACb;AAAA,wBAAAA,OAAC,SAAI,WAAU,sEACb;AAAA,0BAAAD,MAAC,gBAAK,WAAU,mCAAkC,8BAAU;AAAA,UAC5D,gBAAAC,OAAC,SAAI,WAAU,2BAEZ;AAAA,uBAAW,SAAS,KACnB,gBAAAA,OAAC,SAAI,WAAU,yFACb;AAAA,8BAAAD;AAAA,gBAACO;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN,WAAU;AAAA;AAAA,cACZ;AAAA,cACA,gBAAAP,MAAC,UAAK,WAAU,gDACb,qBAAW,CAAC,EAAE,KAAK,MACtB;AAAA,eACF;AAAA,YAGD,WAAW,WAAW,KAAK,sBAC1B,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM;AAAA,gBACN,QAAO;AAAA,gBACP,KAAI;AAAA,gBACJ,WAAU;AAAA,gBAEV;AAAA,kCAAAD;AAAA,oBAACO;AAAA,oBAAA;AAAA,sBACC,MAAM;AAAA,sBACN,WAAU;AAAA;AAAA,kBACZ;AAAA,kBACA,gBAAAP,MAAC,UAAK,WAAU,gDACb,6BAAmB,kBAAkB,GACxC;AAAA;AAAA;AAAA,YACF;AAAA,YAEF,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,WAAU;AAAA,gBAEV;AAAA,kCAAAD,MAAC,gBAAa,MAAM,IAAI;AAAA,kBAAE;AAAA;AAAA;AAAA,YAE5B;AAAA,aACF;AAAA,WACF;AAAA,QACC,oBACC,gBAAAA,MAAC,SAAI,WAAU,mCACb,0BAAAA,MAAC,gBAAK,WAAU,yBAAyB,4BAAiB,GAC5D;AAAA,SAEJ;AAAA,IAEJ;AAGA,QAAI,uBAAuB;AACzB,aACE,gBAAAC,OAAC,SAAI,WAAU,mEACb;AAAA,wBAAAD,MAAC,gBAAK,WAAU,mCAAkC,8BAAU;AAAA,QAC5D,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,YAC9C,aAAY;AAAA,YACZ,WAAU;AAAA;AAAA,QACZ;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU,CAAC,MAAM;AACf,oBAAM,gBAAgB,EAAE,OAAO;AAC/B,kBAAI,iBAAiB,cAAc,SAAS,GAAG;AAC7C,+BAAe,MAAM,KAAK,aAAa,CAAC;AAAA,cAC1C;AACA,kBAAI,aAAa,SAAS;AACxB,6BAAa,QAAQ,QAAQ;AAAA,cAC/B;AAAA,YACF;AAAA,YACA,cAAW;AAAA;AAAA,QACb;AAAA,QAEA,gBAAAC,OAAC,SAAI,WAAU,8DACZ;AAAA,gCAAsB;AAAA,UACvB,gBAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAK;AAAA,cACL,SAAS;AAAA,cACT,UACE,CAAC,YAAY,KAAK,KAClB,cAAc,WAAW,KACzB,CAAC;AAAA,cAEJ;AAAA;AAAA,UAED;AAAA,WACF;AAAA,QACC,KAAK,eACJ,gBAAAC,OAAC,SAAI,WAAU,mCACb;AAAA,0BAAAD,MAAC,gBAAK,WAAU,yBAAwB,wCAExC;AAAA,UACA,gBAAAA,MAAC,gBAAK,WAAU,yBAAyB,eAAK,aAAY;AAAA,WAC5D;AAAA,SAEJ;AAAA,IAEJ;AAGA,WACE,gBAAAC,OAAC,SAAI,WAAU,4HACb;AAAA,sBAAAD,MAAC,gBAAK,WAAU,mCAAkC,8BAAU;AAAA,MAC5D,gBAAAA,MAAC,kBAAO,MAAK,UAAS,MAAK,SAAQ,SAAS,uBAAuB,qBAEnE;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL,kBAAiB;AAAA,MAEjB,0BAAAC,OAAC,SAAI,WAAU,aAEb;AAAA,wBAAAA,OAAC,SAAI,WAAU,2BACb;AAAA,0BAAAD,MAAC,SAAI,WAAU,0EACb,0BAAAA,MAAC,gBAAK,WAAU,0CACb,eAAK,aAAa,OAAO,CAAC,EAAE,YAAY,KAAK,KAChD,GACF;AAAA,UACA,gBAAAA,MAAC,gBAAK,WAAU,qCACb,eAAK,eAAe,SACvB;AAAA,WACF;AAAA,QAGA,gBAAAC,OAAC,SAAI,WAAU,0BACb;AAAA,0BAAAD,MAAC,YAAS,OAAM,QAAO,OAAO,gBAAgB,SAAQ,SAAQ;AAAA,UAC9D,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OAAO,KAAK;AAAA,cACZ,SAAQ;AAAA;AAAA,UACV;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OAAO,KAAK;AAAA,cACZ,SAAQ;AAAA;AAAA,UACV;AAAA,WACF;AAAA,QAGC,yBAAyB;AAAA,QAG1B,gBAAAC,OAAC,SAAI,WAAU,aACb;AAAA,0BAAAD,MAAC,gBAAK,WAAU,mCAAkC,uBAAS;AAAA,UAC3D,gBAAAA,MAAC,kBAAe,MAAK,YAAW,WAAU,aACvC,eAAK,WAAW,IAAI,CAAC,iBAAiB;AACrC,kBAAM,SAAS,0BAA0B,YAAY;AACrD,kBAAM,cAAc,6BAA6B,MAAM;AAEvD,mBACE,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,OAAO,YAAY,aAAa,cAAc;AAAA,gBAC9C,WAAU;AAAA,gBACV,SACE,gBAAAC,OAAC,SAAI,WAAU,sDACb;AAAA,kCAAAA,OAAC,gBAAK,WAAU,qCAAoC;AAAA;AAAA,oBACzC,aAAa;AAAA,qBACxB;AAAA,kBACA,gBAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,WAAW;AAAA,wBACT;AAAA,wBACA,YAAY;AAAA,wBACZ,YAAY;AAAA,sBACd;AAAA,sBAEC,sBAAY;AAAA;AAAA,kBACf;AAAA,mBACF;AAAA,gBAGF,0BAAAC,OAAC,SAAI,WAAU,kBAEZ;AAAA,+BAAa,SAAS,aACrB,gBAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,QAAO;AAAA,sBACP,OAAM;AAAA,sBACN,WAAU;AAAA,sBAET,uBAAa,SAAS;AAAA;AAAA,kBACzB;AAAA,kBAID,sBAAsB,YAAY;AAAA,mBACrC;AAAA;AAAA,cAnCK,aAAa;AAAA,YAoCpB;AAAA,UAEJ,CAAC,GACH;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,+BAAQ;;;AwBx4Bf,SAAS,YAAAS,YAAU,aAAAC,mBAAiB;AAGpC,IAAM,eAAe;AAErB,IAAM,eAAe;AAErB,IAAM,qBAAqB;AAC3B,IAAM,2BAA2B;AACjC,IAAM,2BAA2B;AACjC,IAAM,oBAAoB;AAE1B,IAAM,gBAAgB;AAWtB,IAAM,iBAAiB,MAAc;AACnC,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AACA,SAAO,OAAO;AAChB;AAMO,IAAM,gBAAgB,MAAkB;AAC7C,QAAM,QAAQ,eAAe;AAC7B,SAAO,QAAQ,eAAe,eAAe;AAC/C;AAMO,IAAM,YAAY,MAAM;AAC7B,QAAM,CAAC,UAAU,WAAW,IAAID,WAAS,KAAK;AAC9C,QAAM,CAAC,UAAU,WAAW,IAAIA,WAAS,KAAK;AAC9C,QAAM,CAAC,eAAe,gBAAgB,IAAIA,WAAS,KAAK;AACxD,QAAM,CAAC,oBAAoB,qBAAqB,IAAIA,WAAS,KAAK;AAClE,QAAM,CAAC,oBAAoB,qBAAqB,IAAIA,WAAS,KAAK;AAClE,QAAM,CAAC,cAAc,eAAe,IAAIA,WAAS,KAAK;AAEtD,EAAAC,YAAU,MAAM;AACd,UAAM,kBAAkB,MAAM;AAC5B,YAAM,QAAQ,eAAe;AAC7B,kBAAY,QAAQ,YAAY;AAChC,kBAAY,QAAQ,YAAY;AAChC,uBAAiB,QAAQ,kBAAkB;AAC3C,4BAAsB,QAAQ,wBAAwB;AACtD,4BAAsB,QAAQ,wBAAwB;AACtD,sBAAgB,QAAQ,iBAAiB;AAAA,IAC3C;AAEA,oBAAgB;AAEhB,WAAO,iBAAiB,UAAU,eAAe;AAEjD,WAAO,MAAM,OAAO,oBAAoB,UAAU,eAAe;AAAA,EACnE,GAAG,CAAC,CAAC;AAML,QAAM,0BAA0B,MAAc;AAC5C,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AACA,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAMA,QAAM,yBAAyB,MAAc;AAC3C,WAAO;AAAA,EACT;AAMA,QAAM,0BAA0B,MAAc;AAC5C,WAAO;AAAA,EACT;AAMA,QAAM,mBAAmB,MAAc;AACrC,WAAO,WAAW,uBAAuB,IAAI,wBAAwB;AAAA,EACvE;AAMA,QAAM,2BAA2B,MAAc;AAC7C,QAAI,aAAc,QAAO;AACzB,QAAI,mBAAoB,QAAO;AAC/B,QAAI,cAAe,QAAO;AAC1B,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACtHI,gBAAAC,aAAA;AAdG,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAIE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,MAAM;AAAA;AAAA,IACR;AAAA;AACF;;;ACJE,gBAAAC,aAAA;AAdG,IAAM,cAAc,CAAC;AAAA,EAC1B;AAAA,EACA;AACF,MAIE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,MAAM;AAAA;AAAA,IACR;AAAA;AACF;;;ACJE,gBAAAC,aAAA;AAdG,IAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AACF,MAIE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,MAAM;AAAA;AAAA,IACR;AAAA;AACF;;;ACXF;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeG,gBAAAC,aAAA;AAFH,IAAM,cAAgD;AAAA,EAC3D,yBAAmB,GAAG;AAAA,IACpB,MAAM,gBAAAA,MAAC,QAAK,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC3C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,6BAAqB,GAAG;AAAA,IACtB,MAAM,gBAAAA,MAAC,UAAO,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC7C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,8BAAuB,GAAG;AAAA,IACxB,MAAM,gBAAAA,MAAC,gBAAa,MAAM,IAAI,OAAM,gBAAe;AAAA,IACnD,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,4BAAsB,GAAG;AAAA,IACvB,MAAM,gBAAAA,MAAC,uBAAoB,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC1D,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,0BAAqB,GAAG;AAAA,IACtB,MAAM,gBAAAA,MAAC,cAAW,MAAM,IAAI,OAAM,gBAAe;AAAA,IACjD,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,+BAAsB,GAAG;AAAA,IACvB,MAAM,gBAAAA,MAAC,UAAO,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC7C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,2BAAoB,GAAG;AAAA,IACrB,MAAM,gBAAAA,MAAC,SAAM,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC5C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,oBAAkB,GAAG;AAAA,IACnB,MAAM,gBAAAA,MAAC,WAAQ,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC9C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,iCAAuB,GAAG;AAAA,IACxB,MAAM,gBAAAA,MAAC,kBAAe,MAAM,IAAI,OAAM,gBAAe;AAAA,IACrD,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,4BAAsB,GAAG;AAAA,IACvB,MAAM,gBAAAA,MAAC,eAAY,MAAM,IAAI,OAAM,gBAAe;AAAA,IAClD,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,0BAAqB,GAAG;AAAA,IACtB,MAAM,gBAAAA,MAAC,UAAO,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC7C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,8BAAoB,GAAG;AAAA,IACrB,MAAM,gBAAAA,MAAC,kBAAe,MAAM,IAAI,OAAM,gBAAe;AAAA,IACrD,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,8BAAuB,GAAG;AAAA,IACxB,MAAM,gBAAAA,MAAC,UAAO,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC7C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,yBAAmB,GAAG;AAAA,IACpB,MAAM,gBAAAA,MAAC,UAAO,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC7C,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,sCAA4B,GAAG;AAAA,IAC7B,MAAM,gBAAAA,MAAC,gBAAa,MAAM,IAAI,OAAM,gBAAe;AAAA,IACnD,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,wBAAoB,GAAG;AAAA,IACrB,MAAM,gBAAAA,MAAC,gBAAa,MAAM,IAAI,OAAM,gBAAe;AAAA,IACnD,YAAY;AAAA,IACZ;AAAA,EACF;AACF;AAEO,IAAM,iBAAiB,CAAC,YAAsC;AACnE,SACE,YAAY,OAAO,KAAK;AAAA,IACtB,MAAM,gBAAAA,MAAC,QAAK,MAAM,IAAI,OAAM,gBAAe;AAAA,IAC3C,YAAY;AAAA,IACZ,MAAM;AAAA,EACR;AAEJ;;;AC3HA,SAAS,YAAAC,YAAU,eAAAC,oBAAmB;AAqDtC,IAAM,uBAAuB,CAC3B,cAC2B;AAC3B,QAAM,CAAC,OAAO,QAAQ,IAAID,WAAgC;AAAA,IACxD,WAAW,CAAC;AAAA,IACZ,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,aAAa;AAAA,IACb,OAAO;AAAA,IACP,gBAAgB;AAAA,EAClB,CAAC;AAED,QAAM,cAAcC,aAAY,CAAC,YAA4C;AAC3E,aAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,QAAQ,EAAE;AAAA,EAC9C,GAAG,CAAC,CAAC;AAEL,QAAM,cAAcA;AAAA,IAClB,CAAC,UAAmB;AAClB,cAAQ,MAAM,iCAA8B,KAAK;AACjD,UAAI,eAAe;AAEnB,UAAI,SAAS,OAAO,UAAU,YAAY,cAAc,OAAO;AAC7D,cAAM,aAAa;AAInB,uBACE,YAAY,UAAU,MAAM,WAC5B,YAAY,WACZ;AAAA,MACJ,WAAW,iBAAiB,OAAO;AACjC,uBAAe,MAAM;AAAA,MACvB;AAEA,kBAAY;AAAA,QACV,SAAS;AAAA,QACT,aAAa;AAAA,QACb,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAKA,QAAM,oBAAoB,CACxB,eACsB;AACtB,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO;AAAA,MACL,MAAM,WAAW;AAAA,MACjB,UAAU,WAAW;AAAA,MACrB,OAAO,WAAW;AAAA,MAClB,YAAY,WAAW;AAAA,MACvB,SAAS,WAAW;AAAA,MACpB,aAAa,WAAW;AAAA,IAC1B;AAAA,EACF;AAOA,QAAM,iBAAiBA;AAAA,IACrB,OAAO,SAAwC,SAAkB,UAAU;AACzE,UAAI,QAAQ;AACV,iBAAS,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,MAAM,OAAO,KAAK,EAAE;AAAA,MAClE,OAAO;AACL,oBAAY,EAAE,SAAS,MAAM,OAAO,MAAM,WAAW,CAAC,EAAE,CAAC;AAAA,MAC3D;AAEA,UAAI;AACF,cAAM,mBAAwC;AAAA,UAC5C,GAAG;AAAA,QACL;AAEA,cAAM,WAAW,MAAM,UAAU;AAAA,UAC/B;AAAA,UACA;AAAA,QACF;AAEA,iBAAS,CAAC,UAAU;AAAA,UAClB,SAAS;AAAA,UACT,aAAa;AAAA,UACb,WAAW,SACP,CAAC,GAAG,KAAK,WAAW,GAAG,SAAS,KAAK,KAAK,SAAS,IACnD,SAAS,KAAK,KAAK;AAAA,UACvB,YAAY,kBAAkB,SAAS,KAAK,KAAK,UAAU;AAAA,UAC3D,OAAO;AAAA,UACP,gBAAgB;AAAA,QAClB,EAAE;AAAA,MACJ,SAAS,OAAO;AACd,iBAAS,CAAC,UAAU;AAAA,UAClB,GAAG;AAAA,UACH,SAAS;AAAA,UACT,aAAa;AAAA,QACf,EAAE;AACF,oBAAY,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,WAAW,aAAa,WAAW;AAAA,EACtC;AAQA,QAAM,uBAAuBA;AAAA,IAC3B,OACE,OACA,YACwB;AACxB,UAAI;AACF,cAAM,mBAAwC;AAAA,UAC5C,GAAG;AAAA,UACH,iBAAiB;AAAA,QACnB;AAEA,cAAM,WAAW,MAAM,UAAU;AAAA,UAC/B;AAAA,UACA;AAAA,QACF;AAEA,eAAO,SAAS,KAAK,KAAK;AAAA,MAC5B,SAAS,OAAO;AACd,oBAAY,KAAK;AACjB,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC,WAAW,WAAW;AAAA,EACzB;AAOA,QAAM,sBAAsBA;AAAA,IAC1B,OAAO,gBAA+C;AACpD,UAAI;AACF,cAAM,OAAqD;AAAA,UACzD,cAAc;AAAA,QAChB;AAEA,cAAM,WAAW,MAAM,UAAU;AAAA,UAC/B;AAAA,UACA;AAAA,QACF;AAEA,eAAO,SAAS,KAAK,KAAK;AAAA,MAC5B,SAAS,OAAO;AACd,oBAAY,KAAK;AACjB,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC,WAAW,WAAW;AAAA,EACzB;AAEA,QAAM,WAAWA,aAAY,YAAY;AACvC,aAAS,CAAC,SAAS;AACjB,YAAM,EAAE,gBAAgB,YAAY,aAAa,cAAc,IAAI;AAEnE,UAAI,iBAAiB,CAAC,kBAAkB,CAAC,YAAY,SAAS;AAC5D,eAAO;AAAA,MACT;AAEA,YAAM,kBAAkB;AAAA,QACtB,GAAG;AAAA,QACH,MAAM,WAAW,OAAO;AAAA,MAC1B;AAEA,qBAAe,iBAAiB,IAAI,EAAE,MAAM,CAAC,UAAU;AACrD,gBAAQ,MAAM,sCAAmC,KAAK;AAAA,MACxD,CAAC;AAED,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAKnB,QAAM,QAAQA,aAAY,MAAM;AAC9B,aAAS;AAAA,MACP,WAAW,CAAC;AAAA,MACZ,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,aAAa;AAAA,MACb,OAAO;AAAA,MACP,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAqBO,IAAM,yBAAyB,CAAC,cAA6B;AAClE,SAAO,MAA8B,qBAAqB,SAAS;AACrE;;;ACxQA,IAAM,uBAAuB,IAAI,IAAI,OAAO,OAAO,aAAa,CAAC;AAuP1D,SAAS,yBAAyB,UAAqC;AAC5E,QAAM,cACJ,SAAS,mBAAmB,SAAS,gBAAgB,SAAS,IAC1D;AAAA,IACE,aAAa,SAAS,gBAAgB,CAAC,EAAE,SAAS,QAAQ;AAAA,IAC1D,cAAc,SAAS,gBAAgB,CAAC,EAAE,SAAS,SAAS;AAAA,IAC5D,UAAU,SAAS,gBAAgB,CAAC,EAAE,SAAS,QAAQ;AAAA,EACzD,IACA,CAAC;AAEP,SAAO;AAAA,IACL,IAAI,SAAS;AAAA,IACb,WAAW,SAAS;AAAA,IACpB,cAAc,SAAS;AAAA,IACvB,UAAU,SAAS,UACf;AAAA,MACE,SAAS,SAAS,QAAQ;AAAA,QACxB,CAAC,SAAyC;AAAA,UACxC,IAAI,IAAI;AAAA,UACR,QAAQ,IAAI;AAAA,QACd;AAAA,MACF;AAAA,MACA,kBAAkB,CAAC;AAAA,IACrB,IACA;AAAA,IACJ,GAAG;AAAA,EACL;AACF;;;ACtSA,SAAgB,cAAAC,cAAY,UAAAC,UAAQ,eAAAC,oBAAmB;AAmD3C,SAofR,YAAAC,YApfQ,OAAAC,OAyCE,QAAAC,cAzCF;AA9BL,IAAM,sBAAsBC,aAGjC,CAAC,EAAE,UAAU,GAAG,QAAQ;AACxB,QAAM,mBAAmB,CAAC,UAA0B;AAClD,WAAO,OAAO,cAAc,KAAK,KAAK;AAAA,EACxC;AAEA,QAAM,oBAAoB,CAAC,aAA8B;AACvD,QAAI,CAAC,SAAS,UAAU,WAAW,SAAS,SAAS,QAAQ,WAAW,GAAG;AACzE,aAAO;AAAA,IACT;AAEA,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAO;AAAA,UACL,WAAW;AAAA,UACX,cAAc;AAAA,UACd,aAAa;AAAA,QACf;AAAA,QAEC,mBAAS,SAAS,QAAQ,IAAI,CAAC,WAC9B,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO;AAAA,cACL,cAAc;AAAA,cACd,YAAY;AAAA,YACd;AAAA,YAEA,0BAAAA,MAAC,yBAAc,SAAS,OAAO,QAAQ;AAAA;AAAA,UANlC,OAAO;AAAA,QAOd,CACD;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,QAAM,uBAAuB,CAAC,aAA8B;AAC1D,QAAI,CAAC,SAAS,UAAU,WAAW,SAAS,SAAS,QAAQ,WAAW,GAAG;AACzE,aAAO;AAAA,IACT;AAEA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,WAAW;AAAA,UACX,cAAc;AAAA,QAChB;AAAA,QAEC,mBAAS,SAAS,QAAQ,IAAI,CAAC,QAAQ,UAAU;AAChD,gBAAM,SAAS,iBAAiB,KAAK;AACrC,iBACE,gBAAAC;AAAA,YAAC;AAAA;AAAA,cAEC,OAAO;AAAA,gBACL,cAAc;AAAA,gBACd,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,KAAK;AAAA,gBACL,YAAY;AAAA,cACd;AAAA,cAEA;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,WAAW;AAAA,sBACX,UAAU;AAAA,sBACV,UAAU;AAAA,oBACZ;AAAA,oBACD;AAAA;AAAA,gBAED;AAAA,gBACA,gBAAAC;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,YAAY;AAAA,sBACZ,aAAa;AAAA,oBACf;AAAA,oBAEC;AAAA;AAAA,sBAAO;AAAA;AAAA;AAAA,gBACV;AAAA,gBACA,gBAAAD,MAAC,SAAI,OAAO,EAAE,MAAM,EAAE,GACpB,0BAAAA,MAAC,yBAAc,SAAS,OAAO,QAAQ,GACzC;AAAA;AAAA;AAAA,YA5BK,OAAO;AAAA,UA6Bd;AAAA,QAEJ,CAAC;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,QAAM,qBAAqB,MAAM;AAC/B,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,WAAW;AAAA,UACX,cAAc;AAAA,QAChB;AAAA,QAEA,0BAAAC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK;AAAA,YACP;AAAA,YAEA;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,YAAY;AAAA,oBACZ,WAAW;AAAA,kBACb;AAAA,kBACD;AAAA;AAAA,cAED;AAAA,cACA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,WAAW;AAAA,oBACX,MAAM;AAAA,kBACR;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,QAAM,oBAAoB,CAAC,aAA8B;AACvD,QAAI,CAAC,SAAS,UAAU,WAAW,SAAS,SAAS,QAAQ,WAAW,GAAG;AACzE,aAAO;AAAA,IACT;AAEA,WACE,gBAAAA,MAAC,SAAI,OAAO,EAAE,WAAW,QAAQ,cAAc,OAAO,GACnD,mBAAS,SAAS,QAAQ,IAAI,CAAC,QAAQ,UACtC,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO;AAAA,UACL,cAAc;AAAA,UACd,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,QACP;AAAA,QAEA;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,UAAU;AAAA,cACZ;AAAA,cAEC;AAAA,iCAAiB,KAAK;AAAA,gBAAE;AAAA;AAAA;AAAA,UAC3B;AAAA,UACA,gBAAAD,MAAC,SAAI,OAAO,EAAE,MAAM,EAAE,GACpB,0BAAAA,MAAC,yBAAc,SAAS,OAAO,QAAQ,GACzC;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,YAAY;AAAA,gBACZ,UAAU;AAAA,cACZ;AAAA,cACD;AAAA;AAAA,UAED;AAAA;AAAA;AAAA,MA3BK,OAAO;AAAA,IA4Bd,CACD,GACH;AAAA,EAEJ;AAEA,QAAM,4BAA4B,CAAC,aAA8B;AAK/D,UAAM,YAAmD;AAAA,MACvD,gCAA0B,GAAG;AAAA,MAC7B,0CAA+B,GAAG;AAAA,MAClC,kCAA2B,GAAG,MAAM,mBAAmB;AAAA,MACvD,0CAA+B,GAAG;AAAA,MAClC,kCAA2B,GAAG,MAAM;AAAA,MACpC,4BAAwB,GAAG,MAAM;AAAA,MACjC,sBAAqB,GAAG,MAAM;AAAA,IAChC;AAEA,QAAI,CAAC,SAAS,cAAc;AAC1B,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,UAAU,SAAS,YAAY;AACtD,WAAO,iBAAiB,eAAe,QAAQ,IAAI;AAAA,EACrD;AAEA,QAAM,wBAAwB,CAAC,UAA2B,UAAkB;AAC1E,UAAM,iBAAiB,QAAQ;AAE/B,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO;AAAA,UACL,cAAc;AAAA,UACd,iBAAiB;AAAA,QACnB;AAAA,QAEA;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,cAAc;AAAA,gBACd,OAAO;AAAA,cACT;AAAA,cACD;AAAA;AAAA,gBACU;AAAA;AAAA;AAAA,UACX;AAAA,UAEC,SAAS,aACR,gBAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,cAAc;AAAA,gBACd,YAAY;AAAA,gBACZ,OAAO;AAAA,cACT;AAAA,cAEA,0BAAAA,MAAC,yBAAc,SAAS,SAAS,WAAW;AAAA;AAAA,UAC9C;AAAA,UAGD,0BAA0B,QAAQ;AAAA;AAAA;AAAA,MA7B9B,SAAS;AAAA,IA8BhB;AAAA,EAEJ;AAEA,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MACV,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,KAAK;AAAA,QACL,OAAO;AAAA,QACP,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,QAAQ;AAAA,MACV;AAAA,MAEA;AAAA,wBAAAD,MAAC,WACE;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAsCH;AAAA,QACA,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,OAAO,GAC3B,oBAAU;AAAA,UAAI,CAAC,UAAU,UACxB,sBAAsB,UAAU,KAAK;AAAA,QACvC,GACF;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,oBAAoB,cAAc;AAKlC,IAAM,wBAAwB,MAAgB;AAC5C,QAAM,SAAmB,CAAC;AAC1B,QAAM,cAAc,MAAM,KAAK,SAAS,WAAW;AAEnD,cAAY,QAAQ,CAAC,eAAe;AAClC,QAAI;AACF,YAAM,WAAW,WAAW,YAAY,CAAC;AACzC,YAAM,KAAK,QAAQ,EAAE,QAAQ,CAAC,SAAS;AACrC,cAAM,WAAW,KAAK;AACtB,YAAI,SAAS,SAAS,OAAO,KAAK,SAAS,SAAS,eAAe,GAAG;AACpE,iBAAO,KAAK,QAAQ;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,OAAO,YAAY,eAAe,QAAQ,OAAO;AACnD,gBAAQ,MAAM,8CAA8C,KAAK;AAAA,MACnE;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAYA,IAAM,oBAAoB,CAAC,aAAqB,WAA6B;AAC3E,SAAO;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;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;AAAA;AAAA,YA8DG,OAAO,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,YAKjB,WAAW;AAAA;AAAA;AAAA;AAAA;AAKvB;AAKA,IAAM,0BAA0B,CAAC,gBAA8B;AAC7D,cAAY,SAAS,MAAM;AACzB,UAAM,kBAAkB,MAAM;AAC5B,UAAI;AACF,oBAAY,MAAM;AAAA,MACpB,UAAE;AACA,mBAAW,MAAM;AACf,cAAI,eAAe,CAAC,YAAY,QAAQ;AACtC,wBAAY,MAAM;AAAA,UACpB;AAAA,QACF,GAAG,GAAI;AAAA,MACT;AAAA,IACF;AAEA,UAAM,QAAQ,YAAY,SAAS;AACnC,QAAI,SAAS,WAAW,OAAO;AAC7B,YAAM,MACH,KAAK,MAAM;AACV,mBAAW,iBAAiB,GAAG;AAAA,MACjC,CAAC,EACA,MAAM,MAAM;AACX,mBAAW,iBAAiB,GAAG;AAAA,MACjC,CAAC;AAAA,IACL,OAAO;AACL,iBAAW,iBAAiB,GAAG;AAAA,IACjC;AAAA,EACF;AACF;AAUO,IAAM,uBAAuB,CAClC,WACA,SACA,iBACG;AACH,QAAM,aAAaG,SAAuB,IAAI;AAE9C,QAAM,cAAcC,aAAY,MAAM;AACpC,QAAI;AACF,gBAAU;AAEV,UAAI,CAAC,WAAW,SAAS;AACvB,cAAM,IAAI,MAAM,0CAAuC;AAAA,MACzD;AAEA,YAAM,cAAc,OAAO,KAAK,IAAI,QAAQ;AAC5C,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,kBAAY,SAAS;AAErB,YAAM,cAAc,WAAW,QAAQ;AACvC,YAAM,SAAS,sBAAsB;AACrC,YAAM,cAAc,kBAAkB,aAAa,MAAM;AAEzD,YAAM,MAAM,YAAY;AACxB,UAAI,KAAK;AACT,UAAI,MAAM,WAAW;AACrB,UAAI,MAAM;AAEV,8BAAwB,WAAW;AAAA,IACrC,SAAS,OAAO;AACd,YAAM,WACJ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAC1D,qBAAe,QAAQ;AACvB,cAAQ,MAAM,sBAAsB,QAAQ;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;;;AC/fA,SAAS,eAAAC,oBAAmB;AAmE5B,IAAM,mBAAmB,CACvB,WAC4B;AAC5B,QAAM,YAAqC,CAAC;AAC5C,MAAI,QAAQ,KAAM,WAAU,OAAO,OAAO;AAC1C,MAAI,QAAQ,MAAO,WAAU,QAAQ,OAAO;AAC5C,MAAI,QAAQ,OAAQ,WAAU,SAAS,OAAO;AAC9C,MAAI,QAAQ,UAAW,WAAU,YAAY,OAAO;AACpD,MAAI,QAAQ,OAAQ,WAAU,SAAS,OAAO;AAC9C,SAAO;AACT;AAsBO,IAAM,qBAAqB,CAChC,cAC6B;AAO7B,QAAM,uBAAuBA;AAAA,IAC3B,OACE,IACA,WACiC;AACjC,YAAM,cAAc,iBAAiB,MAAM;AAE3C,YAAM,CAAC,iBAAiB,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,QACxD,UAAU,IAAgC,eAAe,EAAE,YAAY;AAAA,UACrE,QAAQ;AAAA,QACV,CAAC;AAAA,QACD,UAAU,IAAkB,eAAe,EAAE,OAAO,EAAE,MAAM,MAAM,IAAI;AAAA,MACxE,CAAC;AAED,aAAO;AAAA,QACL,GAAG,gBAAgB,KAAK;AAAA,QACxB,UAAU,cAAc,MAAM;AAAA,MAChC;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAQA,QAAM,yBAAyBA;AAAA,IAC7B,OACE,YACA,cAC+C;AAC/C,YAAM,WAAW,MAAM,UAAU;AAAA,QAC/B,uBAAuB,UAAU,SAAS,SAAS;AAAA,MACrD;AACA,aAAO,SAAS;AAAA,IAClB;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AASA,QAAM,oBAAoBA;AAAA,IACxB,OACE,OACA,WACA,aACA,SACkB;AAClB,UAAI,gBAA+B;AAEnC,UAAI,MAAM;AACR,cAAM,eAAe,MAAM,UAAU;AAAA,UACnC;AAAA,UACA;AAAA,YACE,UAAU,KAAK;AAAA,YACf,UAAU,KAAK;AAAA,YACf,UAAU,KAAK;AAAA,UACjB;AAAA,QACF;AAEA,cAAM,EAAE,KAAK,OAAO,IAAI,aAAa,KAAK;AAC1C,cAAM,WAAW,IAAI,SAAS;AAE9B,mBAAW,CAACC,MAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,mBAAS,OAAOA,MAAK,KAAK;AAAA,QAC5B;AACA,iBAAS,OAAO,QAAQ,IAAI;AAE5B,cAAM,MAAM,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC,EAAE,KAAK,CAAC,aAAa;AACpB,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,kCAAkC;AAAA,UACpD;AAAA,QACF,CAAC;AAGD,cAAM,UAAU,IAAI,SAAS,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI;AACvD,cAAM,MAAM,OAAO,IAAI,WAAW,GAAG,IACjC,OAAO,IAAI,MAAM,CAAC,IAClB,OAAO;AACX,wBAAgB,GAAG,OAAO,IAAI,GAAG;AAAA,MACnC;AAEA,YAAM,UAAU;AAAA,QACd,eAAe,KAAK,aAAa,SAAS;AAAA,QAC1C;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAQA,QAAM,2BAA2BD;AAAA,IAC/B,OACE,YACA,WACA,YACkB;AAClB,YAAM,UAAU;AAAA,QACd,eAAe,UAAU,aAAa,SAAS;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACxOO,IAAM,sBAAsB,CACjC,MACA,SACY;AACZ,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO,SAAS;AACpC,MAAI,KAAK,WAAW,KAAK,OAAQ,QAAO;AAExC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAG,QAAO;AAAA,EAClC;AACA,SAAO;AACT;AAKO,IAAM,oBAAoB,CAC/B,UACA,kBACY;AACZ,MAAI,CAAC,SAAS,aAAa,SAAS,UAAU,WAAW,GAAG;AAC1D,WAAO;AAAA,EACT;AACA,SAAO,SAAS,UAAU,MAAM,CAAC,WAAW;AAC1C,UAAM,SAAS,cAAc,KAAK,CAAC,MAAM,EAAE,QAAQ,MAAM;AACzD,WAAO,QAAQ,eAAe,OAAO,YAAY,SAAS;AAAA,EAC5D,CAAC;AACH;AAKO,IAAM,uBAAuB,CAClC,MACA,QACA,kBACY;AACZ,QAAM,YAAY,cAAc,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAO,GAAG;AAChE,QAAM,oBAAoB,WAAW,eAAe,CAAC;AACrD,QAAM,iBAAiB,KAAK,OAAO,aAAa;AAChD,SAAO,kBAAkB,SAAS,OAAO,cAAc,CAAC;AAC1D;AAKO,IAAM,eAAe,CAC1B,UACA,mBACW;AACX,QAAM,aAAa,eAChB,QAAQ,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC,EACpC,IAAI,CAAC,MAAM,EAAE,EAAE;AAClB,QAAM,uBAAuB,WAAW;AAAA,IAAO,CAAC,OAC9C,SAAS,aAAa,SAAS,EAAE;AAAA,EACnC,EAAE;AACF,QAAM,eAAe,WAAW;AAChC,SAAO,GAAG,oBAAoB,OAAO,YAAY,IAC/C,yBAAyB,IAAI,gBAAgB,cAC/C;AACF;AAMO,IAAM,6BAA6B,CACxC,OACA,YACA,wBACkB;AAClB,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,KAAK;AACvD,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,oBAAoB,QAAQ;AAC9C,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMO,IAAM,0CAA0C,CACrD,UACA,kBACW;AACX,MAAI,CAAC,UAAU,aAAa,SAAS,UAAU,WAAW,GAAG;AAC3D,WAAO,UAAU,SAAS,CAAC;AAAA,EAC7B;AAGA,QAAM,YAAY,kBAAkB,UAAU,aAAa;AAG3D,MAAI,CAAC,WAAW;AACd,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UACH,SAAS,cAIF,CAAC;AAEX,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,UAAU,SAAS,CAAC;AAAA,EAC7B;AAEA,QAAM,iBAAiB,QAAQ,IAAI,CAAC,MAAM;AACxC,UAAM,YAAY,cAAc,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG;AAC3D,QAAI,CAAC,WAAW,aAAa,QAAQ;AACnC,aAAO,CAAC;AAAA,IACV;AACA,WAAO,UAAU;AAAA,EACnB,CAAC;AAED,MAAI,eAAe,KAAK,CAAC,QAAQ,IAAI,WAAW,CAAC,GAAG;AAClD,WAAO,CAAC;AAAA,EACV;AAGA,QAAM,iBAAiB,SAAS,SAAS,CAAC,GAAG;AAAA,IAAO,CAAC,SACnD,QAAQ,MAAM,CAAC,WAAW,qBAAqB,MAAM,QAAQ,aAAa,CAAC;AAAA,EAC7E;AAEA,SAAO;AACT;;;A1C0XM,SASE,OAAAE,OATF,QAAAC,cAAA;AAhfC,IAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,iBAAiB;AACnB,MAMM;AACJ,QAAM,CAAC,eAAe,gBAAgB,IAAIC,WAAiB,EAAE;AAG7D,QAAM,0BAA0BC,SAAgB,KAAK;AACrD,QAAM,wBAAwBA,SAAO,kBAAkB;AACvD,QAAM,wBAAwBA,SAAyB,UAAU;AAGjE,EAAAC,YAAU,MAAM;AACd,0BAAsB,UAAU;AAAA,EAClC,GAAG,CAAC,kBAAkB,CAAC;AAKvB,QAAM,8BAA8BC,SAAQ,MAAM;AAChD,WAAO,WAAW,IAAI,CAAC,aAAa;AAElC,YAAM,gBAAgB;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAGA,UACE,cAAc,WAAW,MACxB,CAAC,SAAS,eAAe,SAAS,YAAY,WAAW,IAC1D;AACA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,aAAa,CAAC,cAAc,CAAC,EAAE,EAAE;AAAA,QACnC;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,CAAC;AAIf,EAAAD,YAAU,MAAM;AAEd,UAAM,oBAAoB,eAAe,sBAAsB;AAE/D,QAAI,CAAC,qBAAqB,wBAAwB,SAAS;AAEzD;AAAA,IACF;AAGA,0BAAsB,UAAU;AAGhC,UAAM,0BAA0B,4BAA4B;AAAA,MAC1D,CAAC,KAAK,UAAU;AACd,cAAM,cAAc,WAAW,KAAK;AACpC,eAAO,CAAC,oBAAoB,IAAI,aAAa,YAAY,WAAW;AAAA,MACtE;AAAA,IACF;AAEA,QAAI,yBAAyB;AAC3B,8BAAwB,UAAU;AAElC,4BAAsB,QAAQ,2BAA2B;AAAA,IAC3D,WAAW,mBAAmB;AAE5B,8BAAwB,UAAU;AAAA,IACpC;AAAA,EACF,GAAG,CAAC,6BAA6B,UAAU,CAAC;AAE5C,QAAM,uBAAuB,CAAC,aAAqB,WAAmB;AACpE,UAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW;AAC7D,QAAI,CAAC,SAAU,QAAO;AACtB,WAAO,SAAS,aAAa,SAAS,MAAM,KAAK;AAAA,EACnD;AAEA,QAAM,iCAAiC,CAAC,gBAAwB;AAC9D,UAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW;AAC7D,QAAI,CAAC,SAAU,QAAO;AAGtB,UAAM,iBAAiB,kBAAkB,WAAW;AACpD,UAAM,gBAAgB,eAAe,QAAQ,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC;AACzE,UAAM,kBAAkB,cAAc,IAAI,CAAC,SAAS,KAAK,EAAE;AAG3D,WAAO,gBAAgB;AAAA,MAAK,CAAC,WAC3B,SAAS,aAAa,SAAS,MAAM;AAAA,IACvC;AAAA,EACF;AAGA,QAAM,qBAAqB,CACzB,KACA,iBACe;AACf,UAAM,eAA2B,CAAC;AAClC,eAAW,iBAAiB,KAAK;AAC/B,iBAAW,QAAQ,cAAc;AAC/B,qBAAa,KAAK,CAAC,GAAG,eAAe,IAAI,CAAC;AAAA,MAC5C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,CAAC,QAAgC;AACjD,WAAO,IAAI,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAe;AAAA,EAC1D;AAGA,QAAM,2BAA2B,CAC/B,YACG;AACH,WAAO,QAAQ,IAAI,CAAC,MAAM;AACxB,YAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG;AACxD,UAAI,CAAC,WAAW,aAAa,QAAQ;AACnC,eAAO,CAAC;AAAA,MACV;AACA,aAAO,UAAU;AAAA,IACnB,CAAC;AAAA,EACH;AAGA,QAAM,4BAA4B,CAChC,QACA,YACG;AACH,UAAM,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAO,GAAG;AACvD,WAAO,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,GAAG,QAAQ;AAAA,EAC5D;AAGA,QAAM,+BAA+B,CACnC,SACA,aACG;AACH,UAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,QAAQ,CAAC,EAAE,GAAG;AAChE,UAAM,WACJ,UAAU,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,CAAC,CAAC,GAAG,QAAQ,SAAS,CAAC;AAExE,UAAM,aAAuB,CAAC,QAAQ;AAEtC,aAAS,MAAM,GAAG,MAAM,QAAQ,QAAQ,OAAO;AAC7C,YAAM,IAAI,QAAQ,GAAG;AACrB,YAAM,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG;AAClD,YAAM,MACJ,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,GAAG,CAAC,GAAG,QAAQ,SAAS,GAAG;AACvE,iBAAW,KAAK,IAAI,GAAG,GAAG;AAAA,IAC5B;AACA,WAAO,WAAW,KAAK,GAAG;AAAA,EAC5B;AAGA,QAAM,qBAAqB,CACzB,UACA,SACA,UACA,eACG;AACH,UAAM,iBAAiB,UAAU,SAAS,CAAC,GAAG;AAAA,MAAO,CAAC,SACpD,QAAQ,MAAM,CAAC,GAAG,QAAQ,KAAK,EAAE,aAAa,MAAM,SAAS,GAAG,CAAC;AAAA,IACnE;AAEA,QAAI,cAAc,WAAW,EAAG;AAEhC,QAAI,aAAiC;AAErC,QAAI,QAAQ,WAAW,GAAG;AACxB,mBAAa,0BAA0B,QAAQ,CAAC,GAAG,SAAS,CAAC,CAAC;AAAA,IAChE,WAAW,QAAQ,SAAS,GAAG;AAC7B,mBAAa,6BAA6B,SAAS,QAAQ;AAAA,IAC7D;AAEA,UAAM,MAAM,cAAc;AAC1B,QAAI,CAAC,WAAW,GAAG,GAAG;AACpB,iBAAW,GAAG,IAAI,aAAa,EAAE,YAAY,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE;AAAA,IACzE;AACA,eAAW,GAAG,EAAE,MAAM,KAAK,GAAG,aAAa;AAAA,EAC7C;AAGA,QAAM,0BAA0B,CAAC,gBAAwB;AACvD,UAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW;AAE7D,QAAI,CAAC,UAAU,aAAa,SAAS,UAAU,WAAW,GAAG;AAC3D,aAAO,CAAC,EAAE,OAAO,UAAU,SAAS,CAAC,EAAE,CAAC;AAAA,IAC1C;AAGA,UAAM,YAAY,SAAS,UAAU,MAAM,CAAC,WAAW;AACrD,YAAM,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,MAAM;AACtD,aAAO,QAAQ,eAAe,OAAO,YAAY,SAAS;AAAA,IAC5D,CAAC;AAGD,QAAI,CAAC,WAAW;AACd,aAAO,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;AAAA,IACvB;AAEA,UAAM,UACH,SAAS,cAIF,CAAC;AAEX,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,CAAC,EAAE,OAAO,UAAU,SAAS,CAAC,EAAE,CAAC;AAAA,IAC1C;AAEA,UAAM,iBAAiB,yBAAyB,OAAO;AAEvD,QAAI,eAAe,KAAK,CAAC,QAAQ,IAAI,WAAW,CAAC,GAAG;AAClD,aAAO,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;AAAA,IACvB;AAEA,UAAM,eAAe,UAAU,cAAc;AAC7C,UAAM,aACJ,CAAC;AAEH,eAAW,YAAY,cAAc;AACnC,yBAAmB,UAAU,SAAS,UAAU,UAAU;AAAA,IAC5D;AAEA,UAAM,eAAe,OAAO,OAAO,UAAU,EAAE;AAAA,MAC7C,CAAC,MAAM,EAAE,MAAM;AAAA,IACjB;AAEA,WAAO,aAAa,SAAS,eAAe,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;AAAA,EAC5D;AAEA,QAAM,oBAAoBC,SAAQ,MAAM;AACtC,UAAMC,qBAGF,CAAC;AAEL,eAAW,YAAY,YAAY;AACjC,YAAM,iBAAiB,wBAAwB,SAAS,GAAG;AAC3D,MAAAA,mBAAkB,SAAS,GAAG,IAAI;AAAA,IACpC;AAEA,WAAOA;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,oBAAoB,CAAC,gBAAwB;AACjD,WAAO,kBAAkB,WAAW,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;AAAA,EACzD;AAGA,QAAMC,gBAAe,CAAC,aAAqC;AACzD,UAAM,iBAAiB,kBAAkB,SAAS,GAAG;AACrD,WAAO,aAAmB,UAAU,cAAc;AAAA,EACpD;AAGA,QAAMC,qBAAoB,CAAC,aAAsC;AAC/D,WAAO,kBAAwB,UAAU,UAAU;AAAA,EACrD;AAGA,QAAMC,8BAA6B,CAAC,UAAyC;AAC3E,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACAD;AAAA,IACF;AACA,QAAI,aAAa,MAAM;AACrB,uBAAiB,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,yBAAyB,CAAC,gBAAkC;AAChE,WAAO,WACJ,OAAO,CAAC,QAAQ,IAAI,WAAW,SAAS,WAAW,CAAC,EACpD,IAAI,CAAC,QAAQ,IAAI,GAAG;AAAA,EACzB;AAGA,QAAM,oBAAoB,CACxB,aACA,gBACA,qBACa;AACb,WACE,YAAY,OACR;AAAA,MACA,CAAC,SAAS,KAAK,eAAe,aAAa,MAAM;AAAA,IACnD,EACC,IAAI,CAAC,SAAS,KAAK,EAAE,KAAK,CAAC;AAAA,EAElC;AAGA,QAAM,2BAA2B,CAC/B,gBACA,aACA,kBACA,oBACG;AACH,UAAM,cAAc,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,cAAc;AACnE,QAAI,CAAC,aAAa,WAAY;AAE9B,UAAM,iBAAiB,YAAY,WAAW;AAAA,MAC5C,CAAC,MAAM,EAAE,QAAQ;AAAA,IACnB;AACA,QAAI,CAAC,eAAgB;AAErB,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,cAAc,SAAS,GAAG;AAC5B,sBAAgB,cAAc,IAAI;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,qBAAqB,CACzB,aACA,qBACG;AACH,UAAM,iBAAiB,WACpB,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW,GAChC,OAAO,KAAK,CAAC,SAAS,KAAK,OAAO,gBAAgB;AACtD,QAAI,CAAC,eAAgB,QAAO,CAAC;AAE7B,UAAM,kBAA4C,CAAC;AACnD,UAAM,sBAAsB,uBAAuB,WAAW;AAE9D,eAAW,kBAAkB,qBAAqB;AAChD;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,4BAA4B,CAChC,mBACA,kBACA,aACA,YACqB;AACrB,UAAM,iBACJ,YAAY,aAAa,OAAO,CAAC,OAAO,CAAC,QAAQ,SAAS,EAAE,CAAC,KAAK,CAAC;AAErE,sBAAkB,gBAAgB,IAAI;AAAA,MACpC,GAAG;AAAA,MACH,aAAa;AAAA,IACf;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,wBAAwB,CAC5B,gBACA,SACA,sBACqB;AACrB,QAAI,SAAS;AACb,eAAW,UAAU,SAAS;AAC5B,eAAS,wBAAwB,gBAAgB,QAAQ,MAAM;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AAEA,QAAM,0BAA0B,CAC9B,aACA,kBACA,sBACqB;AACrB,UAAM,kBAAkB,mBAAmB,aAAa,gBAAgB;AACxE,QAAI,oBAAoB,CAAC,GAAG,iBAAiB;AAE7C,eAAW,CAAC,gBAAgB,OAAO,KAAK,OAAO,QAAQ,eAAe,GAAG;AACvE,YAAM,mBAAmB,kBAAkB;AAAA,QACzC,CAAC,MAAM,EAAE,QAAQ;AAAA,MACnB;AAEA,UAAI,qBAAqB,IAAI;AAC3B,cAAM,cAAc,kBAAkB,gBAAgB;AACtD,4BAAoB;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,4BAAoB;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,sBAAsB,CAAC,gBAAwB;AACnD,UAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW;AAC7D,QAAI,CAAC,SAAU;AAGf,UAAM,iBAAiB,kBAAkB,WAAW;AACpD,UAAM,gBAAgB,eAAe,QAAQ,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC;AACzE,UAAM,kBAAkB,cAAc,IAAI,CAAC,SAAS,KAAK,EAAE;AAG3D,UAAM,wBAAwB,gBAAgB;AAAA,MAAO,CAAC,WACpD,SAAS,aAAa,SAAS,MAAM;AAAA,IACvC,EAAE;AAKF,UAAM,sBACJ,0BAA0B,gBAAgB;AAE5C,UAAM,eAAe,sBACjB,SAAS,aAAa,OAAO,CAAC,OAAO,CAAC,gBAAgB,SAAS,EAAE,CAAC,KAClE,CAAC,IACD;AAAA,MACE,GAAI,SAAS,eAAe,CAAC;AAAA,MAC7B,GAAG,gBAAgB;AAAA,QACjB,CAAC,OAAO,CAAC,SAAS,aAAa,SAAS,EAAE;AAAA,MAC5C;AAAA,IACF;AAEJ,QAAI,oBAAoB,WAAW;AAAA,MAAI,CAAC,MACtC,EAAE,QAAQ,cAAc,EAAE,GAAG,GAAG,aAAa,aAAa,IAAI;AAAA,IAChE;AAGA,QAAI,qBAAqB;AACvB,iBAAW,UAAU,iBAAiB;AACpC,4BAAoB;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,uBAAmB,iBAAiB;AAAA,EACtC;AAEA,QAAM,aAAa,CAAC,aAAqB,WAAmB;AAC1D,UAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW;AAC7D,QAAI,CAAC,SAAU;AACf,UAAM,sBAAsB,SAAS,aAAa,SAAS,MAAM;AACjE,UAAM,eAAe,sBACjB,SAAS,aAAa,OAAO,CAAC,OAAO,OAAO,MAAM,IAClD,CAAC,GAAI,SAAS,eAAe,CAAC,GAAI,MAAM;AAE5C,QAAI,oBAAoB,WAAW;AAAA,MAAI,CAAC,MACtC,EAAE,QAAQ,cAAc,EAAE,GAAG,GAAG,aAAa,aAAa,IAAI;AAAA,IAChE;AAGA,QAAI,qBAAqB;AACvB,0BAAoB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,uBAAmB,iBAAiB;AAAA,EACtC;AAGA,QAAM,qBAAqB,CAAC,MAAY,gBAAwB;AAE9D,UAAM,WAAW,GAAG,WAAW,IAAI,KAAK,EAAE;AAE1C,WACE,gBAAAP;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QACV,MAAK;AAAA,QACL,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,aAAa,CAAC,MAAM,EAAE,gBAAgB;AAAA,QACtC,WAAW,CAAC,MAAM,EAAE,gBAAgB;AAAA,QACpC,WAAW,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAEpC;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,SAAS,qBAAqB,aAAa,KAAK,EAAE;AAAA,cAClD,UAAU,MAAM,WAAW,aAAa,KAAK,EAAE;AAAA;AAAA,UACjD;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,WAAU;AAAA,cAET,eAAK;AAAA;AAAA,UACR;AAAA;AAAA;AAAA,MAlBK,KAAK;AAAA,IAmBZ;AAAA,EAEJ;AAGA,QAAM,uBAAuB,CAC3B,gBACA,KACA,gBAEA,gBAAAC;AAAA,IAAC;AAAA;AAAA,MAEC,WAAU;AAAA,MAET;AAAA,wBAAgB,kBAAkB,eAAe,cAChD,gBAAAD,MAAC,gBAAK,MAAK,MAAK,WAAU,QAAO,QAAO,YACrC,yBAAe,YAClB;AAAA,QAED,eAAe,OAAO;AAAA,UAAI,CAAC,SAC1B,mBAAmB,MAAM,WAAW;AAAA,QACtC;AAAA;AAAA;AAAA,IAVK,eAAe,cAAc,SAAS,GAAG;AAAA,EAWhD;AAIF,QAAM,yBAAyB,CAC7B,UACA,cAEA,gBAAAC,OAAC,SAAI,WAAU,gDACb;AAAA,oBAAAA,OAAC,SAAI,WAAU,2BACb;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,+BAA+B,SAAS,GAAG;AAAA,UACpD,UAAU,CAAC;AAAA,UACX,eAAe,+BAA+B,SAAS,GAAG;AAAA,UAC1D,UAAU,MAAM,oBAAoB,SAAS,GAAG;AAAA;AAAA,MAClD;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAO;AAAA,UACP,WAAW,GAAG,iBAAiB,CAAC,aAAa,YAAY;AAAA,UAExD,mBAAS;AAAA;AAAA,MACZ;AAAA,OACF;AAAA,KACE,kBAAkB,SAAS,OAAO,cAClC,gBAAAA,MAAC,iBAAM,SAAQ,SAAQ,QAAO,QAC3B,UAAAO,cAAa,QAAQ,GACxB;AAAA,KAEJ;AAIF,QAAM,0BAA0B,CAAC,aAA6B;AAC5D,UAAM,iBAAiB,kBAAkB,SAAS,GAAG;AACrD,UAAM,WAAW,eAAe,QAAQ,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC;AAEpE,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,SAAS,CAAC;AAE7B,WACE,gBAAAN;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QAEV;AAAA,0BAAAD,MAAC,gBAAK,MAAK,MAAK,QAAO,QAAO,WAAU,iBACrC,mBAAS,OACZ;AAAA,UACA,gBAAAA,MAAC,gBAAK,MAAK,MAAK,WAAU,iBACvB,qBAAW,MACd;AAAA;AAAA;AAAA,MARK,SAAS;AAAA,IAShB;AAAA,EAEJ;AAGA,QAAM,0BAA0B,CAAC,aAA6B;AAE5D,UAAM,YAAYQ,mBAAkB,QAAQ;AAC5C,UAAM,iBAAiB,SAAS,OAAO,WAAW;AAElD,QAAI,kBAAkB,CAAC,qBAAqB,CAAC,gBAAgB;AAC3D,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,kBAAkB,SAAS,GAAG;AACrD,UAAM,WAAW,eAAe,QAAQ,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC;AACpE,UAAM,0BAA0B,SAAS,WAAW;AAGpD,QAAI,qBAAqB,2BAA2B,WAAW;AAC7D,aACE,gBAAAP,OAAC,SACE;AAAA,gCAAwB,QAAQ;AAAA,QAChC,eAAe,gBAAAD,MAAC,mBAAQ;AAAA,WAFjB,SAAS,GAGnB;AAAA,IAEJ;AAEA,UAAM,aAAa,eAAe;AAAA,MAChC,CAAC,UAAU,CAAC,MAAM,SAAS,MAAM,MAAM,WAAW;AAAA,IACpD;AAEA,WACE,gBAAAC,OAAC,SACC;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,SAAS;AAAA,UAChB,UAAU,CAAC;AAAA,UACX,WAAW;AAAA,YACT;AAAA,YACA,kBAAkB,SAAS,OAAO;AAAA,UACpC;AAAA,UACA,SAAS,uBAAuB,UAAU,SAAS;AAAA,UAEnD,0BAAAA,MAAC,SAAI,WAAU,4BACZ,wBAAc,YACb,gBAAAA,MAAC,SAAI,WAAU,aACb,0BAAAA,MAAC,gBAAK,MAAK,MAAK,WAAU,6BAA4B,uBAEtD,GACF,IAEA,eAAe;AAAA,YAAI,CAAC,gBAAgB,QAClC,qBAAqB,gBAAgB,KAAK,SAAS,GAAG;AAAA,UACxD,GAEJ;AAAA;AAAA,MACF;AAAA,MACC,kBAAkB,SAAS,OAAO,eAAe,gBAAAA,MAAC,mBAAQ;AAAA,SAxBnD,SAAS,GAyBnB;AAAA,EAEJ;AAGA,EAAAI,YAAU,MAAM;AACd,QAAI,CAAC,cAAe;AAEpB,UAAM,WAAW,WAAW,KAAK,CAAC,MAAM,EAAE,QAAQ,aAAa;AAC/D,QAAI,CAAC,SAAU;AAGf,UAAM,YAAYI,mBAAkB,QAAQ;AAG5C,QAAI,CAAC,WAAW;AAEd,iBAAW,MAAM;AACf,yBAAiB,EAAE;AAAA,MACrB,GAAG,CAAC;AAAA,IACN;AAAA,EACF,GAAG,CAAC,YAAY,aAAa,CAAC;AAE9B,SACE,gBAAAR;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAW;AAAA,MACX,OAAO;AAAA,MACP,eAAeS;AAAA,MAEd,qBAAW,IAAI,uBAAuB;AAAA;AAAA,EACzC;AAEJ;;;A2C7kBQ,SACE,OAAAC,OADF,QAAAC,cAAA;AAxCD,IAAM,cAAc,CAAC;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AACf,MAAwB;AACtB,QAAM,uBAAuB,CAC3B,aACA,sBACG;AACH,UAAM,aAAa,CAAC,GAAG,aAAa;AACpC,eAAW,WAAW,IAAI;AAAA,MACxB,GAAG,WAAW,WAAW;AAAA,MACzB,YAAY;AAAA,IACd;AACA,oBAAgB,UAAU;AAAA,EAC5B;AAEA,QAAM,cAAc,MAAM;AACxB,YAAQ;AACR,YAAQ;AAAA,EACV;AAEA,QAAM,cAAc,MAAM;AACxB,YAAQ;AAAA,EACV;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QACE,gBAAAC,OAAC,SAAI,WAAU,iCACb;AAAA,wBAAAD,MAAC,kBAAO,SAAQ,WAAU,SAAS,aAChC,sBACH;AAAA,QACA,gBAAAA,MAAC,kBAAO,SAAS,aAAc,sBAAW;AAAA,SAC5C;AAAA,MAGF,0BAAAA,MAAC,SAAI,WAAU,uBACZ,wBAAc,IAAI,CAAC,QAAQ,UAC1B,gBAAAC,OAAC,SAAqB,WAAU,uBAE9B;AAAA,wBAAAA,OAAC,SAAI,WAAU,uEACZ;AAAA,iBAAO,QAAQ,cACd,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,QAAO;AAAA,cACP,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cAEV;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,eAAc;AAAA,oBACd,gBAAe;AAAA;AAAA,gBACjB;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,eAAc;AAAA,oBACd,gBAAe;AAAA;AAAA,gBACjB;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,eAAc;AAAA,oBACd,gBAAe;AAAA;AAAA,gBACjB;AAAA;AAAA;AAAA,UACF;AAAA,UAED,OAAO,QAAQ,aACd,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,QAAO;AAAA,cACP,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cAEV;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,eAAc;AAAA,oBACd,gBAAe;AAAA;AAAA,gBACjB;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,eAAc;AAAA,oBACd,gBAAe;AAAA;AAAA,gBACjB;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,eAAc;AAAA,oBACd,gBAAe;AAAA;AAAA,gBACjB;AAAA;AAAA;AAAA,UACF;AAAA,UAEF,gBAAAA,MAAC,UAAM,iBAAO,OAAM;AAAA,WACtB;AAAA,QAGA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,YAAY,OAAO;AAAA,YACnB,oBAAoB,CAAC,sBACnB,qBAAqB,OAAO,iBAAiB;AAAA;AAAA,QAEjD;AAAA,WA5EQ,OAAO,GA6EjB,CACD,GACH;AAAA;AAAA,EACF;AAEJ;;;AxD9MA,SAAS,cAAc;AAgaf,SAwLF,YAAAE,YAnLI,OAAAC,OALF,QAAAC,cAAA;AAtMD,SAAS,cAAiD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,UAAU;AAAA,EACV,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,iBAAiB,CAAC;AAAA,EAClB,mBAAmB,CAAC;AAAA,EACpB,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AAExB,QAAM,CAAC,aAAa,cAAc,IAAIC,WAAS,EAAE;AAGjD,QAAM,gBAAgB,aAAa,MAAM,EAAE,aAAa,KAAK,CAAC;AAC9D,QAAM,aAAa,kBACf,gBACA;AAAA,IACE,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,YAAY,MAAM;AAAA,IAAC;AAAA,EACrB;AAEJ,QAAM,EAAE,YAAY,YAAY,eAAe,WAAW,IAAI;AAG9D,QAAM,kBAAkB,eAAe,gBAAgB,EAAE,aAAa,KAAK,CAAC;AAG5E,QAAM,uBAAuBC;AAAA,IAC3B,OAAO;AAAA,MACL,eAAe,CAAC;AAAA,MAChB,eAAe,CAAC;AAAA,MAChB,kBAAkB;AAAA,MAClB,eAAe,MAAM;AAAA,MAAC;AAAA,MACtB,cAAc,MAAM;AAAA,MAAC;AAAA,MACrB,cAAc,MAAM;AAAA,MAAC;AAAA,IACvB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,gBAAgB,kBAAkB;AAEvD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,QAAM;AAAA,IACJ,sBAAsB;AAAA,IACtB,sBAAsB,CAAC,IAAI,IAAI,IAAI,GAAG;AAAA,IACtC,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,CAAC,aAAa,cAAc,IAAID,WAAS,CAAC;AAChD,QAAM,CAAC,cAAc,eAAe,IAAIA,WAAS,mBAAmB;AAGpE,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,WAAS,KAAK;AAGhE,QAAM,iBAAiBC,SAAQ,MAAmB;AAChD,UAAM,SAAsB;AAAA,MAC1B,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAEA,QAAI,gBAAgB,aAAa;AAC/B,aAAO,SAAS;AAAA,IAClB;AAEA,QAAI,eAAe;AACjB,aAAO,OAAO,QAAQ,aAAa;AAAA,IACrC;AAEA,QAAI,mBAAmB,cAAc,eAAe;AAClD,aAAO,SAAS;AAChB,aAAO,YAAY;AAAA,IACrB;AAEA,WAAO;AAAA,EACT,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAID,EAAAC,YAAU,MAAM;AACd,qBAAiB,cAAc;AAAA,EACjC,GAAG,CAAC,cAAc,CAAC;AAGnB,QAAM,qBAAqBC,aAAY,CAAC,UAAkB;AACxD,mBAAe,KAAK;AACpB,mBAAe,CAAC;AAAA,EAClB,GAAG,CAAC,CAAC;AAGL,QAAM,oBAAoBA,aAAY,MAAM;AAC1C,iBAAa;AACb,yBAAqB,KAAK;AAC1B,mBAAe,CAAC;AAAA,EAClB,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,mBAAmBA,aAAY,CAAC,SAAiB;AACrD,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,QAAM,2BAA2BA,aAAY,CAAC,UAAkB;AAC9D,oBAAgB,KAAK;AACrB,mBAAe,CAAC;AAAA,EAClB,GAAG,CAAC,CAAC;AAGL,QAAM,yBAAyBA;AAAA,IAC7B,CAAC,KAAQ,UAAkB;AACzB,UAAI,kBAAkB,YAAY;AAChC,mBAAW,KAAK,KAAK;AAAA,MACvB;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB,UAAU;AAAA,EAC7B;AAGA,QAAM,wBAAwBF;AAAA,IAC5B,MACE,oBACA,CAAC,kBACD,eAAe,UACf,eAAe;AAAA,IACjB,CAAC,kBAAkB,gBAAgB,YAAY,UAAU;AAAA,EAC3D;AAGA,QAAM,uBACJ,cACA,KAAK;AAAA,KACF,eACE,wBAAwB,WAAW,SAAS,KAAK,WAClD;AAAA,EACJ;AACF,QAAM,uBACJ,eAAe,wBAAwB,WAAW,SAAS,KAAK;AAGlE,QAAM,cAAcA,SAAQ,MAAM;AAChC,QAAI,CAAC,uBAAuB;AAC1B,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,cAAc,KAAK;AAClC,WAAO,WAAW,MAAM,OAAO,QAAQ,YAAY;AAAA,EACrD,GAAG,CAAC,uBAAuB,YAAY,aAAa,YAAY,CAAC;AAGjE,QAAM,UAAU,KAAK,WAAW;AAGhC,QAAM,cAAc;AACpB,QAAM,qBACJ,CAAC,WAAW,KAAK,WAAW,KAAK,YAAY,KAAK,MAAM;AAC1D,QAAM,YAAY,CAAC,WAAW,KAAK,WAAW,KAAK,YAAY,KAAK,MAAM;AAG1E,QAAM,YAAY,gBAAgB,kBAChC,gBAAAF,OAAC,SAAI,WAAU,2BAEZ;AAAA,qBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS,MAAM,qBAAqB,IAAI;AAAA,QAExC;AAAA,0BAAAD,MAAC,UAAO,MAAM,IAAI;AAAA,UAAE;AAAA,UAEnB,oBACC,gBAAAA,MAAC,UAAK,WAAU,mEACb,iBAAO,KAAK,aAAa,EAAE,QAC9B;AAAA;AAAA;AAAA,IAEJ;AAAA,IAID,gBACC,gBAAAA,MAAC,SAAI,WAAU,UACb,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS,MAAM,mBAAmB,EAAE;AAAA,QACpC,SAAS,CAAC;AAAA,QACV,aAAa;AAAA;AAAA,IACf,GACF;AAAA,KAEJ;AAIF,QAAM,iBAAiB,iBAAiB,aACtC,gBAAAC,OAAC,SAAI,WAAU,iFAEZ;AAAA,qBAAiB,gBAAAD,MAAC,SAAK,yBAAc;AAAA,IAGrC,YAAY,gBAAAA,MAAC,SAAI,WAAU,uBAAuB,oBAAS;AAAA,KAC9D;AAGF,QAAM,QACJ,gBAAAA,MAAC,SAAI,WAAU,0BACb,0BAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAGA;AAAA,wBAAAD,MAAC,WACC,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,YAAY,eAAe,sBAAsB;AAAA,YAEzD,kBAAQ,IAAI,CAAC,QAAQ,UACpB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,UAAU,mBAAmB,OAAO;AAAA,gBACpC,eACE,mBAAmB,eAAe,OAAO,MACrC,gBACA;AAAA,gBAEN,QAAQ,MACN,mBAAmB,OAAO,YAAY,WAAW,OAAO,GAAG;AAAA,gBAE7D,WAAW,OAAO;AAAA,gBAClB,OAAO,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI;AAAA,gBAE/C,iBAAO;AAAA;AAAA,cAbH,UAAU,OAAO,GAAG,IAAI,KAAK;AAAA,YAcpC,CACD;AAAA;AAAA,QACH,GACF;AAAA,QAGA,gBAAAA,MAAC,aACE,oBACC,gBAAAA,MAAC,YACC,0BAAAA,MAAC,aAAU,SAAS,QAAQ,QAAQ,WAAU,oBAC5C,0BAAAA,MAAC,UAAK,WAAU,yBAAwB,2BAAa,GACvD,GACF,IAEA,YAAY,IAAI,CAAC,KAAK,aAAa;AAEjC,gBAAM,iBAAiB,yBAClB,cAAc,KAAK,eAAe,WACnC;AAEJ,gBAAM,cAAc,UACf,MAAM;AACL,kBAAM,WAAW,IAAI,MAAM;AAC3B,gBAAI,aAAa,QAAQ,aAAa,QAAW;AAC/C,qBAAO,OAAO,cAAc;AAAA,YAC9B;AACA,gBAAI,OAAO,aAAa,UAAU;AAChC,qBAAO,KAAK,UAAU,QAAQ;AAAA,YAChC;AACA,mBAAO,OAAO,QAAQ;AAAA,UACxB,GAAG,IACH,OAAO,cAAc;AACzB,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,SACE,YAAY,eAAe,sBAAsB;AAAA,cAEnD,WAAW;AAAA,cACX,SAAS,MAAM,uBAAuB,KAAK,cAAc;AAAA,cAExD,kBAAQ,IAAI,CAAC,QAAQ,cAAc;AAClC,sBAAM,QAAQ,IAAI,OAAO,GAAG;AAE5B,oBAAI,iBAAiB;AAErB,oBAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,sBACE,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,aACjB,OAAO,UAAU,UACjB;AAEA,qCAAiB,OAAO,KAAK;AAAA,kBAC/B,WAAW,OAAO,UAAU,UAAU;AAEpC,qCAAiB,KAAK,UAAU,KAAK;AAAA,kBACvC,WAAW,OAAO,UAAU,YAAY;AAEtC,qCAAiB;AAAA,kBACnB,WAAW,OAAO,UAAU,UAAU;AAEpC,qCAAiB,OAAO,KAAK;AAAA,kBAC/B;AAAA,gBAEF;AAEA,sBAAM,UAAU,OAAO,SACnB,OAAO,OAAO,OAAO,KAAK,cAAc,IACxC;AAEJ,uBACE,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBAEC,WAAW,OAAO;AAAA,oBAClB,OAAO;AAAA,sBACL,WAAW,OAAO;AAAA,oBACpB;AAAA,oBAEC;AAAA;AAAA,kBANI,QAAQ,cAAc,IAAI,SAAS;AAAA,gBAO1C;AAAA,cAEJ,CAAC;AAAA;AAAA,YAjDI;AAAA,UAkDP;AAAA,QAEJ,CAAC,GAEL;AAAA;AAAA;AAAA,EACF,GACF;AAGF,QAAM,aAAa,oBAAoB,CAAC,WACtC,gBAAAA,MAAC,SAAI,WAAU,oBACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,sBAAsB;AAAA,MACtB;AAAA;AAAA,EACF,GACF;AAIF,MAAI,UAAU;AACZ,WACE,gBAAAC,OAAAF,YAAA,EACG;AAAA,eAAS;AAAA,QACR,UAAU,iBAAiB,YAAY;AAAA,QACvC;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MAEA,iBACC,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,SAAS,MAAM,qBAAqB,KAAK;AAAA,UACzC;AAAA,UACA,iBAAiB;AAAA,UACjB,SAAS;AAAA,UACT,SAAS;AAAA;AAAA,MACX;AAAA,OAEJ;AAAA,EAEJ;AAGA,QAAM,mBAAmB,sBAAsB;AAC/C,SACE,gBAAAC,OAAC,SAAI,WAAW,kBACb;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IAGA,iBACC,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS,MAAM,qBAAqB,KAAK;AAAA,QACzC;AAAA,QACA,iBAAiB;AAAA,QACjB,SAAS;AAAA,QACT,SAAS;AAAA;AAAA,IACX;AAAA,KAEJ;AAEJ;;;AV3jBQ,SAy3BM,YAAAM,YAv3BF,OAAAC,OAFJ,QAAAC,cAAA;AAVR,IAAM,qBAAqB,CACzB,sBAC6C;AAAA,EAC7C;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,CAAC,UAAmB;AAC1B,YAAM,OAAO,OAAO,UAAU,WAAW,QAAQ;AACjD,aACE,gBAAAA,OAAC,SAAI,WAAU,2BACb;AAAA,wBAAAD,MAAC,SAAI,WAAU,qEACb,0BAAAA,MAAC,gBAAK,WAAU,0CACb,eAAK,OAAO,CAAC,EAAE,YAAY,GAC9B,GACF;AAAA,QACA,gBAAAA,MAAC,gBAAK,WAAU,qCAAqC,gBAAK;AAAA,SAC5D;AAAA,IAEJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,CAAC,UAAmB;AAC1B,YAAM,SAAS,qBAAqB,KAA8B;AAClE,aACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,OAAO,OAAO,IAAI,OAAO,SAAS;AAAA,UAE/C,iBAAO;AAAA;AAAA,MACV;AAAA,IAEJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,CAAC,UAAmB;AAC1B,UAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,eAAO,gBAAAA,MAAC,gBAAK,WAAU,yBAAwB,eAAC;AAAA,MAClD;AACA,aACE,gBAAAA,MAAC,gBAAK,WAAU,yBACb,gCAAsB,KAAK,GAC9B;AAAA,IAEJ;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,CAAC,UACP,OAAO,KAAK,IAAI,IACd,gBAAAA,MAAC,gBAAK,WAAU,yBACb,0BAAgB,OAAO,KAAK,CAAC,GAChC,IAEA,gBAAAA,MAAC,gBAAK,WAAU,yBAAwB,eAAC;AAAA,EAE/C;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,CAAC,UACP,UAAU,OACR,gBAAAA,MAAC,gBAAK,WAAU,yBAAwB,eAAC,IAEzC,gBAAAA,MAAC,gBAAK,WAAU,uCACb,iBAAO,KAAK,EAAE,QAAQ,CAAC,GAC1B;AAAA,EAEN;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,CAAC,QAAiB,QAAkC;AAC1D,UAAI,IAAI,WAAW,wBAAwB,qBAAqB;AAC9D,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,kBAAkB,IAAI,SAAS;AAAA,YAC9C,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,MAEJ;AAEA,UACE,IAAI,WAAW,wBAAwB,aACvC,IAAI,WAAW,wBAAwB,cACvC;AACA,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,kBAAkB,IAAI,SAAS;AAAA,YAC9C,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,MAEJ;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKA,IAAM,yBAAyB,CAAC,UAC9B,MAAM,IAAI,CAAC,MAAM,WAAW;AAAA,EAC1B,GAAG;AAAA,EACH,UAAU,QAAQ;AACpB,EAAE;AAMG,IAAM,kBAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA4B;AAC1B,QAAM,EAAE,SAAS,IAAI,UAAU;AAG/B,QAAM,CAAC,MAAM,OAAO,IAAIE,WAAS,CAAC;AAClC,QAAM,CAAC,OAAO,QAAQ,IAAIA,WAAS,EAAE;AACrC,QAAM,CAAC,QAAQ,SAAS,IAAIA,WAE1B,MAAS;AACX,QAAM,CAAC,WAAW,YAAY,IAAIA;AAAA,IAChC;AAAA,EACF;AAGA,QAAM,CAAC,MAAM,OAAO,IAAIA,WAAqC,IAAI;AACjE,QAAM,CAAC,gBAAgB,iBAAiB,IACtCA,WAA+C,IAAI;AAGrD,QAAM,CAAC,SAAS,UAAU,IAAIA,WAAS,IAAI;AAC3C,QAAM,CAAC,OAAO,QAAQ,IAAIA,WAAwB,IAAI;AAGtD,QAAM,CAAC,aAAa,cAAc,IAAIA,WAAS,KAAK;AACpD,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,WAAS,KAAK;AAC5D,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,WAAwB,IAAI;AAG1E,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA;AAAA,IAChD,CAAC;AAAA,EACH;AACA,QAAM,CAAC,oBAAoB,qBAAqB,IAAIA,WAAS,KAAK;AAClE,QAAM,CAAC,aAAa,cAAc,IAAIA,WAAS,KAAK;AACpD,QAAM,CAAC,wBAAwB,yBAAyB,IAAIA,WAE1D,IAAI;AAGN,QAAM,WAAW,mBAAc,CAAC,UAAU,MAAM,QAAQ;AAGxD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB,SAAS;AAIhC,QAAM,iBAAiBC,SAEb,IAAI;AACd,QAAM,eAAeA,SAA6B,IAAI;AAGtD,MAAI,aAAa,YAAY,aAAa,CAAC,eAAe,SAAS;AACjE,mBAAe,UAAU,uBAAuB,SAAS;AACzD,iBAAa,UAAU;AAAA,EACzB;AAEA,QAAM,EAAE,oBAAoB,IAAI,eAAe,QAAQ;AAMvD,EAAAC,YAAU,MAAM;AACd,yBAAqB,CAAC,CAAC;AACvB,0BAAsB,KAAK;AAC3B,mBAAe,KAAK;AACpB,8BAA0B,IAAI;AAAA,EAChC,GAAG,CAAC,UAAU,CAAC;AAKf,EAAAA,YAAU,MAAM;AACd,UAAM,WAAW,YAAY;AAC3B,UAAI,CAAC,WAAY;AAEjB,iBAAW,IAAI;AACf,eAAS,IAAI;AAEb,UAAI;AACF,cAAM,SAAS,MAAM,qBAAqB,YAAY;AAAA,UACpD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AACD,gBAAQ,MAAM;AAAA,MAChB,SAAS,KAAK;AACZ;AAAA,UACE,eAAe,QAAQ,IAAI,UAAU;AAAA,QACvC;AAAA,MACF,UAAE;AACA,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF;AAEA,aAAS;AAAA,EACX,GAAG,CAAC,YAAY,MAAM,OAAO,QAAQ,WAAW,oBAAoB,CAAC;AAKrE,QAAM,wBAAwBC;AAAA,IAC5B,OAAO,cAAsB;AAC3B,YAAM,UAAU,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,cAAc,SAAS;AACpE,UAAI,CAAC,WAAW,CAAC,WAAY;AAE7B,YAAM,aACJ,QAAQ,WAAW,wBAAwB;AAC7C,yBAAmB,UAAU;AAE7B,yBAAmB,IAAI;AACvB,UAAI;AACF,cAAM,cAAc,MAAM,uBAAuB,YAAY,SAAS;AAEtE,cAAM,aAAa;AAAA,UACjB;AAAA,UACA;AAAA,UACA,QAAQ,eAAe;AAAA,QACzB;AACA,0BAAkB,UAAU;AAC5B,uBAAe,IAAI;AAAA,MACrB,SAAS,KAAK;AACZ,gBAAQ,MAAM,uCAAuC,GAAG;AACxD;AAAA,UACE,eAAe,QACX,IAAI,UACJ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,MAAM,UAAU,YAAY,sBAAsB;AAAA,EACrD;AAKA,QAAM,mBAAmBA,aAAY,MAAM;AACzC,mBAAe,KAAK;AAAA,EACtB,GAAG,CAAC,CAAC;AAQL,QAAM,0BAA0BA;AAAA,IAC9B,OAAO,WAAmB,aAAqB,UAAkB;AAC/D,UAAI,CAAC,cAAc,CAAC,UAAW;AAC/B,UAAI;AACF,cAAM,OAAO,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI;AAC3C,cAAM,kBAAkB,YAAY,WAAW,aAAa,IAAI;AAAA,MAClE,SAAS,KAAK;AACZ,gBAAQ,MAAM,iCAAiC,GAAG;AAAA,MACpD;AAAA,IACF;AAAA,IACA,CAAC,YAAY,iBAAiB;AAAA,EAChC;AAOA,QAAM,iCAAiCA;AAAA,IACrC,OAAO,WAAmB,YAA2C;AACnE,UAAI,CAAC,cAAc,CAAC,UAAW;AAC/B,UAAI;AACF,cAAM,yBAAyB,YAAY,WAAW,OAAO;AAAA,MAC/D,SAAS,KAAK;AACZ,gBAAQ,MAAM,yCAAyC,GAAG;AAC1D,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,YAAY,wBAAwB;AAAA,EACvC;AAKA,QAAM,YAAwCC,SAAQ,MAAM;AAC1D,QAAI,CAAC,MAAM,SAAU,QAAO,CAAC;AAE7B,WAAO,KAAK,SAAS,IAAI,CAAC,aAAa;AAAA,MACrC,IAAI,QAAQ;AAAA,MACZ,WAAW,QAAQ;AAAA,MACnB,aAAa,QAAQ;AAAA,MACrB,QAAQ,QAAQ;AAAA,MAChB,YAAY,QAAQ;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB,OAAO,QAAQ;AAAA,IACjB,EAAE;AAAA,EACJ,GAAG,CAAC,MAAM,QAAQ,CAAC;AAKnB,QAAM,UAAUA;AAAA,IACd,MAAM,mBAAmB,qBAAqB;AAAA,IAC9C,CAAC,qBAAqB;AAAA,EACxB;AAKA,QAAM,0BAA0B,CAAC,WAAwB;AACvD,QAAI,OAAO,KAAM,SAAQ,OAAO,IAAI;AACpC,QAAI,OAAO,MAAO,UAAS,OAAO,KAAK;AACvC,QAAI,OAAO,WAAW,QAAW;AAE/B,YAAM,YAA6D;AAAA,QACjE,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,OAAO;AAAA,MACT;AACA,gBAAU,OAAO,SAAS,UAAU,OAAO,MAAM,IAAI,MAAS;AAAA,IAChE;AACA,QAAI,OAAO,cAAc,QAAW;AAClC,mBAAa,OAAO,SAAuC;AAAA,IAC7D;AAAA,EACF;AAEA,QAAM,mBAAmBA;AAAA,IACvB,MAAM,uBAAuB,iBAAiB;AAAA,IAC9C,CAAC,iBAAiB;AAAA,EACpB;AAKA,QAAM,EAAE,YAAY,YAAY,IAAI,qBAAqB,gBAAgB;AAMzE,QAAM,+BAA+BD;AAAA,IACnC,OACE,aASwB;AACxB,UAAI,CAAC,UAAU,MAAM,MAAM;AACzB,eAAO,CAAC;AAAA,MACV;AAEA,UAAI,SAAS,KAAK,KAAK,WAAW;AAChC,eAAO,SAAS,KAAK,KAAK;AAAA,MAC5B;AAEA,UAAI,SAAS,KAAK,KAAK,aAAa;AAClC,eAAO,MAAM,oBAAoB,SAAS,KAAK,KAAK,WAAW;AAAA,MACjE;AAEA,aAAO,CAAC;AAAA,IACV;AAAA,IACA,CAAC,mBAAmB;AAAA,EACtB;AAKA,QAAM,uBAAuBA,aAAY,YAAY;AACnD,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,IAE9B,eAAe,UAAU,OAAO;AACnC,aAAO,EAAE,UAAU,OAAO,OAAU;AAAA,IACtC,SAAS,KAAK;AACZ,YAAME,SAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAChE,aAAO,EAAE,UAAU,QAAW,OAAAA,OAAM;AAAA,IACtC;AAAA,EACF,GAAG,CAAC,YAAY,SAAS,CAAC;AAK1B,QAAM,2BAA2BF,aAAY,YAAY;AACvD,QAAI;AACF,YAAM,WAAW,MAAM,UAAU,IAE9B,eAAe,UAAU,EAAE;AAC9B,aAAO,EAAE,UAAU,OAAO,OAAU;AAAA,IACtC,SAAS,KAAK;AACZ,YAAME,SAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAChE,aAAO,EAAE,UAAU,QAAW,OAAAA,OAAM;AAAA,IACtC;AAAA,EACF,GAAG,CAAC,YAAY,SAAS,CAAC;AAM1B,QAAM,8BAA8BF,aAAY,YAE3C;AAEH,UAAM,EAAE,UAAU,cAAc,OAAO,UAAU,IAC/C,MAAM,qBAAqB;AAC7B,QAAI,YAAY,MAAM,6BAA6B,YAAY;AAG/D,QAAI,UAAU,WAAW,GAAG;AAC1B,YAAM,EAAE,UAAU,kBAAkB,OAAO,cAAc,IACvD,MAAM,yBAAyB;AAGjC,UAAI,CAAC,gBAAgB,CAAC,kBAAkB;AACtC,cAAM,eACJ,WAAW,WACX,eAAe,WACf;AACF,cAAM,IAAI,MAAM,YAAY;AAAA,MAC9B;AAEA,kBAAY,MAAM,6BAA6B,gBAAgB;AAAA,IACjE;AAEA,WAAO;AAAA,EACT,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAKD,QAAM,4BAA4BA;AAAA,IAChC,CAAC,iBAAyB;AACxB,cAAQ,MAAM,4CAAyC,YAAY;AACnE,2BAAqB,CAAC,CAAC;AACvB,gCAA0B,YAAY;AACtC,eAAS;AAAA,QACP,OAAO;AAAA,QACP,aAAa;AAAA,QACb,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAMA,QAAM,yBAAyBA,aAAY,YAA8B;AACvE,QAAI,CAAC,WAAY,QAAO;AAExB,0BAAsB,IAAI;AAC1B,8BAA0B,IAAI;AAC9B,QAAI;AACF,YAAM,YAAY,MAAM,4BAA4B;AAGpD,YAAM,mBAAmB,UAAU;AAAA,QAAI,CAAC,MACtC,yBAAyB,CAAC;AAAA,MAC5B;AACA,2BAAqB,gBAAgB;AACrC,gCAA0B,IAAI;AAG9B,UAAI,iBAAiB,WAAW,GAAG;AACjC,iBAAS;AAAA,UACP,OAAO;AAAA,UACP,aAAa;AAAA,UACb,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAEA,aAAO,iBAAiB,SAAS;AAAA,IACnC,SAAS,KAAK;AACZ,YAAM,eACJ,eAAe,QACX,IAAI,UACJ;AACN,gCAA0B,YAAY;AACtC,aAAO;AAAA,IACT,UAAE;AACA,4BAAsB,KAAK;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,6BAA6B,2BAA2B,QAAQ,CAAC;AAKrE,QAAM,oBAAoBA,aAAY,YAAY;AAChD,QAAI;AAEF,UAAI,kBAAkB,WAAW,GAAG;AAClC,cAAM,UAAU,MAAM,uBAAuB;AAE7C,uBAAe,OAAO;AAAA,MACxB,WAAW,kBAAkB,SAAS,GAAG;AACvC,uBAAe,IAAI;AAAA,MACrB,OAAO;AACL,uBAAe,KAAK;AAAA,MACtB;AAAA,IACF,QAAQ;AAEN,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,kBAAkB,QAAQ,sBAAsB,CAAC;AAMrD,EAAAD,YAAU,MAAM;AACd,QAAI,CAAC,aAAa;AAChB;AAAA,IACF;AAGA,QAAI,kBAAkB,WAAW,GAAG;AAClC,qBAAe,KAAK;AACpB;AAAA,IACF;AAGA,QACE,WAAW,WACX,eACA,OAAO,gBAAgB,YACvB;AACA,kBAAY;AACZ,qBAAe,KAAK;AACpB;AAAA,IACF;AAIA,mBAAe,KAAK;AAAA,EACtB,GAAG,CAAC,aAAa,kBAAkB,QAAQ,YAAY,WAAW,CAAC;AAKnE,QAAM,aAAa,MAAM;AACvB,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAKA,QAAM,cACJ,MAAM,UAAU,eAAe,uBAC3B,qBAAqB,KAAK,SAAS,WAAW,IAC9C;AACN,QAAM,cAAkC,cACpC,eAAe,WAAW,IAC1B;AAGJ,MAAI,WAAW,CAAC,MAAM;AACpB,WACE,gBAAAJ,MAAC,SAAI,WAAU,yFACb,0BAAAC,OAAC,SAAI,WAAU,mFAEb;AAAA,sBAAAD,MAAC,SAAI,WAAU,gCACb,0BAAAA,MAAC,gBAAa,OAAO,KAAK,QAAQ,IAAI,GACxC;AAAA,MAGA,gBAAAA,MAAC,mBAAgB,WAAU,oBAAmB;AAAA,MAG9C,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,WAAW,gBAAgB;AAAA,UAC7B;AAAA,UAEC;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,EAAE,IAAI,CAAC,OACL,gBAAAA,MAAC,mBAAyB,WAAU,sBAAd,EAAiC,CACxD;AAAA;AAAA,MACH;AAAA,MAGA,gBAAAA,MAAC,SAAI,WAAU,uCACb,0BAAAA,MAAC,iBAAc,MAAM,GAAG,SAAS,GAAG,YAAU,MAAC,GACjD;AAAA,OACF,GACF;AAAA,EAEJ;AAGA,MAAI,SAAS,CAAC,MAAM;AAClB,WACE,gBAAAA,MAAC,SAAI,WAAU,yEACb,0BAAAA,MAAC,SAAI,WAAU,6EACb,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,OAAM;AAAA,QACN,aACE,SAAS;AAAA;AAAA,IAEb,GACF,GACF;AAAA,EAEJ;AAEA,SACE,gBAAAC,OAAC,SAAI,WAAU,yFAEb;AAAA,oBAAAA,OAAC,SAAI,WAAU,mFAEb;AAAA,sBAAAA,OAAC,SAAI,WAAU,gCACb;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,QACA,gBAAAA,MAACQ,aAAA,EAAW,MAAM,IAAI,WAAU,iBAAgB;AAAA,QAChD,gBAAAR,MAAC,gBAAK,WAAU,mCACb,eAAK,UAAU,SAAS,aAC3B;AAAA,SACF;AAAA,MAGC,KAAK,YACJ,gBAAAA,MAAC,SAAI,WAAU,oDACb,0BAAAC,OAAC,SAAI,WAAU,oCACb;AAAA,wBAAAA,OAAC,SAAI,WAAU,uBACb;AAAA,0BAAAD,MAAC,gBAAK,WAAU,oCACb,eAAK,SAAS,OACjB;AAAA,UACA,gBAAAC,OAAC,SAAI,WAAU,qCACb;AAAA,4BAAAA,OAAC,gBAAK,WAAU,yBAAwB;AAAA;AAAA,cAC/B;AAAA,cACN,KAAK,SAAS,YACX,sBAAsB,KAAK,SAAS,SAAS,IAC7C;AAAA,eACN;AAAA,YACA,gBAAAD,MAAC,UAAK,WAAU,oCAAmC;AAAA,YACnD,gBAAAC,OAAC,gBAAK,WAAU,yBAAwB;AAAA;AAAA,cAC1B;AAAA,cACX,KAAK,SAAS,YACX,sBAAsB,KAAK,SAAS,SAAS,IAC7C;AAAA,eACN;AAAA,YACA,gBAAAD,MAAC,UAAK,WAAU,oCAAmC;AAAA,YACnD,gBAAAA,MAAC,gBAAK,WAAU,yBACb,eAAK,SAAS,YACjB;AAAA,YACA,gBAAAA,MAAC,UAAK,WAAU,oCAAmC;AAAA,YACnD,gBAAAA,MAAC,gBAAK,WAAU,yBACb,eAAK,SAAS,MACjB;AAAA,YACA,gBAAAA,MAAC,UAAK,WAAU,oCAAmC;AAAA,YAClD,cACC,gBAAAC,OAAC,SAAI,WAAU,2BACb;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW;AAAA,oBACT;AAAA,oBACA,YAAY;AAAA,kBACd;AAAA,kBAEC,sBAAY;AAAA;AAAA,cACf;AAAA,cACA,gBAAAA,MAAC,gBAAK,WAAU,yBACb,eAAK,SAAS,aACjB;AAAA,eACF,IAEA,gBAAAA,MAAC,gBAAK,WAAU,yBACb,eAAK,SAAS,aACjB;AAAA,YAEF,gBAAAA,MAAC,UAAK,WAAU,oCAAmC;AAAA,YACnD,gBAAAA,MAAC,gBAAK,WAAU,yBACb,eAAK,SAAS,WACjB;AAAA,aACF;AAAA,WACF;AAAA,QACA,gBAAAC,OAAC,SAAI,WAAU,iCACb;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS;AAAA,cACT,UAAU;AAAA,cACV,UAAU,gBAAAA,MAAC,kBAAe,MAAM,IAAI;AAAA,cACpC,WAAU;AAAA,cAET,+BAAqB,kBAAkB;AAAA;AAAA,UAC1C;AAAA,UACC,0BACC,gBAAAC,OAAC,SAAI,WAAU,yCACb;AAAA,4BAAAD;AAAA,cAACS;AAAA,cAAA;AAAA,gBACC,MAAM;AAAA,gBACN,WAAU;AAAA,gBACV,QAAO;AAAA;AAAA,YACT;AAAA,YACA,gBAAAT,MAAC,gBAAK,WAAU,0BACb,kCACH;AAAA,aACF;AAAA,WAEJ;AAAA,SACF,GACF;AAAA,MAIF,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,cAAc,WAAW,gBAAgB,aAAa;AAAA,UAGpE;AAAA,4BAAAD,MAAC,SAAI,WAAU,8GACb,0BAAAC,OAAC,SAAI,WAAU,8BACb;AAAA,8BAAAA,OAAC,SAAI,WAAU,sCACb;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,IAAG;AAAA,oBACH,IAAG;AAAA,oBACH,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,MAAK;AAAA;AAAA,gBACP;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,IAAG;AAAA,oBACH,IAAG;AAAA,oBACH,GAAE;AAAA,oBACF,QAAO;AAAA,oBACP,aAAY;AAAA,oBACZ,MAAK;AAAA,oBACL,iBAAiB,GAAI,KAAK,aAAa,uBAAuB,MAAO,KAAK;AAAA,oBAC1E,eAAc;AAAA;AAAA,gBAChB;AAAA,iBACF;AAAA,cACA,gBAAAC,OAAC,SAAI,WAAU,8DACb;AAAA,gCAAAA,OAAC,gBAAK,WAAU,wCACb;AAAA,uBAAK,MAAM,KAAK,aAAa,oBAAoB;AAAA,kBAAE;AAAA,mBACtD;AAAA,gBACA,gBAAAD,MAAC,gBAAK,WAAU,8CAA6C,0BAE7D;AAAA,iBACF;AAAA,eACF,GACF;AAAA,YAGA,gBAAAC,OAAC,SAAI,WAAU,sHACb;AAAA,8BAAAD,MAAC,SAAI,WAAU,iFACb,0BAAAA,MAACU,OAAA,EAAK,MAAM,IAAI,WAAU,cAAa,QAAO,WAAU,GAC1D;AAAA,cACA,gBAAAV,MAAC,gBAAK,WAAU,6DAA4D,+BAE5E;AAAA,cACA,gBAAAA,MAAC,gBAAK,WAAU,sCACb,eAAK,aAAa,aAAa,QAAQ,CAAC,GAC3C;AAAA,eACF;AAAA,YAGA,gBAAAC,OAAC,SAAI,WAAU,+GACb;AAAA,8BAAAD,MAAC,SAAI,WAAU,wFACb,0BAAAA,MAACW,QAAA,EAAM,MAAM,IAAI,WAAU,iBAAgB,QAAO,WAAU,GAC9D;AAAA,cACA,gBAAAX,MAAC,gBAAK,WAAU,6DAA4D,0CAE5E;AAAA,cACA,gBAAAA,MAAC,gBAAK,WAAU,sCACb,gCAAsB,KAAK,cAAc,WAAW,GACvD;AAAA,eACF;AAAA,YAGA,gBAAAC,OAAC,SAAI,WAAU,6GACb;AAAA,8BAAAD,MAAC,SAAI,WAAU,wFACb,0BAAAA;AAAA,gBAACS;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN,WAAU;AAAA,kBACV,QAAO;AAAA;AAAA,cACT,GACF;AAAA,cACA,gBAAAT,MAAC,gBAAK,WAAU,2DAA0D,wCAE1E;AAAA,cACA,gBAAAA,MAAC,gBAAK,WAAU,oCACb,gCAAsB,KAAK,cAAc,aAAa,GACzD;AAAA,eACF;AAAA,YAGA,gBAAAC,OAAC,SAAI,WAAU,mHACb;AAAA,8BAAAD,MAAC,SAAI,WAAU,8EACb,0BAAAA;AAAA,gBAACS;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN,WAAU;AAAA,kBACV,QAAO;AAAA;AAAA,cACT,GACF;AAAA,cACA,gBAAAT,MAAC,gBAAK,WAAU,0DAAyD,4CAEzE;AAAA,cACA,gBAAAA,MAAC,gBAAK,WAAU,mCACb,gCAAsB,KAAK,cAAc,WAAW,GACvD;AAAA,eACF;AAAA;AAAA;AAAA,MACF;AAAA,MAGC,mBACC,gBAAAC,OAAC,SAAI,WAAU,qFACb;AAAA,wBAAAD,MAACS,gBAAA,EAAc,MAAM,IAAI,WAAU,kBAAiB,QAAO,QAAO;AAAA,QAClE,gBAAAT,MAAC,gBAAK,WAAU,0BAA0B,2BAAgB;AAAA,SAC5D;AAAA,MAIF,gBAAAA,MAAC,SAAI,WAAU,iDACb,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,UACT,SAAQ;AAAA,UACR,iBAAe;AAAA,UACf,kBAAgB;AAAA,UAChB,kBAAkB;AAAA,YAChB,WAAW;AAAA,YACX,qBAAqB,CAAC,IAAI,IAAI,EAAE;AAAA,YAChC,qBAAqB;AAAA,YACrB,YAAY,KAAK,WAAW;AAAA,YAC5B,YAAY,KAAK,WAAW;AAAA,UAC9B;AAAA,UACA,YAAY;AAAA,YACV,WACE,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,OAAM;AAAA,gBACN,aAAY;AAAA;AAAA,YACd;AAAA,UAEJ;AAAA,UACA,gBAAgB;AAAA,UAEf,WAAC,EAAE,OAAO,WAAW,MACpB,gBAAAC,OAAAF,YAAA,EACG;AAAA;AAAA,YACA;AAAA,aACH;AAAA;AAAA,MAEJ,GACF;AAAA,OACF;AAAA,IAGA,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,qBAAqB;AAAA,QACrB,4BAA4B;AAAA;AAAA,IAC9B;AAAA,IAGA,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,OAAO,GAC5B,0BAAAA,MAAC,uBAAoB,KAAK,YAAY,WAAW,kBAAkB,GACrE;AAAA,KACF;AAEJ;AAEA,IAAO,0BAAQ;","names":["useState","useMemo","useCallback","useEffect","useRef","Medal","Star","CaretRight","WarningCircle","QUESTION_TYPE","answer","jsx","jsx","jsxs","VARIANT_ACTION_CLASSES","SIZE_CLASSES","jsx","jsxs","jsx","jsxs","_","useState","useEffect","useMemo","useCallback","forwardRef","CaretDown","jsx","jsxs","jsx","jsxs","jsx","jsxs","forwardRef","CaretDown","useEffect","useState","useMemo","X","forwardRef","useState","useId","useMemo","useEffect","useRef","CaretRight","forwardRef","useEffect","isValidElement","Children","useState","create","useEffect","jsx","jsxs","SIZE_CLASSES","useEffect","useState","useEffect","forwardRef","jsx","jsxs","forwardRef","useEffect","create","devtools","useEffect","jsx","useState","useEffect","jsx","jsxs","create","Children","isValidElement","useEffect","forwardRef","useState","CaretRight","jsx","jsxs","forwardRef","useState","useRef","useMemo","useEffect","useId","disabled","readOnly","X","useEffect","useMemo","useRef","useState","Element","Fragment","jsx","jsxs","Element","forwardRef","useState","useId","jsx","jsxs","SIZE_CLASSES","forwardRef","useId","useState","forwardRef","useId","useEffect","useRef","Children","cloneElement","isValidElement","create","useStore","jsx","create","injectStore","Children","isValidElement","cloneElement","forwardRef","useId","useRef","useStore","useEffect","forwardRef","useState","useId","jsx","jsxs","SIZE_CLASSES","STATE_CLASSES","forwardRef","useId","useState","jsx","forwardRef","useState","useId","useEffect","useRef","Children","cloneElement","isValidElement","create","useStore","jsx","jsxs","SIZE_CLASSES","STATE_CLASSES","forwardRef","useId","useRef","useState","create","injectStore","Children","isValidElement","cloneElement","useStore","useEffect","create","Fragment","jsx","jsxs","SIZE_CLASSES","useState","useRef","useEffect","useCallback","Paperclip","X","WarningCircle","forwardRef","useId","useState","useEffect","forwardRef","Fragment","useState","useRef","useEffect","CaretRight","cloneElement","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","cloneElement","Fragment","jsx","jsxs","forwardRef","CaretRight","status","useState","useRef","useEffect","CaretRight","jsx","jsxs","forwardRef","useState","useId","useEffect","CaretRight","Children","cloneElement","forwardRef","isValidElement","useEffect","useRef","useState","create","jsx","injectStore","useRef","X","jsx","jsxs","CheckCircle","XCircle","forwardRef","useId","useState","jsx","jsxs","useId","useState","getStatusStyles","isReadonly","getStatusBadge","CheckCircle","XCircle","value","forwardRef","jsx","useEffect","useState","CheckCircle","XCircle","Check","jsx","jsxs","useState","useEffect","getStatusBadge","CheckCircle","XCircle","getStatusStyles","Check","jsx","forwardRef","useCallback","useEffect","useId","useMemo","useRef","useState","CheckCircle","XCircle","Fragment","jsx","jsxs","forwardRef","jsx","useId","CheckCircle","XCircle","jsx","jsxs","CheckCircle","XCircle","useId","jsx","jsxs","jsx","jsxs","jsx","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","WarningCircle","useState","useRef","useEffect","useCallback","Paperclip","X","useState","useEffect","jsx","jsx","jsx","jsx","useState","useCallback","forwardRef","useRef","useCallback","Fragment","jsx","jsxs","forwardRef","useRef","useCallback","useCallback","key","jsx","jsxs","useState","useRef","useEffect","useMemo","formattedItemsMap","getBadgeText","isCategoryEnabled","handleAccordionValueChange","jsx","jsxs","Fragment","jsx","jsxs","useState","useMemo","useEffect","useCallback","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useMemo","error","CaretRight","WarningCircle","Star","Medal"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ActivityDetails/ActivityDetails.tsx","../../src/utils/utils.ts","../../src/components/Quiz/useQuizStore.ts","../../src/types/activityDetails.ts","../../src/utils/activityDetailsUtils.ts","../../src/components/Text/Text.tsx","../../src/components/Button/Button.tsx","../../src/components/Badge/Badge.tsx","../../src/components/EmptyState/EmptyState.tsx","../../src/components/Skeleton/Skeleton.tsx","../../src/components/TableProvider/TableProvider.tsx","../../src/components/Table/Table.tsx","../../src/components/NoSearchResult/NoSearchResult.tsx","../../src/components/Table/TablePagination.tsx","../../src/components/Filter/useTableFilter.ts","../../src/components/Search/Search.tsx","../../src/components/DropdownMenu/DropdownMenu.tsx","../../src/components/Modal/Modal.tsx","../../src/components/Modal/utils/videoUtils.ts","../../src/components/ThemeToggle/ThemeToggle.tsx","../../src/components/SelectionButton/SelectionButton.tsx","../../src/hooks/useTheme.ts","../../src/store/themeStore.ts","../../src/components/CheckBoxGroup/CheckBoxGroup.tsx","../../src/components/LatexRenderer/LatexRenderer.tsx","../../src/components/CheckBox/CheckBox.tsx","../../src/components/CheckBox/CheckboxList.tsx","../../src/components/TextArea/TextArea.tsx","../../src/components/Divider/Divider.tsx","../../src/components/Radio/Radio.tsx","../../src/components/Toast/utils/ToastStore.ts","../../src/components/ProgressBar/ProgressBar.tsx","../../src/components/CorrectActivityModal/CorrectActivityModal.tsx","../../src/components/Accordation/Accordation.tsx","../../src/components/Card/Card.tsx","../../src/components/IconRender/IconRender.tsx","../../src/assets/icons/subjects/ChatPT.tsx","../../src/assets/icons/subjects/ChatEN.tsx","../../src/assets/icons/subjects/ChatES.tsx","../../src/components/Accordation/AccordionGroup.tsx","../../src/components/FileAttachment/FileAttachment.tsx","../../src/utils/studentActivityCorrection/constants.ts","../../src/utils/studentActivityCorrection/utils.ts","../../src/utils/studentActivityCorrection/converter.ts","../../src/components/Alternative/Alternative.tsx","../../src/utils/questionRenderer/alternative/index.tsx","../../src/components/MultipleChoice/MultipleChoice.tsx","../../src/utils/questionRenderer/multipleChoice/index.tsx","../../src/components/Quiz/QuizContent.tsx","../../src/utils/questionRenderer/components/index.tsx","../../src/utils/questionRenderer/trueOrFalse/index.tsx","../../src/utils/questionRenderer/dissertative/index.tsx","../../src/utils/questionRenderer/fill/index.tsx","../../src/utils/questionRenderer/image/index.tsx","../../src/utils/questionRenderer/connectDots/index.tsx","../../src/utils/questionRenderer/index.tsx","../../src/hooks/useMobile.ts","../../src/assets/icons/subjects/BookOpenText.tsx","../../src/assets/icons/subjects/HeadCircuit.tsx","../../src/assets/icons/subjects/Microscope.tsx","../../src/components/SubjectInfo/SubjectInfo.tsx","../../src/hooks/useQuestionsList.ts","../../src/components/ActivityCreate/ActivityCreate.utils.ts","../../src/components/QuestionsPdfGenerator/QuestionsPdfGenerator.tsx","../../src/hooks/useActivityDetails.ts","../../src/components/CheckBoxGroup/CheckBoxGroup.helpers.ts","../../src/components/Filter/FilterModal.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect, useRef } from 'react';\nimport {\n Medal,\n Star,\n CaretRight,\n WarningCircle,\n DownloadSimple,\n} from 'phosphor-react';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Badge from '../Badge/Badge';\nimport EmptyState from '../EmptyState/EmptyState';\nimport {\n SkeletonText,\n SkeletonRounded,\n SkeletonTable,\n} from '../Skeleton/Skeleton';\nimport { TableProvider } from '../TableProvider/TableProvider';\nimport CorrectActivityModal from '../CorrectActivityModal/CorrectActivityModal';\nimport { getSubjectInfo, type SubjectData } from '../SubjectInfo/SubjectInfo';\nimport { useMobile } from '../../hooks/useMobile';\nimport { cn } from '../../utils/utils';\nimport { SubjectEnum } from '../../enums/SubjectEnum';\nimport type { ColumnConfig, TableParams } from '../TableProvider/TableProvider';\nimport type {\n StudentActivityCorrectionData,\n SaveQuestionCorrectionPayload,\n} from '../../utils/studentActivityCorrection';\nimport { convertApiResponseToCorrectionData } from '../../utils/studentActivityCorrection';\nimport {\n STUDENT_ACTIVITY_STATUS,\n type ActivityDetailsData,\n type ActivityStudentTableItem,\n type StudentActivityStatus,\n} from '../../types/activityDetails';\nimport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from '../../utils/activityDetailsUtils';\nimport type { BaseApiClient } from '../../types/api';\nimport { useActivityDetails } from '../../hooks/useActivityDetails';\nimport {\n useQuestionsPdfPrint,\n QuestionsPdfContent,\n} from '../QuestionsPdfGenerator';\nimport type { PreviewQuestion } from '../ActivityPreview/ActivityPreview';\nimport { convertQuestionToPreview } from '../ActivityCreate/ActivityCreate.utils';\nimport type { Question } from '../../types/questions';\nimport { createUseQuestionsList } from '../../hooks/useQuestionsList';\nimport useToastStore from '../Toast/utils/ToastStore';\n\n/**\n * Props for the ActivityDetails component\n */\nexport interface ActivityDetailsProps {\n /** Activity ID to display details for */\n activityId: string;\n /** API client instance for making requests */\n apiClient: BaseApiClient;\n /** Callback when back button is clicked */\n onBack?: () => void;\n /** Image for empty state */\n emptyStateImage?: string;\n /** Function to map subject name to SubjectEnum */\n mapSubjectNameToEnum?: (subjectName: string) => SubjectEnum | null;\n}\n\n/**\n * Create table columns configuration\n * @param onCorrectActivity - Callback for correction action\n * @returns Column configuration array\n */\nconst createTableColumns = (\n onCorrectActivity: (studentId: string) => void\n): ColumnConfig<ActivityStudentTableItem>[] => [\n {\n key: 'studentName',\n label: 'Aluno',\n sortable: true,\n render: (value: unknown) => {\n const name = typeof value === 'string' ? value : '';\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"w-6 h-6 bg-blue-100 rounded-full flex items-center justify-center\">\n <Text className=\"text-xs font-semibold text-primary-700\">\n {name.charAt(0).toUpperCase()}\n </Text>\n </div>\n <Text className=\"text-sm font-normal text-text-950\">{name}</Text>\n </div>\n );\n },\n },\n {\n key: 'status',\n label: 'Status',\n sortable: false,\n render: (value: unknown) => {\n const config = getStatusBadgeConfig(value as StudentActivityStatus);\n return (\n <Badge\n className={`${config.bgColor} ${config.textColor} text-xs px-2 py-1`}\n >\n {config.label}\n </Badge>\n );\n },\n },\n {\n key: 'answeredAt',\n label: 'Respondido em',\n sortable: true,\n render: (value: unknown) => {\n if (!value || typeof value !== 'string') {\n return <Text className=\"text-sm text-text-400\">-</Text>;\n }\n return (\n <Text className=\"text-sm text-text-700\">\n {formatDateToBrazilian(value)}\n </Text>\n );\n },\n },\n {\n key: 'timeSpent',\n label: 'Duração',\n sortable: false,\n render: (value: unknown) =>\n Number(value) > 0 ? (\n <Text className=\"text-sm text-text-700\">\n {formatTimeSpent(Number(value))}\n </Text>\n ) : (\n <Text className=\"text-sm text-text-400\">-</Text>\n ),\n },\n {\n key: 'score',\n label: 'Nota',\n sortable: true,\n render: (value: unknown) =>\n value === null ? (\n <Text className=\"text-sm text-text-400\">-</Text>\n ) : (\n <Text className=\"text-sm font-semibold text-text-950\">\n {Number(value).toFixed(1)}\n </Text>\n ),\n },\n {\n key: 'actions',\n label: 'Resultado',\n sortable: false,\n render: (_value: unknown, row: ActivityStudentTableItem) => {\n if (row.status === STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO) {\n return (\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={() => onCorrectActivity(row.studentId)}\n className=\"text-xs\"\n >\n Corrigir atividade\n </Button>\n );\n }\n\n if (\n row.status === STUDENT_ACTIVITY_STATUS.CONCLUIDO ||\n row.status === STUDENT_ACTIVITY_STATUS.NAO_ENTREGUE\n ) {\n return (\n <Button\n variant=\"link\"\n size=\"small\"\n onClick={() => onCorrectActivity(row.studentId)}\n className=\"text-xs\"\n >\n Ver detalhes\n </Button>\n );\n }\n\n return null;\n },\n },\n];\n\n/**\n * Normalize questions with positions\n */\nconst normalizeWithPositions = (items: PreviewQuestion[]) =>\n items.map((item, index) => ({\n ...item,\n position: index + 1,\n }));\n\n/**\n * ActivityDetails component\n * Displays detailed information about an activity including statistics and student progress\n */\nexport const ActivityDetails = ({\n activityId,\n apiClient,\n onBack,\n emptyStateImage,\n mapSubjectNameToEnum,\n}: ActivityDetailsProps) => {\n const { isMobile } = useMobile();\n\n // Pagination and sorting state\n const [page, setPage] = useState(1);\n const [limit, setLimit] = useState(10);\n const [sortBy, setSortBy] = useState<\n 'name' | 'score' | 'answeredAt' | undefined\n >(undefined);\n const [sortOrder, setSortOrder] = useState<'asc' | 'desc' | undefined>(\n undefined\n );\n\n // Data state\n const [data, setData] = useState<ActivityDetailsData | null>(null);\n const [correctionData, setCorrectionData] =\n useState<StudentActivityCorrectionData | null>(null);\n\n // Loading/Error state\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Modal state\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [isViewOnlyModal, setIsViewOnlyModal] = useState(false);\n const [correctionError, setCorrectionError] = useState<string | null>(null);\n\n // PDF download state\n const [activityQuestions, setActivityQuestions] = useState<PreviewQuestion[]>(\n []\n );\n const [isLoadingQuestions, setIsLoadingQuestions] = useState(false);\n const [shouldPrint, setShouldPrint] = useState(false);\n const [activityQuestionsError, setActivityQuestionsError] = useState<\n string | null\n >(null);\n\n // Toast store for notifications\n const addToast = useToastStore((state) => state.addToast);\n\n // Use activity details hook\n const {\n fetchActivityDetails,\n fetchStudentCorrection,\n submitObservation,\n submitQuestionCorrection,\n } = useActivityDetails(apiClient);\n\n // Use questions list hook for fetching questions by IDs\n // Store hook factory in ref to preserve identity across renders\n const hookFactoryRef = useRef<ReturnType<\n typeof createUseQuestionsList\n > | null>(null);\n const apiClientRef = useRef<BaseApiClient | null>(null);\n\n // Create hook factory only when apiClient changes\n if (apiClientRef.current !== apiClient || !hookFactoryRef.current) {\n hookFactoryRef.current = createUseQuestionsList(apiClient);\n apiClientRef.current = apiClient;\n }\n\n const { fetchQuestionsByIds } = hookFactoryRef.current();\n\n /**\n * Reset PDF/question state when activityId changes\n * Prevents printing stale data when navigating between activities\n */\n useEffect(() => {\n setActivityQuestions([]);\n setIsLoadingQuestions(false);\n setShouldPrint(false);\n setActivityQuestionsError(null);\n }, [activityId]);\n\n /**\n * Fetch activity details when params change\n */\n useEffect(() => {\n const loadData = async () => {\n if (!activityId) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await fetchActivityDetails(activityId, {\n page,\n limit,\n sortBy,\n sortOrder,\n });\n setData(result);\n } catch (err) {\n setError(\n err instanceof Error ? err.message : 'Erro ao carregar detalhes'\n );\n } finally {\n setLoading(false);\n }\n };\n\n loadData();\n }, [activityId, page, limit, sortBy, sortOrder, fetchActivityDetails]);\n\n /**\n * Handle correct activity button click\n */\n const handleCorrectActivity = useCallback(\n async (studentId: string) => {\n const student = data?.students.find((s) => s.studentId === studentId);\n if (!student || !activityId) return;\n\n const isViewOnly =\n student.status !== STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO;\n setIsViewOnlyModal(isViewOnly);\n\n setCorrectionError(null);\n try {\n const apiResponse = await fetchStudentCorrection(activityId, studentId);\n // Convert API response to StudentActivityCorrectionData format\n const correction = convertApiResponseToCorrectionData(\n apiResponse,\n studentId,\n student.studentName || 'Aluno'\n );\n setCorrectionData(correction);\n setIsModalOpen(true);\n } catch (err) {\n console.error('Failed to fetch student correction:', err);\n setCorrectionError(\n err instanceof Error\n ? err.message\n : 'Erro ao carregar dados de correção'\n );\n }\n },\n [data?.students, activityId, fetchStudentCorrection]\n );\n\n /**\n * Handle modal close\n */\n const handleCloseModal = useCallback(() => {\n setIsModalOpen(false);\n }, []);\n\n /**\n * Handle observation submit\n * @param studentId - Student ID from modal (passed explicitly to avoid stale closure)\n * @param observation - Observation text\n * @param files - Attached files (only first file is used)\n */\n const handleObservationSubmit = useCallback(\n async (studentId: string, observation: string, files: File[]) => {\n if (!activityId || !studentId) return;\n try {\n const file = files.length > 0 ? files[0] : null;\n await submitObservation(activityId, studentId, observation, file);\n } catch (err) {\n console.error('Failed to submit observation:', err);\n }\n },\n [activityId, submitObservation]\n );\n\n /**\n * Handle question correction submit\n * @param studentId - Student ID from modal\n * @param payload - Question correction payload\n */\n const handleQuestionCorrectionSubmit = useCallback(\n async (studentId: string, payload: SaveQuestionCorrectionPayload) => {\n if (!activityId || !studentId) return;\n try {\n await submitQuestionCorrection(activityId, studentId, payload);\n } catch (err) {\n console.error('Failed to submit question correction:', err);\n throw err;\n }\n },\n [activityId, submitQuestionCorrection]\n );\n\n /**\n * Convert student data to table format\n */\n const tableData: ActivityStudentTableItem[] = useMemo(() => {\n if (!data?.students) return [];\n\n return data.students.map((student) => ({\n id: student.studentId,\n studentId: student.studentId,\n studentName: student.studentName,\n status: student.status,\n answeredAt: student.answeredAt,\n timeSpent: student.timeSpent,\n score: student.score,\n }));\n }, [data?.students]);\n\n /**\n * Table columns configuration\n */\n const columns = useMemo(\n () => createTableColumns(handleCorrectActivity),\n [handleCorrectActivity]\n );\n\n /**\n * Handle table parameters change\n */\n const handleTableParamsChange = (params: TableParams) => {\n if (params.page) setPage(params.page);\n if (params.limit) setLimit(params.limit);\n if (params.sortBy !== undefined) {\n // Map table column keys to API parameter names\n const sortByMap: Record<string, 'name' | 'score' | 'answeredAt'> = {\n studentName: 'name',\n answeredAt: 'answeredAt',\n score: 'score',\n };\n setSortBy(params.sortBy ? sortByMap[params.sortBy] : undefined);\n }\n if (params.sortOrder !== undefined) {\n setSortOrder(params.sortOrder as 'asc' | 'desc' | undefined);\n }\n };\n\n const orderedQuestions = useMemo(\n () => normalizeWithPositions(activityQuestions),\n [activityQuestions]\n );\n\n /**\n * Use PDF print hook\n */\n const { contentRef, handlePrint } = useQuestionsPdfPrint(orderedQuestions);\n\n /**\n * Extract questions from API response\n * Handles both direct questions array and questionIds array\n */\n const extractQuestionsFromResponse = useCallback(\n async (\n response:\n | Awaited<\n ReturnType<\n typeof apiClient.get<{\n data: { questions?: Question[]; questionIds?: string[] };\n }>\n >\n >\n | undefined\n ): Promise<Question[]> => {\n if (!response?.data?.data) {\n return [];\n }\n\n if (response.data.data.questions) {\n return response.data.data.questions;\n }\n\n if (response.data.data.questionIds) {\n return await fetchQuestionsByIds(response.data.data.questionIds);\n }\n\n return [];\n },\n [fetchQuestionsByIds]\n );\n\n /**\n * Try to fetch questions from quiz endpoint\n */\n const tryFetchQuizResponse = useCallback(async () => {\n try {\n const response = await apiClient.get<{\n data: { questions?: Question[]; questionIds?: string[] };\n }>(`/activities/${activityId}/quiz`);\n return { response, error: undefined };\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n return { response: undefined, error };\n }\n }, [activityId, apiClient]);\n\n /**\n * Try to fetch questions from activity endpoint\n */\n const tryFetchActivityResponse = useCallback(async () => {\n try {\n const response = await apiClient.get<{\n data: { questions?: Question[]; questionIds?: string[] };\n }>(`/activities/${activityId}`);\n return { response, error: undefined };\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n return { response: undefined, error };\n }\n }, [activityId, apiClient]);\n\n /**\n * Fetch questions from both endpoints (quiz and activity)\n * Returns questions array or throws error if both fail\n */\n const fetchQuestionsFromEndpoints = useCallback(async (): Promise<\n Question[]\n > => {\n // Try quiz endpoint first\n const { response: quizResponse, error: quizError } =\n await tryFetchQuizResponse();\n let questions = await extractQuestionsFromResponse(quizResponse);\n\n // If quiz endpoint didn't return questions, try activity endpoint\n if (questions.length === 0) {\n const { response: activityResponse, error: activityError } =\n await tryFetchActivityResponse();\n\n // If both endpoints failed, throw error\n if (!quizResponse && !activityResponse) {\n const errorMessage =\n quizError?.message ||\n activityError?.message ||\n 'Erro ao buscar questões da atividade. Tente novamente.';\n throw new Error(errorMessage);\n }\n\n questions = await extractQuestionsFromResponse(activityResponse);\n }\n\n return questions;\n }, [\n tryFetchQuizResponse,\n tryFetchActivityResponse,\n extractQuestionsFromResponse,\n ]);\n\n /**\n * Handle fetch error and show toast notification\n */\n const handleQuestionsFetchError = useCallback(\n (errorMessage: string) => {\n console.error('Erro ao buscar questões da atividade:', errorMessage);\n setActivityQuestions([]);\n setActivityQuestionsError(errorMessage);\n addToast({\n title: 'Erro ao carregar questões',\n description: errorMessage,\n variant: 'solid',\n action: 'warning',\n position: 'top-right',\n });\n },\n [addToast]\n );\n\n /**\n * Fetch activity questions for PDF download\n * @returns Promise that resolves to true if questions were successfully loaded (non-empty), false otherwise\n */\n const fetchActivityQuestions = useCallback(async (): Promise<boolean> => {\n if (!activityId) return false;\n\n setIsLoadingQuestions(true);\n setActivityQuestionsError(null);\n try {\n const questions = await fetchQuestionsFromEndpoints();\n\n // Convert questions to PreviewQuestion format\n const previewQuestions = questions.map((q) =>\n convertQuestionToPreview(q)\n );\n setActivityQuestions(previewQuestions);\n setActivityQuestionsError(null);\n\n // Notify user if no questions were found\n if (previewQuestions.length === 0) {\n addToast({\n title: 'Nenhuma questão encontrada',\n description: 'Esta atividade não possui questões para download.',\n variant: 'solid',\n action: 'info',\n position: 'top-right',\n });\n }\n\n return previewQuestions.length > 0;\n } catch (err) {\n const errorMessage =\n err instanceof Error\n ? err.message\n : 'Erro ao buscar questões da atividade. Tente novamente.';\n handleQuestionsFetchError(errorMessage);\n return false;\n } finally {\n setIsLoadingQuestions(false);\n }\n }, [fetchQuestionsFromEndpoints, handleQuestionsFetchError, addToast]);\n\n /**\n * Handle download PDF button click\n */\n const handleDownloadPdf = useCallback(async () => {\n try {\n // If questions are not loaded yet, fetch them first\n if (activityQuestions.length === 0) {\n const success = await fetchActivityQuestions();\n // Only set print flag if fetch succeeded and returned questions\n setShouldPrint(success);\n } else if (activityQuestions.length > 0) {\n setShouldPrint(true);\n } else {\n setShouldPrint(false);\n }\n } catch {\n // Error already handled in fetchActivityQuestions, ensure print flag is false\n setShouldPrint(false);\n }\n }, [activityQuestions.length, fetchActivityQuestions]);\n\n /**\n * Effect to handle PDF printing when shouldPrint flag is set\n * Waits for contentRef to be ready and questions to be loaded\n */\n useEffect(() => {\n if (!shouldPrint) {\n return;\n }\n\n // Guard against empty activityQuestions - reset flag if empty\n if (activityQuestions.length === 0) {\n setShouldPrint(false);\n return;\n }\n\n // Check if all conditions are met for printing\n if (\n contentRef.current &&\n handlePrint &&\n typeof handlePrint === 'function'\n ) {\n handlePrint();\n setShouldPrint(false);\n return;\n }\n\n // If conditions aren't met but shouldPrint is true, reset it to prevent getting stuck\n // This handles cases where contentRef or handlePrint aren't ready yet\n setShouldPrint(false);\n }, [shouldPrint, activityQuestions.length, contentRef, handlePrint]);\n\n /**\n * Handle back navigation\n */\n const handleBack = () => {\n if (onBack) {\n onBack();\n }\n };\n\n /**\n * Get subject info for icon display\n */\n const subjectEnum =\n data?.activity?.subjectName && mapSubjectNameToEnum\n ? mapSubjectNameToEnum(data.activity.subjectName)\n : null;\n const subjectInfo: SubjectData | null = subjectEnum\n ? getSubjectInfo(subjectEnum)\n : null;\n\n // Loading state\n if (loading && !data) {\n return (\n <div className=\"flex flex-col w-full h-auto relative justify-center items-center mb-5 overflow-hidden\">\n <div className=\"flex flex-col w-full h-full max-w-[1150px] mx-auto z-10 lg:px-0 px-4 pt-4 gap-4\">\n {/* Breadcrumb Skeleton */}\n <div className=\"flex items-center gap-2 py-4\">\n <SkeletonText width={100} height={14} />\n </div>\n\n {/* Header Card Skeleton */}\n <SkeletonRounded className=\"w-full h-[120px]\" />\n\n {/* Statistics Cards Skeleton */}\n <div\n className={cn(\n 'grid gap-5',\n isMobile ? 'grid-cols-2' : 'grid-cols-5'\n )}\n >\n {[\n 'total-students',\n 'completed',\n 'pending',\n 'avg-score',\n 'avg-time',\n ].map((id) => (\n <SkeletonRounded key={id} className=\"w-full h-[150px]\" />\n ))}\n </div>\n\n {/* Table Skeleton */}\n <div className=\"w-full bg-background rounded-xl p-6\">\n <SkeletonTable rows={5} columns={6} showHeader />\n </div>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error || !data) {\n return (\n <div className=\"flex flex-col w-full h-auto relative justify-center items-center mb-5\">\n <div className=\"flex flex-col w-full h-full max-w-[1150px] mx-auto z-10 lg:px-0 px-4 pt-4\">\n <EmptyState\n image={emptyStateImage}\n title=\"Erro ao carregar detalhes\"\n description={\n error || 'Não foi possível carregar os detalhes da atividade'\n }\n />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col w-full h-auto relative justify-center items-center mb-5 overflow-hidden\">\n {/* Main container */}\n <div className=\"flex flex-col w-full h-full max-w-[1150px] mx-auto z-10 lg:px-0 px-4 pt-4 gap-4\">\n {/* Breadcrumb */}\n <div className=\"flex items-center gap-2 py-4\">\n <button\n onClick={handleBack}\n className=\"text-text-500 hover:text-text-700 text-sm font-bold underline\"\n >\n Atividades\n </button>\n <CaretRight size={16} className=\"text-text-500\" />\n <Text className=\"text-text-950 text-sm font-bold\">\n {data.activity?.title || 'Atividade'}\n </Text>\n </div>\n\n {/* Activity header card */}\n {data.activity && (\n <div className=\"bg-background rounded-xl p-4 flex flex-col gap-2\">\n <div className=\"flex justify-between items-start\">\n <div className=\"flex flex-col gap-2\">\n <Text className=\"text-2xl font-bold text-text-950\">\n {data.activity.title}\n </Text>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <Text className=\"text-sm text-text-500\">\n Início{' '}\n {data.activity.startDate\n ? formatDateToBrazilian(data.activity.startDate)\n : '00/00/0000'}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n Prazo final{' '}\n {data.activity.finalDate\n ? formatDateToBrazilian(data.activity.finalDate)\n : '00/00/0000'}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n {data.activity.schoolName}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n {data.activity.year}\n </Text>\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n {subjectInfo ? (\n <div className=\"flex items-center gap-1\">\n <span\n className={cn(\n 'w-[21px] h-[21px] flex items-center justify-center rounded-sm text-text-950 shrink-0',\n subjectInfo.colorClass\n )}\n >\n {subjectInfo.icon}\n </span>\n <Text className=\"text-sm text-text-500\">\n {data.activity.subjectName}\n </Text>\n </div>\n ) : (\n <Text className=\"text-sm text-text-500\">\n {data.activity.subjectName}\n </Text>\n )}\n <span className=\"w-1 h-1 rounded-full bg-text-500\" />\n <Text className=\"text-sm text-text-500\">\n {data.activity.className}\n </Text>\n </div>\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Button\n size=\"small\"\n onClick={handleDownloadPdf}\n disabled={isLoadingQuestions}\n iconLeft={<DownloadSimple size={16} />}\n className=\"bg-primary-950 text-text gap-2\"\n >\n {isLoadingQuestions ? 'Carregando...' : 'Baixar Atividade'}\n </Button>\n {activityQuestionsError && (\n <div className=\"flex items-center gap-2 max-w-[300px]\">\n <WarningCircle\n size={16}\n className=\"text-error-600 shrink-0\"\n weight=\"fill\"\n />\n <Text className=\"text-error-700 text-xs\">\n {activityQuestionsError}\n </Text>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Statistics cards */}\n <div\n className={cn('grid gap-5', isMobile ? 'grid-cols-2' : 'grid-cols-5')}\n >\n {/* Completion percentage */}\n <div className=\"border border-border-50 rounded-xl py-4 px-0 flex flex-col items-center justify-center gap-2 bg-primary-50\">\n <div className=\"relative w-[90px] h-[90px]\">\n <svg className=\"w-full h-full transform -rotate-90\">\n <circle\n cx=\"45\"\n cy=\"45\"\n r=\"40\"\n stroke=\"var(--color-primary-100)\"\n strokeWidth=\"8\"\n fill=\"none\"\n />\n <circle\n cx=\"45\"\n cy=\"45\"\n r=\"40\"\n stroke=\"var(--color-primary-700)\"\n strokeWidth=\"8\"\n fill=\"none\"\n strokeDasharray={`${(data.generalStats.completionPercentage / 100) * 251.2} 251.2`}\n strokeLinecap=\"round\"\n />\n </svg>\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\n <Text className=\"text-xl font-medium text-primary-600\">\n {Math.round(data.generalStats.completionPercentage)}%\n </Text>\n <Text className=\"text-2xs font-bold text-text-600 uppercase\">\n Concluído\n </Text>\n </div>\n </div>\n </div>\n\n {/* Average score */}\n <div className=\"border border-border-50 rounded-xl py-4 px-3 flex flex-col items-center justify-center gap-1 bg-warning-background\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-warning-300\">\n <Star size={16} className=\"text-white\" weight=\"regular\" />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-warning-600\">\n Média da Turma\n </Text>\n <Text className=\"text-xl font-bold text-warning-600\">\n {data.generalStats.averageScore.toFixed(1)}\n </Text>\n </div>\n\n {/* Most correct questions */}\n <div className=\"border border-border-50 rounded-xl py-2 px-3 flex flex-col items-center justify-center gap-1 bg-success-200\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-indicator-positive\">\n <Medal size={16} className=\"text-text-950\" weight=\"regular\" />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-success-700\">\n Questões com mais acertos\n </Text>\n <Text className=\"text-xl font-bold text-success-700\">\n {formatQuestionNumbers(data.questionStats.mostCorrect)}\n </Text>\n </div>\n\n {/* Most incorrect questions */}\n <div className=\"border border-border-50 rounded-xl py-2 px-3 flex flex-col items-center justify-center gap-1 bg-error-100\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-indicator-negative\">\n <WarningCircle\n size={16}\n className=\"text-white\"\n weight=\"regular\"\n />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-error-700\">\n Questões com mais erros\n </Text>\n <Text className=\"text-xl font-bold text-error-700\">\n {formatQuestionNumbers(data.questionStats.mostIncorrect)}\n </Text>\n </div>\n\n {/* Not answered questions */}\n <div className=\"border border-border-50 rounded-xl py-2 px-3 flex flex-col items-center justify-center gap-1 bg-info-background\">\n <div className=\"w-[30px] h-[30px] rounded-2xl flex items-center justify-center bg-info-500\">\n <WarningCircle\n size={16}\n className=\"text-white\"\n weight=\"regular\"\n />\n </div>\n <Text className=\"text-2xs font-bold uppercase text-center text-info-700\">\n Questões não respondidas\n </Text>\n <Text className=\"text-xl font-bold text-info-700\">\n {formatQuestionNumbers(data.questionStats.notAnswered)}\n </Text>\n </div>\n </div>\n\n {/* Correction error message */}\n {correctionError && (\n <div className=\"w-full bg-error-50 border border-error-200 rounded-xl p-4 flex items-center gap-3\">\n <WarningCircle size={20} className=\"text-error-600\" weight=\"fill\" />\n <Text className=\"text-error-700 text-sm\">{correctionError}</Text>\n </div>\n )}\n\n {/* Students table */}\n <div className=\"w-full bg-background rounded-xl p-6 space-y-4\">\n <TableProvider<ActivityStudentTableItem>\n data={tableData}\n headers={columns}\n loading={false}\n variant=\"borderless\"\n enableTableSort\n enablePagination\n paginationConfig={{\n itemLabel: 'alunos',\n itemsPerPageOptions: [10, 20, 50],\n defaultItemsPerPage: 10,\n totalItems: data.pagination.total,\n totalPages: data.pagination.totalPages,\n }}\n emptyState={{\n component: (\n <EmptyState\n image={emptyStateImage}\n title=\"Nenhum aluno encontrado\"\n description=\"Não há alunos matriculados nesta atividade\"\n />\n ),\n }}\n onParamsChange={handleTableParamsChange}\n >\n {({ table, pagination }) => (\n <>\n {table}\n {pagination}\n </>\n )}\n </TableProvider>\n </div>\n </div>\n\n {/* Correct Activity Modal */}\n <CorrectActivityModal\n isOpen={isModalOpen}\n onClose={handleCloseModal}\n data={correctionData}\n isViewOnly={isViewOnlyModal}\n onObservationSubmit={handleObservationSubmit}\n onQuestionCorrectionSubmit={handleQuestionCorrectionSubmit}\n />\n\n {/* Hidden PDF content for printing */}\n <div style={{ display: 'none' }}>\n <QuestionsPdfContent ref={contentRef} questions={orderedQuestions} />\n </div>\n </div>\n );\n};\n\nexport default ActivityDetails;\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\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n areFiltersEqual,\n} from './activityFilters';\nexport {\n mapQuestionTypeToEnum,\n mapQuestionTypeToEnumRequired,\n} from './questionTypeUtils';\nexport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from './activityDetailsUtils';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n","import { create } from 'zustand';\nimport { devtools } from 'zustand/middleware';\n\nexport enum QUESTION_DIFFICULTY {\n FACIL = 'FACIL',\n MEDIO = 'MEDIO',\n DIFICIL = 'DIFICIL',\n}\n\n// Enum para tipos de quiz\nexport enum QUIZ_TYPE {\n SIMULADO = 'SIMULADO',\n QUESTIONARIO = 'QUESTIONARIO',\n ATIVIDADE = 'ATIVIDADE',\n}\n\nexport enum QUESTION_TYPE {\n ALTERNATIVA = 'ALTERNATIVA',\n DISSERTATIVA = 'DISSERTATIVA',\n MULTIPLA_ESCOLHA = 'MULTIPLA_ESCOLHA',\n VERDADEIRO_FALSO = 'VERDADEIRO_FALSO',\n LIGAR_PONTOS = 'LIGAR_PONTOS',\n PREENCHER = 'PREENCHER',\n IMAGEM = 'IMAGEM',\n}\n\nexport enum QUESTION_STATUS {\n PENDENTE_AVALIACAO = 'PENDENTE_AVALIACAO',\n RESPOSTA_CORRETA = 'RESPOSTA_CORRETA',\n RESPOSTA_INCORRETA = 'RESPOSTA_INCORRETA',\n NAO_RESPONDIDO = 'NAO_RESPONDIDO',\n}\n\nexport enum ANSWER_STATUS {\n RESPOSTA_CORRETA = 'RESPOSTA_CORRETA',\n RESPOSTA_INCORRETA = 'RESPOSTA_INCORRETA',\n PENDENTE_AVALIACAO = 'PENDENTE_AVALIACAO',\n NAO_RESPONDIDO = 'NAO_RESPONDIDO',\n}\n\nexport enum SUBTYPE_ENUM {\n PROVA = 'PROVA',\n ENEM_PROVA_1 = 'ENEM_PROVA_1',\n ENEM_PROVA_2 = 'ENEM_PROVA_2',\n VESTIBULAR = 'VESTIBULAR',\n SIMULADO = 'SIMULADO',\n SIMULADAO = 'SIMULADAO',\n}\n\nexport interface QuestionResult {\n answers: {\n id: string;\n questionId: string;\n answer: string | null;\n selectedOptions: {\n optionId: string;\n }[];\n answerStatus: ANSWER_STATUS;\n statement: string;\n questionType: QUESTION_TYPE;\n difficultyLevel: QUESTION_DIFFICULTY;\n solutionExplanation: string | null;\n correctOption: string;\n createdAt: string;\n updatedAt: string;\n options?: {\n id: string;\n option: string;\n isCorrect: boolean;\n }[];\n knowledgeMatrix: {\n areaKnowledge: {\n id: string;\n name: string;\n } | null;\n subject: {\n id: string;\n name: string;\n color: string;\n icon: string;\n } | null;\n topic: {\n id: string;\n name: string;\n } | null;\n subtopic: {\n id: string;\n name: string;\n } | null;\n content: {\n id: string;\n name: string;\n } | null;\n }[];\n teacherFeedback: string | null;\n attachment: string | null;\n score: number | null;\n gradedAt: string | null;\n gradedBy: string | null;\n }[];\n statistics: {\n totalAnswered: number;\n correctAnswers: number;\n incorrectAnswers: number;\n pendingAnswers: number;\n score: number;\n timeSpent: number;\n };\n}\n\nexport interface Question {\n id: string;\n statement: string;\n questionType: QUESTION_TYPE;\n difficultyLevel: QUESTION_DIFFICULTY;\n description: string;\n examBoard: string | null;\n examYear: string | null;\n solutionExplanation: string | null;\n answer: null;\n answerStatus: ANSWER_STATUS;\n options: {\n id: string;\n option: string;\n }[];\n knowledgeMatrix: {\n areaKnowledge: {\n id: string;\n name: string;\n };\n subject: {\n id: string;\n name: string;\n color: string;\n icon: string;\n };\n topic: {\n id: string;\n name: string;\n };\n subtopic: {\n id: string;\n name: string;\n };\n content: {\n id: string;\n name: string;\n };\n }[];\n correctOptionIds?: string[];\n}\n\nexport interface QuizInterface {\n id: string;\n title: string;\n type: QUIZ_TYPE;\n subtype: SUBTYPE_ENUM | string;\n difficulty: string | null;\n notification: string | null;\n status: string;\n startDate: string | null;\n finalDate: string | null;\n canRetry: boolean;\n createdAt: string | null;\n updatedAt: string | null;\n questions: Question[];\n}\n\nexport interface UserAnswerItem {\n questionId: string;\n activityId: string;\n userId: string;\n answer: string | null;\n optionId: string | null;\n questionType: QUESTION_TYPE;\n answerStatus: ANSWER_STATUS;\n}\n\nexport interface QuizState {\n // Data\n quiz: QuizInterface | null;\n\n // UI State\n currentQuestionIndex: number;\n selectedAnswers: Record<string, string>;\n userAnswers: UserAnswerItem[];\n timeElapsed: number;\n isStarted: boolean;\n isFinished: boolean;\n userId: string;\n variant: 'result' | 'default';\n minuteCallback: (() => void) | null;\n dissertativeCharLimit?: number;\n // Actions\n setQuiz: (quiz: QuizInterface) => void;\n setQuestionResult: (questionResult: QuestionResult) => void;\n setUserId: (userId: string) => void;\n setUserAnswers: (userAnswers: UserAnswerItem[]) => void;\n setVariant: (variant: 'result' | 'default') => void;\n setDissertativeCharLimit: (limit?: number) => void;\n getDissertativeCharLimit: () => number | undefined;\n // Quiz Navigation\n goToNextQuestion: () => void;\n goToPreviousQuestion: () => void;\n goToQuestion: (index: number) => void;\n\n // Quiz Actions\n selectAnswer: (questionId: string, answerId: string) => void;\n selectMultipleAnswer: (questionId: string, answerIds: string[]) => void;\n selectDissertativeAnswer: (questionId: string, answer: string) => void;\n skipQuestion: () => void;\n skipCurrentQuestionIfUnanswered: () => void;\n addUserAnswer: (questionId: string, answerId?: string) => void;\n startQuiz: () => void;\n finishQuiz: () => void;\n resetQuiz: () => void;\n\n // Timer\n updateTime: (time: number) => void;\n startTimer: () => void;\n stopTimer: () => void;\n\n // Minute Callback\n setMinuteCallback: (callback: (() => void) | null) => void;\n startMinuteCallback: () => void;\n stopMinuteCallback: () => void;\n\n // Getters\n getCurrentQuestion: () => Question | null;\n getTotalQuestions: () => number;\n getAnsweredQuestions: () => number;\n getUnansweredQuestions: () => number[];\n getSkippedQuestions: () => number;\n getProgress: () => number;\n isQuestionAnswered: (questionId: string) => boolean;\n isQuestionSkipped: (questionId: string) => boolean;\n getCurrentAnswer: () => UserAnswerItem | undefined;\n getAllCurrentAnswer: () => UserAnswerItem[] | undefined;\n getQuizTitle: () => string;\n formatTime: (seconds: number) => string;\n getUserAnswers: () => UserAnswerItem[];\n getUnansweredQuestionsFromUserAnswers: () => number[];\n getQuestionsGroupedBySubject: () => { [key: string]: Question[] };\n getUserId: () => string;\n setCurrentQuestion: (question: Question) => void;\n\n // New methods for userAnswers\n getQuestionIndex: (questionId: string) => number;\n getUserAnswerByQuestionId: (questionId: string) => UserAnswerItem | null;\n isQuestionAnsweredByUserAnswers: (questionId: string) => boolean;\n getQuestionStatusFromUserAnswers: (\n questionId: string\n ) => 'answered' | 'unanswered' | 'skipped';\n getUserAnswersForActivity: () => UserAnswerItem[];\n // Answer status management\n setAnswerStatus: (questionId: string, status: ANSWER_STATUS) => void;\n getAnswerStatus: (questionId: string) => ANSWER_STATUS | null;\n\n // Question Result\n questionsResult: QuestionResult | null;\n currentQuestionResult: QuestionResult['answers'] | null;\n setQuestionsResult: (questionsResult: QuestionResult) => void;\n setCurrentQuestionResult: (\n currentQuestionResult: QuestionResult['answers']\n ) => void;\n getQuestionResultByQuestionId: (\n questionId: string\n ) => QuestionResult['answers'][number] | null;\n getQuestionResultStatistics: () => QuestionResult['statistics'] | null;\n getQuestionResult: () => QuestionResult | null;\n getCurrentQuestionResult: () => QuestionResult['answers'] | null;\n}\n\n// Constants\nexport const MINUTE_INTERVAL_MS = 60000; // 60 seconds = 1 minute\n\nexport const useQuizStore = create<QuizState>()(\n devtools(\n (set, get) => {\n let timerInterval: ReturnType<typeof setInterval> | null = null;\n let minuteCallbackInterval: ReturnType<typeof setInterval> | null = null;\n\n const startTimer = () => {\n if (get().isFinished) {\n return;\n }\n\n if (timerInterval) {\n clearInterval(timerInterval);\n }\n\n timerInterval = setInterval(() => {\n const { timeElapsed } = get();\n set({ timeElapsed: timeElapsed + 1 });\n }, 1000);\n };\n\n const stopTimer = () => {\n if (timerInterval) {\n clearInterval(timerInterval);\n timerInterval = null;\n }\n };\n\n const setMinuteCallback = (callback: (() => void) | null) => {\n set({ minuteCallback: callback });\n };\n\n const startMinuteCallback = () => {\n const { minuteCallback, isFinished } = get();\n\n if (isFinished || !minuteCallback) {\n return;\n }\n\n if (minuteCallbackInterval) {\n clearInterval(minuteCallbackInterval);\n }\n\n minuteCallbackInterval = setInterval(() => {\n const {\n minuteCallback: currentCallback,\n isFinished: currentIsFinished,\n } = get();\n\n if (currentIsFinished || !currentCallback) {\n stopMinuteCallback();\n return;\n }\n\n currentCallback();\n }, MINUTE_INTERVAL_MS);\n };\n\n const stopMinuteCallback = () => {\n if (minuteCallbackInterval) {\n clearInterval(minuteCallbackInterval);\n minuteCallbackInterval = null;\n }\n };\n\n return {\n // Initial State\n quiz: null,\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n variant: 'default',\n minuteCallback: null,\n dissertativeCharLimit: undefined,\n questionsResult: null,\n currentQuestionResult: null,\n // Setters\n setQuiz: (quiz) => set({ quiz }),\n setUserId: (userId) => set({ userId }),\n setUserAnswers: (userAnswers) => set({ userAnswers }),\n getUserId: () => get().userId,\n setVariant: (variant) => set({ variant }),\n setQuestionResult: (questionsResult) => set({ questionsResult }),\n setDissertativeCharLimit: (limit?: number) =>\n set({ dissertativeCharLimit: limit }),\n getDissertativeCharLimit: () => get().dissertativeCharLimit,\n // Navigation\n goToNextQuestion: () => {\n const { currentQuestionIndex, getTotalQuestions } = get();\n const totalQuestions = getTotalQuestions();\n\n if (currentQuestionIndex < totalQuestions - 1) {\n set({ currentQuestionIndex: currentQuestionIndex + 1 });\n }\n },\n\n goToPreviousQuestion: () => {\n const { currentQuestionIndex } = get();\n\n if (currentQuestionIndex > 0) {\n set({ currentQuestionIndex: currentQuestionIndex - 1 });\n }\n },\n\n goToQuestion: (index) => {\n const { getTotalQuestions } = get();\n const totalQuestions = getTotalQuestions();\n\n if (index >= 0 && index < totalQuestions) {\n set({ currentQuestionIndex: index });\n }\n },\n\n selectAnswer: (questionId, answerId) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? answerId\n : null,\n optionId:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? null\n : answerId,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n selectMultipleAnswer: (questionId, answerIds) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n // Remove all existing answers for this questionId\n const filteredUserAnswers = userAnswers.filter(\n (answer) => answer.questionId !== questionId\n );\n\n // Create new UserAnswerItem objects for each answerId\n const newUserAnswers: UserAnswerItem[] = answerIds.map(\n (answerId) => ({\n questionId,\n activityId,\n userId,\n answer: null, // selectMultipleAnswer is for non-dissertative questions\n optionId: answerId, // selectMultipleAnswer should only set optionId\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n })\n );\n\n // Combine filtered answers with new answers\n const updatedUserAnswers = [\n ...filteredUserAnswers,\n ...newUserAnswers,\n ];\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n selectDissertativeAnswer: (questionId, answer) => {\n const { quiz, userAnswers, dissertativeCharLimit } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (\n !question ||\n question.questionType !== QUESTION_TYPE.DISSERTATIVA\n ) {\n // Silent validation - wrong question type\n return;\n }\n\n // Validate character limit if set\n let validatedAnswer = answer;\n if (\n dissertativeCharLimit !== undefined &&\n answer.length > dissertativeCharLimit\n ) {\n validatedAnswer = answer.substring(0, dissertativeCharLimit);\n }\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answerItem) => answerItem.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer: validatedAnswer,\n optionId: null,\n questionType: QUESTION_TYPE.DISSERTATIVA,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n skipQuestion: () => {\n const { getCurrentQuestion, userAnswers, quiz } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!quiz) return;\n\n if (currentQuestion) {\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId: currentQuestion.id,\n activityId,\n userId,\n answer: null,\n optionId: null,\n questionType: currentQuestion.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n // Update existing answer\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n // Add new answer\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n }\n },\n\n skipCurrentQuestionIfUnanswered: () => {\n const { getCurrentQuestion, getCurrentAnswer, skipQuestion } = get();\n const currentQuestion = getCurrentQuestion();\n const currentAnswer = getCurrentAnswer();\n\n // Se não há questão atual, não faz nada\n if (!currentQuestion) return;\n\n // Se não há resposta ou a resposta está vazia (null), marca como pulada\n if (\n !currentAnswer ||\n (currentAnswer.optionId === null && currentAnswer.answer === null)\n ) {\n skipQuestion();\n }\n },\n\n addUserAnswer: (questionId, answerId) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n // Add to userAnswers array with new structure\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? answerId || null\n : null,\n optionId:\n question.questionType !== QUESTION_TYPE.DISSERTATIVA\n ? answerId || null\n : null,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n if (existingAnswerIndex !== -1) {\n // Update existing answer\n const updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n set({ userAnswers: updatedUserAnswers });\n } else {\n // Add new answer\n set({ userAnswers: [...userAnswers, newUserAnswer] });\n }\n },\n\n startQuiz: () => {\n set({ isStarted: true, timeElapsed: 0 });\n startTimer();\n startMinuteCallback();\n },\n\n finishQuiz: () => {\n set({ isFinished: true });\n stopTimer();\n stopMinuteCallback();\n },\n\n resetQuiz: () => {\n stopTimer();\n stopMinuteCallback();\n set({\n quiz: null,\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n variant: 'default',\n minuteCallback: null,\n dissertativeCharLimit: undefined,\n questionsResult: null,\n currentQuestionResult: null,\n });\n },\n\n // Timer\n updateTime: (time) => set({ timeElapsed: time }),\n startTimer,\n stopTimer,\n\n // Minute Callback\n setMinuteCallback,\n startMinuteCallback,\n stopMinuteCallback,\n\n // Getters\n getCurrentQuestion: () => {\n const { currentQuestionIndex, quiz } = get();\n\n if (!quiz) {\n return null;\n }\n\n return quiz.questions[currentQuestionIndex];\n },\n\n getTotalQuestions: () => {\n const { quiz } = get();\n\n return quiz?.questions?.length || 0;\n },\n\n getAnsweredQuestions: () => {\n const { userAnswers } = get();\n return userAnswers.filter(\n (answer) => answer.optionId !== null || answer.answer !== null\n ).length;\n },\n\n getUnansweredQuestions: () => {\n const { quiz, userAnswers } = get();\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const isAnswered =\n userAnswer &&\n (userAnswer.optionId !== null || userAnswer.answer !== null);\n const isSkipped =\n userAnswer &&\n userAnswer.optionId === null &&\n userAnswer.answer === null;\n\n if (!isAnswered && !isSkipped) {\n unansweredQuestions.push(index + 1); // index + 1 para mostrar número da questão\n }\n });\n return unansweredQuestions;\n },\n\n getSkippedQuestions: () => {\n const { userAnswers } = get();\n return userAnswers.filter(\n (answer) => answer.optionId === null && answer.answer === null\n ).length;\n },\n\n getProgress: () => {\n const { getTotalQuestions, getAnsweredQuestions } = get();\n const total = getTotalQuestions();\n const answered = getAnsweredQuestions();\n\n return total > 0 ? (answered / total) * 100 : 0;\n },\n\n isQuestionAnswered: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer\n ? userAnswer.optionId !== null || userAnswer.answer !== null\n : false;\n },\n\n isQuestionSkipped: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer\n ? userAnswer.optionId === null && userAnswer.answer === null\n : false;\n },\n\n getCurrentAnswer: () => {\n const { getCurrentQuestion, userAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!currentQuestion) return undefined;\n\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n // Retorna undefined se a resposta está vazia (não respondida)\n const hasAnswerContent = (ua?: UserAnswerItem | null) =>\n !!ua &&\n ((ua.optionId !== null && ua.optionId !== '') ||\n (ua.answer !== null && ua.answer !== ''));\n\n if (!hasAnswerContent(userAnswer)) {\n return undefined;\n }\n\n return userAnswer;\n },\n\n getAllCurrentAnswer: () => {\n const { getCurrentQuestion, userAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!currentQuestion) return undefined;\n\n const userAnswer = userAnswers.filter(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n return userAnswer;\n },\n\n getQuizTitle: () => {\n const { quiz } = get();\n\n return quiz?.title || 'Quiz';\n },\n\n formatTime: (seconds: number) => {\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\n },\n\n getUserAnswers: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n\n getUnansweredQuestionsFromUserAnswers: () => {\n const { quiz, userAnswers } = get();\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const hasAnswer =\n userAnswer &&\n (userAnswer.optionId !== null || userAnswer.answer !== null);\n const isSkipped =\n userAnswer &&\n userAnswer.optionId === null &&\n userAnswer.answer === null;\n\n // Se não há resposta do usuário OU se a questão foi pulada\n if (!hasAnswer || isSkipped) {\n unansweredQuestions.push(index + 1); // index + 1 para mostrar número da questão\n }\n });\n\n return unansweredQuestions;\n },\n\n getQuestionsGroupedBySubject: () => {\n const { getQuestionResult, quiz, variant } = get();\n const questions =\n variant == 'result'\n ? getQuestionResult()?.answers\n : quiz?.questions;\n if (!questions) return {};\n const groupedQuestions: {\n [key: string]: (Question | QuestionResult['answers'][number])[];\n } = {};\n questions.forEach((question) => {\n const subjectId =\n question.knowledgeMatrix?.[0]?.subject?.id || 'Sem matéria';\n\n if (!groupedQuestions[subjectId]) {\n groupedQuestions[subjectId] = [];\n }\n\n groupedQuestions[subjectId].push(question);\n });\n\n return groupedQuestions;\n },\n\n // New methods for userAnswers\n getUserAnswerByQuestionId: (questionId) => {\n const { userAnswers } = get();\n return (\n userAnswers.find((answer) => answer.questionId === questionId) ||\n null\n );\n },\n isQuestionAnsweredByUserAnswers: (questionId) => {\n const { userAnswers } = get();\n const answer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return answer\n ? answer.optionId !== null || answer.answer !== null\n : false;\n },\n getQuestionStatusFromUserAnswers: (questionId) => {\n const { userAnswers } = get();\n const answer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n if (!answer) return 'unanswered';\n if (answer.optionId === null) return 'skipped';\n return 'answered';\n },\n getUserAnswersForActivity: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n setCurrentQuestion: (question) => {\n const { quiz, variant, questionsResult } = get();\n if (!quiz) return;\n let questionIndex = 0;\n if (variant == 'result') {\n if (!questionsResult) return;\n const questionResult =\n questionsResult.answers.find((q) => q.id === question.id) ??\n questionsResult.answers.find((q) => q.questionId === question.id);\n if (!questionResult) return;\n questionIndex = quiz.questions.findIndex(\n (q) => q.id === questionResult.questionId\n );\n } else {\n questionIndex = quiz.questions.findIndex(\n (q) => q.id === question.id\n );\n }\n\n // Validate that the question was found before updating currentQuestionIndex\n if (questionIndex === -1) {\n // Silent validation - question not found\n return;\n }\n\n set({ currentQuestionIndex: questionIndex });\n },\n\n setAnswerStatus: (questionId, status) => {\n const { userAnswers } = get();\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n if (existingAnswerIndex !== -1) {\n const updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = {\n ...updatedUserAnswers[existingAnswerIndex],\n answerStatus: status,\n };\n set({ userAnswers: updatedUserAnswers });\n }\n },\n\n getAnswerStatus: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer ? userAnswer.answerStatus : null;\n },\n getQuestionIndex: (questionId) => {\n const { questionsResult, variant, quiz } = get();\n if (variant == 'result') {\n if (!questionsResult) return 0;\n\n let idx = questionsResult.answers.findIndex(\n (q) => q.questionId === questionId\n );\n if (idx === -1) {\n idx = questionsResult.answers.findIndex(\n (q) => q.id === questionId\n );\n }\n return idx !== -1 ? idx + 1 : 0;\n } else {\n if (!quiz) return 0;\n const idx = quiz.questions.findIndex((q) => q.id === questionId);\n return idx !== -1 ? idx + 1 : 0;\n }\n },\n\n // Question Result\n getQuestionResultByQuestionId: (questionId) => {\n const { questionsResult } = get();\n const question = questionsResult?.answers.find(\n (answer) => answer.questionId === questionId\n );\n\n return question || null;\n },\n getQuestionResultStatistics: () => {\n const { questionsResult } = get();\n return questionsResult?.statistics || null;\n },\n getQuestionResult: () => {\n const { questionsResult } = get();\n return questionsResult;\n },\n setQuestionsResult: (questionsResult) => {\n set({ questionsResult });\n },\n setCurrentQuestionResult: (currentQuestionResult) => {\n set({ currentQuestionResult });\n },\n getCurrentQuestionResult: () => {\n const { currentQuestionResult } = get();\n return currentQuestionResult;\n },\n };\n },\n {\n name: 'quiz-store',\n }\n )\n);\n","/**\n * Activity Details Types\n * Types and helper functions for activity details components\n */\n\nimport { z } from 'zod';\n\n/**\n * Student activity status enum\n */\nexport const STUDENT_ACTIVITY_STATUS = {\n CONCLUIDO: 'CONCLUIDO',\n AGUARDANDO_CORRECAO: 'AGUARDANDO_CORRECAO',\n AGUARDANDO_RESPOSTA: 'AGUARDANDO_RESPOSTA',\n NAO_ENTREGUE: 'NAO_ENTREGUE',\n} as const;\n\nexport type StudentActivityStatus =\n (typeof STUDENT_ACTIVITY_STATUS)[keyof typeof STUDENT_ACTIVITY_STATUS];\n\n/**\n * Zod schema for student activity status\n */\nexport const studentActivityStatusSchema = z.enum([\n STUDENT_ACTIVITY_STATUS.CONCLUIDO,\n STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO,\n STUDENT_ACTIVITY_STATUS.AGUARDANDO_RESPOSTA,\n STUDENT_ACTIVITY_STATUS.NAO_ENTREGUE,\n]);\n\n/**\n * Student data interface\n */\nexport interface ActivityStudentData {\n studentId: string;\n studentName: string;\n answeredAt: string | null;\n timeSpent: number;\n score: number | null;\n status: StudentActivityStatus;\n}\n\n/**\n * Pagination interface\n */\nexport interface Pagination {\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n hasNext?: boolean;\n hasPrev?: boolean;\n}\n\n/**\n * General statistics interface\n */\nexport interface GeneralStats {\n averageScore: number;\n completionPercentage: number;\n}\n\n/**\n * Question statistics interface\n */\nexport interface QuestionStats {\n mostCorrect: number[];\n mostIncorrect: number[];\n notAnswered: number[];\n}\n\n/**\n * Activity metadata interface\n */\nexport interface ActivityMetadata {\n id: string;\n title: string;\n type?: string;\n startDate: string | null;\n finalDate: string | null;\n schoolName: string;\n year: string;\n subjectName: string;\n className: string;\n}\n\n/**\n * Activity details data interface\n */\nexport interface ActivityDetailsData {\n activity?: ActivityMetadata;\n students: ActivityStudentData[];\n pagination: Pagination;\n generalStats: GeneralStats;\n questionStats: QuestionStats;\n}\n\n/**\n * Activity details query params interface\n */\nexport interface ActivityDetailsQueryParams {\n page?: number;\n limit?: number;\n sortBy?: 'name' | 'score' | 'answeredAt';\n sortOrder?: 'asc' | 'desc';\n status?: StudentActivityStatus;\n}\n\n/**\n * Activity student table item interface\n */\nexport interface ActivityStudentTableItem extends Record<string, unknown> {\n id: string;\n studentId: string;\n studentName: string;\n status: StudentActivityStatus;\n answeredAt: string | null;\n timeSpent: number;\n score: number | null;\n}\n\n/**\n * Status badge configuration interface\n */\nexport interface StatusBadgeConfig {\n label: string;\n bgColor: string;\n textColor: string;\n}\n\n/**\n * Activity availability status enum\n * Used to determine if an activity is available based on start/end dates\n */\nexport const ACTIVITY_AVAILABILITY = {\n DISPONIVEL: 'DISPONIVEL',\n NAO_INICIADA: 'NAO_INICIADA',\n EXPIRADA: 'EXPIRADA',\n} as const;\n\nexport type ActivityAvailability =\n (typeof ACTIVITY_AVAILABILITY)[keyof typeof ACTIVITY_AVAILABILITY];\n\n/**\n * Quiz API response\n */\nexport interface QuizResponse {\n message: string;\n data: ActivityMetadata;\n}\n\n/**\n * Activity details API response (without activity)\n */\nexport interface ActivityDetailsApiResponse {\n message: string;\n data: Omit<ActivityDetailsData, 'activity'>;\n}\n\n/**\n * Presigned URL response\n */\nexport interface PresignedUrlResponse {\n data: {\n url: string;\n fields: Record<string, string>;\n };\n}\n","/**\n * Activity Details Utilities\n * Helper functions for activity details components\n */\n\nimport type {\n StudentActivityStatus,\n StatusBadgeConfig,\n} from '../types/activityDetails';\nimport { STUDENT_ACTIVITY_STATUS } from '../types/activityDetails';\n\n/**\n * Get status badge configuration\n * @param status - Student activity status\n * @returns Status badge configuration with label and colors\n */\nexport const getStatusBadgeConfig = (\n status: StudentActivityStatus\n): StatusBadgeConfig => {\n const configs: Record<StudentActivityStatus, StatusBadgeConfig> = {\n [STUDENT_ACTIVITY_STATUS.CONCLUIDO]: {\n label: 'Concluído',\n bgColor: 'bg-green-50',\n textColor: 'text-green-800',\n },\n [STUDENT_ACTIVITY_STATUS.AGUARDANDO_CORRECAO]: {\n label: 'Aguardando Correção',\n bgColor: 'bg-yellow-50',\n textColor: 'text-yellow-800',\n },\n [STUDENT_ACTIVITY_STATUS.AGUARDANDO_RESPOSTA]: {\n label: 'Aguardando Resposta',\n bgColor: 'bg-blue-50',\n textColor: 'text-blue-800',\n },\n [STUDENT_ACTIVITY_STATUS.NAO_ENTREGUE]: {\n label: 'Não Entregue',\n bgColor: 'bg-red-50',\n textColor: 'text-red-800',\n },\n };\n\n return configs[status];\n};\n\n/**\n * Format time spent in seconds to HH:MM:SS\n * @param seconds - Time in seconds\n * @returns Formatted time string in HH:MM:SS format\n */\nexport const formatTimeSpent = (seconds: number): string => {\n const totalSeconds = Math.floor(Math.abs(seconds));\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const secs = totalSeconds % 60;\n\n return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n};\n\n/**\n * Format question numbers to display\n * @param numbers - Array of zero-based question indices\n * @returns Formatted string with question numbers (1-indexed, padded)\n */\nexport const formatQuestionNumbers = (numbers: number[]): string => {\n if (numbers.length === 0) return '-';\n\n return numbers.map((n) => String(n + 1).padStart(2, '0')).join(', ');\n};\n\n/**\n * Format date string to Brazilian format (DD/MM/YYYY)\n * @param dateString - ISO date string\n * @returns Formatted date string\n */\nexport const formatDateToBrazilian = (dateString: string): string => {\n const date = new Date(dateString);\n const day = String(date.getUTCDate()).padStart(2, '0');\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const year = date.getUTCFullYear();\n return `${day}/${month}/${year}`;\n};\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n primary:\n 'bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed',\n secondary:\n 'bg-text-950 text-text border border-text-800 hover:bg-text-800 hover:border-text-950 focus-visible:outline-none focus-visible:bg-text-900 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-text-700 active:border-text-700 disabled:bg-text-500 disabled:border-text-500 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n outline: {\n primary:\n 'bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n secondary:\n 'bg-transparent text-text-950 border border-text-800 hover:bg-background-50 hover:text-text-700 hover:border-text-700 focus-visible:border-0 focus-visible:outline-none focus-visible:text-text-900 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-text-700 active:border-text-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n link: {\n primary:\n 'bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed',\n secondary:\n 'bg-transparent text-text-950 hover:text-text-800 focus-visible:outline-none focus-visible:text-text-900 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-text-700 disabled:opacity-40 disabled:cursor-not-allowed',\n positive:\n 'bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed',\n negative:\n 'bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed',\n },\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n 'extra-small': 'text-xs px-3.5 py-2',\n small: 'text-sm px-4 py-2.5',\n medium: 'text-md px-5 py-2.5',\n large: 'text-lg px-6 py-3',\n 'extra-large': 'text-lg px-7 py-3.5',\n} as const;\n\n/**\n * Button component props interface\n */\ntype ButtonProps = {\n /** Content to be displayed inside the button */\n children: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Size of the button */\n size?: 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large';\n /** Visual variant of the button */\n variant?: 'solid' | 'outline' | 'link';\n /** Action type of the button */\n action?: 'primary' | 'secondary' | 'positive' | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Button component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the button\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, secondary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard button HTML attributes\n * @returns A styled button element\n *\n * @example\n * ```tsx\n * <Button variant=\"solid\" action=\"primary\" size=\"medium\" onClick={() => console.log('clicked')}>\n * Click me\n * </Button>\n * ```\n */\nconst Button = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'primary',\n className = '',\n disabled,\n type = 'button',\n ...props\n}: ButtonProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_ACTION_CLASSES[variant][action];\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-full cursor-pointer font-medium';\n\n return (\n <button\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n disabled={disabled}\n type={type}\n {...props}\n >\n {iconLeft && <span className=\"mr-2 flex items-center\">{iconLeft}</span>}\n {children}\n {iconRight && <span className=\"ml-2 flex items-center\">{iconRight}</span>}\n </button>\n );\n};\n\nexport default Button;\n","import { HTMLAttributes, ReactNode } from 'react';\nimport { Bell } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n error: 'bg-error-background text-error-700 focus-visible:outline-none',\n warning: 'bg-warning text-warning-800 focus-visible:outline-none',\n success: 'bg-success text-success-800 focus-visible:outline-none',\n info: 'bg-info text-info-800 focus-visible:outline-none',\n muted: 'bg-background-muted text-background-800 focus-visible:outline-none',\n },\n outlined: {\n error:\n 'bg-error text-error-700 border border-error-300 focus-visible:outline-none',\n warning:\n 'bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none',\n success:\n 'bg-success text-success-800 border border-success-300 focus-visible:outline-none',\n info: 'bg-info text-info-800 border border-info-300 focus-visible:outline-none',\n muted:\n 'bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none',\n },\n exams: {\n exam1: 'bg-exam-1 text-info-700 focus-visible:outline-none',\n exam2: 'bg-exam-2 text-typography-1 focus-visible:outline-none',\n exam3: 'bg-exam-3 text-typography-2 focus-visible:outline-none',\n exam4: 'bg-exam-4 text-success-700 focus-visible:outline-none',\n },\n examsOutlined: {\n exam1:\n 'bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none',\n exam2:\n 'bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none',\n exam3:\n 'bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none',\n exam4:\n 'bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none',\n },\n resultStatus: {\n negative: 'bg-error text-error-800 focus-visible:outline-none',\n positive: 'bg-success text-success-800 focus-visible:outline-none',\n },\n notification: 'text-primary',\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-2xs px-2 py-1',\n medium: 'text-xs px-2 py-1',\n large: 'text-sm px-2 py-1',\n} as const;\n\nconst SIZE_CLASSES_ICON = {\n small: 'size-3',\n medium: 'size-3.5',\n large: 'size-4',\n} as const;\n\n/**\n * Badge component props interface\n */\ntype BadgeProps = {\n /** Content to be displayed inside the badge */\n children?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Size of the badge */\n size?: 'small' | 'medium' | 'large';\n /** Visual variant of the badge */\n variant?:\n | 'solid'\n | 'outlined'\n | 'exams'\n | 'examsOutlined'\n | 'resultStatus'\n | 'notification';\n /** Action type of the badge */\n action?:\n | 'error'\n | 'warning'\n | 'success'\n | 'info'\n | 'muted'\n | 'exam1'\n | 'exam2'\n | 'exam3'\n | 'exam4'\n | 'positive'\n | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n notificationActive?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\n/**\n * Badge component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the badge\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard div HTML attributes\n * @returns A styled badge element\n *\n * @example\n * ```tsx\n * <Badge variant=\"solid\" action=\"info\" size=\"medium\">\n * Information\n * </Badge>\n * ```\n */\nconst Badge = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'error',\n className = '',\n notificationActive = false,\n ...props\n}: BadgeProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const sizeClassesIcon = SIZE_CLASSES_ICON[size];\n const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};\n const variantClasses =\n typeof variantActionMap === 'string'\n ? variantActionMap\n : ((variantActionMap as Record<string, string>)[action] ??\n (variantActionMap as Record<string, string>).muted ??\n '');\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-xs font-normal gap-1 relative';\n\n const baseClassesIcon = 'flex items-center';\n if (variant === 'notification') {\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n <Bell size={24} className=\"text-current\" aria-hidden=\"true\" />\n\n {notificationActive && (\n <span\n data-testid=\"notification-dot\"\n className=\"absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white\"\n />\n )}\n </div>\n );\n }\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n {iconLeft && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>{iconLeft}</span>\n )}\n {children}\n {iconRight && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>\n {iconRight}\n </span>\n )}\n </div>\n );\n};\n\nexport default Badge;\n","import { type ReactNode } from 'react';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\n\nexport interface EmptyStateProps {\n /**\n * Image source for the illustration (optional)\n */\n image?: string;\n /**\n * Title text to display\n * @default \"Nenhum dado disponível\"\n */\n title?: string;\n /**\n * Description text to display below the title\n * @default \"Não há dados para exibir no momento.\"\n */\n description?: string;\n /**\n * Button text (optional - if not provided, button won't be displayed)\n */\n buttonText?: string;\n /**\n * Icon to display on the left side of the button\n */\n buttonIcon?: ReactNode;\n /**\n * Callback function when button is clicked\n */\n onButtonClick?: () => void;\n /**\n * Button variant\n * @default \"solid\"\n */\n buttonVariant?: 'solid' | 'outline' | 'link';\n /**\n * Button action color\n * @default \"primary\"\n */\n buttonAction?: 'primary' | 'positive' | 'negative';\n}\n\n/**\n * Component displayed when there is no data to show (empty state)\n * Shows an illustration with customizable title, description, and optional button in horizontal layout\n *\n * @example\n * ```tsx\n * import { EmptyState } from 'analytica-frontend-lib';\n * import activityImage from './assets/activity.png';\n * import { Plus } from 'phosphor-react';\n *\n * <EmptyState\n * image={activityImage}\n * title=\"Incentive sua turma ao aprendizado\"\n * description=\"Crie uma nova atividade e ajude seus alunos a colocarem o conteúdo em prática!\"\n * buttonText=\"Criar atividade\"\n * buttonIcon={<Plus size={18} />}\n * buttonVariant=\"outline\"\n * onButtonClick={handleCreateActivity}\n * />\n * ```\n */\nconst EmptyState = ({\n image,\n title,\n description,\n buttonText,\n buttonIcon,\n onButtonClick,\n buttonVariant = 'solid',\n buttonAction = 'primary',\n}: EmptyStateProps) => {\n const displayTitle = title || 'Nenhum dado disponível';\n const displayDescription =\n description || 'Não há dados para exibir no momento.';\n\n return (\n <div className=\"flex flex-col justify-center items-center gap-6 w-full min-h-[705px] bg-background rounded-xl p-6\">\n {/* Illustration */}\n {image && (\n <img src={image} alt={displayTitle} className=\"w-[170px] h-[150px]\" />\n )}\n\n {/* Text Content Container */}\n <div className=\"flex flex-col items-center gap-4 w-full max-w-[600px] px-6\">\n {/* Title */}\n <Text\n as=\"h2\"\n className=\"text-text-950 font-semibold text-3xl leading-[35px] text-center\"\n >\n {displayTitle}\n </Text>\n\n {/* Description */}\n <Text className=\"text-text-600 font-normal text-[18px] leading-[27px] text-center\">\n {displayDescription}\n </Text>\n </div>\n\n {/* Button */}\n {buttonText && onButtonClick && (\n <Button\n variant={buttonVariant}\n action={buttonAction}\n size=\"large\"\n onClick={onButtonClick}\n iconLeft={buttonIcon}\n className=\"rounded-full px-5 py-2.5\"\n >\n {buttonText}\n </Button>\n )}\n </div>\n );\n};\n\nexport default EmptyState;\n","import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\nimport { cn } from '../../utils/utils';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col', spacingClass, className)}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={cn(variantClass, animationClass)}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={cn(variantClass, animationClass, className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full p-4 bg-background border border-border-200 rounded-lg',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('space-y-3', className)} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n","import { useState, useEffect, useMemo, useCallback, ReactNode } from 'react';\nimport Table, {\n TableBody,\n TableHead,\n TableRow,\n TableCell,\n useTableSort,\n TablePagination,\n} from '../Table/Table';\nimport { useTableFilter, FilterConfig } from '../Filter/useTableFilter';\nimport Search from '../Search/Search';\nimport { FilterModal } from '../Filter/FilterModal';\nimport Button from '../Button/Button';\nimport { Funnel } from 'phosphor-react';\n\n/**\n * Column configuration with flexible rendering options\n */\nexport interface ColumnConfig<T = Record<string, unknown>> {\n /** Column key (must match data object key) */\n key: string;\n /** Column label - can be string or JSX */\n label: string | ReactNode;\n /** Enable sorting for this column */\n sortable?: boolean;\n /** Custom render function for cell content */\n render?: (value: unknown, row: T, index: number) => ReactNode;\n /** Column width */\n width?: string;\n /** Additional CSS classes */\n className?: string;\n /** Text alignment */\n align?: 'left' | 'center' | 'right';\n}\n\n/**\n * Combined parameters sent via onParamsChange\n */\nexport interface TableParams {\n /** Current page number */\n page: number;\n /** Items per page */\n limit: number;\n /** Search query */\n search?: string;\n /** Active filters (dynamic keys based on filter configs) */\n [key: string]: unknown;\n /** Sort column */\n sortBy?: string;\n /** Sort direction */\n sortOrder?: 'asc' | 'desc';\n}\n\n/**\n * Pagination configuration\n */\nexport interface PaginationConfig {\n /** Label for items (e.g., \"atividades\") */\n itemLabel?: string;\n /** Items per page options */\n itemsPerPageOptions?: number[];\n /** Default items per page */\n defaultItemsPerPage?: number;\n /** Total items (for displaying pagination info) */\n totalItems?: number;\n /** Total pages (if known from backend) */\n totalPages?: number;\n}\n\n/**\n * Empty state configuration\n */\nexport interface EmptyStateConfig {\n /** Custom component to render when table is empty (no data and no search active) */\n component?: ReactNode;\n /** Image to display in empty state (path from project) */\n image?: string;\n /** Title text for empty state */\n title?: string;\n /** Description text for empty state */\n description?: string;\n /** Button text for empty state action (optional) */\n buttonText?: string;\n /** Icon to display on button (optional) */\n buttonIcon?: ReactNode;\n /** Callback when empty state button is clicked */\n onButtonClick?: () => void;\n /** Button variant (solid, outline, or link) */\n buttonVariant?: 'solid' | 'outline' | 'link';\n /** Button action color (primary, positive, or negative) */\n buttonAction?: 'primary' | 'positive' | 'negative';\n}\n\n/**\n * Loading state configuration\n */\nexport interface LoadingStateConfig {\n /** Custom component to render when table is loading */\n component?: ReactNode;\n}\n\n/**\n * No search result state configuration\n */\nexport interface NoSearchResultConfig {\n /** Custom component to render when search returns no results */\n component?: ReactNode;\n /** Title for no search result state */\n title?: string;\n /** Description for no search result state */\n description?: string;\n /** Image to display in no search result state */\n image?: string;\n}\n\n/**\n * Table components exposed via render prop\n */\nexport interface TableComponents {\n /** Search and filter controls */\n controls: ReactNode;\n /** Table with data */\n table: ReactNode;\n /** Pagination controls */\n pagination: ReactNode;\n}\n\n/**\n * TableProvider Props\n */\nexport interface TableProviderProps<T = Record<string, unknown>> {\n /** Data to display in the table */\n readonly data: T[];\n /** Column configurations */\n readonly headers: ColumnConfig<T>[];\n /** Loading state */\n readonly loading?: boolean;\n /** Table variant */\n readonly variant?: 'default' | 'borderless';\n\n /** Enable search functionality */\n readonly enableSearch?: boolean;\n /** Enable filters functionality */\n readonly enableFilters?: boolean;\n /** Enable table sorting */\n readonly enableTableSort?: boolean;\n /** Enable pagination */\n readonly enablePagination?: boolean;\n /** Enable row click functionality */\n readonly enableRowClick?: boolean;\n\n /** Initial filter configurations */\n readonly initialFilters?: FilterConfig[];\n /** Pagination configuration */\n readonly paginationConfig?: PaginationConfig;\n /** Search placeholder text */\n readonly searchPlaceholder?: string;\n /** Empty state configuration (when table is empty with no search) */\n readonly emptyState?: EmptyStateConfig;\n /** Loading state configuration (when table is loading) */\n readonly loadingState?: LoadingStateConfig;\n /** No search result state configuration (when search returns no results) */\n readonly noSearchResultState?: NoSearchResultConfig;\n /** Key field name to use for unique row identification (recommended for better performance) */\n readonly rowKey?: keyof T;\n\n /** Callback when any parameter changes */\n readonly onParamsChange?: (params: TableParams) => void;\n /** Callback when row is clicked */\n readonly onRowClick?: (row: T, index: number) => void;\n\n /**\n * Content to display in the header area (e.g., action buttons)\n * Rendered above the search/filter controls\n */\n readonly headerContent?: ReactNode;\n\n /**\n * Additional CSS classes for the container wrapper\n */\n readonly containerClassName?: string;\n\n /**\n * Render prop for custom layout control\n * When provided, gives full control over component positioning\n * @param components - Table components (controls, table, pagination)\n * @returns Custom layout JSX\n *\n * @example\n * ```tsx\n * <TableProvider {...props}>\n * {({ controls, table, pagination }) => (\n * <>\n * <div className=\"mb-4\">{controls}</div>\n * <div className=\"bg-white p-6\">\n * {table}\n * {pagination}\n * </div>\n * </>\n * )}\n * </TableProvider>\n * ```\n */\n readonly children?: (components: TableComponents) => ReactNode;\n}\n\n/**\n * TableProvider - Self-contained table component with search, filters, sorting, and pagination\n *\n * @example\n * ```tsx\n * <TableProvider\n * data={activities}\n * headers={[\n * { key: 'title', label: 'Título', sortable: true },\n * { key: 'status', label: 'Status', render: (value) => <Badge>{value}</Badge> }\n * ]}\n * loading={loading}\n * variant=\"borderless\"\n * enableSearch\n * enableFilters\n * enableTableSort\n * enablePagination\n * enableRowClick\n * initialFilters={filterConfigs}\n * paginationConfig={{ itemLabel: 'atividades' }}\n * onParamsChange={handleParamsChange}\n * onRowClick={handleRowClick}\n * />\n * ```\n */\nexport function TableProvider<T extends Record<string, unknown>>({\n data,\n headers,\n loading = false,\n variant = 'default',\n enableSearch = false,\n enableFilters = false,\n enableTableSort = false,\n enablePagination = false,\n enableRowClick = false,\n initialFilters = [],\n paginationConfig = {},\n searchPlaceholder = 'Buscar...',\n emptyState,\n loadingState,\n noSearchResultState,\n rowKey,\n onParamsChange,\n onRowClick,\n headerContent,\n containerClassName,\n children,\n}: TableProviderProps<T>) {\n // Search state\n const [searchQuery, setSearchQuery] = useState('');\n\n // Sorting state - always call hook (React Rules of Hooks)\n const sortResultRaw = useTableSort(data, { syncWithUrl: true });\n const sortResult = enableTableSort\n ? sortResultRaw\n : {\n sortedData: data,\n sortColumn: null,\n sortDirection: null,\n handleSort: () => {},\n };\n\n const { sortedData, sortColumn, sortDirection, handleSort } = sortResult;\n\n // Filter state - always call hook (React Rules of Hooks)\n const filterResultRaw = useTableFilter(initialFilters, { syncWithUrl: true });\n\n // Memoize disabled filter result to prevent recreating object on every render\n const disabledFilterResult = useMemo(\n () => ({\n filterConfigs: [],\n activeFilters: {},\n hasActiveFilters: false,\n updateFilters: () => {},\n applyFilters: () => {},\n clearFilters: () => {},\n }),\n []\n );\n\n const filterResult = enableFilters ? filterResultRaw : disabledFilterResult;\n\n const {\n filterConfigs,\n activeFilters,\n hasActiveFilters,\n updateFilters,\n applyFilters,\n clearFilters,\n } = filterResult;\n\n // Pagination state (only if enabled)\n const {\n defaultItemsPerPage = 10,\n itemsPerPageOptions = [10, 20, 50, 100],\n itemLabel = 'itens',\n totalItems,\n totalPages,\n } = paginationConfig;\n\n const [currentPage, setCurrentPage] = useState(1);\n const [itemsPerPage, setItemsPerPage] = useState(defaultItemsPerPage);\n\n // Filter modal state\n const [isFilterModalOpen, setIsFilterModalOpen] = useState(false);\n\n // Combine all parameters\n const combinedParams = useMemo((): TableParams => {\n const params: TableParams = {\n page: currentPage,\n limit: itemsPerPage,\n };\n\n if (enableSearch && searchQuery) {\n params.search = searchQuery;\n }\n\n if (enableFilters) {\n Object.assign(params, activeFilters);\n }\n\n if (enableTableSort && sortColumn && sortDirection) {\n params.sortBy = sortColumn;\n params.sortOrder = sortDirection;\n }\n\n return params;\n }, [\n currentPage,\n itemsPerPage,\n searchQuery,\n activeFilters,\n sortColumn,\n sortDirection,\n enableSearch,\n enableFilters,\n enableTableSort,\n ]);\n\n // Notify parent when parameters change\n // Note: onParamsChange is omitted from dependencies intentionally to prevent infinite loops\n useEffect(() => {\n onParamsChange?.(combinedParams);\n }, [combinedParams]);\n\n // Handle search changes\n const handleSearchChange = useCallback((value: string) => {\n setSearchQuery(value);\n setCurrentPage(1); // Reset to first page on search\n }, []);\n\n // Handle filter apply\n const handleFilterApply = useCallback(() => {\n applyFilters();\n setIsFilterModalOpen(false);\n setCurrentPage(1); // Reset to first page on filter\n }, [applyFilters]);\n\n // Handle pagination change\n const handlePageChange = useCallback((page: number) => {\n setCurrentPage(page);\n }, []);\n\n const handleItemsPerPageChange = useCallback((items: number) => {\n setItemsPerPage(items);\n setCurrentPage(1); // Reset to first page when changing items per page\n }, []);\n\n // Handle row click\n const handleRowClickInternal = useCallback(\n (row: T, index: number) => {\n if (enableRowClick && onRowClick) {\n onRowClick(row, index);\n }\n },\n [enableRowClick, onRowClick]\n );\n\n // Detect if pagination should be managed internally\n const useInternalPagination = useMemo(\n () =>\n enablePagination &&\n !onParamsChange &&\n totalItems === undefined &&\n totalPages === undefined,\n [enablePagination, onParamsChange, totalItems, totalPages]\n );\n\n // Calculate total pages from data if not provided\n const calculatedTotalPages =\n totalPages ??\n Math.ceil(\n (totalItems ??\n (useInternalPagination ? sortedData.length : data.length)) /\n itemsPerPage\n );\n const calculatedTotalItems =\n totalItems ?? (useInternalPagination ? sortedData.length : data.length);\n\n // Apply pagination to data when managed internally\n const displayData = useMemo(() => {\n if (!useInternalPagination) {\n return sortedData;\n }\n\n const start = (currentPage - 1) * itemsPerPage;\n return sortedData.slice(start, start + itemsPerPage);\n }, [useInternalPagination, sortedData, currentPage, itemsPerPage]);\n\n // Empty state check\n const isEmpty = data.length === 0;\n\n // Calculate state control booleans - Table is responsible for rendering, TableProvider controls WHEN\n const showLoading = loading;\n const showNoSearchResult =\n !loading && data.length === 0 && searchQuery.trim() !== '';\n const showEmpty = !loading && data.length === 0 && searchQuery.trim() === '';\n\n // Extract components for render prop pattern\n const controls = (enableSearch || enableFilters) && (\n <div className=\"flex items-center gap-4\">\n {/* Filter Button */}\n {enableFilters && (\n <Button\n variant=\"outline\"\n size=\"medium\"\n onClick={() => setIsFilterModalOpen(true)}\n >\n <Funnel size={20} />\n Filtros\n {hasActiveFilters && (\n <span className=\"ml-2 rounded-full bg-primary-500 px-2 py-0.5 text-xs text-white\">\n {Object.keys(activeFilters).length}\n </span>\n )}\n </Button>\n )}\n\n {/* Search */}\n {enableSearch && (\n <div className=\"flex-1\">\n <Search\n value={searchQuery}\n onSearch={handleSearchChange}\n onClear={() => handleSearchChange('')}\n options={[]}\n placeholder={searchPlaceholder}\n />\n </div>\n )}\n </div>\n );\n\n // Header with content and controls\n const headerSection = (headerContent || controls) && (\n <div className=\"flex flex-col md:flex-row items-stretch md:items-center justify-between gap-4\">\n {/* Header Content (e.g., action buttons) */}\n {headerContent && <div>{headerContent}</div>}\n\n {/* Controls (search and filters) */}\n {controls && <div className=\"flex-1 md:flex-none\">{controls}</div>}\n </div>\n );\n\n const table = (\n <div className=\"w-full overflow-x-auto\">\n <Table\n variant={variant}\n showLoading={showLoading}\n loadingState={loadingState}\n showNoSearchResult={showNoSearchResult}\n noSearchResultState={noSearchResultState}\n showEmpty={showEmpty}\n emptyState={emptyState}\n >\n {/* Table Header */}\n <thead>\n <TableRow\n variant={variant === 'borderless' ? 'defaultBorderless' : 'default'}\n >\n {headers.map((header, index) => (\n <TableHead\n key={`header-${header.key}-${index}`}\n sortable={enableTableSort && header.sortable}\n sortDirection={\n enableTableSort && sortColumn === header.key\n ? sortDirection\n : null\n }\n onSort={() =>\n enableTableSort && header.sortable && handleSort(header.key)\n }\n className={header.className}\n style={header.width ? { width: header.width } : undefined}\n >\n {header.label}\n </TableHead>\n ))}\n </TableRow>\n </thead>\n\n {/* Table Body */}\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell colSpan={headers.length} className=\"text-center py-8\">\n <span className=\"text-text-400 text-sm\">Carregando...</span>\n </TableCell>\n </TableRow>\n ) : (\n displayData.map((row, rowIndex) => {\n // Calculate effective index for row click and keys\n const effectiveIndex = useInternalPagination\n ? (currentPage - 1) * itemsPerPage + rowIndex\n : rowIndex;\n\n const rowKeyValue = rowKey\n ? (() => {\n const keyValue = row[rowKey];\n if (keyValue === null || keyValue === undefined) {\n return `row-${effectiveIndex}`;\n }\n if (typeof keyValue === 'object') {\n return JSON.stringify(keyValue);\n }\n return String(keyValue);\n })()\n : `row-${effectiveIndex}`;\n return (\n <TableRow\n key={rowKeyValue}\n variant={\n variant === 'borderless' ? 'defaultBorderless' : 'default'\n }\n clickable={enableRowClick}\n onClick={() => handleRowClickInternal(row, effectiveIndex)}\n >\n {headers.map((header, cellIndex) => {\n const value = row[header.key];\n\n let defaultContent = '';\n\n if (value !== null && value !== undefined) {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'bigint'\n ) {\n // Only convert primitives directly to string\n defaultContent = String(value);\n } else if (typeof value === 'object') {\n // Serialize objects and arrays with JSON\n defaultContent = JSON.stringify(value);\n } else if (typeof value === 'function') {\n // Handle functions - don't expose function code\n defaultContent = '[Function]';\n } else if (typeof value === 'symbol') {\n // Handle symbols\n defaultContent = String(value);\n }\n // All possible types covered - no else needed\n }\n\n const content = header.render\n ? header.render(value, row, effectiveIndex)\n : defaultContent;\n\n return (\n <TableCell\n key={`cell-${effectiveIndex}-${cellIndex}`}\n className={header.className}\n style={{\n textAlign: header.align,\n }}\n >\n {content}\n </TableCell>\n );\n })}\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n );\n\n const pagination = enablePagination && !isEmpty && (\n <div className=\"flex justify-end\">\n <TablePagination\n currentPage={currentPage}\n totalPages={calculatedTotalPages}\n totalItems={calculatedTotalItems}\n itemsPerPage={itemsPerPage}\n itemsPerPageOptions={itemsPerPageOptions}\n onPageChange={handlePageChange}\n onItemsPerPageChange={handleItemsPerPageChange}\n itemLabel={itemLabel}\n />\n </div>\n );\n\n // If children prop provided, use render props pattern\n if (children) {\n return (\n <>\n {children({\n controls: headerSection || controls || null,\n table,\n pagination,\n })}\n {/* Filter Modal */}\n {enableFilters && (\n <FilterModal\n isOpen={isFilterModalOpen}\n onClose={() => setIsFilterModalOpen(false)}\n filterConfigs={filterConfigs}\n onFiltersChange={updateFilters}\n onApply={handleFilterApply}\n onClear={clearFilters}\n />\n )}\n </>\n );\n }\n\n // Default layout (backward compatible)\n const wrapperClassName = containerClassName || 'w-full space-y-4';\n return (\n <div className={wrapperClassName}>\n {headerSection}\n {table}\n {pagination}\n\n {/* Filter Modal */}\n {enableFilters && (\n <FilterModal\n isOpen={isFilterModalOpen}\n onClose={() => setIsFilterModalOpen(false)}\n filterConfigs={filterConfigs}\n onFiltersChange={updateFilters}\n onApply={handleFilterApply}\n onClear={clearFilters}\n />\n )}\n </div>\n );\n}\n\nexport default TableProvider;\n","import React, {\n forwardRef,\n HTMLAttributes,\n TdHTMLAttributes,\n ThHTMLAttributes,\n useState,\n useMemo,\n useEffect,\n Children,\n isValidElement,\n ReactNode,\n} from 'react';\nimport { cn } from '../../utils/utils';\nimport { CaretUp, CaretDown } from 'phosphor-react';\nimport NoSearchResult from '../NoSearchResult/NoSearchResult';\nimport EmptyState from '../EmptyState/EmptyState';\nimport { SkeletonTable } from '../Skeleton/Skeleton';\nimport type {\n EmptyStateConfig,\n LoadingStateConfig,\n NoSearchResultConfig,\n} from '../TableProvider/TableProvider';\n\ntype TableVariant = 'default' | 'borderless';\ntype TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';\nexport type SortDirection = 'asc' | 'desc' | null;\n\nexport interface UseTableSortOptions {\n /** Se true, sincroniza o estado de ordenação com os parâmetros da URL */\n syncWithUrl?: boolean;\n}\n\n/**\n * Hook para gerenciar ordenação de dados da tabela\n *\n * @param data - Array de dados a serem ordenados\n * @param options - Opções de configuração do hook\n * @returns Objeto com dados ordenados, coluna/direção atual e função de sort\n *\n * @example\n * ```tsx\n * const activities = [\n * { id: 1, name: 'Task A', date: '2024-01-01' },\n * { id: 2, name: 'Task B', date: '2024-01-02' },\n * ];\n *\n * // Sem sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities);\n *\n * // Com sincronização com URL\n * const { sortedData, sortColumn, sortDirection, handleSort } = useTableSort(activities, { syncWithUrl: true });\n *\n * <TableHead\n * sortDirection={sortColumn === 'name' ? sortDirection : null}\n * onSort={() => handleSort('name')}\n * >\n * Name\n * </TableHead>\n * ```\n */\nexport function useTableSort<T extends Record<string, unknown>>(\n data: T[],\n options: UseTableSortOptions = {}\n) {\n const { syncWithUrl = false } = options;\n\n // Inicializar estado a partir da URL se syncWithUrl estiver habilitado\n const getInitialState = () => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return { column: null, direction: null };\n }\n\n const params = new URLSearchParams(globalThis.location.search);\n const sortBy = params.get('sortBy');\n const sort = params.get('sort');\n\n if (sortBy && sort && (sort === 'ASC' || sort === 'DESC')) {\n return {\n column: sortBy,\n direction: sort.toLowerCase() as SortDirection,\n };\n }\n\n return { column: null, direction: null };\n };\n\n const initialState = getInitialState();\n const [sortColumn, setSortColumn] = useState<string | null>(\n initialState.column\n );\n const [sortDirection, setSortDirection] = useState<SortDirection>(\n initialState.direction\n );\n\n // Atualizar URL quando o estado de ordenação mudar\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) return;\n\n const url = new URL(globalThis.location.href);\n const params = url.searchParams;\n\n if (sortColumn && sortDirection) {\n params.set('sortBy', sortColumn);\n params.set('sort', sortDirection.toUpperCase());\n } else {\n params.delete('sortBy');\n params.delete('sort');\n }\n\n // Atualizar URL sem recarregar a página\n globalThis.history.replaceState({}, '', url.toString());\n }, [sortColumn, sortDirection, syncWithUrl]);\n\n const handleSort = (column: string) => {\n if (sortColumn === column) {\n if (sortDirection === 'asc') {\n setSortDirection('desc');\n } else if (sortDirection === 'desc') {\n setSortColumn(null);\n setSortDirection(null);\n }\n } else {\n setSortColumn(column);\n setSortDirection('asc');\n }\n };\n\n const sortedData = useMemo(() => {\n if (!sortColumn || !sortDirection) {\n return data;\n }\n\n return [...data].sort((a, b) => {\n const aValue = a[sortColumn as keyof T];\n const bValue = b[sortColumn as keyof T];\n\n if (typeof aValue === 'string' && typeof bValue === 'string') {\n const comparison = aValue.localeCompare(bValue);\n return sortDirection === 'asc' ? comparison : -comparison;\n }\n\n if (typeof aValue === 'number' && typeof bValue === 'number') {\n return sortDirection === 'asc' ? aValue - bValue : bValue - aValue;\n }\n\n return 0;\n });\n }, [data, sortColumn, sortDirection]);\n\n return { sortedData, sortColumn, sortDirection, handleSort };\n}\n\ninterface TableProps extends HTMLAttributes<HTMLTableElement> {\n variant?: TableVariant;\n\n /** Show loading state (controlled by TableProvider) */\n showLoading?: boolean;\n /** Loading state configuration */\n loadingState?: LoadingStateConfig;\n\n /** Show no search result state (controlled by TableProvider) */\n showNoSearchResult?: boolean;\n /** No search result state configuration */\n noSearchResultState?: NoSearchResultConfig;\n\n /** Show empty state (controlled by TableProvider) */\n showEmpty?: boolean;\n /** Empty state configuration */\n emptyState?: EmptyStateConfig;\n}\n\ninterface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n state?: TableRowState;\n}\n\n/**\n * Renders the table header and caption from children\n */\nconst renderHeaderElements = (children: ReactNode) => {\n return Children.map(children, (child) => {\n if (\n isValidElement(child) &&\n (child.type === TableCaption || child.type === TableHeader)\n ) {\n return child;\n }\n return null;\n });\n};\n\n/**\n * Gets no search result content based on configuration\n */\nconst getNoSearchResultContent = (\n config: NoSearchResultConfig,\n defaultTitle: string,\n defaultDescription: string\n) => {\n if (config.component) {\n return config.component;\n }\n\n if (config.image) {\n return (\n <NoSearchResult\n image={config.image}\n title={config.title || defaultTitle}\n description={config.description || defaultDescription}\n />\n );\n }\n\n return (\n <div className=\"text-center\">\n <p className=\"text-text-600 text-lg font-semibold mb-2\">\n {config.title || defaultTitle}\n </p>\n <p className=\"text-text-500 text-sm\">\n {config.description || defaultDescription}\n </p>\n </div>\n );\n};\n\n/**\n * Gets empty state content based on configuration\n */\nconst getEmptyStateContent = (\n config: EmptyStateConfig | undefined,\n defaultTitle: string,\n defaultDescription: string\n) => {\n if (config?.component) {\n return config.component;\n }\n\n return (\n <EmptyState\n image={config?.image}\n title={config?.title || defaultTitle}\n description={config?.description || defaultDescription}\n buttonText={config?.buttonText}\n buttonIcon={config?.buttonIcon}\n onButtonClick={config?.onButtonClick}\n buttonVariant={config?.buttonVariant}\n buttonAction={config?.buttonAction}\n />\n );\n};\n\n/**\n * Renders table wrapper with header and state content\n */\nconst renderTableWrapper = (\n variant: TableVariant,\n tableRef: React.Ref<HTMLTableElement>,\n className: string | undefined,\n children: ReactNode,\n stateContent: ReactNode,\n tableProps: HTMLAttributes<HTMLTableElement>\n) => {\n return (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={tableRef}\n className={cn(\n 'analytica-table w-full caption-bottom text-sm border-separate border-spacing-0',\n className\n )}\n {...tableProps}\n >\n {renderHeaderElements(children)}\n </table>\n <div className=\"py-8 flex justify-center\">{stateContent}</div>\n </div>\n );\n};\n\nconst Table = forwardRef<HTMLTableElement, TableProps>(\n (\n {\n variant = 'default',\n className,\n children,\n showLoading = false,\n loadingState,\n showNoSearchResult = false,\n noSearchResultState,\n showEmpty = false,\n emptyState,\n ...props\n },\n ref\n ) => {\n // Default configurations\n const defaultNoSearchResultState: NoSearchResultConfig = {\n title: 'Nenhum resultado encontrado',\n description:\n 'Não encontramos nenhum resultado com esse nome. Tente revisar a busca ou usar outra palavra-chave.',\n };\n\n const defaultEmptyState: EmptyStateConfig = {\n title: 'Nenhum dado disponível',\n description: 'Não há dados para exibir no momento.',\n };\n\n const finalNoSearchResultState =\n noSearchResultState || defaultNoSearchResultState;\n const finalEmptyState = emptyState || defaultEmptyState;\n\n // Render Loading State FIRST (highest priority)\n if (showLoading) {\n const loadingContent = loadingState?.component || (\n <SkeletonTable rows={5} columns={4} showHeader={false} />\n );\n return renderTableWrapper(\n variant,\n ref,\n className,\n children,\n loadingContent,\n props\n );\n }\n\n // Render NoSearchResult outside table\n if (showNoSearchResult) {\n const noSearchContent = getNoSearchResultContent(\n finalNoSearchResultState,\n defaultNoSearchResultState.title || '',\n defaultNoSearchResultState.description || ''\n );\n return renderTableWrapper(\n variant,\n ref,\n className,\n children,\n noSearchContent,\n props\n );\n }\n\n // Render Empty State outside table (same pattern as NoSearchResult)\n if (showEmpty) {\n const emptyContent = getEmptyStateContent(\n finalEmptyState,\n defaultEmptyState.title || 'Nenhum dado disponível',\n defaultEmptyState.description || 'Não há dados para exibir no momento.'\n );\n return renderTableWrapper(\n variant,\n ref,\n className,\n children,\n emptyContent,\n props\n );\n }\n\n return (\n <div\n className={cn(\n 'relative w-full overflow-x-auto',\n variant === 'default' && 'border border-border-200 rounded-xl'\n )}\n >\n <table\n ref={ref}\n className={cn(\n variant === 'default' && 'analytica-table',\n variant === 'default' && 'border-separate border-spacing-0',\n 'w-full caption-bottom text-sm',\n className\n )}\n {...props}\n >\n {/* Render fallback caption only if no TableCaption provided */}\n {!Children.toArray(children).some(\n (child) => isValidElement(child) && child.type === TableCaption\n ) && <caption className=\"sr-only\">My Table</caption>}\n {children}\n </table>\n </div>\n );\n }\n);\n\nTable.displayName = 'Table';\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead\n ref={ref}\n className={cn('[&_tr:first-child]:border-0', className)}\n {...props}\n />\n));\nTableHeader.displayName = 'TableHeader';\n\ninterface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, variant = 'default', ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn(\n '[&_tr:last-child]:border-border-200',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableBody.displayName = 'TableBody';\n\ninterface TableFooterProps extends HTMLAttributes<HTMLTableSectionElement> {\n variant?: TableVariant;\n}\n\nconst TableFooter = forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ variant = 'default', className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'bg-background-50 font-medium [&>tr]:last:border-b-0 px-6 py-3.5',\n variant === 'default' && 'border-t border-border-200',\n className\n )}\n {...props}\n />\n )\n);\nTableFooter.displayName = 'TableFooter';\n\nconst VARIANT_STATES_ROW = {\n default: {\n default: 'border border-border-200',\n defaultBorderless: 'border-b border-border-200',\n borderless: '',\n },\n selected: {\n default: 'border-b-2 border-indicator-primary',\n defaultBorderless: 'border-b border-indicator-primary',\n borderless: 'bg-indicator-primary/10',\n },\n invalid: {\n default: 'border-b-2 border-indicator-error',\n defaultBorderless: 'border-b border-indicator-error',\n borderless: 'bg-indicator-error/10',\n },\n disabled: {\n default:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n defaultBorderless:\n 'border-b border-border-100 bg-background-50 opacity-50 cursor-not-allowed',\n borderless: 'bg-background-50 opacity-50 cursor-not-allowed',\n },\n} as const;\n\ninterface TableRowPropsExtended extends TableRowProps {\n variant?: TableVariant | 'defaultBorderless';\n clickable?: boolean;\n}\n\nconst TableRow = forwardRef<HTMLTableRowElement, TableRowPropsExtended>(\n (\n {\n variant = 'default',\n state = 'default',\n clickable = false,\n className,\n ...props\n },\n ref\n ) => {\n return (\n <tr\n ref={ref}\n className={cn(\n 'transition-colors',\n state === 'disabled' ? '' : 'hover:bg-muted/50',\n state === 'disabled' || !clickable ? '' : 'cursor-pointer',\n VARIANT_STATES_ROW[state][variant],\n className\n )}\n aria-disabled={state === 'disabled'}\n {...props}\n />\n );\n }\n);\nTableRow.displayName = 'TableRow';\n\ninterface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Enable sorting on this column (default: true) */\n sortable?: boolean;\n /** Current sort direction for this column */\n sortDirection?: SortDirection;\n /** Callback when column header is clicked */\n onSort?: () => void;\n}\n\nconst TableHead = forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n sortable = true,\n sortDirection = null,\n onSort,\n children,\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (sortable && onSort) {\n onSort();\n }\n };\n\n return (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-6 py-3.5 text-left align-middle font-bold text-base text-text-800 tracking-[0.2px] leading-none [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] whitespace-nowrap',\n sortable && 'cursor-pointer select-none hover:bg-muted/30',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n {children}\n {sortable && (\n <div className=\"flex flex-col\">\n {sortDirection === 'asc' && (\n <CaretUp size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n {sortDirection === 'desc' && (\n <CaretDown size={16} weight=\"fill\" className=\"text-text-800\" />\n )}\n </div>\n )}\n </div>\n </th>\n );\n }\n);\nTableHead.displayName = 'TableHead';\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px] text-base font-normal text-text-800 leading-[150%] tracking-normal px-6 py-3.5 whitespace-nowrap',\n className\n )}\n {...props}\n />\n));\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = forwardRef<\n HTMLTableCaptionElement,\n HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn(\n 'border-t border-border-200 text-sm text-text-800 px-6 py-3.5',\n className\n )}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport { default as TablePagination } from './TablePagination';\nexport type { TablePaginationProps } from './TablePagination';\n\nexport default Table;\nexport {\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n","import Text from '../Text/Text';\n\nexport interface NoSearchResultProps {\n /**\n * Image source for the illustration\n */\n image: string;\n /**\n * Title text to display\n * @default \"Nenhum resultado encontrado\"\n */\n title?: string;\n /**\n * Description text to display below the title\n * @default \"Não encontramos nenhum resultado com esse nome. Tente revisar a busca ou usar outra palavra-chave.\"\n */\n description?: string;\n}\n\n/**\n * Component displayed when no search results are found\n * Shows an illustration with customizable title and description in horizontal layout\n *\n * @example\n * ```tsx\n * import { NoSearchResult } from 'analytica-frontend-lib';\n * import noSearchImage from './assets/no-search.png';\n *\n * <NoSearchResult\n * image={noSearchImage}\n * title=\"Nenhum resultado encontrado\"\n * description=\"Tente usar outros filtros\"\n * />\n * ```\n */\nconst NoSearchResult = ({ image, title, description }: NoSearchResultProps) => {\n const displayTitle = title || 'Nenhum resultado encontrado';\n const displayDescription =\n description ||\n 'Não encontramos nenhum resultado com esse nome. Tente revisar a busca ou usar outra palavra-chave.';\n\n return (\n <div className=\"flex flex-row justify-center items-center gap-8 w-full max-w-4xl min-h-96\">\n {/* Illustration */}\n <div className=\"w-72 h-72 flex-shrink-0 relative\">\n <img\n src={image}\n alt=\"No search results\"\n className=\"w-full h-full object-contain\"\n />\n </div>\n\n {/* Text Content */}\n <div className=\"flex flex-col items-start w-full max-w-md\">\n {/* Header Container */}\n <div className=\"flex flex-row justify-between items-end px-6 pt-6 pb-4 w-full rounded-t-xl\">\n {/* Title */}\n <Text\n as=\"h2\"\n className=\"text-text-950 font-semibold text-3xl leading-tight w-full flex items-center\"\n >\n {displayTitle}\n </Text>\n </div>\n\n {/* Description Container */}\n <div className=\"flex flex-row justify-center items-center px-6 gap-2 w-full\">\n {/* Description */}\n <Text className=\"text-text-600 font-normal text-lg leading-relaxed w-full text-justify\">\n {displayDescription}\n </Text>\n </div>\n </div>\n </div>\n );\n};\n\nexport default NoSearchResult;\n","import { HTMLAttributes, ChangeEvent } from 'react';\nimport { CaretLeft, CaretRight, CaretDown } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nexport interface TablePaginationProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Total number of items\n */\n totalItems: number;\n /**\n * Current page (1-based)\n */\n currentPage: number;\n /**\n * Total number of pages\n */\n totalPages: number;\n /**\n * Items per page\n */\n itemsPerPage: number;\n /**\n * Available options for items per page\n * @default [10, 20, 50, 100]\n */\n itemsPerPageOptions?: number[];\n /**\n * Callback when page changes\n */\n onPageChange: (page: number) => void;\n /**\n * Callback when items per page changes\n */\n onItemsPerPageChange?: (itemsPerPage: number) => void;\n /**\n * Customizable label for items (e.g., \"escolas\", \"alunos\", \"atividades\")\n * @default \"itens\"\n */\n itemLabel?: string;\n}\n\n/**\n * Table pagination component with navigation controls and items per page selector\n *\n * @example\n * ```tsx\n * import { TablePagination } from 'analytica-frontend-lib';\n *\n * <TablePagination\n * totalItems={1000}\n * currentPage={1}\n * totalPages={10}\n * itemsPerPage={10}\n * itemsPerPageOptions={[10, 20, 50, 100]}\n * onPageChange={(page) => setCurrentPage(page)}\n * onItemsPerPageChange={(items) => setItemsPerPage(items)}\n * itemLabel=\"escolas\"\n * />\n * ```\n */\nconst TablePagination = ({\n totalItems,\n currentPage,\n totalPages,\n itemsPerPage,\n itemsPerPageOptions = [10, 20, 50, 100],\n onPageChange,\n onItemsPerPageChange,\n itemLabel = 'itens',\n className,\n ...props\n}: TablePaginationProps) => {\n const startItem = (currentPage - 1) * itemsPerPage + 1;\n\n const handlePrevious = () => {\n if (currentPage > 1) {\n onPageChange(currentPage - 1);\n }\n };\n\n const handleNext = () => {\n if (currentPage < totalPages) {\n onPageChange(currentPage + 1);\n }\n };\n\n const handleItemsPerPageChange = (e: ChangeEvent<HTMLSelectElement>) => {\n if (onItemsPerPageChange) {\n onItemsPerPageChange(Number(e.target.value));\n }\n };\n\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n return (\n <div\n className={cn(\n 'flex flex-col sm:flex-row items-center gap-3 sm:gap-4 w-full bg-background-50 rounded-xl p-4',\n 'sm:justify-between',\n className\n )}\n {...props}\n >\n {/* Items count - isolado à esquerda no desktop */}\n <span className=\"font-normal text-xs leading-[14px] text-text-800\">\n {startItem} de {totalItems} {itemLabel}\n </span>\n\n {/* Grupo direita: selector + page info + botões */}\n <div className=\"flex flex-wrap sm:flex-nowrap items-center gap-2 sm:gap-4 justify-center sm:justify-start\">\n {/* Items per page selector */}\n {onItemsPerPageChange && (\n <div className=\"relative\">\n <select\n value={itemsPerPage}\n onChange={handleItemsPerPageChange}\n className=\"w-24 h-9 py-0 px-3 pr-8 bg-background border border-border-300 rounded appearance-none cursor-pointer font-normal text-sm leading-[21px] text-text-900\"\n aria-label=\"Items por página\"\n >\n {itemsPerPageOptions.map((option) => (\n <option key={option} value={option}>\n {option} itens\n </option>\n ))}\n </select>\n <CaretDown\n size={14}\n weight=\"regular\"\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-background-600 pointer-events-none\"\n />\n </div>\n )}\n\n {/* Page info */}\n <span className=\"font-normal text-xs leading-[14px] text-text-950\">\n Página {currentPage} de {totalPages}\n </span>\n\n {/* Previous button */}\n <button\n onClick={handlePrevious}\n disabled={isFirstPage}\n className={cn(\n 'flex flex-row justify-center items-center py-2 px-4 gap-2 rounded-3xl transition-all',\n isFirstPage\n ? 'opacity-50 cursor-not-allowed'\n : 'hover:bg-primary-950/10 cursor-pointer'\n )}\n aria-label=\"Página anterior\"\n >\n <CaretLeft size={12} weight=\"bold\" className=\"text-primary-950\" />\n <span className=\"font-medium text-xs leading-[14px] text-primary-950\">\n Anterior\n </span>\n </button>\n\n {/* Next button */}\n <button\n onClick={handleNext}\n disabled={isLastPage}\n className={cn(\n 'flex flex-row justify-center items-center py-2 px-4 gap-2 rounded-3xl transition-all',\n isLastPage\n ? 'opacity-50 cursor-not-allowed'\n : 'hover:bg-primary-950/10 cursor-pointer'\n )}\n aria-label=\"Próxima página\"\n >\n <span className=\"font-medium text-xs leading-[14px] text-primary-950\">\n Próxima\n </span>\n <CaretRight size={12} weight=\"bold\" className=\"text-primary-950\" />\n </button>\n </div>\n </div>\n );\n};\n\nTablePagination.displayName = 'TablePagination';\n\nexport default TablePagination;\n","import { useEffect, useState, useCallback, useMemo } from 'react';\nimport type { CategoryConfig } from '../CheckBoxGroup/CheckBoxGroup';\n\nexport type FilterConfig = {\n key: string;\n label: string;\n categories: CategoryConfig[];\n};\n\nexport type UseTableFilterOptions = {\n syncWithUrl?: boolean;\n};\n\nexport type UseTableFilterReturn = {\n filterConfigs: FilterConfig[];\n activeFilters: Record<string, string[]>;\n hasActiveFilters: boolean;\n updateFilters: (configs: FilterConfig[]) => void;\n applyFilters: () => void;\n clearFilters: () => void;\n};\n\n/**\n * Hook for managing table filters with URL synchronization\n *\n * @param initialConfigs - Initial filter configurations\n * @param options - Hook options including URL sync\n * @returns Filter state and management functions\n *\n * @example\n * ```tsx\n * const { filterConfigs, activeFilters, updateFilters, applyFilters } = useTableFilter(\n * [\n * {\n * key: 'academic',\n * label: 'Dados Acadêmicos',\n * categories: [...]\n * }\n * ],\n * { syncWithUrl: true }\n * );\n * ```\n */\nexport const useTableFilter = (\n initialConfigs: FilterConfig[],\n options: UseTableFilterOptions = {}\n): UseTableFilterReturn => {\n const { syncWithUrl = false } = options;\n\n // Get initial state from URL if syncWithUrl is enabled\n const getInitialState = useCallback((): FilterConfig[] => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return initialConfigs;\n }\n\n const params = new URLSearchParams(globalThis.window.location.search);\n const configsWithUrlState = initialConfigs.map((config) => ({\n ...config,\n categories: config.categories.map((category) => {\n const urlValue = params.get(`filter_${category.key}`);\n const selectedIds = urlValue ? urlValue.split(',').filter(Boolean) : [];\n return {\n ...category,\n selectedIds,\n };\n }),\n }));\n\n return configsWithUrlState;\n }, [initialConfigs, syncWithUrl]);\n\n const [filterConfigs, setFilterConfigs] =\n useState<FilterConfig[]>(getInitialState);\n\n // Calculate active filters (only categories with selections)\n // Memoize to prevent creating new object reference on every render\n const activeFilters = useMemo(() => {\n const filters: Record<string, string[]> = {};\n\n for (const config of filterConfigs) {\n for (const category of config.categories) {\n if (category.selectedIds && category.selectedIds.length > 0) {\n filters[category.key] = category.selectedIds;\n }\n }\n }\n\n return filters;\n }, [filterConfigs]);\n\n const hasActiveFilters = Object.keys(activeFilters).length > 0;\n\n /**\n * Update filter configs (temporary state, not applied to URL yet)\n */\n const updateFilters = useCallback((configs: FilterConfig[]) => {\n setFilterConfigs(configs);\n }, []);\n\n /**\n * Apply filters to URL (commit the changes)\n */\n const applyFilters = useCallback(() => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return;\n }\n\n const url = new URL(globalThis.window.location.href);\n const params = url.searchParams;\n\n // Update URL parameters for each category\n for (const config of filterConfigs) {\n for (const category of config.categories) {\n const paramKey = `filter_${category.key}`;\n\n if (category.selectedIds && category.selectedIds.length > 0) {\n params.set(paramKey, category.selectedIds.join(','));\n } else {\n params.delete(paramKey);\n }\n }\n }\n\n // Update URL without page reload\n globalThis.window.history.replaceState({}, '', url.toString());\n }, [filterConfigs, syncWithUrl]);\n\n /**\n * Clear all filters\n */\n const clearFilters = useCallback(() => {\n const clearedConfigs = filterConfigs.map((config) => ({\n ...config,\n categories: config.categories.map((category) => ({\n ...category,\n selectedIds: [],\n })),\n }));\n\n setFilterConfigs(clearedConfigs);\n\n // If syncWithUrl, also clear URL parameters\n if (syncWithUrl && globalThis.window !== undefined) {\n const url = new URL(globalThis.window.location.href);\n const params = url.searchParams;\n\n for (const config of filterConfigs) {\n for (const category of config.categories) {\n params.delete(`filter_${category.key}`);\n }\n }\n\n globalThis.window.history.replaceState({}, '', url.toString());\n }\n }, [filterConfigs, syncWithUrl]);\n\n // Sync with URL on mount and when URL changes externally\n useEffect(() => {\n if (!syncWithUrl || globalThis.window === undefined) {\n return;\n }\n\n const handlePopState = () => {\n setFilterConfigs(getInitialState());\n };\n\n globalThis.window.addEventListener('popstate', handlePopState);\n return () =>\n globalThis.window.removeEventListener('popstate', handlePopState);\n }, [syncWithUrl, getInitialState]);\n\n return {\n filterConfigs,\n activeFilters,\n hasActiveFilters,\n updateFilters,\n applyFilters,\n clearFilters,\n };\n};\n","import { X, MagnifyingGlass } from 'phosphor-react';\nimport {\n InputHTMLAttributes,\n forwardRef,\n useState,\n useId,\n useMemo,\n useEffect,\n useRef,\n ChangeEvent,\n MouseEvent,\n KeyboardEvent,\n} from 'react';\nimport DropdownMenu, {\n DropdownMenuContent,\n DropdownMenuItem,\n createDropdownStore,\n} from '../DropdownMenu/DropdownMenu';\n\n/**\n * Search component props interface\n */\ntype SearchProps = {\n /** List of options to show in dropdown */\n options: string[];\n /** Callback when an option is selected from dropdown */\n onSelect?: (value: string) => void;\n /** Callback when search input changes */\n onSearch?: (query: string) => void;\n /** Control dropdown visibility externally */\n showDropdown?: boolean;\n /** Callback when dropdown open state changes */\n onDropdownChange?: (open: boolean) => void;\n /** Maximum height of dropdown in pixels */\n dropdownMaxHeight?: number;\n /** Text to show when no results are found */\n noResultsText?: string;\n /** Additional CSS classes to apply to the input */\n className?: string;\n /** Additional CSS classes to apply to the container */\n containerClassName?: string;\n /** Callback when clear button is clicked */\n onClear?: () => void;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'onSelect'>;\n\n/**\n * Search component for Analytica Ensino platforms\n *\n * A specialized search input component with dropdown suggestions.\n * Features filtering, keyboard navigation, and customizable options.\n *\n * @param options - Array of search options to display in dropdown\n * @param onSelect - Callback when an option is selected\n * @param onSearch - Callback when search query changes\n * @param placeholder - Placeholder text for the input\n * @param noResultsText - Text to show when no results are found\n * @param dropdownMaxHeight - Maximum height of dropdown in pixels\n * @param className - Additional CSS classes for the input\n * @param containerClassName - Additional CSS classes for the container\n * @param props - All other standard input HTML attributes\n * @returns A styled search input with dropdown functionality\n *\n * @example\n * ```tsx\n * // Basic search\n * <Search\n * options={['Filosofia', 'Física', 'Matemática']}\n * placeholder=\"Buscar matéria...\"\n * onSelect={(value) => console.log('Selected:', value)}\n * />\n *\n * // With custom filtering\n * <Search\n * options={materias}\n * onSearch={(query) => setFilteredMaterias(filterMaterias(query))}\n * noResultsText=\"Nenhum resultado encontrado\"\n * />\n * ```\n */\n\n/**\n * Filter options based on search query\n */\nconst filterOptions = (options: string[], query: string): string[] => {\n if (!query || query.length < 1) return [];\n\n return options.filter((option) =>\n option.toLowerCase().includes(query.toLowerCase())\n );\n};\n\n/**\n * Updates input value and creates appropriate change event\n */\nconst updateInputValue = (\n value: string,\n ref:\n | { current: HTMLInputElement | null }\n | ((instance: HTMLInputElement | null) => void)\n | null,\n onChange?: (event: ChangeEvent<HTMLInputElement>) => void\n) => {\n if (!onChange) return;\n\n if (ref && 'current' in ref && ref.current) {\n ref.current.value = value;\n const event = new Event('input', { bubbles: true });\n Object.defineProperty(event, 'target', {\n writable: false,\n value: ref.current,\n });\n onChange(event as unknown as ChangeEvent<HTMLInputElement>);\n } else {\n // Fallback for cases where ref is not available\n const event = {\n target: { value },\n currentTarget: { value },\n } as ChangeEvent<HTMLInputElement>;\n onChange(event);\n }\n};\n\nconst Search = forwardRef<HTMLInputElement, SearchProps>(\n (\n {\n options = [],\n onSelect,\n onSearch,\n showDropdown: controlledShowDropdown,\n onDropdownChange,\n dropdownMaxHeight = 240,\n noResultsText = 'Nenhum resultado encontrado',\n className = '',\n containerClassName = '',\n disabled,\n readOnly,\n id,\n onClear,\n value,\n onChange,\n placeholder = 'Buscar...',\n onKeyDown: userOnKeyDown,\n ...props\n },\n ref\n ) => {\n // Dropdown state and logic\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const [forceClose, setForceClose] = useState(false);\n const justSelectedRef = useRef(false);\n const dropdownStore = useRef(createDropdownStore()).current;\n const dropdownRef = useRef<HTMLDivElement>(null);\n const inputElRef = useRef<HTMLInputElement>(null);\n\n // Filter options based on input value\n const filteredOptions = useMemo(() => {\n if (!options.length) {\n return [];\n }\n const filtered = filterOptions(options, (value as string) || '');\n return filtered;\n }, [options, value]);\n\n // Control dropdown visibility\n const showDropdown =\n !forceClose &&\n (controlledShowDropdown ??\n (dropdownOpen && value && String(value).length > 0));\n\n // Helper to keep all consumers in sync\n const setOpenAndNotify = (open: boolean) => {\n setDropdownOpen(open);\n dropdownStore.setState({ open });\n onDropdownChange?.(open);\n };\n\n // Handle dropdown visibility changes\n useEffect(() => {\n // Don't reopen dropdown if we just selected an option\n if (justSelectedRef.current) {\n justSelectedRef.current = false;\n return;\n }\n // Respect forceClose even if value is non-empty\n if (forceClose) {\n setOpenAndNotify(false);\n return;\n }\n\n const shouldShow = Boolean(value && String(value).length > 0);\n setOpenAndNotify(shouldShow);\n }, [value, forceClose, onDropdownChange, dropdownStore]);\n\n // Handle option selection\n const handleSelectOption = (option: string) => {\n justSelectedRef.current = true; // Prevent immediate dropdown reopen\n setForceClose(true); // Force dropdown to close immediately\n onSelect?.(option);\n setOpenAndNotify(false);\n\n // Update input value if onChange is provided\n updateInputValue(option, ref, onChange);\n };\n\n // Handle click outside dropdown\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n dropdownRef.current &&\n !dropdownRef.current.contains(event.target as Node)\n ) {\n setOpenAndNotify(false);\n }\n };\n\n if (showDropdown) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [showDropdown, dropdownStore, onDropdownChange]);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `search-${generatedId}`;\n const dropdownId = `${inputId}-dropdown`;\n\n // Handle clear button\n const handleClear = () => {\n if (onClear) {\n onClear();\n } else {\n updateInputValue('', ref, onChange);\n }\n };\n\n // Handle clear button click - mantém foco no input\n const handleClearClick = (e: MouseEvent) => {\n e.preventDefault(); // Evita que o input perca foco\n e.stopPropagation(); // Para propagação do evento\n handleClear();\n };\n\n // Handle search icon click - focus on input\n const handleSearchIconClick = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setTimeout(() => {\n inputElRef.current?.focus();\n }, 0);\n };\n\n // Handle input change\n const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {\n setForceClose(false); // Allow dropdown to open when user types\n onChange?.(e);\n onSearch?.(e.target.value);\n };\n\n // Handle keyboard events\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n // Let consumer run first; if they prevent default, skip our logic\n userOnKeyDown?.(e);\n if (e.defaultPrevented) return;\n\n if (e.key === 'Enter') {\n e.preventDefault();\n\n // If dropdown is open and there are filtered options, select the first one\n if (showDropdown && filteredOptions.length > 0) {\n handleSelectOption(filteredOptions[0]);\n } else if (value) {\n // If no dropdown or no options, execute search\n onSearch?.(String(value));\n setForceClose(true);\n setOpenAndNotify(false);\n }\n }\n };\n\n // Helper function for input state classes\n const getInputStateClasses = (disabled?: boolean, readOnly?: boolean) => {\n if (disabled) return 'cursor-not-allowed opacity-40';\n if (readOnly) return 'cursor-default focus:outline-none !text-text-900';\n return 'hover:border-border-400';\n };\n\n // Determine which icon to show\n const hasValue = String(value ?? '').length > 0;\n const showClearButton = hasValue && !disabled && !readOnly;\n const showSearchIcon = !hasValue && !disabled && !readOnly;\n\n return (\n <div\n ref={dropdownRef}\n className={`w-full max-w-lg md:w-[488px] ${containerClassName}`}\n >\n {/* Search Input Container */}\n <div className=\"relative flex items-center\">\n {/* Search Input Field */}\n <input\n ref={(node) => {\n // Forward to parent\n if (ref) {\n if (typeof ref === 'function') ref(node);\n else\n (ref as { current: HTMLInputElement | null }).current = node;\n }\n // Keep our own handle\n inputElRef.current = node;\n }}\n id={inputId}\n type=\"text\"\n className={`w-full py-0 px-4 pr-10 font-normal text-text-900 focus:outline-primary-950 border rounded-full bg-background focus:bg-primary-50 border-border-300 focus:border-2 focus:border-primary-950 h-10 placeholder:text-text-600 ${getInputStateClasses(disabled, readOnly)} ${className}`}\n value={value}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={placeholder}\n aria-expanded={showDropdown ? 'true' : undefined}\n aria-haspopup={options.length > 0 ? 'listbox' : undefined}\n aria-controls={showDropdown ? dropdownId : undefined}\n aria-autocomplete=\"list\"\n role={options.length > 0 ? 'combobox' : undefined}\n {...props}\n />\n\n {/* Right Icon - Clear Button */}\n {showClearButton && (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2\">\n <button\n type=\"button\"\n className=\"p-0 border-0 bg-transparent cursor-pointer\"\n onMouseDown={handleClearClick}\n aria-label=\"Limpar busca\"\n >\n <span className=\"w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors\">\n <X />\n </span>\n </button>\n </div>\n )}\n\n {/* Right Icon - Search Icon */}\n {showSearchIcon && (\n <div className=\"absolute right-3 top-1/2 transform -translate-y-1/2\">\n <button\n type=\"button\"\n className=\"p-0 border-0 bg-transparent cursor-pointer\"\n onMouseDown={handleSearchIconClick}\n aria-label=\"Buscar\"\n >\n <span className=\"w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors\">\n <MagnifyingGlass />\n </span>\n </button>\n </div>\n )}\n </div>\n\n {/* Search Dropdown */}\n {showDropdown && (\n <DropdownMenu open={showDropdown} onOpenChange={setDropdownOpen}>\n <DropdownMenuContent\n id={dropdownId}\n className=\"w-full mt-1\"\n style={{ maxHeight: dropdownMaxHeight }}\n align=\"start\"\n >\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option) => (\n <DropdownMenuItem\n key={option}\n onClick={() => handleSelectOption(option)}\n className=\"text-text-700 text-base leading-6 cursor-pointer\"\n >\n {option}\n </DropdownMenuItem>\n ))\n ) : (\n <div className=\"px-3 py-3 text-text-700 text-base\">\n {noResultsText}\n </div>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n }\n);\n\nSearch.displayName = 'Search';\n\nexport default Search;\n","import { CaretRight, SignOut, User } from 'phosphor-react';\nimport {\n forwardRef,\n ReactNode,\n ButtonHTMLAttributes,\n useEffect,\n useLayoutEffect,\n useRef,\n HTMLAttributes,\n MouseEvent,\n KeyboardEvent,\n isValidElement,\n Children,\n cloneElement,\n ReactElement,\n useState,\n RefObject,\n CSSProperties,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { create, StoreApi, useStore } from 'zustand';\nimport Button from '../Button/Button';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\nimport Modal from '../Modal/Modal';\nimport { ThemeToggle } from '../ThemeToggle/ThemeToggle';\nimport type { ThemeMode } from '@/hooks/useTheme';\nimport { useTheme } from '../../hooks/useTheme';\n\ninterface DropdownStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\ntype DropdownStoreApi = StoreApi<DropdownStore>;\n\nexport function createDropdownStore(): DropdownStoreApi {\n return create<DropdownStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n }));\n}\n\nexport const useDropdownStore = (externalStore?: DropdownStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a DropdownMenu (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nconst injectStore = (\n children: ReactNode,\n store: DropdownStoreApi\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: DropdownStoreApi;\n children?: ReactNode;\n }>;\n\n // Aqui tu checa o displayName do componente\n const displayName = (\n typedChild.type as unknown as { displayName: string }\n ).displayName;\n\n // Lista de componentes que devem receber o store\n const allowed = [\n 'DropdownMenuTrigger',\n 'DropdownContent',\n 'DropdownMenuContent',\n 'DropdownMenuSeparator',\n 'DropdownMenuItem',\n 'MenuLabel',\n 'ProfileMenuTrigger',\n 'ProfileMenuHeader',\n 'ProfileMenuFooter',\n 'ProfileToggleTheme',\n ];\n\n let newProps: Partial<{\n store: DropdownStoreApi;\n children: ReactNode;\n }> = {};\n\n if (allowed.includes(displayName)) {\n newProps.store = store;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(typedChild.props.children, store);\n }\n\n return cloneElement(typedChild, newProps);\n }\n\n return child;\n });\n};\n\ninterface DropdownMenuProps {\n children: ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst DropdownMenu = ({\n children,\n open: propOpen,\n onOpenChange,\n}: DropdownMenuProps) => {\n const storeRef = useRef<DropdownStoreApi | null>(null);\n storeRef.current ??= createDropdownStore();\n const store = storeRef.current;\n const { open, setOpen: storeSetOpen } = useStore(store, (s) => s);\n\n const setOpen = (newOpen: boolean) => {\n storeSetOpen(newOpen);\n };\n\n const menuRef = useRef<HTMLDivElement | null>(null);\n\n const handleArrowDownOrArrowUp = (event: globalThis.KeyboardEvent) => {\n const menuContent = menuRef.current?.querySelector('[role=\"menu\"]');\n if (menuContent) {\n event.preventDefault();\n\n const items = Array.from(\n menuContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n if (items.length === 0) return;\n\n const focusedItem = document.activeElement as HTMLElement;\n const currentIndex = items.indexOf(focusedItem);\n\n let nextIndex;\n if (event.key === 'ArrowDown') {\n nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n // ArrowUp\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n\n items[nextIndex]?.focus();\n }\n };\n\n const handleDownkey = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false);\n } else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n handleArrowDownOrArrowUp(event);\n }\n };\n\n const handleClickOutside = (event: Event) => {\n const target = event.target as Node;\n\n if (menuRef.current?.contains(target)) {\n return;\n }\n\n if (\n target instanceof Element &&\n target.closest('[data-dropdown-content=\"true\"]')\n ) {\n return;\n }\n\n setOpen(false);\n };\n\n useEffect(() => {\n if (open) {\n document.addEventListener('pointerdown', handleClickOutside);\n document.addEventListener('keydown', handleDownkey);\n }\n\n return () => {\n document.removeEventListener('pointerdown', handleClickOutside);\n document.removeEventListener('keydown', handleDownkey);\n };\n }, [open]);\n\n useEffect(() => {\n onOpenChange?.(open);\n }, [open, onOpenChange]);\n\n useEffect(() => {\n if (propOpen !== undefined) {\n setOpen(propOpen);\n }\n }, [propOpen]);\n\n return (\n <div className=\"relative\" ref={menuRef}>\n {injectStore(children, store)}\n </div>\n );\n};\n\n// Componentes genéricos do DropdownMenu\nconst DropdownMenuTrigger = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n }\n>(({ className, children, onClick, store: externalStore, ...props }, ref) => {\n const store = useDropdownStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n onClick?.(e);\n }}\n aria-expanded={open}\n className={cn(\n 'appearance-none bg-transparent border-none p-0',\n className\n )}\n {...props}\n >\n {children}\n </button>\n );\n});\nDropdownMenuTrigger.displayName = 'DropdownMenuTrigger';\n\nconst ITEM_SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full',\n right: 'top-full',\n bottom: 'top-full',\n left: 'top-full',\n};\n\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\nconst MENUCONTENT_VARIANT_CLASSES = {\n menu: 'p-1',\n profile: 'p-6',\n};\n\nconst MenuLabel = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n store?: DropdownStoreApi;\n }\n>(({ className, inset, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('text-sm w-full', inset ? 'pl-8' : '', className)}\n {...props}\n />\n );\n});\nMenuLabel.displayName = 'MenuLabel';\n\nconst DropdownMenuContent = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n variant?: 'menu' | 'profile';\n sideOffset?: number;\n store?: DropdownStoreApi;\n portal?: boolean;\n triggerRef?: RefObject<HTMLElement | null>;\n }\n>(\n (\n {\n className,\n align = 'start',\n side = 'bottom',\n variant = 'menu',\n sideOffset = 4,\n children,\n store: externalStore,\n portal = false,\n triggerRef,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const [isVisible, setIsVisible] = useState(open);\n const [portalPosition, setPortalPosition] = useState({ top: 0, left: 0 });\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (open) {\n setIsVisible(true);\n } else {\n const timer = setTimeout(() => setIsVisible(false), 200);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n useLayoutEffect(() => {\n if (portal && open && triggerRef?.current) {\n const rect = triggerRef.current.getBoundingClientRect();\n let top = rect.bottom + sideOffset;\n let left = rect.left;\n\n // Handle horizontal sides (left/right)\n if (side === 'left') {\n left = rect.left - sideOffset;\n top = rect.top;\n } else if (side === 'right') {\n left = rect.right + sideOffset;\n top = rect.top;\n } else {\n // Handle vertical sides (top/bottom)\n if (align === 'end') {\n left = rect.right;\n } else if (align === 'center') {\n left = rect.left + rect.width / 2;\n }\n\n if (side === 'top') {\n top = rect.top - sideOffset;\n }\n }\n\n setPortalPosition({ top, left });\n }\n }, [portal, open, triggerRef, align, side, sideOffset]);\n\n if (!isVisible) return null;\n\n const getPositionClasses = () => {\n if (portal) {\n return 'fixed';\n }\n const vertical = SIDE_CLASSES[side];\n const horizontal = ALIGN_CLASSES[align];\n\n return `absolute ${vertical} ${horizontal}`;\n };\n\n const getPortalAlignStyle = () => {\n if (!portal) return {};\n\n const baseStyle: CSSProperties = {\n top: portalPosition.top,\n };\n\n if (align === 'end') {\n baseStyle.right = window.innerWidth - portalPosition.left;\n } else if (align === 'center') {\n baseStyle.left = portalPosition.left;\n baseStyle.transform = 'translateX(-50%)';\n } else {\n baseStyle.left = portalPosition.left;\n }\n\n return baseStyle;\n };\n\n const variantClasses = MENUCONTENT_VARIANT_CLASSES[variant];\n\n const content = (\n <div\n ref={portal ? contentRef : ref}\n role=\"menu\"\n data-dropdown-content=\"true\"\n className={`\n bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md border-border-100\n ${open ? 'animate-in fade-in-0 zoom-in-95' : 'animate-out fade-out-0 zoom-out-95'}\n ${getPositionClasses()}\n ${variantClasses}\n ${className}\n `}\n style={{\n ...(portal\n ? getPortalAlignStyle()\n : {\n marginTop: side === 'bottom' ? sideOffset : undefined,\n marginBottom: side === 'top' ? sideOffset : undefined,\n marginLeft: side === 'right' ? sideOffset : undefined,\n marginRight: side === 'left' ? sideOffset : undefined,\n }),\n }}\n {...props}\n >\n {children}\n </div>\n );\n\n if (portal && typeof document !== 'undefined') {\n return createPortal(content, document.body);\n }\n\n return content;\n }\n);\nDropdownMenuContent.displayName = 'DropdownMenuContent';\n\nconst DropdownMenuItem = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n inset?: boolean;\n size?: 'small' | 'medium';\n iconLeft?: ReactNode;\n iconRight?: ReactNode;\n disabled?: boolean;\n variant?: 'profile' | 'menu';\n store?: DropdownStoreApi;\n preventClose?: boolean;\n }\n>(\n (\n {\n className,\n size = 'small',\n children,\n iconRight,\n iconLeft,\n disabled = false,\n onClick,\n variant = 'menu',\n store: externalStore,\n preventClose = false,\n ...props\n },\n ref\n ) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n const sizeClasses = ITEM_SIZE_CLASSES[size];\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.type === 'click') {\n onClick?.(e as MouseEvent<HTMLDivElement>);\n } else if (e.type === 'keydown') {\n // For keyboard events, call onClick if Enter or Space was pressed\n if (\n (e as KeyboardEvent<HTMLDivElement>).key === 'Enter' ||\n (e as KeyboardEvent<HTMLDivElement>).key === ' '\n ) {\n onClick?.(e as unknown as MouseEvent<HTMLDivElement>);\n }\n // honor any user-provided key handler\n props.onKeyDown?.(e as KeyboardEvent<HTMLDivElement>);\n }\n if (!preventClose) {\n setOpen(false);\n }\n };\n\n const getVariantClasses = () => {\n if (variant === 'profile') {\n return 'relative flex flex-row justify-between select-none items-center gap-2 rounded-sm p-4 text-sm outline-none transition-colors [&>svg]:size-6 [&>svg]:shrink-0';\n }\n return 'relative flex select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0';\n };\n\n const getVariantProps = () => {\n return variant === 'profile' ? { 'data-variant': 'profile' } : {};\n };\n\n return (\n <div\n ref={ref}\n role=\"menuitem\"\n {...getVariantProps()}\n aria-disabled={disabled}\n className={`\n focus-visible:bg-background-50\n ${getVariantClasses()}\n ${sizeClasses}\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n handleClick(e);\n }\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n {iconLeft}\n <div className=\"w-full\">{children}</div>\n {iconRight}\n </div>\n );\n }\n);\nDropdownMenuItem.displayName = 'DropdownMenuItem';\n\nconst DropdownMenuSeparator = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, store: _store, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('my-1 h-px bg-border-200', className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = 'DropdownMenuSeparator';\n\n// Componentes específicos do ProfileMenu\nconst ProfileMenuTrigger = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & { store?: DropdownStoreApi }\n>(({ className, onClick, store: externalStore, ...props }, ref) => {\n const store = useDropdownStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n return (\n <button\n ref={ref}\n className={cn(\n 'rounded-lg size-10 bg-primary-50 flex items-center justify-center cursor-pointer',\n className\n )}\n onClick={(e) => {\n e.stopPropagation();\n toggleOpen();\n onClick?.(e);\n }}\n aria-expanded={open}\n {...props}\n >\n <span className=\"size-6 rounded-full bg-primary-100 flex items-center justify-center\">\n <User className=\"text-primary-950\" size={18} />\n </span>\n </button>\n );\n});\nProfileMenuTrigger.displayName = 'ProfileMenuTrigger';\n\nconst ProfileMenuHeader = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n name: string;\n email: string;\n photoUrl?: string | null;\n store?: DropdownStoreApi;\n }\n>(({ className, name, email, photoUrl, store: _store, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-component=\"ProfileMenuHeader\"\n className={cn(\n 'flex flex-row gap-4 items-center min-w-[280px]',\n className\n )}\n {...props}\n >\n <span className=\"w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center overflow-hidden flex-shrink-0\">\n {photoUrl ? (\n <img\n src={photoUrl}\n alt=\"Foto de perfil\"\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <User size={34} className=\"text-primary-800\" />\n )}\n </span>\n <div className=\"flex flex-col min-w-0\">\n <Text\n size=\"xl\"\n weight=\"bold\"\n color=\"text-text-950\"\n className=\"truncate\"\n >\n {name}\n </Text>\n <Text size=\"md\" color=\"text-text-600\" className=\"truncate\">\n {email}\n </Text>\n </div>\n </div>\n );\n});\nProfileMenuHeader.displayName = 'ProfileMenuHeader';\n\nconst ProfileMenuInfo = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n schoolName: string;\n classYearName: string;\n schoolYearName: string;\n store?: DropdownStoreApi;\n }\n>(\n (\n {\n className,\n schoolName,\n classYearName,\n schoolYearName,\n store: _store,\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n data-component=\"ProfileMenuInfo\"\n className={cn('flex flex-row gap-4 items-center', className)}\n {...props}\n >\n <span className=\"w-16 h-16\" />\n <div className=\"flex flex-col \">\n <Text size=\"md\" color=\"text-text-600\">\n {schoolName}\n </Text>\n\n <span className=\"flex flex-row items-center gap-2\">\n <Text size=\"md\" color=\"text-text-600\">\n {classYearName}\n </Text>\n <p className=\"text-text-600 text-xs align-middle\">●</p>\n <Text size=\"md\" color=\"text-text-600\">\n {schoolYearName}\n </Text>\n </span>\n </div>\n </div>\n );\n }\n);\nProfileMenuInfo.displayName = 'ProfileMenuInfo';\n\nconst ProfileToggleTheme = ({\n store: externalStore,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }) => {\n const { themeMode, setTheme } = useTheme();\n const [modalThemeToggle, setModalThemeToggle] = useState(false);\n const [selectedTheme, setSelectedTheme] = useState<ThemeMode>(themeMode);\n\n const internalStoreRef = useRef<DropdownStoreApi | null>(null);\n internalStoreRef.current ??= createDropdownStore();\n const store = externalStore ?? internalStoreRef.current;\n const setOpen = useStore(store, (s) => s.setOpen);\n\n const handleClick = (e: MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setModalThemeToggle(true);\n };\n\n const handleSave = () => {\n setTheme(selectedTheme);\n setModalThemeToggle(false);\n setOpen(false); // Close dropdown after saving\n };\n\n const handleCancel = () => {\n setSelectedTheme(themeMode); // Reset to current theme\n setModalThemeToggle(false);\n setOpen(false); // Close dropdown after canceling\n };\n\n return (\n <>\n <DropdownMenuItem\n variant=\"profile\"\n preventClose={true}\n store={store}\n iconLeft={\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12.5 2.75C15.085 2.75276 17.5637 3.78054 19.3916 5.6084C21.2195 7.43628 22.2473 9.915 22.25 12.5C22.25 14.4284 21.6778 16.3136 20.6064 17.917C19.5352 19.5201 18.0128 20.7699 16.2314 21.5078C14.4499 22.2458 12.489 22.4387 10.5977 22.0625C8.70642 21.6863 6.96899 20.758 5.60547 19.3945C4.24197 18.031 3.31374 16.2936 2.9375 14.4023C2.56129 12.511 2.75423 10.5501 3.49219 8.76855C4.23012 6.98718 5.47982 5.46483 7.08301 4.39355C8.68639 3.32221 10.5716 2.75 12.5 2.75ZM11.75 4.28516C9.70145 4.47452 7.7973 5.42115 6.41016 6.94043C5.02299 8.4599 4.25247 10.4426 4.25 12.5C4.25247 14.5574 5.02299 16.5401 6.41016 18.0596C7.7973 19.5789 9.70145 20.5255 11.75 20.7148V4.28516Z\"\n fill=\"currentColor\"\n />\n </svg>\n }\n iconRight={<CaretRight />}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n setModalThemeToggle(true);\n }\n }}\n {...props}\n >\n <Text size=\"md\" color=\"text-text-700\">\n Aparência\n </Text>\n </DropdownMenuItem>\n\n <Modal\n isOpen={modalThemeToggle}\n onClose={handleCancel}\n title=\"Aparência\"\n size=\"md\"\n footer={\n <div className=\"flex gap-3\">\n <Button variant=\"outline\" onClick={handleCancel}>\n Cancelar\n </Button>\n <Button variant=\"solid\" onClick={handleSave}>\n Salvar\n </Button>\n </div>\n }\n >\n <div className=\"flex flex-col\">\n <p className=\"text-sm text-text-500\">Escolha o tema:</p>\n <ThemeToggle variant=\"with-save\" onToggle={setSelectedTheme} />\n </div>\n </Modal>\n </>\n );\n};\nProfileToggleTheme.displayName = 'ProfileToggleTheme';\n\nconst ProfileMenuSection = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & { store?: DropdownStoreApi }\n>(({ className, children, store: _store, ...props }, ref) => {\n return (\n <div ref={ref} className={cn('flex flex-col p-2', className)} {...props}>\n {children}\n </div>\n );\n});\nProfileMenuSection.displayName = 'ProfileMenuSection';\n\nconst ProfileMenuFooter = ({\n className,\n disabled = false,\n onClick,\n store: externalStore,\n ...props\n}: HTMLAttributes<HTMLButtonElement> & {\n disabled?: boolean;\n store?: DropdownStoreApi;\n}) => {\n const store = useDropdownStore(externalStore);\n const setOpen = useStore(store, (s) => s.setOpen);\n\n return (\n <Button\n variant=\"outline\"\n className={cn('w-full', className)}\n disabled={disabled}\n onClick={(e) => {\n setOpen(false);\n onClick?.(e);\n }}\n {...props}\n >\n <span className=\"mr-2 flex items-center\">\n <SignOut className=\"text-inherit\" />\n </span>\n <Text color=\"inherit\">Sair</Text>\n </Button>\n );\n};\nProfileMenuFooter.displayName = 'ProfileMenuFooter';\n\n// Exportações\nexport default DropdownMenu;\nexport {\n // Componentes genéricos\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n MenuLabel,\n DropdownMenuSeparator,\n\n // Componentes específicos do ProfileMenu\n ProfileMenuTrigger,\n ProfileMenuHeader,\n ProfileMenuSection,\n ProfileMenuFooter,\n ProfileToggleTheme,\n ProfileMenuInfo,\n};\n","import { ReactNode, useEffect, useId } from 'react';\nimport { X } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\nimport Button from '../Button/Button';\nimport {\n isYouTubeUrl,\n getYouTubeVideoId,\n getYouTubeEmbedUrl,\n} from './utils/videoUtils';\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n xs: 'max-w-[360px]',\n sm: 'max-w-[420px]',\n md: 'max-w-[510px]',\n lg: 'max-w-[640px]',\n xl: 'max-w-[970px]',\n} as const;\n\n/**\n * Modal component props interface\n */\ntype ModalProps = {\n contentClassName?: string;\n /** Whether the modal is open */\n isOpen: boolean;\n /** Function to close the modal */\n onClose: () => void;\n /** Modal title */\n title: string;\n /** Modal description/content */\n children?: ReactNode;\n /** Size of the modal */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n /** Additional CSS classes for the modal content */\n className?: string;\n /** Whether pressing Escape should close the modal */\n closeOnEscape?: boolean;\n /** Footer content (typically buttons) */\n footer?: ReactNode;\n /** Hide the close button */\n hideCloseButton?: boolean;\n /** Modal variant */\n variant?: 'default' | 'activity';\n /** Description for activity variant */\n description?: string;\n /** Image URL for activity variant */\n image?: string;\n /** Alt text for activity image (leave empty for decorative images) */\n imageAlt?: string;\n /** Action link for activity variant */\n actionLink?: string;\n /** Action button label for activity variant */\n actionLabel?: string;\n};\n\n/**\n * Modal component for Analytica Ensino platforms\n *\n * A flexible modal component with multiple size variants and customizable behavior.\n *\n * @param isOpen - Whether the modal is currently open\n * @param onClose - Callback function called when the modal should be closed\n * @param title - The title displayed at the top of the modal\n * @param children - The main content of the modal\n * @param size - The size variant (xs, sm, md, lg, xl)\n * @param className - Additional CSS classes for the modal content\n * @param closeOnEscape - Whether pressing Escape closes the modal (default: true)\n * @param footer - Footer content, typically action buttons\n * @param hideCloseButton - Whether to hide the X close button (default: false)\n * @returns A modal overlay with content\n *\n * @example\n * ```tsx\n * <Modal\n * isOpen={isModalOpen}\n * onClose={() => setIsModalOpen(false)}\n * title=\"Invite your team\"\n * size=\"md\"\n * footer={\n * <div className=\"flex gap-3\">\n * <Button variant=\"outline\" onClick={() => setIsModalOpen(false)}>Cancel</Button>\n * <Button variant=\"solid\" onClick={handleExplore}>Explore</Button>\n * </div>\n * }\n * >\n * Elevate user interactions with our versatile modals.\n * </Modal>\n * ```\n */\nconst Modal = ({\n isOpen,\n onClose,\n title,\n children,\n size = 'md',\n className = '',\n closeOnEscape = true,\n footer,\n hideCloseButton = false,\n variant = 'default',\n description,\n image,\n imageAlt,\n actionLink,\n actionLabel,\n contentClassName = '',\n}: ModalProps) => {\n const titleId = useId();\n\n // Handle escape key\n useEffect(() => {\n if (!isOpen || !closeOnEscape) return;\n\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen, closeOnEscape, onClose]);\n\n // Handle body scroll lock and scrollbar shift fix\n useEffect(() => {\n if (!isOpen) return;\n\n // Calculate scrollbar width before hiding overflow\n const scrollbarWidth =\n window.innerWidth - document.documentElement.clientWidth;\n\n // Save original styles\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n // Apply scroll lock\n document.body.style.overflow = 'hidden';\n\n // Fix scrollbar shift: add padding to compensate for lost scrollbar\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n\n // Create overlay to cover the padding area with backdrop color\n const overlay = document.createElement('div');\n overlay.id = 'modal-scrollbar-overlay';\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n right: 0;\n width: ${scrollbarWidth}px;\n height: 100vh;\n background-color: rgb(0 0 0 / 0.6);\n z-index: 40;\n pointer-events: none;\n `;\n document.body.appendChild(overlay);\n }\n\n return () => {\n // Restore original styles\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n\n // Remove overlay\n const overlay = document.getElementById('modal-scrollbar-overlay');\n if (overlay) {\n overlay.remove();\n }\n };\n }, [isOpen]);\n\n if (!isOpen) return null;\n\n const sizeClasses = SIZE_CLASSES[size];\n const baseClasses =\n 'bg-secondary-50 rounded-3xl shadow-hard-shadow-2 border border-border-100 w-full mx-4';\n // Reset dialog default styles to prevent positioning issues\n const dialogResetClasses =\n 'p-0 m-0 border-none outline-none max-h-none static';\n const modalClasses = cn(\n baseClasses,\n sizeClasses,\n dialogResetClasses,\n className\n );\n\n // Normalize URLs missing protocol\n const normalizeUrl = (href: string) =>\n /^https?:\\/\\//i.test(href) ? href : `https://${href}`;\n\n // Handle action link click\n const handleActionClick = () => {\n if (actionLink) {\n window.open(normalizeUrl(actionLink), '_blank', 'noopener,noreferrer');\n }\n };\n\n // Activity variant rendering\n if (variant === 'activity') {\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default\">\n <dialog\n className={modalClasses}\n aria-labelledby={titleId}\n aria-modal=\"true\"\n open\n >\n {/* Header simples com X */}\n <div className=\"flex justify-end p-6 pb-0\">\n {!hideCloseButton && (\n <button\n onClick={onClose}\n className=\"p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2\"\n aria-label=\"Fechar modal\"\n >\n <X size={18} />\n </button>\n )}\n </div>\n\n {/* Conteúdo centralizado */}\n <div className=\"flex flex-col items-center px-6 pb-6 gap-5\">\n {/* Imagem ilustrativa */}\n {image && (\n <div className=\"flex justify-center\">\n <img\n src={image}\n alt={imageAlt ?? ''}\n className=\"w-[122px] h-[122px] object-contain\"\n />\n </div>\n )}\n\n {/* Título */}\n <h2\n id={titleId}\n className=\"text-lg font-semibold text-text-950 text-center\"\n >\n {title}\n </h2>\n\n {/* Descrição */}\n {description && (\n <p className=\"text-sm font-normal text-text-400 text-center max-w-md leading-[21px]\">\n {description}\n </p>\n )}\n\n {/* Ação: Botão ou Vídeo Embedado */}\n {actionLink && (\n <div className=\"w-full\">\n {(() => {\n const normalized = normalizeUrl(actionLink);\n const isYT = isYouTubeUrl(normalized);\n if (!isYT) return null;\n const id = getYouTubeVideoId(normalized);\n if (!id) {\n return (\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"large\"\n className=\"w-full\"\n onClick={handleActionClick}\n >\n {actionLabel || 'Iniciar Atividade'}\n </Button>\n );\n }\n return (\n <iframe\n src={getYouTubeEmbedUrl(id)}\n className=\"w-full aspect-video rounded-lg\"\n allowFullScreen\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n title=\"Vídeo YouTube\"\n />\n );\n })()}\n {!isYouTubeUrl(normalizeUrl(actionLink)) && (\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"large\"\n className=\"w-full\"\n onClick={handleActionClick}\n >\n {actionLabel || 'Iniciar Atividade'}\n </Button>\n )}\n </div>\n )}\n </div>\n </dialog>\n </div>\n );\n }\n\n // Default variant rendering\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default\">\n <dialog\n className={modalClasses}\n aria-labelledby={titleId}\n aria-modal=\"true\"\n open\n >\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-6\">\n <h2 id={titleId} className=\"text-lg font-semibold text-text-950\">\n {title}\n </h2>\n {!hideCloseButton && (\n <button\n onClick={onClose}\n className=\"p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2\"\n aria-label=\"Fechar modal\"\n >\n <X size={18} />\n </button>\n )}\n </div>\n\n {/* Content */}\n {children && (\n <div className={cn('px-6 pb-6', contentClassName)}>\n <div className=\"text-text-500 font-normal text-sm leading-6\">\n {children}\n </div>\n </div>\n )}\n\n {/* Footer */}\n {footer && (\n <div className=\"flex justify-end gap-3 px-6 pb-6\">{footer}</div>\n )}\n </dialog>\n </div>\n );\n};\n\nexport default Modal;\n","/**\n * Video utilities for Modal component\n *\n * Utilities to handle YouTube video embedding and URL detection\n */\n\n/**\n * Check if a given URL is a YouTube URL\n *\n * @param url - The URL to check\n * @returns true if the URL is from YouTube, false otherwise\n */\nexport const isYouTubeUrl = (url: string): boolean => {\n const youtubeRegex =\n /^(https?:\\/\\/)?((www|m|music)\\.)?(youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/.+/i;\n return youtubeRegex.test(url);\n};\n\n/**\n * Validate if hostname is a legitimate YouTube host\n *\n * @param host - The hostname to validate\n * @returns The type of YouTube host or null if invalid\n */\nconst isValidYouTubeHost = (\n host: string\n): 'youtu.be' | 'youtube' | 'nocookie' | null => {\n if (host === 'youtu.be') return 'youtu.be';\n\n const isValidYouTubeCom =\n host === 'youtube.com' ||\n (host.endsWith('.youtube.com') &&\n /^(www|m|music)\\.youtube\\.com$/.test(host));\n\n if (isValidYouTubeCom) return 'youtube';\n\n const isValidNoCookie =\n host === 'youtube-nocookie.com' ||\n (host.endsWith('.youtube-nocookie.com') &&\n /^(www|m|music)\\.youtube-nocookie\\.com$/.test(host));\n\n if (isValidNoCookie) return 'nocookie';\n\n return null;\n};\n\n/**\n * Extract video ID from youtu.be path\n *\n * @param pathname - The URL pathname\n * @returns The video ID or null\n */\nconst extractYoutuBeId = (pathname: string): string | null => {\n const firstSeg = pathname.split('/').filter(Boolean)[0];\n return firstSeg || null;\n};\n\n/**\n * Extract video ID from YouTube or nocookie domains\n *\n * @param pathname - The URL pathname\n * @param searchParams - The URL search parameters\n * @returns The video ID or null\n */\nconst extractYouTubeId = (\n pathname: string,\n searchParams: URLSearchParams\n): string | null => {\n const parts = pathname.split('/').filter(Boolean);\n const [first, second] = parts;\n\n if (first === 'embed' && second) return second;\n if (first === 'shorts' && second) return second;\n if (first === 'live' && second) return second;\n\n const v = searchParams.get('v');\n if (v) return v;\n\n return null;\n};\n\n/**\n * Extract YouTube video ID from URL\n *\n * @param url - The YouTube URL\n * @returns The video ID if found, null otherwise\n */\nexport const getYouTubeVideoId = (url: string): string | null => {\n try {\n const u = new URL(url);\n const hostType = isValidYouTubeHost(u.hostname.toLowerCase());\n\n if (!hostType) return null;\n\n if (hostType === 'youtu.be') {\n return extractYoutuBeId(u.pathname);\n }\n\n return extractYouTubeId(u.pathname, u.searchParams);\n } catch {\n return null;\n }\n};\n\n/**\n * Generate YouTube embed URL for iframe\n *\n * @param videoId - The YouTube video ID\n * @returns The embed URL for the video\n */\nexport const getYouTubeEmbedUrl = (videoId: string): string => {\n return `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=0&rel=0&modestbranding=1`;\n};\n","import { Moon, Sun } from 'phosphor-react';\nimport { useState, useEffect } from 'react';\nimport SelectionButton from '../SelectionButton/SelectionButton';\nimport type { ThemeMode } from '@/hooks/useTheme';\nimport { useTheme } from '../../hooks/useTheme';\n\ninterface ThemeToggleProps {\n variant?: 'default' | 'with-save';\n onToggle?: (theme: ThemeMode) => void;\n}\n\nexport const ThemeToggle = ({\n variant = 'default',\n onToggle,\n}: ThemeToggleProps) => {\n const { themeMode, setTheme } = useTheme();\n const [tempTheme, setTempTheme] = useState<ThemeMode>(themeMode);\n\n // Update temp theme when themeMode changes externally\n useEffect(() => {\n setTempTheme(themeMode);\n }, [themeMode]);\n\n const problemTypes = [\n {\n id: 'light' as ThemeMode,\n title: 'Claro',\n icon: <Sun size={24} />,\n },\n {\n id: 'dark' as ThemeMode,\n title: 'Escuro',\n icon: <Moon size={24} />,\n },\n {\n id: 'system' as ThemeMode,\n title: 'Sistema',\n icon: (\n <svg\n width=\"25\"\n height=\"25\"\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12.5 2.75C15.085 2.75276 17.5637 3.78054 19.3916 5.6084C21.2195 7.43628 22.2473 9.915 22.25 12.5C22.25 14.4284 21.6778 16.3136 20.6064 17.917C19.5352 19.5201 18.0128 20.7699 16.2314 21.5078C14.4499 22.2458 12.489 22.4387 10.5977 22.0625C8.70642 21.6863 6.96899 20.758 5.60547 19.3945C4.24197 18.031 3.31374 16.2936 2.9375 14.4023C2.56129 12.511 2.75423 10.5501 3.49219 8.76855C4.23012 6.98718 5.47982 5.46483 7.08301 4.39355C8.68639 3.32221 10.5716 2.75 12.5 2.75ZM11.75 4.28516C9.70145 4.47452 7.7973 5.42115 6.41016 6.94043C5.02299 8.4599 4.25247 10.4426 4.25 12.5C4.25247 14.5574 5.02299 16.5401 6.41016 18.0596C7.7973 19.5789 9.70145 20.5255 11.75 20.7148V4.28516Z\"\n fill=\"#525252\"\n />\n </svg>\n ),\n },\n ];\n\n const handleThemeSelect = (selectedTheme: ThemeMode) => {\n if (variant === 'with-save') {\n setTempTheme(selectedTheme);\n } else {\n setTheme(selectedTheme);\n }\n\n if (onToggle) {\n onToggle(selectedTheme);\n }\n };\n\n const currentTheme = variant === 'with-save' ? tempTheme : themeMode;\n\n return (\n <div className=\"flex flex-row gap-2 sm:gap-4 py-2\">\n {problemTypes.map((type) => (\n <SelectionButton\n key={type.id}\n icon={type.icon}\n label={type.title}\n selected={currentTheme === type.id}\n onClick={() => handleThemeSelect(type.id)}\n className=\"w-full p-2 sm:p-4\"\n />\n ))}\n </div>\n );\n};\n","import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * SelectionButton component props interface\n */\ntype SelectionButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * SelectionButton component for Analytica Ensino platforms\n *\n * Um botão com ícone e texto para ações e navegação com estado de seleção.\n * Ideal para filtros, tags, categorias, seleção de tipos, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado\n *\n * @example\n * ```tsx\n * <SelectionButton\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={false}\n * onClick={() => handleSelection()}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <SelectionButton\n * ref={buttonRef}\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={isSelected}\n * onClick={() => setSelected(!isSelected)}\n * />\n * ```\n */\nconst SelectionButton = forwardRef<HTMLButtonElement, SelectionButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'inline-flex',\n 'items-center',\n 'justify-start',\n 'gap-2',\n 'p-4',\n 'rounded-xl',\n 'cursor-pointer',\n 'border',\n 'border-border-50',\n 'bg-background',\n 'text-sm',\n 'text-text-700',\n 'font-bold',\n 'shadow-soft-shadow-1',\n 'hover:bg-background-100',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-indicator-info',\n 'focus-visible:ring-offset-0',\n 'focus-visible:shadow-none',\n 'active:ring-2',\n 'active:ring-primary-950',\n 'active:ring-offset-0',\n 'active:shadow-none',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n ];\n\n const stateClasses = selected\n ? ['ring-primary-950', 'ring-2', 'ring-offset-0', 'shadow-none']\n : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(allClasses, className)}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-6 h-6\">{icon}</span>\n <span>{label}</span>\n </button>\n );\n }\n);\n\nSelectionButton.displayName = 'SelectionButton';\n\nexport default SelectionButton;\n","import { useEffect } from 'react';\nimport { useThemeStore, ThemeMode } from '../store/themeStore';\n\nexport type { ThemeMode };\n\n/**\n * Hook para gerenciar temas com suporte a alternância manual e detecção automática do sistema\n * Este hook permite alternar entre temas light, dark e automático baseado nas preferências do sistema\n * Utiliza Zustand para persistir o estado entre múltiplos arquivos e sessões\n */\nexport const useTheme = () => {\n const {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n initializeTheme,\n handleSystemThemeChange,\n } = useThemeStore();\n\n useEffect(() => {\n // Initialize theme on first render\n initializeTheme();\n\n // Listener para mudanças nas preferências do sistema (apenas quando mode é 'system')\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, [initializeTheme, handleSystemThemeChange]);\n\n return {\n themeMode,\n isDark,\n toggleTheme,\n setTheme,\n };\n};\n","import { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n/**\n * Theme store state interface\n */\nexport interface ThemeState {\n /**\n * Current theme mode\n */\n themeMode: ThemeMode;\n /**\n * Whether the current theme is dark\n */\n isDark: boolean;\n}\n\n/**\n * Theme store actions interface\n */\nexport interface ThemeActions {\n /**\n * Apply theme based on the mode selected\n */\n applyTheme: (mode: ThemeMode) => void;\n /**\n * Toggle between themes\n */\n toggleTheme: () => void;\n /**\n * Set a specific theme mode\n */\n setTheme: (mode: ThemeMode) => void;\n /**\n * Initialize theme on app start\n */\n initializeTheme: () => void;\n /**\n * Handle system theme change\n */\n handleSystemThemeChange: () => void;\n}\n\nexport type ThemeStore = ThemeState & ThemeActions;\n\n/**\n * Apply theme to DOM based on mode\n */\nconst applyThemeToDOM = (mode: ThemeMode): boolean => {\n const htmlElement = document.documentElement;\n const originalTheme = htmlElement.getAttribute('data-original-theme');\n\n if (mode === 'dark') {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (mode === 'light') {\n if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n }\n return false;\n } else if (mode === 'system') {\n const isSystemDark = window.matchMedia(\n '(prefers-color-scheme: dark)'\n ).matches;\n if (isSystemDark) {\n htmlElement.setAttribute('data-theme', 'dark');\n return true;\n } else if (originalTheme) {\n htmlElement.setAttribute('data-theme', originalTheme);\n return false;\n }\n }\n return false;\n};\n\n/**\n * Save original theme from white label\n */\nconst saveOriginalTheme = () => {\n const htmlElement = document.documentElement;\n const currentTheme = htmlElement.getAttribute('data-theme');\n if (currentTheme && !htmlElement.getAttribute('data-original-theme')) {\n htmlElement.setAttribute('data-original-theme', currentTheme);\n }\n};\n\n/**\n * Theme store using Zustand with persistence\n */\nexport const useThemeStore = create<ThemeStore>()(\n devtools(\n persist(\n (set, get) => ({\n // Initial state\n themeMode: 'system',\n isDark: false,\n\n // Actions\n applyTheme: (mode: ThemeMode) => {\n const isDark = applyThemeToDOM(mode);\n set({ isDark });\n },\n\n toggleTheme: () => {\n const { themeMode, applyTheme } = get();\n let newMode: ThemeMode;\n\n if (themeMode === 'light') {\n newMode = 'dark';\n } else if (themeMode === 'dark') {\n newMode = 'light';\n } else {\n // Se estiver em 'system', vai para 'dark'\n newMode = 'dark';\n }\n\n set({ themeMode: newMode });\n applyTheme(newMode);\n },\n\n setTheme: (mode: ThemeMode) => {\n const { applyTheme } = get();\n set({ themeMode: mode });\n applyTheme(mode);\n },\n\n initializeTheme: () => {\n const { themeMode, applyTheme } = get();\n\n // Save original theme from white label\n saveOriginalTheme();\n\n // Apply the current theme mode\n applyTheme(themeMode);\n },\n\n handleSystemThemeChange: () => {\n const { themeMode, applyTheme } = get();\n // Only respond to system changes when in system mode\n if (themeMode === 'system') {\n applyTheme('system');\n }\n },\n }),\n {\n name: 'theme-store', // Nome da chave no localStorage\n partialize: (state) => ({\n themeMode: state.themeMode,\n }), // Só persiste o themeMode, não o isDark\n }\n ),\n {\n name: 'theme-store',\n }\n )\n);\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n AccordionGroup,\n Badge,\n CardAccordation,\n CheckBox,\n cn,\n Text,\n Divider,\n} from '../../';\nimport {\n areSelectedIdsEqual,\n isCategoryEnabled as isCategoryEnabledHelper,\n getBadgeText as getBadgeTextHelper,\n handleAccordionValueChange as handleAccordionValueChangeHelper,\n calculateFormattedItemsForAutoSelection,\n} from './CheckBoxGroup.helpers';\n\nexport type Item = {\n id: string;\n name: string;\n [key: string]: unknown;\n};\n\nexport type CategoryConfig = {\n key: string;\n label: string;\n selectedIds?: string[];\n dependsOn?: string[];\n itens?: Item[];\n filteredBy?: { key: string; internalField: string }[];\n};\n\nexport const CheckboxGroup = ({\n categories,\n onCategoriesChange,\n compactSingleItem = true,\n showDivider = true,\n showSingleItem = false,\n}: {\n categories: CategoryConfig[];\n onCategoriesChange: (categories: CategoryConfig[]) => void;\n compactSingleItem?: boolean;\n showDivider?: boolean;\n showSingleItem?: boolean;\n}) => {\n const [openAccordion, setOpenAccordion] = useState<string>('');\n\n // Refs to prevent infinite loops and track auto-selection state\n const onCategoriesChangeRef = useRef(onCategoriesChange);\n const previousCategoriesRef = useRef<CategoryConfig[]>(categories);\n // Track which categories have had auto-selection applied (by stringified selectedIds)\n const appliedAutoSelectionRef = useRef<string>('');\n\n // Update ref when onCategoriesChange changes\n useEffect(() => {\n onCategoriesChangeRef.current = onCategoriesChange;\n }, [onCategoriesChange]);\n\n // Use helper function for comparing selectedIds arrays\n\n // Auto-seleciona categorias com apenas um item (considerando itens filtrados)\n const categoriesWithAutoSelection = useMemo(() => {\n return categories.map((category) => {\n // Get filtered/visible items for this category\n const filteredItems = calculateFormattedItemsForAutoSelection(\n category,\n categories\n );\n\n // Se tem apenas um item filtrado/visível e nenhum está selecionado, auto-seleciona\n if (\n filteredItems.length === 1 &&\n (!category.selectedIds || category.selectedIds.length === 0)\n ) {\n return {\n ...category,\n selectedIds: [filteredItems[0].id],\n };\n }\n return category;\n });\n }, [categories]);\n\n // Aplica a auto-seleção se necessário\n // Note: onCategoriesChange should be memoized by the parent component to prevent re-renders\n useEffect(() => {\n // Check if categories have actually changed by comparing with previous reference\n const categoriesChanged = categories !== previousCategoriesRef.current;\n previousCategoriesRef.current = categories;\n\n // Check for auto-selection changes using efficient comparison\n const hasAutoSelectionChanges = categoriesWithAutoSelection.some(\n (cat, index) => {\n const originalCat = categories[index];\n return !areSelectedIdsEqual(cat.selectedIds, originalCat.selectedIds);\n }\n );\n\n if (!hasAutoSelectionChanges) {\n // No auto-selection needed, reset tracking if categories changed\n if (categoriesChanged) {\n appliedAutoSelectionRef.current = '';\n }\n return;\n }\n\n // Create a signature of the auto-selection to prevent duplicate notifications\n const autoSelectionSignature = JSON.stringify(\n categoriesWithAutoSelection.map((c) => c.selectedIds)\n );\n\n // Only notify if this exact auto-selection hasn't been applied yet\n if (appliedAutoSelectionRef.current !== autoSelectionSignature) {\n appliedAutoSelectionRef.current = autoSelectionSignature;\n onCategoriesChangeRef.current(categoriesWithAutoSelection);\n }\n }, [categoriesWithAutoSelection, categories]);\n\n const isCheckBoxIsSelected = (categoryKey: string, itemId: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return false;\n return category.selectedIds?.includes(itemId) || false;\n };\n\n const isMinimalOneCheckBoxIsSelected = (categoryKey: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return false;\n\n // Obtém apenas os itens filtrados (visíveis)\n const formattedItems = getFormattedItems(categoryKey);\n const filteredItems = formattedItems.flatMap((group) => group.itens || []);\n const filteredItemIds = filteredItems.map((item) => item.id);\n\n // Verifica se pelo menos um item filtrado está selecionado\n return filteredItemIds.some((itemId) =>\n category.selectedIds?.includes(itemId)\n );\n };\n\n // Helper function to create combination of two arrays\n const createCombinations = (\n acc: string[][],\n currentArray: string[]\n ): string[][] => {\n const combinations: string[][] = [];\n for (const existingCombo of acc) {\n for (const item of currentArray) {\n combinations.push([...existingCombo, item]);\n }\n }\n return combinations;\n };\n\n // Helper function to calculate cartesian product of arrays\n const cartesian = (arr: string[][]): string[][] => {\n return arr.reduce(createCombinations, [[]] as string[][]);\n };\n\n // Helper function to get selected IDs for filters\n const getSelectedIdsForFilters = (\n filters: { key: string; internalField: string; label?: string }[]\n ) => {\n return filters.map((f) => {\n const parentCat = categories.find((c) => c.key === f.key);\n if (!parentCat?.selectedIds?.length) {\n return [];\n }\n return parentCat.selectedIds;\n });\n };\n\n // Helper function to generate group label for single filter\n const generateSingleFilterLabel = (\n filter: { key: string; internalField: string },\n comboId: string\n ) => {\n const cat = categories.find((c) => c.key === filter.key);\n return cat?.itens?.find((i) => i.id === comboId)?.name || comboId;\n };\n\n // Helper function to generate group label for multiple filters\n const generateMultipleFiltersLabel = (\n filters: { key: string; internalField: string }[],\n comboIds: string[]\n ) => {\n const firstCat = categories.find((c) => c.key === filters[0].key);\n const firstVal =\n firstCat?.itens?.find((i) => i.id === comboIds[0])?.name || comboIds[0];\n\n const labelParts: string[] = [firstVal];\n\n for (let idx = 1; idx < filters.length; idx++) {\n const f = filters[idx];\n const cat = categories.find((c) => c.key === f.key);\n const val =\n cat?.itens?.find((i) => i.id === comboIds[idx])?.name || comboIds[idx];\n labelParts.push(`(${val})`);\n }\n return labelParts.join(' ');\n };\n\n // Helper function to process combination and add to grouped map\n const processCombination = (\n comboIds: string[],\n filters: { key: string; internalField: string; label?: string }[],\n category: CategoryConfig,\n groupedMap: Record<string, { groupLabel?: string; itens: Item[] }>\n ) => {\n const filteredItems = (category?.itens || []).filter((item) =>\n filters.every((f, idx) => item[f.internalField] === comboIds[idx])\n );\n\n if (filteredItems.length === 0) return;\n\n let groupLabel: string | undefined = undefined;\n\n if (filters.length === 1) {\n groupLabel = generateSingleFilterLabel(filters[0], comboIds[0]);\n } else if (filters.length > 1) {\n groupLabel = generateMultipleFiltersLabel(filters, comboIds);\n }\n\n const key = groupLabel || '';\n if (!groupedMap[key]) {\n groupedMap[key] = groupLabel ? { groupLabel, itens: [] } : { itens: [] };\n }\n groupedMap[key].itens.push(...filteredItems);\n };\n\n // Helper function to calculate formatted items for a category\n const calculateFormattedItems = (categoryKey: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n\n if (!category?.dependsOn || category.dependsOn.length === 0) {\n return [{ itens: category?.itens || [] }];\n }\n\n // Check if category is enabled based on dependencies (inline to avoid stale closure)\n const isEnabled = category.dependsOn.every((depKey) => {\n const depCat = categories.find((c) => c.key === depKey);\n return depCat?.selectedIds && depCat.selectedIds.length > 0;\n });\n\n // If category is disabled, return empty items array to hide all items\n if (!isEnabled) {\n return [{ itens: [] }];\n }\n\n const filters =\n (category.filteredBy as {\n key: string;\n internalField: string;\n label?: string;\n }[]) || [];\n\n if (filters.length === 0) {\n return [{ itens: category?.itens || [] }];\n }\n\n const selectedIdsArr = getSelectedIdsForFilters(filters);\n\n if (selectedIdsArr.some((arr) => arr.length === 0)) {\n return [{ itens: [] }];\n }\n\n const combinations = cartesian(selectedIdsArr);\n const groupedMap: Record<string, { groupLabel?: string; itens: Item[] }> =\n {};\n\n for (const comboIds of combinations) {\n processCombination(comboIds, filters, category, groupedMap);\n }\n\n const groupedItems = Object.values(groupedMap).filter(\n (g) => g.itens.length\n );\n\n return groupedItems.length ? groupedItems : [{ itens: [] }];\n };\n\n const formattedItemsMap = useMemo(() => {\n const formattedItemsMap: Record<\n string,\n { groupLabel?: string; itens: Item[] }[]\n > = {};\n\n for (const category of categories) {\n const formattedItems = calculateFormattedItems(category.key);\n formattedItemsMap[category.key] = formattedItems;\n }\n\n return formattedItemsMap;\n }, [categories]);\n\n const getFormattedItems = (categoryKey: string) => {\n return formattedItemsMap[categoryKey] || [{ itens: [] }];\n };\n\n // Helper function to get badge text for category\n const getBadgeText = (category: CategoryConfig): string => {\n const formattedItems = getFormattedItems(category.key);\n return getBadgeTextHelper(category, formattedItems);\n };\n\n // Helper function to check if category is enabled\n const isCategoryEnabled = (category: CategoryConfig): boolean => {\n return isCategoryEnabledHelper(category, categories);\n };\n\n // Helper function to handle accordion value change\n const handleAccordionValueChange = (value: string | string[] | undefined) => {\n const newValue = handleAccordionValueChangeHelper(\n value,\n categories,\n isCategoryEnabled\n );\n if (newValue !== null) {\n setOpenAccordion(newValue);\n }\n };\n\n const getDependentCategories = (categoryKey: string): string[] => {\n return categories\n .filter((cat) => cat.dependsOn?.includes(categoryKey))\n .map((cat) => cat.key);\n };\n\n // Helper function to find items to remove from dependent category\n const findItemsToRemove = (\n depCategory: CategoryConfig,\n relevantFilter: { key: string; internalField: string },\n deselectedItemId: string\n ): string[] => {\n return (\n depCategory.itens\n ?.filter(\n (item) => item[relevantFilter.internalField] === deselectedItemId\n )\n .map((item) => item.id) || []\n );\n };\n\n // Helper function to process dependent category for deselection\n const processDependentCategory = (\n depCategoryKey: string,\n categoryKey: string,\n deselectedItemId: string,\n itemsToDeselect: Record<string, string[]>\n ) => {\n const depCategory = categories.find((c) => c.key === depCategoryKey);\n if (!depCategory?.filteredBy) return;\n\n const relevantFilter = depCategory.filteredBy.find(\n (f) => f.key === categoryKey\n );\n if (!relevantFilter) return;\n\n const itemsToRemove = findItemsToRemove(\n depCategory,\n relevantFilter,\n deselectedItemId\n );\n if (itemsToRemove.length > 0) {\n itemsToDeselect[depCategoryKey] = itemsToRemove;\n }\n };\n\n const getItemsToDeselect = (\n categoryKey: string,\n deselectedItemId: string\n ) => {\n const deselectedItem = categories\n .find((c) => c.key === categoryKey)\n ?.itens?.find((item) => item.id === deselectedItemId);\n if (!deselectedItem) return {};\n\n const itemsToDeselect: Record<string, string[]> = {};\n const dependentCategories = getDependentCategories(categoryKey);\n\n for (const depCategoryKey of dependentCategories) {\n processDependentCategory(\n depCategoryKey,\n categoryKey,\n deselectedItemId,\n itemsToDeselect\n );\n }\n\n return itemsToDeselect;\n };\n\n // Helper function to update category with new selected IDs\n const updateCategorySelectedIds = (\n updatedCategories: CategoryConfig[],\n depCategoryIndex: number,\n depCategory: CategoryConfig,\n itemIds: string[]\n ): CategoryConfig[] => {\n const newSelectedIds =\n depCategory.selectedIds?.filter((id) => !itemIds.includes(id)) || [];\n\n updatedCategories[depCategoryIndex] = {\n ...depCategory,\n selectedIds: newSelectedIds,\n };\n\n return updatedCategories;\n };\n\n // Helper function to apply recursive cascade deselection\n const applyRecursiveCascade = (\n depCategoryKey: string,\n itemIds: string[],\n updatedCategories: CategoryConfig[]\n ): CategoryConfig[] => {\n let result = updatedCategories;\n for (const itemId of itemIds) {\n result = applyCascadeDeselection(depCategoryKey, itemId, result);\n }\n return result;\n };\n\n const applyCascadeDeselection = (\n categoryKey: string,\n deselectedItemId: string,\n currentCategories: CategoryConfig[]\n ): CategoryConfig[] => {\n const itemsToDeselect = getItemsToDeselect(categoryKey, deselectedItemId);\n let updatedCategories = [...currentCategories];\n\n for (const [depCategoryKey, itemIds] of Object.entries(itemsToDeselect)) {\n const depCategoryIndex = updatedCategories.findIndex(\n (c) => c.key === depCategoryKey\n );\n\n if (depCategoryIndex !== -1) {\n const depCategory = updatedCategories[depCategoryIndex];\n updatedCategories = updateCategorySelectedIds(\n updatedCategories,\n depCategoryIndex,\n depCategory,\n itemIds\n );\n updatedCategories = applyRecursiveCascade(\n depCategoryKey,\n itemIds,\n updatedCategories\n );\n }\n }\n\n return updatedCategories;\n };\n\n const toggleAllInCategory = (categoryKey: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return;\n\n // Obtém apenas os itens filtrados (visíveis)\n const formattedItems = getFormattedItems(categoryKey);\n const filteredItems = formattedItems.flatMap((group) => group.itens || []);\n const filteredItemIds = filteredItems.map((item) => item.id);\n\n // Verifica quantos itens filtrados estão selecionados\n const selectedFilteredCount = filteredItemIds.filter((itemId) =>\n category.selectedIds?.includes(itemId)\n ).length;\n\n // Se NENHUM item filtrado está selecionado OU pelo menos um está selecionado mas não todos,\n // então seleciona todos os itens filtrados\n // Se TODOS os itens filtrados estão selecionados, então deseleciona todos os filtrados\n const allFilteredSelected =\n selectedFilteredCount === filteredItemIds.length;\n\n const newSelection = allFilteredSelected\n ? category.selectedIds?.filter((id) => !filteredItemIds.includes(id)) ||\n []\n : [\n ...(category.selectedIds || []),\n ...filteredItemIds.filter(\n (id) => !category.selectedIds?.includes(id)\n ),\n ];\n\n let updatedCategories = categories.map((c) =>\n c.key === categoryKey ? { ...c, selectedIds: newSelection } : c\n );\n\n // Se está deselecionando, aplica cascata para os itens que foram deselecionados\n if (allFilteredSelected) {\n for (const itemId of filteredItemIds) {\n updatedCategories = applyCascadeDeselection(\n categoryKey,\n itemId,\n updatedCategories\n );\n }\n }\n\n onCategoriesChange(updatedCategories);\n };\n\n const toggleItem = (categoryKey: string, itemId: string) => {\n const category = categories.find((c) => c.key === categoryKey);\n if (!category) return;\n const isCurrentlySelected = category.selectedIds?.includes(itemId);\n const newSelection = isCurrentlySelected\n ? category.selectedIds?.filter((id) => id !== itemId)\n : [...(category.selectedIds || []), itemId];\n\n let updatedCategories = categories.map((c) =>\n c.key === categoryKey ? { ...c, selectedIds: newSelection } : c\n );\n\n // Se está deselecionando, aplica cascata\n if (isCurrentlySelected) {\n updatedCategories = applyCascadeDeselection(\n categoryKey,\n itemId,\n updatedCategories\n );\n }\n\n onCategoriesChange(updatedCategories);\n };\n\n // Helper component to render individual checkbox item\n const renderCheckboxItem = (item: Item, categoryKey: string) => {\n // Generate unique ID by combining category key and item id to avoid conflicts\n const uniqueId = `${categoryKey}-${item.id}`;\n\n return (\n <div key={item.id} className=\"flex items-center gap-3 px-2\">\n <CheckBox\n id={uniqueId}\n checked={isCheckBoxIsSelected(categoryKey, item.id)}\n onChange={() => toggleItem(categoryKey, item.id)}\n />\n <label\n htmlFor={uniqueId}\n className=\"text-sm text-text-950 cursor-pointer select-none\"\n >\n {item.name}\n </label>\n </div>\n );\n };\n\n // Helper component to render formatted group\n const renderFormattedGroup = (\n formattedGroup: { groupLabel?: string; itens: Item[] },\n idx: number,\n categoryKey: string\n ) => (\n <div\n key={formattedGroup.groupLabel || `group-${idx}`}\n className=\"flex flex-col gap-3\"\n >\n {'groupLabel' in formattedGroup && formattedGroup.groupLabel && (\n <Text size=\"sm\" className=\"mt-2\" weight=\"semibold\">\n {formattedGroup.groupLabel}\n </Text>\n )}\n {formattedGroup.itens?.map((item: Item) =>\n renderCheckboxItem(item, categoryKey)\n )}\n </div>\n );\n\n // Helper component to render accordion trigger\n const renderAccordionTrigger = (\n category: CategoryConfig,\n isEnabled: boolean\n ) => (\n <div className=\"flex items-center justify-between w-full p-2\">\n <div className=\"flex items-center gap-3\">\n <CheckBox\n checked={isMinimalOneCheckBoxIsSelected(category.key)}\n disabled={!isEnabled}\n indeterminate={isMinimalOneCheckBoxIsSelected(category.key)}\n onChange={() => toggleAllInCategory(category.key)}\n />\n <Text\n size=\"sm\"\n weight=\"medium\"\n className={cn('text-text-800', !isEnabled && 'opacity-40')}\n >\n {category.label}\n </Text>\n </div>\n {(openAccordion === category.key || isEnabled) && (\n <Badge variant=\"solid\" action=\"info\">\n {getBadgeText(category)}\n </Badge>\n )}\n </div>\n );\n\n // Helper component to render compact single item view\n const renderCompactSingleItem = (category: CategoryConfig) => {\n const formattedItems = getFormattedItems(category.key);\n const allItems = formattedItems.flatMap((group) => group.itens || []);\n\n if (allItems.length !== 1) {\n return null;\n }\n\n const singleItem = allItems[0];\n\n return (\n <div\n key={category.key}\n className=\"flex items-center justify-between w-full px-3 py-2\"\n >\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-800\">\n {category.label}\n </Text>\n <Text size=\"sm\" className=\"text-text-950\">\n {singleItem.name}\n </Text>\n </div>\n );\n };\n\n // Helper component to render category accordion\n const renderCategoryAccordion = (category: CategoryConfig) => {\n // Check if category is enabled based on dependencies\n const isEnabled = isCategoryEnabled(category);\n const hasOnlyOneItem = category.itens?.length === 1;\n\n if (hasOnlyOneItem && !compactSingleItem && !showSingleItem) {\n return null;\n }\n\n const formattedItems = getFormattedItems(category.key);\n const allItems = formattedItems.flatMap((group) => group.itens || []);\n const hasOnlyOneAvailableItem = allItems.length === 1;\n\n // If compactSingleItem is enabled and there's only one available item, render compact version\n if (compactSingleItem && hasOnlyOneAvailableItem && isEnabled) {\n return (\n <div key={category.key}>\n {renderCompactSingleItem(category)}\n {showDivider && <Divider />}\n </div>\n );\n }\n\n const hasNoItems = formattedItems.every(\n (group) => !group.itens || group.itens.length === 0\n );\n\n return (\n <div key={category.key}>\n <CardAccordation\n value={category.key}\n disabled={!isEnabled}\n className={cn(\n 'bg-transparent border-0',\n openAccordion === category.key && 'bg-background-50 border-none'\n )}\n trigger={renderAccordionTrigger(category, isEnabled)}\n >\n <div className=\"flex flex-col gap-3 pt-2\">\n {hasNoItems && isEnabled ? (\n <div className=\"px-2 py-4\">\n <Text size=\"sm\" className=\"text-text-500 text-center\">\n Sem dados\n </Text>\n </div>\n ) : (\n formattedItems.map((formattedGroup, idx) =>\n renderFormattedGroup(formattedGroup, idx, category.key)\n )\n )}\n </div>\n </CardAccordation>\n {openAccordion !== category.key && showDivider && <Divider />}\n </div>\n );\n };\n\n // Auto-collapse accordion when category becomes disabled\n useEffect(() => {\n if (!openAccordion) return;\n\n const category = categories.find((c) => c.key === openAccordion);\n if (!category) return;\n\n // Check if the open category is now disabled\n const isEnabled = isCategoryEnabled(category);\n\n // If category is disabled, close it\n if (!isEnabled) {\n // Use setTimeout to ensure this runs after any other state updates\n setTimeout(() => {\n setOpenAccordion('');\n }, 0);\n }\n }, [categories, openAccordion]);\n\n return (\n <AccordionGroup\n type=\"single\"\n collapsible\n value={openAccordion}\n onValueChange={handleAccordionValueChange}\n >\n {categories.map(renderCategoryAccordion)}\n </AccordionGroup>\n );\n};\n","import { CSSProperties, ReactNode } from 'react';\nimport 'katex/dist/katex.min.css';\nimport { InlineMath, BlockMath } from 'react-katex';\nimport DOMPurify from 'dompurify';\nimport parse, {\n DOMNode,\n Element,\n HTMLReactParserOptions,\n} from 'html-react-parser';\nimport { cn } from '../../utils/utils';\n\n/**\n * Props for the LatexRenderer component\n */\nexport interface LatexRendererProps {\n /** HTML content containing LaTeX expressions to render */\n content: string;\n /** Additional CSS classes to apply */\n className?: string;\n /** Inline styles to apply */\n style?: CSSProperties;\n /** Custom error renderer for invalid LaTeX expressions */\n onError?: (latex: string) => ReactNode;\n}\n\n/**\n * Helper function to sanitize HTML content to prevent XSS attacks\n */\nconst sanitizeHtml = (value: string): string => {\n return DOMPurify.sanitize(value, {\n ADD_ATTR: ['data-latex', 'data-display-mode', 'data-math', 'data-math-id'],\n });\n};\n\n/**\n * Helper function to decode HTML entities\n * Converts entities like &, <, > back to their actual characters\n */\nconst decodeHtmlEntities = (str: string): string => {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = str;\n return textarea.value;\n};\n\n/**\n * Helper function to clean latex from invisible characters\n */\nconst cleanLatex = (str: string): string => {\n // Remove zero-width characters, invisible characters, and other problematic Unicode\n return str.replaceAll(/[\\u200B-\\u200D\\uFEFF]/g, '').trim();\n};\n\n/**\n * Type for math parts used in rendering\n */\ninterface MathPart {\n id: number;\n type: 'inline' | 'block';\n latex: string;\n}\n\n/**\n * Creates a replace function for html-react-parser that replaces math placeholders\n * with KaTeX components\n */\nconst createMathReplacer = (\n mathParts: MathPart[],\n errorRenderer: (latex: string) => ReactNode\n) => {\n return (domNode: DOMNode) => {\n if (\n domNode instanceof Element &&\n domNode.name === 'span' &&\n domNode.attribs['data-math-id']\n ) {\n const mathId = Number.parseInt(domNode.attribs['data-math-id'], 10);\n const mathPart = mathParts[mathId];\n\n if (!mathPart) return domNode;\n\n if (mathPart.type === 'inline') {\n return (\n <InlineMath\n key={`math-${mathId}`}\n math={mathPart.latex}\n renderError={() => errorRenderer(mathPart.latex)}\n />\n );\n } else {\n return (\n <div key={`math-${mathId}`} className=\"my-2.5 text-center\">\n <BlockMath\n math={mathPart.latex}\n renderError={() => errorRenderer(mathPart.latex)}\n />\n </div>\n );\n }\n }\n return domNode;\n };\n};\n\n/**\n * LatexRenderer component for Analytica Ensino platforms\n *\n * Renders HTML content with embedded LaTeX/KaTeX mathematical expressions.\n * Supports multiple LaTeX formats:\n * - Inline math: `$...$` or `<latex>...</latex>`\n * - Block math: `$$...$$`\n * - LaTeX environments: `\\begin{equation}...\\end{equation}`, etc.\n * - Editor format: `<span class=\"math-formula\" data-latex=\"...\">...</span>`\n *\n * @param content - HTML content with LaTeX expressions\n * @param className - Additional CSS classes\n * @param style - Inline styles\n * @param onError - Custom error renderer\n * @returns Rendered content with mathematical expressions\n *\n * @example\n * ```tsx\n * <LatexRenderer content=\"The formula is $E = mc^2$\" />\n *\n * <LatexRenderer\n * content=\"Block equation: $$\\sum_{i=1}^{n} x_i$$\"\n * className=\"my-custom-class\"\n * />\n *\n * <LatexRenderer\n * content=\"<p>Matrix: \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix}</p>\"\n * onError={(latex) => <span>Invalid: {latex}</span>}\n * />\n * ```\n */\nconst LatexRenderer = ({\n content,\n className,\n style,\n onError,\n}: LatexRendererProps) => {\n const renderContentWithMath = (htmlContent: string) => {\n if (!htmlContent) return null;\n\n let processedContent = htmlContent;\n const mathParts: MathPart[] = [];\n\n // Step 1: Handle math-formula spans (from the editor)\n const mathFormulaPattern =\n /<span[^>]*class=\"math-formula\"[^>]*data-latex=\"([^\"]*)\"[^>]*>[\\s\\S]*?<\\/span>/g;\n processedContent = processedContent.replaceAll(\n mathFormulaPattern,\n (match, latex) => {\n const isDisplayMode = match.includes('data-display-mode=\"true\"');\n const id = mathParts.length;\n mathParts.push({\n id,\n type: isDisplayMode ? 'block' : 'inline',\n latex: cleanLatex(decodeHtmlEntities(latex)),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 2: Handle wrapped math expressions (from math modal - legacy)\n const wrappedMathPattern =\n /<span[^>]*class=\"math-expression\"[^>]*data-math=\"([^\"]*)\"[^>]*>.*?<\\/span>/g;\n processedContent = processedContent.replaceAll(\n wrappedMathPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'inline',\n latex: cleanLatex(decodeHtmlEntities(latex)),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 3: Handle raw $$...$$ expressions (manual input or saved content) - BEFORE single $\n const doubleDollarPattern = /(?<!\\\\)\\$\\$([\\s\\S]+?)\\$\\$/g;\n processedContent = processedContent.replaceAll(\n doubleDollarPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'block',\n latex: cleanLatex(latex),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 4: Handle single $...$ expressions for inline math\n const singleDollarPattern = /(?<!\\\\)\\$([\\s\\S]+?)\\$/g;\n processedContent = processedContent.replaceAll(\n singleDollarPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'inline',\n latex: cleanLatex(latex),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 5: Handle <latex>...</latex> tags for inline math\n const latexTagPattern =\n /(?:<latex>|<latex>)([\\s\\S]*?)(?:<\\/latex>|<\\/latex>)/g;\n processedContent = processedContent.replaceAll(\n latexTagPattern,\n (match, latex) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'inline',\n latex: cleanLatex(latex),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n }\n );\n\n // Step 6: Handle standalone LaTeX environments (align, equation, pmatrix, etc.) for block math\n const latexEnvPattern = /\\\\begin\\{([^}]+)\\}([\\s\\S]*?)\\\\end\\{\\1\\}/g;\n processedContent = processedContent.replaceAll(latexEnvPattern, (match) => {\n const id = mathParts.length;\n mathParts.push({\n id,\n type: 'block',\n latex: cleanLatex(match),\n });\n return `<span data-math-id=\"${id}\"></span>`;\n });\n\n // Sanitize the HTML with placeholders\n const sanitizedContent = sanitizeHtml(processedContent);\n\n // Default error renderer\n const defaultErrorRenderer = (latex: string) => (\n <span className=\"text-red-600\">Math Error: {latex}</span>\n );\n\n const errorRenderer = onError || defaultErrorRenderer;\n\n // Parse HTML and replace math placeholders with React components\n const options: HTMLReactParserOptions = {\n replace: createMathReplacer(mathParts, errorRenderer),\n };\n\n return <>{parse(sanitizedContent, options)}</>;\n };\n\n return (\n <div\n className={cn('whitespace-pre-wrap leading-relaxed', className)}\n style={style}\n >\n {renderContentWithMath(content)}\n </div>\n );\n};\n\nexport default LatexRenderer;\n","import {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n} from 'react';\nimport Text from '../Text/Text';\nimport { Check, Minus } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckBox size variants\n */\ntype CheckBoxSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckBox visual state\n */\ntype CheckBoxState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n checkbox: 'w-4 h-4', // 16px x 16px\n textSize: 'sm' as const,\n spacing: 'gap-1.5', // 6px\n borderWidth: 'border-2',\n iconSize: 14, // pixels for Phosphor icons\n labelHeight: 'h-[21px]',\n },\n medium: {\n checkbox: 'w-5 h-5', // 20px x 20px\n textSize: 'md' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-2',\n iconSize: 16, // pixels for Phosphor icons\n labelHeight: 'h-6',\n },\n large: {\n checkbox: 'w-6 h-6', // 24px x 24px\n textSize: 'lg' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-[3px]', // 3px border\n iconSize: 20, // pixels for Phosphor icons\n labelHeight: 'h-[27px]',\n },\n} as const;\n\n/**\n * Base checkbox styling classes using design system colors\n */\nconst BASE_CHECKBOX_CLASSES =\n 'rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked:\n 'border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-primary-800 bg-primary-800 text-text',\n },\n focused: {\n unchecked:\n 'border-indicator-info bg-background ring-2 ring-indicator-info/20',\n checked:\n 'border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20',\n },\n invalid: {\n unchecked: 'border-error-700 bg-background hover:border-error-600',\n checked: 'border-error-700 bg-primary-950 text-text',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed opacity-40',\n checked:\n 'border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40',\n },\n} as const;\n\n/**\n * CheckBox component props interface\n */\nexport type CheckBoxProps = {\n /** Label text to display next to the checkbox */\n label?: ReactNode;\n /** Size variant of the checkbox */\n size?: CheckBoxSize;\n /** Visual state of the checkbox */\n state?: CheckBoxState;\n /** Indeterminate state for partial selections */\n indeterminate?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>;\n\n/**\n * CheckBox component for Analytica Ensino platforms\n *\n * A checkbox component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic checkbox\n * <CheckBox label=\"Option\" />\n *\n * // Small size\n * <CheckBox size=\"small\" label=\"Small option\" />\n *\n * // Invalid state\n * <CheckBox state=\"invalid\" label=\"Required field\" />\n *\n * // Disabled state\n * <CheckBox disabled label=\"Disabled option\" />\n * ```\n */\nconst CheckBox = forwardRef<HTMLInputElement, CheckBoxProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n indeterminate = false,\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n disabled,\n id,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-${generatedId}`;\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalChecked(event.target.checked);\n }\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Determine checkbox visual variant\n const checkVariant = checked || indeterminate ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][checkVariant];\n\n // Special border width handling for focused/hovered states and large size\n const borderWidthClass =\n state === 'focused' || (state === 'hovered' && size === 'large')\n ? 'border-[3px]'\n : sizeClasses.borderWidth;\n\n // Get final checkbox classes\n const checkboxClasses = cn(\n BASE_CHECKBOX_CLASSES,\n sizeClasses.checkbox,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Render appropriate icon based on state\n const renderIcon = () => {\n if (indeterminate) {\n return (\n <Minus\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n if (checked) {\n return (\n <Check\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n return null;\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n\n {/* Custom styled checkbox */}\n <label htmlFor={inputId} className={checkboxClasses}>\n {/* Show appropriate icon based on state */}\n {renderIcon()}\n </label>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n 'cursor-pointer select-none leading-[150%] flex items-center font-roboto',\n labelClassName\n )}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nCheckBox.displayName = 'CheckBox';\n\nexport default CheckBox;\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n","import {\n TextareaHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n FocusEvent,\n} from 'react';\nimport { WarningCircle } from 'phosphor-react';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * TextArea size variants\n */\ntype TextAreaSize = 'small' | 'medium' | 'large' | 'extraLarge';\n\n/**\n * TextArea visual state\n */\ntype TextAreaState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations with exact pixel specifications\n */\nconst SIZE_CLASSES = {\n small: {\n textarea: 'h-24 text-sm', // 96px height, 14px font\n textSize: 'sm' as const,\n },\n medium: {\n textarea: 'h-24 text-base', // 96px height, 16px font\n textSize: 'md' as const,\n },\n large: {\n textarea: 'h-24 text-lg', // 96px height, 18px font\n textSize: 'lg' as const,\n },\n extraLarge: {\n textarea: 'h-24 text-xl', // 96px height, 20px font\n textSize: 'xl' as const,\n },\n} as const;\n\n/**\n * Base textarea styling classes using design system colors\n */\nconst BASE_TEXTAREA_CLASSES =\n 'w-full box-border p-3 bg-background border border-solid rounded-[4px] resize-none focus:outline-none font-roboto font-normal leading-[150%] placeholder:text-text-600 transition-all duration-200';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n base: 'border-border-300 bg-background text-text-600',\n hover: 'hover:border-border-400',\n focus: 'focus:border-border-500',\n },\n hovered: {\n base: 'border-border-400 bg-background text-text-600',\n hover: '',\n focus: 'focus:border-border-500',\n },\n focused: {\n base: 'border-2 border-primary-950 bg-background text-text-900',\n hover: '',\n focus: '',\n },\n invalid: {\n base: 'border-2 border-red-700 bg-white text-gray-800',\n hover: 'hover:border-red-700',\n focus: 'focus:border-red-700',\n },\n disabled: {\n base: 'border-border-300 bg-background text-text-600 cursor-not-allowed opacity-40',\n hover: '',\n focus: '',\n },\n} as const;\n\n/**\n * TextArea component props interface\n */\nexport type TextAreaProps = {\n /** Label text to display above the textarea */\n label?: ReactNode;\n /** Size variant of the textarea */\n size?: TextAreaSize;\n /** Visual state of the textarea */\n state?: TextAreaState;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperMessage?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Show character count when maxLength is provided */\n showCharacterCount?: boolean;\n} & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'size'>;\n\n/**\n * TextArea component for Analytica Ensino platforms\n *\n * A textarea component with essential states, sizes and themes.\n * Uses exact design specifications with 288px width, 96px height, and specific\n * color values. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic textarea\n * <TextArea label=\"Description\" placeholder=\"Enter description...\" />\n *\n * // Small size\n * <TextArea size=\"small\" label=\"Comment\" />\n *\n * // Invalid state\n * <TextArea state=\"invalid\" label=\"Required field\" errorMessage=\"This field is required\" />\n *\n * // Disabled state\n * <TextArea disabled label=\"Read-only field\" />\n * ```\n */\nconst TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n errorMessage,\n helperMessage,\n className = '',\n labelClassName = '',\n disabled,\n id,\n onChange,\n placeholder,\n required,\n showCharacterCount = false,\n maxLength,\n value,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `textarea-${generatedId}`;\n\n // Internal state for focus tracking\n const [isFocused, setIsFocused] = useState(false);\n\n // Calculate current character count\n const currentLength = typeof value === 'string' ? value.length : 0;\n const isNearLimit = maxLength && currentLength >= maxLength * 0.8;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n onChange?.(event);\n };\n\n // Handle focus events\n const handleFocus = (event: FocusEvent<HTMLTextAreaElement>) => {\n setIsFocused(true);\n props.onFocus?.(event);\n };\n\n // Handle blur events\n const handleBlur = (event: FocusEvent<HTMLTextAreaElement>) => {\n setIsFocused(false);\n props.onBlur?.(event);\n };\n\n // Determine current state based on props and focus\n let currentState = disabled ? 'disabled' : state;\n\n // Override state based on focus\n if (\n isFocused &&\n currentState !== 'invalid' &&\n currentState !== 'disabled'\n ) {\n currentState = 'focused';\n }\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Get styling classes\n const stateClasses = STATE_CLASSES[currentState];\n\n // Get final textarea classes\n const textareaClasses = cn(\n BASE_TEXTAREA_CLASSES,\n sizeClasses.textarea,\n stateClasses.base,\n stateClasses.hover,\n stateClasses.focus,\n className\n );\n\n return (\n <div className={`flex flex-col`}>\n {/* Label */}\n {label && (\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"medium\"\n color=\"text-text-950\"\n className={cn('mb-1.5', labelClassName)}\n >\n {label}{' '}\n {required && <span className=\"text-indicator-error\">*</span>}\n </Text>\n )}\n\n {/* Textarea */}\n <textarea\n ref={ref}\n id={inputId}\n disabled={disabled}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className={textareaClasses}\n placeholder={placeholder}\n required={required}\n maxLength={maxLength}\n value={value}\n {...props}\n />\n\n {/* Error message */}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error mt-1.5\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n\n {/* Helper text or Character count */}\n {!errorMessage && showCharacterCount && maxLength && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className={`mt-1.5 ${isNearLimit ? 'text-indicator-warning' : 'text-text-500'}`}\n >\n {currentLength}/{maxLength} caracteres\n </Text>\n )}\n {!errorMessage &&\n helperMessage &&\n !(showCharacterCount && maxLength) && (\n <Text size=\"sm\" weight=\"normal\" className=\"mt-1.5 text-text-500\">\n {helperMessage}\n </Text>\n )}\n </div>\n );\n }\n);\n\nTextArea.displayName = 'TextArea';\n\nexport default TextArea;\n","import { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Divider component props interface\n */\ntype DividerProps = {\n /** Orientation of the divider */\n orientation?: 'horizontal' | 'vertical';\n /** Additional CSS classes to apply */\n className?: string;\n} & HTMLAttributes<HTMLHRElement>;\n\n/**\n * Divider component for Analytica Ensino platforms\n *\n * A simple divider component that creates a visual separation between content sections.\n * Can be used both horizontally and vertically.\n *\n * @param orientation - The orientation of the divider (horizontal or vertical)\n * @param className - Additional CSS classes\n * @param props - All other standard hr HTML attributes\n * @returns A styled divider element\n *\n * @example\n * ```tsx\n * <Divider orientation=\"horizontal\" />\n * <Divider orientation=\"vertical\" className=\"h-8\" />\n * ```\n */\nconst Divider = ({\n orientation = 'horizontal',\n className = '',\n ...props\n}: DividerProps) => {\n const baseClasses = 'bg-border-200 border-0';\n\n const orientationClasses = {\n horizontal: 'w-full h-px',\n vertical: 'h-full w-px',\n };\n\n return (\n <hr\n className={cn(baseClasses, orientationClasses[orientation], className)}\n aria-orientation={orientation}\n {...props}\n />\n );\n};\n\nexport default Divider;\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * Radio size variants\n */\ntype RadioSize = 'small' | 'medium' | 'large' | 'extraLarge';\n\n/**\n * Radio visual state\n */\ntype RadioState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n radio: 'w-5 h-5',\n textSize: 'sm' as const,\n spacing: 'gap-1.5',\n borderWidth: 'border-2',\n dotSize: 'w-2.5 h-2.5',\n labelHeight: 'h-5',\n },\n medium: {\n radio: 'w-6 h-6',\n textSize: 'md' as const,\n spacing: 'gap-2',\n borderWidth: 'border-2',\n dotSize: 'w-3 h-3',\n labelHeight: 'h-6',\n },\n large: {\n radio: 'w-7 h-7',\n textSize: 'lg' as const,\n spacing: 'gap-2',\n borderWidth: 'border-2',\n dotSize: 'w-3.5 h-3.5',\n labelHeight: 'h-7',\n },\n extraLarge: {\n radio: 'w-8 h-8',\n textSize: 'xl' as const,\n spacing: 'gap-3',\n borderWidth: 'border-2',\n dotSize: 'w-4 h-4',\n labelHeight: 'h-8',\n },\n} as const;\n\n/**\n * Focused state maintains the same sizes as default state\n * Only adds wrapper styling, does not change radio/dot sizes\n */\n\n/**\n * Base radio styling classes using design system colors\n */\nconst BASE_RADIO_CLASSES =\n 'rounded-full border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked: 'border-primary-950 bg-background hover:border-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-info-700 bg-background',\n },\n focused: {\n unchecked: 'border-border-400 bg-background',\n checked: 'border-primary-950 bg-background',\n },\n invalid: {\n unchecked: 'border-border-400 bg-background',\n checked: 'border-primary-950 bg-background',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed',\n checked: 'border-primary-950 bg-background cursor-not-allowed',\n },\n} as const;\n\n/**\n * Dot styling classes for the inner dot when checked\n */\nconst DOT_CLASSES = {\n default: 'bg-primary-950',\n hovered: 'bg-info-700',\n focused: 'bg-primary-950',\n invalid: 'bg-primary-950',\n disabled: 'bg-primary-950',\n} as const;\n\n/**\n * Radio component props interface\n */\nexport type RadioProps = {\n /** Label text to display next to the radio */\n label?: ReactNode;\n /** Size variant of the radio */\n size?: RadioSize;\n /** Visual state of the radio */\n state?: RadioState;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Radio group name */\n name?: string;\n /** Radio value */\n value?: string;\n /** Default checked state for uncontrolled radios */\n defaultChecked?: boolean;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'defaultChecked'\n>;\n\n/**\n * Radio component for Analytica Ensino platforms\n *\n * A radio button component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic radio\n * <Radio name=\"option\" value=\"1\" label=\"Option 1\" />\n *\n * // Small size\n * <Radio size=\"small\" name=\"option\" value=\"2\" label=\"Small option\" />\n *\n * // Invalid state\n * <Radio state=\"invalid\" name=\"option\" value=\"3\" label=\"Required field\" />\n *\n * // Disabled state\n * <Radio disabled name=\"option\" value=\"4\" label=\"Disabled option\" />\n *\n * // Default checked (uncontrolled)\n * <Radio defaultChecked name=\"option\" value=\"5\" label=\"Initially checked\" />\n * ```\n */\nconst Radio = forwardRef<HTMLInputElement, RadioProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n defaultChecked = false,\n disabled,\n id,\n name,\n value,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `radio-${generatedId}`;\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newChecked = event.target.checked;\n\n if (!isControlled) {\n setInternalChecked(newChecked);\n }\n\n // Prevent automatic scroll when input changes\n if (event.target) {\n event.target.blur();\n }\n\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Focused state maintains original sizes, only adds wrapper\n const actualRadioSize = sizeClasses.radio;\n const actualDotSize = sizeClasses.dotSize;\n\n // Determine radio visual variant\n const radioVariant = checked ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][radioVariant];\n\n // Border width logic - consistent across all states and sizes\n const getBorderWidth = () => {\n if (currentState === 'focused') {\n return 'border-2';\n }\n return sizeClasses.borderWidth;\n };\n\n const borderWidthClass = getBorderWidth();\n\n // Get final radio classes\n const radioClasses = cn(\n BASE_RADIO_CLASSES,\n actualRadioSize,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Get dot classes\n const dotClasses = cn(\n actualDotSize,\n 'rounded-full',\n DOT_CLASSES[currentState],\n 'transition-all duration-200'\n );\n\n // Determine if wrapper is needed only for focused or invalid states\n const isWrapperNeeded =\n currentState === 'focused' || currentState === 'invalid';\n const wrapperBorderColor =\n currentState === 'focused'\n ? 'border-indicator-info'\n : 'border-indicator-error';\n\n // Determine text color based on state and checked status\n const getTextColor = () => {\n if (currentState === 'disabled') {\n return checked ? 'text-text-900' : 'text-text-600';\n }\n\n if (currentState === 'focused') {\n return 'text-text-900';\n }\n\n return checked ? 'text-text-900' : 'text-text-600';\n };\n\n // Determine cursor class based on disabled state\n const getCursorClass = () => {\n return currentState === 'disabled'\n ? 'cursor-not-allowed'\n : 'cursor-pointer';\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n isWrapperNeeded\n ? cn('p-1 border-2', wrapperBorderColor, 'rounded-lg gap-1.5')\n : sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={(node) => {\n inputRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"radio\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n name={name}\n value={value}\n onChange={handleChange}\n className=\"sr-only\"\n style={{\n position: 'absolute',\n left: '-9999px',\n visibility: 'hidden',\n }}\n {...props}\n />\n\n {/* Custom styled radio */}\n <button\n type=\"button\"\n className={radioClasses}\n disabled={disabled}\n aria-pressed={checked}\n onClick={(e) => {\n // Prevent scroll when radio is clicked\n e.preventDefault();\n if (!disabled) {\n // Simulate click on hidden input\n if (inputRef.current) {\n inputRef.current.click();\n // Remove focus to prevent scroll behavior\n inputRef.current.blur();\n }\n }\n }}\n onKeyDown={(e) => {\n // Handle keyboard activation (Enter or Space)\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault();\n if (inputRef.current) {\n inputRef.current.click();\n inputRef.current.blur();\n }\n }\n }}\n >\n {/* Show dot when checked */}\n {checked && <div className={dotClasses} />}\n </button>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight,\n 'flex-1 min-w-0'\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n getCursorClass(),\n 'select-none leading-normal flex items-center font-roboto truncate',\n labelClassName\n )}\n color={getTextColor()}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5 truncate\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5 truncate\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nRadio.displayName = 'Radio';\n\n/**\n * RadioGroup store interface\n */\ninterface RadioGroupStore {\n value: string;\n setValue: (value: string) => void;\n onValueChange?: (value: string) => void;\n disabled: boolean;\n name: string;\n}\n\ntype RadioGroupStoreApi = StoreApi<RadioGroupStore>;\n\n/**\n * Create a new RadioGroup store\n */\nconst createRadioGroupStore = (\n name: string,\n defaultValue: string,\n disabled: boolean,\n onValueChange?: (value: string) => void\n): RadioGroupStoreApi =>\n create<RadioGroupStore>((set, get) => ({\n value: defaultValue,\n setValue: (value) => {\n if (!get().disabled) {\n set({ value });\n get().onValueChange?.(value);\n }\n },\n onValueChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access RadioGroup store\n */\nexport const useRadioGroupStore = (externalStore?: RadioGroupStoreApi) => {\n if (!externalStore) {\n throw new Error('RadioGroupItem must be used within a RadioGroup');\n }\n return externalStore;\n};\n\n/**\n * Inject store into RadioGroupItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: RadioGroupStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\n const typedChild = child as ReactElement<any>;\n const shouldInject = typedChild.type === RadioGroupItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * RadioGroup component props interface\n */\nexport type RadioGroupProps = {\n /** Current selected value */\n value?: string;\n /** Default selected value for uncontrolled usage */\n defaultValue?: string;\n /** Callback when selection changes */\n onValueChange?: (value: string) => void;\n /** Group name for all radios */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'>;\n\n/**\n * RadioGroup component for flexible radio group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with RadioGroupItem.\n *\n * @example\n * ```tsx\n * <RadioGroup defaultValue=\"option1\" onValueChange={setValue}>\n * <div className=\"flex items-center gap-3\">\n * <RadioGroupItem value=\"option1\" id=\"r1\" />\n * <label htmlFor=\"r1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <RadioGroupItem value=\"option2\" id=\"r2\" />\n * <label htmlFor=\"r2\">Option 2</label>\n * </div>\n * </RadioGroup>\n * ```\n */\nconst RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(\n (\n {\n value: propValue,\n defaultValue = '',\n onValueChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `radio-group-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<RadioGroupStoreApi>(null);\n storeRef.current ??= createRadioGroupStore(\n name,\n defaultValue,\n disabled,\n onValueChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValue } = useStore(store, (s) => s);\n\n // Call onValueChange with initial value\n useEffect(() => {\n const currentValue = store.getState().value;\n if (currentValue && onValueChange) {\n onValueChange(currentValue);\n }\n }, []); // Empty dependency array for mount only\n\n // Handle controlled value changes\n useEffect(() => {\n if (propValue !== undefined) {\n setValue(propValue);\n }\n }, [propValue, setValue]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={className}\n role=\"radiogroup\"\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nRadioGroup.displayName = 'RadioGroup';\n\n/**\n * RadioGroupItem component props interface\n */\nexport type RadioGroupItemProps = {\n /** Value for this radio item */\n value: string;\n /** Store reference (automatically injected by RadioGroup) */\n store?: RadioGroupStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: RadioSize;\n /** Visual state */\n state?: RadioState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * RadioGroupItem component for use within RadioGroup\n *\n * A radio button without label that works within RadioGroup context.\n * Provides just the radio input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <RadioGroup defaultValue=\"option1\">\n * <div className=\"flex items-center gap-3\">\n * <RadioGroupItem value=\"option1\" id=\"r1\" />\n * <label htmlFor=\"r1\">Option 1</label>\n * </div>\n * </RadioGroup>\n * ```\n */\nconst RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useRadioGroupStore(externalStore);\n const {\n value: groupValue,\n setValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `radio-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValue === value;\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard Radio component for consistency and simplicity\n return (\n <Radio\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={(e) => {\n if (e.target.checked && !isDisabled) {\n setValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nRadioGroupItem.displayName = 'RadioGroupItem';\n\nexport default Radio;\nexport { RadioGroup, RadioGroupItem };\n","import { create } from 'zustand';\n\ntype ToastPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right'\n | 'default';\n\ntype ToastData = {\n id: string;\n title: string;\n description?: string;\n variant?: 'solid' | 'outlined';\n action?: 'warning' | 'success' | 'info';\n position?: ToastPosition;\n};\n\ntype ToastStore = {\n toasts: ToastData[];\n addToast: (toast: Omit<ToastData, 'id'>) => void;\n removeToast: (id: string) => void;\n};\n\nconst useToastStore = create<ToastStore>((set) => ({\n toasts: [],\n addToast: (toast) => {\n const id = crypto.randomUUID();\n\n set((state) => ({\n toasts: [...state.toasts, { id, ...toast }],\n }));\n },\n removeToast: (id) => {\n set((state) => ({\n toasts: state.toasts.filter((t) => t.id !== id),\n }));\n },\n}));\n\nexport default useToastStore;\n","import { ReactNode } from 'react';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * Progress bar size variants\n */\ntype ProgressBarSize = 'small' | 'medium';\n\n/**\n * Progress bar color variants\n */\ntype ProgressBarVariant = 'blue' | 'green';\n\n/**\n * Progress bar layout variants\n */\ntype ProgressBarLayout = 'default' | 'stacked' | 'compact';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n container: 'h-1', // 4px height (h-1 = 4px in Tailwind)\n bar: 'h-1', // 4px height for the fill bar\n spacing: 'gap-2', // 8px gap between label and progress bar\n layout: 'flex-col', // vertical layout for small\n borderRadius: 'rounded-full', // 9999px border radius\n },\n medium: {\n container: 'h-2', // 8px height (h-2 = 8px in Tailwind)\n bar: 'h-2', // 8px height for the fill bar\n spacing: 'gap-2', // 8px gap between progress bar and label\n layout: 'flex-row items-center', // horizontal layout for medium\n borderRadius: 'rounded-lg', // 8px border radius\n },\n} as const;\n\n/**\n * Color configurations using design system colors\n */\nconst VARIANT_CLASSES = {\n blue: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-primary-700', // Blue for activity progress (#2271C4)\n },\n green: {\n background: 'bg-background-300', // Background track color (#D5D4D4)\n fill: 'bg-success-200', // Green for performance (#84D3A2)\n },\n} as const;\n\n/**\n * Type for size classes\n */\ntype SizeClassType = (typeof SIZE_CLASSES)[keyof typeof SIZE_CLASSES];\n\n/**\n * Type for variant classes\n */\ntype VariantClassType = (typeof VARIANT_CLASSES)[keyof typeof VARIANT_CLASSES];\n\n/**\n * Common props shared across all layout components\n */\ninterface BaseLayoutProps {\n className: string;\n label: ReactNode;\n showPercentage: boolean;\n showHitCount: boolean;\n labelClassName: string;\n percentageClassName: string;\n clampedValue: number;\n max: number;\n percentage: number;\n variantClasses: VariantClassType;\n}\n\n/**\n * Dimensions configuration for layouts\n */\ninterface LayoutDimensions {\n width: string;\n height: string;\n}\n\n/**\n * Props for StackedLayout component\n */\ninterface StackedLayoutProps extends BaseLayoutProps {\n dimensions: LayoutDimensions;\n}\n\n/**\n * Props for CompactLayout component\n */\ninterface CompactLayoutProps extends BaseLayoutProps {\n dimensions: LayoutDimensions;\n}\n\n/**\n * Props for DefaultLayout component\n */\ninterface DefaultLayoutProps {\n className: string;\n size: ProgressBarSize;\n sizeClasses: SizeClassType;\n variantClasses: VariantClassType;\n label: ReactNode;\n showPercentage: boolean;\n labelClassName: string;\n percentageClassName: string;\n clampedValue: number;\n max: number;\n percentage: number;\n}\n\n/**\n * ProgressBar component props interface\n */\nexport type ProgressBarProps = {\n /** Progress value between 0 and 100 */\n value: number;\n /** Maximum value (defaults to 100) */\n max?: number;\n /** Size variant of the progress bar */\n size?: ProgressBarSize;\n /** Color variant of the progress bar */\n variant?: ProgressBarVariant;\n /** Layout variant of the progress bar */\n layout?: ProgressBarLayout;\n /** Optional label to display */\n label?: ReactNode;\n /** Show percentage text */\n showPercentage?: boolean;\n /**\n * Show hit count (e.g., \"28 de 30\") instead of percentage\n *\n * PRIORITY: When both showHitCount and showPercentage are true,\n * showHitCount takes precedence (stacked and compact layouts only).\n * Default layout does not support showHitCount.\n */\n showHitCount?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n /** Percentage text CSS classes */\n percentageClassName?: string;\n /** Custom width for stacked layout (defaults to w-[380px]) */\n stackedWidth?: string;\n /** Custom height for stacked layout (defaults to h-[35px]) */\n stackedHeight?: string;\n /** Custom width for compact layout (defaults to w-[131px]) */\n compactWidth?: string;\n /** Custom height for compact layout (defaults to h-[24px]) */\n compactHeight?: string;\n};\n\n/**\n * Helper function to calculate safe progress values\n */\nconst calculateProgressValues = (value: number, max: number) => {\n const safeValue = isNaN(value) ? 0 : value;\n const clampedValue = Math.max(0, Math.min(safeValue, max));\n const percentage = max === 0 ? 0 : (clampedValue / max) * 100;\n\n return { clampedValue, percentage };\n};\n\n/**\n * Helper function to determine if header content should be shown\n */\nconst shouldShowHeader = (\n label: ReactNode,\n showPercentage: boolean,\n showHitCount: boolean\n): boolean => {\n return !!(label || showPercentage || showHitCount);\n};\n\n/**\n * Centralized function to determine display priority and content\n *\n * PRIORITY ORDER (consistent across all layouts):\n * 1. showHitCount (highest priority) - displays \"X de Y\" format\n * 2. showPercentage - displays \"X%\" format\n * 3. label (lowest priority) - displays custom label\n *\n * @param showHitCount - Whether to show hit count format\n * @param showPercentage - Whether to show percentage format\n * @param label - Custom label to display\n * @param clampedValue - Current progress value\n * @param max - Maximum progress value\n * @param percentage - Calculated percentage value\n * @returns Object with content type and formatted content\n */\nconst getDisplayPriority = (\n showHitCount: boolean,\n showPercentage: boolean,\n label: ReactNode,\n clampedValue: number,\n max: number,\n percentage: number\n) => {\n if (showHitCount) {\n return {\n type: 'hitCount' as const,\n content: `${Math.round(clampedValue)} de ${max}`,\n hasMetrics: true,\n };\n }\n\n if (showPercentage) {\n return {\n type: 'percentage' as const,\n content: `${Math.round(percentage)}%`,\n hasMetrics: true,\n };\n }\n\n return {\n type: 'label' as const,\n content: label,\n hasMetrics: false,\n };\n};\n\n/**\n * Parameters for compact layout configuration\n */\ninterface CompactLayoutConfigParams {\n showPercentage: boolean;\n showHitCount: boolean;\n percentage: number;\n clampedValue: number;\n max: number;\n label: ReactNode;\n percentageClassName: string;\n labelClassName: string;\n}\n\n/**\n * Helper function to get compact layout configuration\n *\n * PRIORITY ORDER (consistent across all layouts):\n * 1. showHitCount (highest priority) - displays \"X de Y\" format\n * 2. showPercentage - displays \"X%\" format\n * 3. label (lowest priority) - displays custom label\n *\n * When both showHitCount and showPercentage are true, showHitCount takes precedence.\n */\nconst getCompactLayoutConfig = ({\n showPercentage,\n showHitCount,\n percentage,\n clampedValue,\n max,\n label,\n percentageClassName,\n labelClassName,\n}: CompactLayoutConfigParams) => {\n // Use centralized priority logic for consistency\n const displayPriority = getDisplayPriority(\n showHitCount,\n showPercentage,\n label,\n clampedValue,\n max,\n percentage\n );\n\n return {\n color: displayPriority.hasMetrics ? 'text-primary-600' : 'text-primary-700',\n className: displayPriority.hasMetrics\n ? percentageClassName\n : labelClassName,\n content: displayPriority.content,\n };\n};\n\n/**\n * Helper function to get default layout display configuration\n *\n * PRIORITY ORDER for default layout (showHitCount is not supported):\n * 1. showPercentage (when enabled, takes precedence over label)\n * 2. label (shown only when showPercentage is false)\n *\n * Note: Default layout does not support showHitCount feature.\n */\nconst getDefaultLayoutDisplayConfig = (\n size: ProgressBarSize,\n label: ReactNode,\n showPercentage: boolean\n) => ({\n showHeader: size === 'small' && !!(label || showPercentage),\n showPercentage: size === 'medium' && showPercentage,\n showLabel: size === 'medium' && !!label && !showPercentage, // Only show label when percentage is not shown\n});\n\n/**\n * Helper function to render hit count or percentage display for stacked layout\n *\n * PRIORITY ORDER (consistent across all layouts):\n * 1. showHitCount (highest priority) - displays \"X de Y\" format\n * 2. showPercentage - displays \"X%\" format\n *\n * When both showHitCount and showPercentage are true, showHitCount takes precedence.\n */\nconst renderStackedHitCountDisplay = (\n showHitCount: boolean,\n showPercentage: boolean,\n clampedValue: number,\n max: number,\n percentage: number,\n percentageClassName: string\n): ReactNode => {\n if (!showHitCount && !showPercentage) return null;\n\n // Use centralized priority logic for consistency\n const displayPriority = getDisplayPriority(\n showHitCount,\n showPercentage,\n null, // label is not relevant for stacked layout metrics display\n clampedValue,\n max,\n percentage\n );\n\n return (\n <div\n className={cn(\n 'text-xs font-medium leading-[14px] text-right',\n percentageClassName\n )}\n >\n {displayPriority.type === 'hitCount' ? (\n <>\n <span className=\"text-success-200\">{Math.round(clampedValue)}</span>\n <span className=\"text-text-600\"> de {max}</span>\n </>\n ) : (\n <Text size=\"xs\" weight=\"medium\" className=\"text-success-200\">\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n );\n};\n\n/**\n * Base progress bar component with common rendering logic\n */\nconst ProgressBarBase = ({\n clampedValue,\n max,\n percentage,\n label,\n variantClasses,\n containerClassName,\n fillClassName,\n}: {\n clampedValue: number;\n max: number;\n percentage: number;\n label: ReactNode;\n variantClasses: VariantClassType;\n containerClassName: string;\n fillClassName: string;\n}) => (\n <div\n className={cn(\n containerClassName,\n variantClasses.background,\n 'overflow-hidden relative'\n )}\n >\n <progress\n value={clampedValue}\n max={max}\n aria-label={\n typeof label === 'string'\n ? `${label}: ${Math.round(percentage)}% complete`\n : `Progress: ${Math.round(percentage)}% of ${max}`\n }\n className=\"absolute inset-0 w-full h-full opacity-0\"\n />\n <div\n className={cn(\n fillClassName,\n variantClasses.fill,\n 'transition-all duration-300 ease-out'\n )}\n style={{ width: `${percentage}%` }}\n />\n </div>\n);\n\n/**\n * Stacked layout component\n */\nconst StackedLayout = ({\n className,\n label,\n showPercentage,\n showHitCount,\n labelClassName,\n percentageClassName,\n clampedValue,\n max,\n percentage,\n variantClasses,\n dimensions,\n}: StackedLayoutProps) => (\n <div\n className={cn(\n 'flex flex-col items-start gap-2',\n dimensions.width,\n dimensions.height,\n className\n )}\n >\n {shouldShowHeader(label, showPercentage, showHitCount) && (\n <div className=\"flex flex-row justify-between items-center w-full h-[19px]\">\n {label && (\n <Text\n as=\"div\"\n size=\"md\"\n weight=\"medium\"\n className={cn('text-text-600 leading-[19px]', labelClassName)}\n >\n {label}\n </Text>\n )}\n\n {renderStackedHitCountDisplay(\n showHitCount,\n showPercentage,\n clampedValue,\n max,\n percentage,\n percentageClassName\n )}\n </div>\n )}\n\n <ProgressBarBase\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n label={label}\n variantClasses={variantClasses}\n containerClassName=\"w-full h-2 rounded-lg\"\n fillClassName=\"h-2 rounded-lg shadow-hard-shadow-3\"\n />\n </div>\n);\n\n/**\n * Compact layout component\n */\nconst CompactLayout = ({\n className,\n label,\n showPercentage,\n showHitCount,\n labelClassName,\n percentageClassName,\n clampedValue,\n max,\n percentage,\n variantClasses,\n dimensions,\n}: CompactLayoutProps) => {\n const {\n color,\n className: compactClassName,\n content,\n } = getCompactLayoutConfig({\n showPercentage,\n showHitCount,\n percentage,\n clampedValue,\n max,\n label,\n percentageClassName,\n labelClassName,\n });\n\n return (\n <div\n className={cn(\n 'flex flex-col items-start gap-1',\n dimensions.width,\n dimensions.height,\n className\n )}\n >\n {shouldShowHeader(label, showPercentage, showHitCount) && (\n <Text\n as=\"div\"\n size=\"sm\"\n weight=\"medium\"\n color={color}\n className={cn('leading-4 w-full', compactClassName)}\n >\n {content}\n </Text>\n )}\n\n <ProgressBarBase\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n label={label}\n variantClasses={variantClasses}\n containerClassName=\"w-full h-1 rounded-full\"\n fillClassName=\"h-1 rounded-full\"\n />\n </div>\n );\n};\n\n/**\n * Default layout component\n */\nconst DefaultLayout = ({\n className,\n size,\n sizeClasses,\n variantClasses,\n label,\n showPercentage,\n labelClassName,\n percentageClassName,\n clampedValue,\n max,\n percentage,\n}: DefaultLayoutProps) => {\n const gapClass = size === 'medium' ? 'gap-2' : sizeClasses.spacing;\n const progressBarClass = size === 'medium' ? 'flex-grow' : 'w-full';\n const displayConfig = getDefaultLayoutDisplayConfig(\n size,\n label,\n showPercentage\n );\n\n return (\n <div className={cn('flex', sizeClasses.layout, gapClass, className)}>\n {displayConfig.showHeader && (\n <div className=\"flex flex-row items-center justify-between w-full\">\n {label && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center',\n labelClassName\n )}\n >\n {label}\n </Text>\n )}\n\n {showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center',\n percentageClassName\n )}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n </div>\n )}\n\n <ProgressBarBase\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n label={label}\n variantClasses={variantClasses}\n containerClassName={cn(\n progressBarClass,\n sizeClasses.container,\n sizeClasses.borderRadius\n )}\n fillClassName={cn(\n sizeClasses.bar,\n sizeClasses.borderRadius,\n 'shadow-hard-shadow-3'\n )}\n />\n\n {displayConfig.showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none',\n percentageClassName\n )}\n >\n {Math.round(percentage)}%\n </Text>\n )}\n\n {displayConfig.showLabel && (\n <Text\n as=\"div\"\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none',\n labelClassName\n )}\n >\n {label}\n </Text>\n )}\n </div>\n );\n};\n\n/**\n * ProgressBar component for Analytica Ensino platforms\n *\n * A progress bar component with size and color variants designed for tracking\n * activity progress (blue) and performance metrics (green).\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * CONTENT DISPLAY PRIORITY (Consistent across all layouts):\n * 1. showHitCount (highest) - \"X de Y\" format (stacked/compact only)\n * 2. showPercentage - \"X%\" format\n * 3. label (lowest) - Custom label text\n *\n * When multiple display options are enabled, higher priority options take precedence.\n *\n * @example\n * ```tsx\n * // Basic progress bar\n * <ProgressBar value={65} />\n *\n * // Activity progress (blue)\n * <ProgressBar variant=\"blue\" value={45} label=\"Progress\" showPercentage />\n *\n * // Performance metrics (green)\n * <ProgressBar variant=\"green\" size=\"medium\" value={85} label=\"Performance\" />\n *\n * // Small size with custom max value\n * <ProgressBar size=\"small\" value={3} max={5} showPercentage />\n *\n * // Stacked layout with fixed width and hit count\n * <ProgressBar layout=\"stacked\" variant=\"green\" value={28} max={30} label=\"Fáceis\" showHitCount />\n *\n * // Compact layout for small cards\n * <ProgressBar layout=\"compact\" variant=\"blue\" value={70} label=\"Questão 08\" />\n * ```\n */\nconst ProgressBar = ({\n value,\n max = 100,\n size = 'medium',\n variant = 'blue',\n layout = 'default',\n label,\n showPercentage = false,\n showHitCount = false,\n className = '',\n labelClassName = '',\n percentageClassName = '',\n stackedWidth,\n stackedHeight,\n compactWidth,\n compactHeight,\n}: ProgressBarProps) => {\n const { clampedValue, percentage } = calculateProgressValues(value, max);\n const sizeClasses = SIZE_CLASSES[size];\n const variantClasses = VARIANT_CLASSES[variant];\n\n if (layout === 'stacked') {\n return (\n <StackedLayout\n className={className}\n label={label}\n showPercentage={showPercentage}\n showHitCount={showHitCount}\n labelClassName={labelClassName}\n percentageClassName={percentageClassName}\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n variantClasses={variantClasses}\n dimensions={{\n width: stackedWidth ?? 'w-[380px]',\n height: stackedHeight ?? 'h-[35px]',\n }}\n />\n );\n }\n\n if (layout === 'compact') {\n return (\n <CompactLayout\n className={className}\n label={label}\n showPercentage={showPercentage}\n showHitCount={showHitCount}\n labelClassName={labelClassName}\n percentageClassName={percentageClassName}\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n variantClasses={variantClasses}\n dimensions={{\n width: compactWidth ?? 'w-[131px]',\n height: compactHeight ?? 'h-[24px]',\n }}\n />\n );\n }\n\n return (\n <DefaultLayout\n className={className}\n size={size}\n sizeClasses={sizeClasses}\n variantClasses={variantClasses}\n label={label}\n showPercentage={showPercentage}\n labelClassName={labelClassName}\n percentageClassName={percentageClassName}\n clampedValue={clampedValue}\n max={max}\n percentage={percentage}\n />\n );\n};\n\nexport default ProgressBar;\n","import {\n useState,\n useRef,\n useEffect,\n useCallback,\n type ReactNode,\n} from 'react';\nimport {\n PencilSimple,\n Paperclip,\n X,\n Star,\n Medal,\n WarningCircle,\n} from 'phosphor-react';\nimport type { Icon } from 'phosphor-react';\nimport Modal from '../Modal/Modal';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Badge from '../Badge/Badge';\nimport Radio from '../Radio/Radio';\nimport TextArea from '../TextArea/TextArea';\nimport { CardAccordation, AccordionGroup } from '../Accordation';\nimport { generateFileId } from '../FileAttachment/FileAttachment';\nimport type { AttachedFile } from '../FileAttachment/FileAttachment';\nimport { cn } from '../../utils/utils';\nimport { QUESTION_TYPE } from '../Quiz/useQuizStore';\nimport {\n type StudentActivityCorrectionData,\n type SaveQuestionCorrectionPayload,\n getQuestionStatusBadgeConfig,\n getQuestionStatusFromData,\n} from '../../utils/studentActivityCorrection';\nimport {\n renderQuestionAlternative,\n renderQuestionMultipleChoice,\n renderQuestionTrueOrFalse,\n renderQuestionDissertative,\n renderQuestionFill,\n renderQuestionImage,\n renderQuestionConnectDots,\n} from '../../utils/questionRenderer/index';\n\n/**\n * Props for the CorrectActivityModal component\n */\nexport interface CorrectActivityModalProps {\n /** Whether the modal is open */\n isOpen: boolean;\n /** Function to close the modal */\n onClose: () => void;\n /** Student activity correction data */\n data: StudentActivityCorrectionData | null;\n /** Whether the modal is in view-only mode */\n isViewOnly?: boolean;\n /** Callback when observation is submitted with optional files */\n onObservationSubmit?: (\n studentId: string,\n observation: string,\n files: File[]\n ) => void;\n /** Callback when question correction is saved (for essay questions) */\n onQuestionCorrectionSubmit?: (\n studentId: string,\n payload: SaveQuestionCorrectionPayload\n ) => Promise<void>;\n}\n\n/**\n * Props for the StatCard component\n */\ninterface StatCardProps {\n label: string;\n value: string | number;\n variant: 'score' | 'correct' | 'incorrect';\n}\n\n/**\n * Configuration for each stat card variant\n */\nconst variantConfig: Record<\n StatCardProps['variant'],\n {\n bg: string;\n text: string;\n iconBg: string;\n iconColor: string;\n IconComponent: Icon;\n }\n> = {\n score: {\n bg: 'bg-warning-background',\n text: 'text-warning-600',\n iconBg: 'bg-warning-300',\n iconColor: 'text-white',\n IconComponent: Star,\n },\n correct: {\n bg: 'bg-success-200',\n text: 'text-success-700',\n iconBg: 'bg-indicator-positive',\n iconColor: 'text-text-950',\n IconComponent: Medal,\n },\n incorrect: {\n bg: 'bg-error-100',\n text: 'text-error-700',\n iconBg: 'bg-indicator-negative',\n iconColor: 'text-white',\n IconComponent: WarningCircle,\n },\n};\n\n/**\n * Stat card component for displaying statistics with icon\n * @param props - Component props\n * @returns JSX element\n */\nconst StatCard = ({ label, value, variant }: StatCardProps) => {\n const config = variantConfig[variant];\n const IconComponent = config.IconComponent;\n\n return (\n <div\n className={cn(\n 'border border-border-50 rounded-xl py-4 px-3 flex flex-col items-center justify-center gap-1',\n config.bg\n )}\n >\n <div\n className={cn(\n 'w-[30px] h-[30px] rounded-2xl flex items-center justify-center',\n config.iconBg\n )}\n >\n <IconComponent\n size={16}\n className={config.iconColor}\n weight=\"regular\"\n />\n </div>\n <Text\n className={cn('text-2xs font-bold uppercase text-center', config.text)}\n >\n {label}\n </Text>\n <Text className={cn('text-xl font-bold', config.text)}>{value}</Text>\n </div>\n );\n};\n\n/**\n * Modal component for correcting or viewing student activity details\n *\n * Displays student information, statistics cards, observation section,\n * and a list of questions with their status.\n *\n * @param props - Component props\n * @returns JSX element\n *\n * @example\n * ```tsx\n * <CorrectActivityModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * data={studentData}\n * isViewOnly={false}\n * onObservationSubmit={(obs, files) => console.log(obs, files)}\n * />\n * ```\n */\nconst CorrectActivityModal = ({\n isOpen,\n onClose,\n data,\n isViewOnly = false,\n onObservationSubmit,\n onQuestionCorrectionSubmit,\n}: CorrectActivityModalProps) => {\n const [observation, setObservation] = useState('');\n const [isObservationExpanded, setIsObservationExpanded] = useState(false);\n const [isObservationSaved, setIsObservationSaved] = useState(false);\n const [savedObservation, setSavedObservation] = useState('');\n const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]);\n const [savedFiles, setSavedFiles] = useState<AttachedFile[]>([]);\n const [existingAttachment, setExistingAttachment] = useState<string | null>(\n null\n );\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // State for essay question corrections\n const [essayCorrections, setEssayCorrections] = useState<\n Record<\n number,\n {\n isCorrect: boolean | null;\n teacherFeedback: string;\n isSaving: boolean;\n }\n >\n >({});\n\n /**\n * Reset state when modal opens or student changes\n * Load existing observation and attachment if available\n */\n useEffect(() => {\n if (isOpen) {\n setObservation('');\n setIsObservationExpanded(false);\n setAttachedFiles([]);\n setSavedFiles([]);\n setExistingAttachment(data?.attachment ?? null);\n\n // Load existing observation/attachment if available\n if (data?.observation || data?.attachment) {\n setIsObservationSaved(true);\n setSavedObservation(data.observation || '');\n } else {\n setIsObservationSaved(false);\n setSavedObservation('');\n }\n\n // Initialize essay corrections from data\n const initialCorrections: Record<\n number,\n {\n isCorrect: boolean | null;\n teacherFeedback: string;\n isSaving: boolean;\n }\n > = {};\n data?.questions?.forEach((questionData) => {\n if (questionData.question.questionType === QUESTION_TYPE.DISSERTATIVA) {\n initialCorrections[questionData.questionNumber] = {\n isCorrect: questionData.correction?.isCorrect ?? null,\n teacherFeedback: questionData.correction?.teacherFeedback || '',\n isSaving: false,\n };\n }\n });\n setEssayCorrections(initialCorrections);\n }\n }, [\n isOpen,\n data?.studentId,\n data?.observation,\n data?.attachment,\n data?.questions,\n ]);\n\n /**\n * Handle opening observation section\n */\n const handleOpenObservation = () => {\n setIsObservationExpanded(true);\n };\n\n /**\n * Handle adding files (single file mode - replaces existing file)\n * @param files - Files to add\n */\n const handleFilesAdd = (files: File[]) => {\n const newFile = files[0];\n if (newFile) {\n setAttachedFiles([{ file: newFile, id: generateFileId() }]);\n }\n };\n\n /**\n * Handle removing a file\n * @param id - File ID to remove\n */\n const handleFileRemove = (id: string) => {\n setAttachedFiles((prev) => prev.filter((f) => f.id !== id));\n };\n\n /**\n * Handle saving observation\n */\n const handleSaveObservation = () => {\n if (observation.trim() || attachedFiles.length > 0 || existingAttachment) {\n // Validate studentId before saving to prevent silent no-op\n if (!data?.studentId) {\n return;\n }\n\n setSavedObservation(observation);\n setSavedFiles([...attachedFiles]);\n setIsObservationSaved(true);\n setIsObservationExpanded(false);\n\n // Pass studentId explicitly from data prop to avoid stale closure issues\n onObservationSubmit?.(\n data.studentId,\n observation,\n attachedFiles.map((f) => f.file)\n );\n }\n };\n\n /**\n * Handle editing observation\n */\n const handleEditObservation = () => {\n setObservation(savedObservation);\n setAttachedFiles([...savedFiles]);\n setIsObservationSaved(false);\n setIsObservationExpanded(true);\n };\n\n /**\n * Handle saving essay question correction\n */\n const handleSaveEssayCorrection = useCallback(\n async (questionNumber: number) => {\n if (!data?.studentId || !onQuestionCorrectionSubmit) return;\n\n const correction = essayCorrections[questionNumber];\n if (correction?.isCorrect == null) {\n return;\n }\n\n setEssayCorrections((prev) => ({\n ...prev,\n [questionNumber]: { ...prev[questionNumber], isSaving: true },\n }));\n\n try {\n // Find the question data to get questionId\n const questionData = data?.questions.find(\n (q) => q.questionNumber === questionNumber\n );\n if (!questionData) {\n console.error('Questão não encontrada:', questionNumber);\n return;\n }\n\n await onQuestionCorrectionSubmit(data.studentId, {\n questionId: questionData.question.id,\n isCorrect: correction.isCorrect,\n teacherFeedback: correction.teacherFeedback,\n });\n } catch (error) {\n console.error('Erro ao salvar correção da questão:', error);\n } finally {\n setEssayCorrections((prev) => ({\n ...prev,\n [questionNumber]: { ...prev[questionNumber], isSaving: false },\n }));\n }\n },\n [\n data?.studentId,\n data?.questions,\n essayCorrections,\n onQuestionCorrectionSubmit,\n ]\n );\n\n /**\n * Update essay correction state\n */\n const updateEssayCorrection = useCallback(\n (\n questionNumber: number,\n field: 'isCorrect' | 'teacherFeedback',\n value: boolean | string\n ) => {\n setEssayCorrections((prev) => ({\n ...prev,\n [questionNumber]: {\n ...prev[questionNumber],\n [field]: value,\n },\n }));\n },\n []\n );\n\n /**\n * Get accordion title based on question type\n */\n const getAccordionTitle = (questionType: QUESTION_TYPE): string => {\n switch (questionType) {\n case QUESTION_TYPE.ALTERNATIVA:\n case QUESTION_TYPE.MULTIPLA_ESCOLHA:\n case QUESTION_TYPE.VERDADEIRO_FALSO:\n return 'Alternativas';\n case QUESTION_TYPE.DISSERTATIVA:\n return 'Resposta';\n case QUESTION_TYPE.PREENCHER:\n return 'Preencher Lacunas';\n case QUESTION_TYPE.IMAGEM:\n return 'Imagem';\n case QUESTION_TYPE.LIGAR_PONTOS:\n return 'Ligar Pontos';\n default:\n return 'Resposta';\n }\n };\n\n /**\n * Render question content using Quiz format renderers with accordion\n */\n const renderQuestionContent = (\n questionData: StudentActivityCorrectionData['questions'][number]\n ) => {\n const { question, result } = questionData;\n const questionType = question.questionType;\n const accordionTitle = getAccordionTitle(questionType);\n\n let content: ReactNode;\n\n switch (questionType) {\n case QUESTION_TYPE.ALTERNATIVA:\n content = renderQuestionAlternative({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.MULTIPLA_ESCOLHA:\n content = renderQuestionMultipleChoice({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.VERDADEIRO_FALSO:\n content = renderQuestionTrueOrFalse({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.DISSERTATIVA:\n content = (\n <>\n {renderQuestionDissertative({\n result,\n })}\n {onQuestionCorrectionSubmit && (\n <div className=\"space-y-4 border-t border-border-100 pt-4 mt-4\">\n {renderEssayCorrectionFields(questionData)}\n </div>\n )}\n </>\n );\n break;\n case QUESTION_TYPE.PREENCHER:\n content = renderQuestionFill({\n question,\n result,\n });\n break;\n case QUESTION_TYPE.IMAGEM:\n content = renderQuestionImage({\n result,\n });\n break;\n case QUESTION_TYPE.LIGAR_PONTOS:\n content = renderQuestionConnectDots({ paddingBottom: '' });\n break;\n default:\n // Fallback: try to render based on options presence\n if (question.options && question.options.length > 0) {\n content = renderQuestionAlternative({\n question,\n result,\n });\n } else {\n content = renderQuestionDissertative({\n result,\n });\n }\n }\n\n return (\n <CardAccordation\n value={`accordion-${questionData.questionNumber}`}\n className=\"border border-border-100 rounded-lg\"\n trigger={\n <div className=\"py-3 pr-2 w-full\">\n <Text className=\"text-sm font-bold text-text-950\">\n {accordionTitle}\n </Text>\n </div>\n }\n >\n {content}\n </CardAccordation>\n );\n };\n\n /**\n * Render essay correction fields (radio group, textarea, save button)\n */\n const renderEssayCorrectionFields = (\n questionData: StudentActivityCorrectionData['questions'][number]\n ) => {\n const correction = essayCorrections[questionData.questionNumber] || {\n isCorrect: null,\n teacherFeedback: '',\n isSaving: false,\n };\n\n let radioValue;\n if (correction.isCorrect === null) {\n radioValue = undefined;\n } else if (correction.isCorrect) {\n radioValue = 'true';\n } else {\n radioValue = 'false';\n }\n\n return (\n <>\n {/* Is correct radio group */}\n <div className=\"space-y-2\">\n <Text className=\"text-sm font-semibold text-text-950\">\n Resposta está correta?\n </Text>\n <div className=\"flex gap-4\">\n <Radio\n name={`isCorrect-${questionData.questionNumber}`}\n value=\"true\"\n id={`correct-yes-${questionData.questionNumber}`}\n label=\"Sim\"\n size=\"medium\"\n checked={radioValue === 'true'}\n onChange={(e) => {\n if (e.target.checked) {\n updateEssayCorrection(\n questionData.questionNumber,\n 'isCorrect',\n true\n );\n }\n }}\n />\n <Radio\n name={`isCorrect-${questionData.questionNumber}`}\n value=\"false\"\n id={`correct-no-${questionData.questionNumber}`}\n label=\"Não\"\n size=\"medium\"\n checked={radioValue === 'false'}\n onChange={(e) => {\n if (e.target.checked) {\n updateEssayCorrection(\n questionData.questionNumber,\n 'isCorrect',\n false\n );\n }\n }}\n />\n </div>\n </div>\n\n {/* Teacher feedback textarea */}\n <div className=\"space-y-2\">\n <Text className=\"text-sm font-semibold text-text-950\">\n Incluir observação\n </Text>\n <TextArea\n value={correction.teacherFeedback}\n onChange={(e) => {\n updateEssayCorrection(\n questionData.questionNumber,\n 'teacherFeedback',\n e.target.value\n );\n }}\n placeholder=\"Escreva uma observação sobre a resposta do aluno\"\n rows={4}\n size=\"medium\"\n />\n </div>\n\n {/* Save button */}\n <Button\n size=\"small\"\n onClick={() => handleSaveEssayCorrection(questionData.questionNumber)}\n disabled={\n correction.isCorrect === null ||\n correction.isSaving ||\n !onQuestionCorrectionSubmit\n }\n >\n {correction.isSaving ? 'Salvando...' : 'Salvar'}\n </Button>\n </>\n );\n };\n\n if (!data) return null;\n\n const title = isViewOnly ? 'Detalhes da atividade' : 'Corrigir atividade';\n const formattedScore = data.score == null ? '-' : data.score.toFixed(1);\n\n /**\n * Render observation section based on current state\n * Allows observations in all activity statuses (not just pending correction)\n * @returns JSX element for observation section\n */\n const renderObservationSection = () => {\n /**\n * Get file name from URL\n * @param url - File URL\n * @returns File name extracted from URL\n */\n const getFileNameFromUrl = (url: string): string => {\n try {\n const urlObj = new URL(url);\n const urlPath = urlObj.pathname;\n return urlPath.split('/').pop() || 'Anexo';\n } catch {\n return 'Anexo';\n }\n };\n\n /**\n * Render attachment input section for expanded state\n * @returns JSX element for attachment input\n */\n const renderAttachmentInput = () => {\n if (attachedFiles.length > 0) {\n return (\n <div className=\"flex items-center justify-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px]\">\n <Paperclip size={18} className=\"text-text-800 flex-shrink-0\" />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {attachedFiles[0].file.name}\n </span>\n <button\n type=\"button\"\n onClick={() => handleFileRemove(attachedFiles[0].id)}\n className=\"text-text-700 hover:text-text-800 flex-shrink-0\"\n aria-label={`Remover ${attachedFiles[0].file.name}`}\n >\n <X size={18} />\n </button>\n </div>\n );\n }\n\n if (existingAttachment) {\n return (\n <div className=\"flex items-center gap-2\">\n <a\n href={existingAttachment}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px] hover:bg-secondary-600 transition-colors\"\n >\n <Paperclip size={18} className=\"text-text-800 flex-shrink-0\" />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {getFileNameFromUrl(existingAttachment)}\n </span>\n </a>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => fileInputRef.current?.click()}\n className=\"flex items-center gap-2\"\n >\n <Paperclip size={18} />\n Trocar\n </Button>\n </div>\n );\n }\n\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => fileInputRef.current?.click()}\n className=\"flex items-center gap-2\"\n >\n <Paperclip size={18} />\n Anexar\n </Button>\n );\n };\n\n // State: Saved\n if (isObservationSaved) {\n return (\n <div className=\"bg-background border border-border-100 rounded-lg p-4 space-y-2\">\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <Text className=\"text-sm font-bold text-text-950\">Observação</Text>\n <div className=\"flex items-center gap-3\">\n {/* Show newly attached file */}\n {savedFiles.length > 0 && (\n <div className=\"flex items-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px]\">\n <Paperclip\n size={18}\n className=\"text-text-800 flex-shrink-0\"\n />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {savedFiles[0].file.name}\n </span>\n </div>\n )}\n {/* Show existing attachment from server (URL) */}\n {savedFiles.length === 0 && existingAttachment && (\n <a\n href={existingAttachment}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 px-5 h-10 bg-secondary-500 rounded-full min-w-0 max-w-[150px] hover:bg-secondary-600 transition-colors\"\n >\n <Paperclip\n size={18}\n className=\"text-text-800 flex-shrink-0\"\n />\n <span className=\"text-base font-medium text-text-800 truncate\">\n {getFileNameFromUrl(existingAttachment)}\n </span>\n </a>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={handleEditObservation}\n className=\"flex items-center gap-2 flex-shrink-0\"\n >\n <PencilSimple size={16} />\n Editar\n </Button>\n </div>\n </div>\n {savedObservation && (\n <div className=\"p-3 bg-background-50 rounded-lg\">\n <Text className=\"text-sm text-text-700\">{savedObservation}</Text>\n </div>\n )}\n </div>\n );\n }\n\n // State: Expanded\n if (isObservationExpanded) {\n return (\n <div className=\"bg-background border border-border-100 rounded-lg p-4 space-y-3\">\n <Text className=\"text-sm font-bold text-text-950\">Observação</Text>\n <textarea\n value={observation}\n onChange={(e) => setObservation(e.target.value)}\n placeholder=\"Escreva uma observação para o estudante\"\n className=\"w-full min-h-[80px] p-3 border border-border-100 rounded-lg text-sm text-text-700 placeholder:text-text-400 resize-none focus:outline-none focus:ring-2 focus:ring-primary-500\"\n />\n {/* Hidden file input */}\n <input\n type=\"file\"\n ref={fileInputRef}\n className=\"hidden\"\n onChange={(e) => {\n const selectedFiles = e.target.files;\n if (selectedFiles && selectedFiles.length > 0) {\n handleFilesAdd(Array.from(selectedFiles));\n }\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n }}\n aria-label=\"Selecionar arquivo\"\n />\n {/* Buttons row: File indicator or Anexar button left, Salvar right */}\n <div className=\"flex flex-col-reverse sm:flex-row gap-3 sm:justify-between\">\n {renderAttachmentInput()}\n <Button\n type=\"button\"\n size=\"small\"\n onClick={handleSaveObservation}\n disabled={\n !observation.trim() &&\n attachedFiles.length === 0 &&\n !existingAttachment\n }\n >\n Salvar\n </Button>\n </div>\n {data.observation && (\n <div className=\"p-3 bg-background-50 rounded-lg\">\n <Text className=\"text-xs text-text-500\">\n Observação anterior:\n </Text>\n <Text className=\"text-sm text-text-700\">{data.observation}</Text>\n </div>\n )}\n </div>\n );\n }\n\n // State: Closed (default)\n return (\n <div className=\"bg-background border border-border-100 rounded-lg p-4 flex flex-col sm:flex-row gap-3 sm:items-center sm:justify-between\">\n <Text className=\"text-sm font-bold text-text-950\">Observação</Text>\n <Button type=\"button\" size=\"small\" onClick={handleOpenObservation}>\n Incluir\n </Button>\n </div>\n );\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size=\"lg\"\n contentClassName=\"max-h-[80vh] overflow-y-auto\"\n >\n <div className=\"space-y-6\">\n {/* Student Info */}\n <div className=\"flex items-center gap-3\">\n <div className=\"w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center\">\n <Text className=\"text-lg font-semibold text-primary-700\">\n {data.studentName?.charAt(0).toUpperCase() || '-'}\n </Text>\n </div>\n <Text className=\"text-lg font-medium text-text-950\">\n {data.studentName || 'Aluno'}\n </Text>\n </div>\n\n {/* Stats Cards */}\n <div className=\"grid grid-cols-3 gap-4\">\n <StatCard label=\"Nota\" value={formattedScore} variant=\"score\" />\n <StatCard\n label=\"N° de questões corretas\"\n value={data.correctCount}\n variant=\"correct\"\n />\n <StatCard\n label=\"N° de questões incorretas\"\n value={data.incorrectCount}\n variant=\"incorrect\"\n />\n </div>\n\n {/* Observation Section */}\n {renderObservationSection()}\n\n {/* Questions List */}\n <div className=\"space-y-2\">\n <Text className=\"text-sm font-bold text-text-950\">Respostas</Text>\n <AccordionGroup type=\"multiple\" className=\"space-y-2\">\n {data.questions?.map((questionData) => {\n const status = getQuestionStatusFromData(questionData);\n const badgeConfig = getQuestionStatusBadgeConfig(status);\n\n return (\n <CardAccordation\n key={questionData.questionNumber}\n value={`question-${questionData.questionNumber}`}\n className=\"bg-background rounded-xl\"\n trigger={\n <div className=\"flex items-center justify-between w-full py-3 pr-2\">\n <Text className=\"text-base font-bold text-text-950\">\n Questão {questionData.questionNumber}\n </Text>\n <Badge\n className={cn(\n 'text-xs px-2 py-1',\n badgeConfig.bgColor,\n badgeConfig.textColor\n )}\n >\n {badgeConfig.label}\n </Badge>\n </div>\n }\n >\n <div className=\"space-y-4 pt-2\">\n {/* Question statement */}\n {questionData.question.statement && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n color=\"text-text-700\"\n className=\"whitespace-pre-wrap\"\n >\n {questionData.question.statement}\n </Text>\n )}\n\n {/* Question content based on type */}\n {renderQuestionContent(questionData)}\n </div>\n </CardAccordation>\n );\n })}\n </AccordionGroup>\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default CorrectActivityModal;\n","import {\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n ReactNode,\n useId,\n useState,\n useEffect,\n} from 'react';\nimport { CardBase } from '../Card/Card';\nimport { CaretRight } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\ninterface CardAccordationProps extends HTMLAttributes<HTMLDivElement> {\n trigger: ReactNode;\n children: ReactNode;\n defaultExpanded?: boolean;\n expanded?: boolean;\n onToggleExpanded?: (isExpanded: boolean) => void;\n value?: string;\n disabled?: boolean;\n /** Additional class for the trigger button */\n triggerClassName?: string;\n /** Additional class for the content wrapper */\n contentClassName?: string;\n}\n\nconst CardAccordation = forwardRef<HTMLDivElement, CardAccordationProps>(\n (\n {\n trigger,\n children,\n className,\n defaultExpanded = false,\n expanded: controlledExpanded,\n onToggleExpanded,\n value,\n disabled = false,\n triggerClassName,\n contentClassName,\n ...props\n },\n ref\n ) => {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const generatedId = useId();\n\n // Use value as ID base for better semantics, fallback to generated ID\n const contentId = value ? `accordion-content-${value}` : generatedId;\n const headerId = value\n ? `accordion-header-${value}`\n : `${generatedId}-header`;\n\n // Determine if component is controlled\n const isControlled = controlledExpanded !== undefined;\n const isExpanded = isControlled ? controlledExpanded : internalExpanded;\n\n // Sync internal state when controlled value changes\n useEffect(() => {\n if (isControlled) {\n setInternalExpanded(controlledExpanded);\n }\n }, [isControlled, controlledExpanded]);\n\n const handleToggle = () => {\n if (disabled) return;\n\n const newExpanded = !isExpanded;\n\n if (!isControlled) {\n setInternalExpanded(newExpanded);\n }\n\n onToggleExpanded?.(newExpanded);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) return;\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleToggle();\n }\n };\n\n return (\n <CardBase\n ref={ref}\n layout=\"vertical\"\n padding=\"none\"\n minHeight=\"none\"\n className={cn('overflow-hidden', className)}\n {...props}\n >\n {/* Clickable header */}\n <button\n id={headerId}\n type=\"button\"\n onClick={handleToggle}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n className={cn(\n 'w-full cursor-pointer not-aria-expanded:rounded-xl aria-expanded:rounded-t-xl flex items-center justify-between gap-3 text-left transition-colors duration-200 focus:outline-none focus:border-2 focus:border-primary-950 focus:ring-inset px-2',\n disabled && 'cursor-not-allowed text-text-400',\n triggerClassName\n )}\n aria-expanded={isExpanded}\n aria-controls={contentId}\n aria-disabled={disabled}\n data-value={value}\n >\n {trigger}\n\n <CaretRight\n size={20}\n className={cn(\n 'transition-transform duration-200 flex-shrink-0',\n disabled ? 'text-gray-400' : 'text-text-700',\n isExpanded ? 'rotate-90' : 'rotate-0'\n )}\n data-testid=\"accordion-caret\"\n />\n </button>\n\n {/* Expandable content */}\n <section\n id={contentId}\n aria-labelledby={headerId}\n aria-hidden={!isExpanded}\n className={cn(\n 'transition-all duration-300 ease-in-out overflow-hidden',\n isExpanded ? 'max-h-screen opacity-100' : 'max-h-0 opacity-0'\n )}\n data-testid=\"accordion-content\"\n data-value={value}\n >\n <div className={cn('p-4 pt-0', contentClassName)}>{children}</div>\n </section>\n </CardBase>\n );\n }\n);\n\nCardAccordation.displayName = 'CardAccordation';\n\nexport { CardAccordation };\nexport type { CardAccordationProps };\n","import {\n forwardRef,\n Fragment,\n HTMLAttributes,\n ReactNode,\n useState,\n useRef,\n MouseEvent,\n ChangeEvent,\n KeyboardEvent,\n Ref,\n useEffect,\n} from 'react';\nimport Button from '../Button/Button';\nimport Badge from '../Badge/Badge';\nimport ProgressBar from '../ProgressBar/ProgressBar';\nimport {\n CaretRight,\n ChatCircleText,\n CheckCircle,\n Clock,\n DotsThreeVertical,\n Play,\n SpeakerHigh,\n SpeakerLow,\n SpeakerSimpleX,\n XCircle,\n} from 'phosphor-react';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\nimport IconRender from '../IconRender/IconRender';\n\n// Componente base reutilizável para todos os cards\ninterface CardBaseProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n variant?: 'default' | 'compact' | 'minimal';\n layout?: 'horizontal' | 'vertical';\n padding?: 'none' | 'small' | 'medium' | 'large';\n minHeight?: 'none' | 'small' | 'medium' | 'large';\n cursor?: 'default' | 'pointer';\n}\n\nconst CARD_BASE_CLASSES = {\n default: 'w-full bg-background border border-border-50 rounded-xl',\n compact: 'w-full bg-background border border-border-50 rounded-lg',\n minimal: 'w-full bg-background border border-border-100 rounded-md',\n};\n\nconst CARD_PADDING_CLASSES = {\n none: '',\n small: 'p-2',\n medium: 'p-4',\n large: 'p-6',\n};\n\nconst CARD_MIN_HEIGHT_CLASSES = {\n none: '',\n small: 'min-h-16',\n medium: 'min-h-20',\n large: 'min-h-24',\n};\n\nconst CARD_LAYOUT_CLASSES = {\n horizontal: 'flex flex-row',\n vertical: 'flex flex-col',\n};\n\nconst CARD_CURSOR_CLASSES = {\n default: '',\n pointer: 'cursor-pointer',\n};\n\nconst CardBase = forwardRef<HTMLDivElement, CardBaseProps>(\n (\n {\n children,\n variant = 'default',\n layout = 'horizontal',\n padding = 'medium',\n minHeight = 'medium',\n cursor = 'default',\n className = '',\n ...props\n },\n ref\n ) => {\n const baseClasses = CARD_BASE_CLASSES[variant];\n const paddingClasses = CARD_PADDING_CLASSES[padding];\n const minHeightClasses = CARD_MIN_HEIGHT_CLASSES[minHeight];\n const layoutClasses = CARD_LAYOUT_CLASSES[layout];\n const cursorClasses = CARD_CURSOR_CLASSES[cursor];\n\n return (\n <div\n ref={ref}\n className={cn(\n baseClasses,\n paddingClasses,\n minHeightClasses,\n layoutClasses,\n cursorClasses,\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\ninterface CardActivitiesResultsProps extends HTMLAttributes<HTMLDivElement> {\n icon: ReactNode;\n title: string;\n subTitle: string;\n header: string;\n description?: string;\n extended?: boolean;\n action?: 'warning' | 'success' | 'error' | 'info';\n}\n\nconst ACTION_CARD_CLASSES = {\n warning: 'bg-warning-background',\n success: 'bg-success-200',\n error: 'bg-error-100',\n info: 'bg-info-background',\n};\n\nconst ACTION_ICON_CLASSES = {\n warning: 'bg-warning-300 text-text',\n success: 'bg-indicator-positive text-text-950',\n error: 'bg-indicator-negative text-text',\n info: 'bg-info-500 text-text',\n};\n\nconst ACTION_SUBTITLE_CLASSES = {\n warning: 'text-warning-600',\n success: 'text-success-700',\n error: 'text-error-700',\n info: 'text-info-700',\n};\n\nconst ACTION_HEADER_CLASSES = {\n warning: 'text-warning-300',\n success: 'text-success-300',\n error: 'text-error-300',\n info: 'text-info-300',\n};\n\nconst CardActivitiesResults = forwardRef<\n HTMLDivElement,\n CardActivitiesResultsProps\n>(\n (\n {\n icon,\n title,\n subTitle,\n header,\n extended = false,\n action = 'success',\n description,\n className,\n ...props\n },\n ref\n ) => {\n const actionCardClasses = ACTION_CARD_CLASSES[action];\n const actionIconClasses = ACTION_ICON_CLASSES[action];\n const actionSubTitleClasses = ACTION_SUBTITLE_CLASSES[action];\n const actionHeaderClasses = ACTION_HEADER_CLASSES[action];\n\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full flex flex-col border border-border-50 bg-background rounded-xl',\n className\n )}\n {...props}\n >\n <div\n className={cn(\n 'flex flex-col gap-1 items-center justify-center p-4',\n actionCardClasses,\n extended ? 'rounded-t-xl' : 'rounded-xl'\n )}\n >\n <span\n className={cn(\n 'size-7.5 rounded-full flex items-center justify-center',\n actionIconClasses\n )}\n >\n {icon}\n </span>\n\n <Text\n size=\"2xs\"\n weight=\"medium\"\n className=\"text-text-800 uppercase truncate\"\n >\n {title}\n </Text>\n\n <p\n className={cn('text-lg font-bold truncate', actionSubTitleClasses)}\n >\n {subTitle}\n </p>\n </div>\n\n {extended && (\n <div className=\"flex flex-col items-center gap-2.5 pb-9.5 pt-2.5\">\n <p\n className={cn(\n 'text-2xs font-medium uppercase truncate',\n actionHeaderClasses\n )}\n >\n {header}\n </p>\n <Badge size=\"large\" action=\"info\">\n {description}\n </Badge>\n </div>\n )}\n </div>\n );\n }\n);\n\ninterface CardQuestionProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n state?: 'done' | 'undone';\n onClickButton?: (valueButton?: unknown) => void;\n valueButton?: unknown;\n}\n\nconst CardQuestions = forwardRef<HTMLDivElement, CardQuestionProps>(\n (\n {\n header,\n state = 'undone',\n className,\n onClickButton,\n valueButton,\n ...props\n },\n ref\n ) => {\n const isDone = state === 'done';\n const stateLabel = isDone ? 'Realizado' : 'Não Realizado';\n const buttonLabel = isDone ? 'Ver Resultado' : 'Responder';\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"medium\"\n className={cn('justify-between gap-4', className)}\n {...props}\n >\n <section className=\"flex flex-col gap-1 flex-1 min-w-0\">\n <p className=\"font-bold text-xs text-text-950 truncate\">{header}</p>\n\n <div className=\"flex flex-row gap-6 items-center\">\n <Badge\n size=\"medium\"\n variant=\"solid\"\n action={isDone ? 'success' : 'error'}\n >\n {stateLabel}\n </Badge>\n </div>\n </section>\n\n <span className=\"flex-shrink-0\">\n <Button\n size=\"extra-small\"\n onClick={() => onClickButton?.(valueButton)}\n className=\"min-w-fit\"\n >\n {buttonLabel}\n </Button>\n </span>\n </CardBase>\n );\n }\n);\n\ninterface CardProgressProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n subhead?: string;\n initialDate?: string;\n endDate?: string;\n progress?: number;\n direction?: 'horizontal' | 'vertical';\n icon: ReactNode;\n color?: string;\n progressVariant?: 'blue' | 'green';\n showDates?: boolean;\n}\n\nconst CardProgress = forwardRef<HTMLDivElement, CardProgressProps>(\n (\n {\n header,\n subhead,\n initialDate,\n endDate,\n progress = 0,\n direction = 'horizontal',\n icon,\n color = '#B7DFFF',\n progressVariant = 'blue',\n showDates = true,\n className,\n ...props\n },\n ref\n ) => {\n const isHorizontal = direction === 'horizontal';\n const contentComponent = {\n horizontal: (\n <>\n {showDates && (\n <div className=\"flex flex-row gap-6 items-center\">\n {initialDate && (\n <span className=\"flex flex-row gap-1 items-center text-2xs\">\n <p className=\"text-text-800 font-semibold\">Início</p>\n <p className=\"text-text-600\">{initialDate}</p>\n </span>\n )}\n {endDate && (\n <span className=\"flex flex-row gap-1 items-center text-2xs\">\n <p className=\"text-text-800 font-semibold\">Fim</p>\n <p className=\"text-text-600\">{endDate}</p>\n </span>\n )}\n </div>\n )}\n <span className=\"grid grid-cols-[1fr_auto] items-center gap-2\">\n <ProgressBar\n size=\"small\"\n value={progress}\n variant={progressVariant}\n data-testid=\"progress-bar\"\n />\n\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none'\n )}\n >\n {Math.round(progress)}%\n </Text>\n </span>\n </>\n ),\n vertical: <p className=\"text-sm text-text-800\">{subhead}</p>,\n };\n\n return (\n <CardBase\n ref={ref}\n layout={isHorizontal ? 'horizontal' : 'vertical'}\n padding=\"none\"\n minHeight=\"medium\"\n cursor=\"pointer\"\n className={cn(isHorizontal ? 'h-20' : '', className)}\n {...props}\n >\n <div\n className={cn(\n 'flex justify-center items-center [&>svg]:size-6 text-text-950',\n isHorizontal\n ? 'min-w-[80px] min-h-[80px] rounded-l-xl'\n : 'min-h-[50px] w-full rounded-t-xl',\n !color.startsWith('#') ? `${color}` : ''\n )}\n style={color.startsWith('#') ? { backgroundColor: color } : undefined}\n data-testid=\"icon-container\"\n >\n {icon}\n </div>\n\n <div\n className={cn(\n 'p-4 flex flex-col justify-between w-full h-full',\n !isHorizontal && 'gap-4'\n )}\n >\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-950 truncate\">\n {header}\n </Text>\n {contentComponent[direction]}\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardTopicProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n subHead?: string[];\n progress: number;\n showPercentage?: boolean;\n progressVariant?: 'blue' | 'green';\n}\n\nconst CardTopic = forwardRef<HTMLDivElement, CardTopicProps>(\n (\n {\n header,\n subHead,\n progress,\n showPercentage = false,\n progressVariant = 'blue',\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <CardBase\n ref={ref}\n layout=\"vertical\"\n padding=\"small\"\n minHeight=\"medium\"\n cursor=\"pointer\"\n className={cn('justify-center gap-2 py-2 px-4', className)}\n {...props}\n >\n {subHead && (\n <span className=\"text-text-600 text-2xs flex flex-row gap-1\">\n {subHead.map((text, index) => (\n <Fragment key={`${text} - ${index}`}>\n <p>{text}</p>\n {index < subHead.length - 1 && <p>•</p>}\n </Fragment>\n ))}\n </span>\n )}\n\n <p className=\"text-sm text-text-950 font-bold truncate\">{header}</p>\n\n <span className=\"grid grid-cols-[1fr_auto] items-center gap-2\">\n <ProgressBar\n size=\"small\"\n value={progress}\n variant={progressVariant}\n data-testid=\"progress-bar\"\n />\n {showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none'\n )}\n >\n {Math.round(progress)}%\n </Text>\n )}\n </span>\n </CardBase>\n );\n }\n);\n\ninterface CardPerformanceProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n description?: string;\n progress?: number;\n labelProgress?: string;\n actionVariant?: 'button' | 'caret';\n progressVariant?: 'blue' | 'green';\n onClickButton?: (valueButton?: unknown) => void;\n valueButton?: unknown;\n}\n\nconst CardPerformance = forwardRef<HTMLDivElement, CardPerformanceProps>(\n (\n {\n header,\n progress,\n description = 'Sem dados ainda! Você ainda não fez um questionário neste assunto.',\n actionVariant = 'button',\n progressVariant = 'blue',\n labelProgress = '',\n className = '',\n onClickButton,\n valueButton,\n ...props\n },\n ref\n ) => {\n const hasProgress = progress !== undefined;\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n actionVariant == 'caret' ? 'cursor-pointer' : '',\n className\n )}\n onClick={() => actionVariant == 'caret' && onClickButton?.(valueButton)}\n {...props}\n >\n <div className=\"w-full flex flex-col justify-between gap-2\">\n <div className=\"flex flex-row justify-between items-center gap-2\">\n <p className=\"text-lg font-bold text-text-950 truncate flex-1 min-w-0\">\n {header}\n </p>\n {actionVariant === 'button' && (\n <Button\n variant=\"outline\"\n size=\"extra-small\"\n onClick={() => onClickButton?.(valueButton)}\n className=\"min-w-fit flex-shrink-0\"\n >\n Ver Aula\n </Button>\n )}\n </div>\n\n <div className=\"w-full\">\n {hasProgress ? (\n <ProgressBar\n value={progress}\n label={`${progress}% ${labelProgress}`}\n variant={progressVariant}\n />\n ) : (\n <p className=\"text-xs text-text-600 truncate\">{description}</p>\n )}\n </div>\n </div>\n\n {actionVariant == 'caret' && (\n <CaretRight\n className=\"size-4.5 text-text-800 cursor-pointer\"\n data-testid=\"caret-icon\"\n />\n )}\n </CardBase>\n );\n }\n);\n\ninterface CardResultsProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n icon: string;\n correct_answers: number;\n incorrect_answers: number;\n direction?: 'row' | 'col';\n color?: string;\n}\n\nconst CardResults = forwardRef<HTMLDivElement, CardResultsProps>(\n (\n {\n header,\n correct_answers,\n incorrect_answers,\n icon,\n direction = 'col',\n color = '#B7DFFF',\n className,\n ...props\n },\n ref\n ) => {\n const isRow = direction == 'row';\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"none\"\n minHeight=\"medium\"\n className={cn('items-stretch cursor-pointer pr-4', className)}\n {...props}\n >\n <div\n className={cn(\n 'flex justify-center items-center [&>svg]:size-8 text-text-950 min-w-20 max-w-20 min-h-full rounded-l-xl'\n )}\n style={{\n backgroundColor: color,\n }}\n >\n <IconRender iconName={icon} color=\"currentColor\" size={20} />\n </div>\n\n <div className=\"w-full flex flex-row justify-between items-center\">\n <div\n className={cn(\n 'p-4 flex flex-wrap justify-between w-full h-full',\n isRow ? 'flex-row items-center gap-2' : 'flex-col'\n )}\n >\n <p className=\"text-sm font-bold text-text-950 flex-1\">{header}</p>\n <span className=\"flex flex-wrap flex-row gap-1 items-center\">\n <Badge\n action=\"success\"\n variant=\"solid\"\n size=\"large\"\n iconLeft={<CheckCircle />}\n >\n {correct_answers} Corretas\n </Badge>\n\n <Badge\n action=\"error\"\n variant=\"solid\"\n size=\"large\"\n iconLeft={<XCircle />}\n >\n {incorrect_answers} Incorretas\n </Badge>\n </span>\n </div>\n\n <CaretRight className=\"min-w-6 min-h-6 text-text-800\" />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardStatusProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n status?: 'correct' | 'incorrect' | 'unanswered' | 'pending';\n label?: string;\n}\n\nconst CardStatus = forwardRef<HTMLDivElement, CardStatusProps>(\n ({ header, className, status, label, ...props }, ref) => {\n const getLabelBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return 'Correta';\n case 'incorrect':\n return 'Incorreta';\n case 'unanswered':\n return 'Em branco';\n case 'pending':\n return 'Avaliação pendente';\n default:\n return 'Em branco';\n }\n };\n\n const getIconBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return <CheckCircle />;\n case 'incorrect':\n return <XCircle />;\n case 'pending':\n return <Clock />;\n default:\n return <XCircle />;\n }\n };\n\n const getActionBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return 'success';\n case 'incorrect':\n return 'error';\n case 'pending':\n return 'info';\n default:\n return 'info';\n }\n };\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"medium\"\n className={cn('items-center cursor-pointer', className)}\n {...props}\n >\n <div className=\"flex justify-between w-full h-full flex-row items-center gap-2\">\n <p className=\"text-sm font-bold text-text-950 truncate flex-1 min-w-0\">\n {header}\n </p>\n <span className=\"flex flex-row gap-1 items-center flex-shrink-0\">\n {status && (\n <Badge\n action={getActionBadge(status)}\n variant=\"solid\"\n size=\"medium\"\n iconLeft={getIconBadge(status)}\n >\n {getLabelBadge(status)}\n </Badge>\n )}\n {label && <p className=\"text-sm text-text-800\">{label}</p>}\n </span>\n <CaretRight className=\"min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2\" />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardSettingsProps extends HTMLAttributes<HTMLDivElement> {\n icon: ReactNode;\n header: string;\n}\n\nconst CardSettings = forwardRef<HTMLDivElement, CardSettingsProps>(\n ({ header, className, icon, ...props }, ref) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"small\"\n minHeight=\"none\"\n className={cn(\n 'border-none items-center gap-2 text-text-700',\n className\n )}\n {...props}\n >\n <span className=\"[&>svg]:size-6\">{icon}</span>\n\n <p className=\"w-full text-sm truncate\">{header}</p>\n\n <CaretRight size={24} className=\"cursor-pointer\" />\n </CardBase>\n );\n }\n);\n\ninterface CardSupportProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n direction?: 'row' | 'col';\n children: ReactNode;\n}\n\nconst CardSupport = forwardRef<HTMLDivElement, CardSupportProps>(\n ({ header, className, direction = 'col', children, ...props }, ref) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n 'border-none items-center gap-2 text-text-700',\n className\n )}\n {...props}\n >\n <div\n className={cn(\n 'w-full flex',\n direction == 'col' ? 'flex-col' : 'flex-row items-center'\n )}\n >\n <span className=\"w-full min-w-0\">\n <p className=\"text-sm text-text-950 font-bold truncate\">{header}</p>\n </span>\n <span className=\"flex flex-row gap-1\">{children}</span>\n </div>\n\n <CaretRight className=\"text-text-800 cursor-pointer\" size={24} />\n </CardBase>\n );\n }\n);\n\ninterface CardForumProps<T = unknown> extends HTMLAttributes<HTMLDivElement> {\n title: string;\n content: string;\n comments: number;\n date: string;\n hour: string;\n onClickComments?: (value?: T) => void;\n valueComments?: T;\n onClickProfile?: (profile?: T) => void;\n valueProfile?: T;\n}\n\nconst CardForum = forwardRef<HTMLDivElement, CardForumProps>(\n (\n {\n title,\n content,\n comments,\n onClickComments,\n valueComments,\n onClickProfile,\n valueProfile,\n className = '',\n date,\n hour,\n ...props\n },\n ref\n ) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n variant=\"minimal\"\n className={cn('w-auto h-auto gap-3', className)}\n {...props}\n >\n <button\n type=\"button\"\n aria-label=\"Ver perfil\"\n onClick={() => onClickProfile?.(valueProfile)}\n className=\"min-w-8 h-8 rounded-full bg-background-950\"\n />\n\n <div className=\"flex flex-col gap-2 flex-1 min-w-0\">\n <div className=\"flex flex-row gap-1 items-center flex-wrap\">\n <p className=\"text-xs font-semibold text-primary-700 truncate\">\n {title}\n </p>\n <p className=\"text-xs text-text-600\">\n • {date} • {hour}\n </p>\n </div>\n\n <p className=\"text-text-950 text-sm line-clamp-2 truncate\">\n {content}\n </p>\n\n <button\n type=\"button\"\n aria-label=\"Ver comentários\"\n onClick={() => onClickComments?.(valueComments)}\n className=\"text-text-600 flex flex-row gap-2 items-center\"\n >\n <ChatCircleText aria-hidden=\"true\" size={16} />\n <p className=\"text-xs\">{comments} respostas</p>\n </button>\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardAudioProps extends HTMLAttributes<HTMLDivElement> {\n src?: string;\n title?: string;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onAudioTimeUpdate?: (currentTime: number, duration: number) => void;\n loop?: boolean;\n preload?: 'none' | 'metadata' | 'auto';\n tracks?: Array<{\n kind: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata';\n src: string;\n srcLang: string;\n label: string;\n default?: boolean;\n }>;\n}\n\nconst CardAudio = forwardRef<HTMLDivElement, CardAudioProps>(\n (\n {\n src,\n title,\n onPlay,\n onPause,\n onEnded,\n onAudioTimeUpdate,\n loop = false,\n preload = 'metadata',\n tracks,\n className,\n ...props\n },\n ref\n ) => {\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [volume, setVolume] = useState(1);\n const [showVolumeControl, setShowVolumeControl] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const [playbackRate, setPlaybackRate] = useState(1);\n const audioRef = useRef<HTMLAudioElement>(null);\n const volumeControlRef = useRef<HTMLDivElement>(null);\n const speedMenuRef = useRef<HTMLDivElement>(null);\n\n const formatTime = (time: number) => {\n const minutes = Math.floor(time / 60);\n const seconds = Math.floor(time % 60);\n return `${minutes}:${seconds.toString().padStart(2, '0')}`;\n };\n\n const handlePlayPause = () => {\n if (isPlaying) {\n audioRef.current?.pause();\n setIsPlaying(false);\n onPause?.();\n } else {\n audioRef.current?.play();\n setIsPlaying(true);\n onPlay?.();\n }\n };\n\n const handleTimeUpdate = () => {\n const current = audioRef.current?.currentTime ?? 0;\n const total = audioRef.current?.duration ?? 0;\n\n setCurrentTime(current);\n setDuration(total);\n onAudioTimeUpdate?.(current, total);\n };\n\n const handleLoadedMetadata = () => {\n setDuration(audioRef.current?.duration ?? 0);\n };\n\n const handleEnded = () => {\n setIsPlaying(false);\n setCurrentTime(0);\n onEnded?.();\n };\n\n const handleProgressClick = (e: MouseEvent<HTMLButtonElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const width = rect.width;\n const percentage = clickX / width;\n const newTime = percentage * duration;\n\n if (audioRef.current) {\n audioRef.current.currentTime = newTime;\n }\n setCurrentTime(newTime);\n };\n\n const handleVolumeChange = (e: ChangeEvent<HTMLInputElement>) => {\n const newVolume = parseFloat(e.target.value);\n setVolume(newVolume);\n if (audioRef.current) {\n audioRef.current.volume = newVolume;\n }\n };\n\n const toggleVolumeControl = () => {\n setShowVolumeControl(!showVolumeControl);\n setShowSpeedMenu(false);\n };\n\n const toggleSpeedMenu = () => {\n setShowSpeedMenu(!showSpeedMenu);\n setShowVolumeControl(false);\n };\n\n const handleSpeedChange = (speed: number) => {\n setPlaybackRate(speed);\n if (audioRef.current) {\n audioRef.current.playbackRate = speed;\n }\n setShowSpeedMenu(false);\n };\n\n const getVolumeIcon = () => {\n if (volume === 0) {\n return <SpeakerSimpleX size={24} />;\n }\n if (volume < 0.5) {\n return <SpeakerLow size={24} />;\n }\n return <SpeakerHigh size={24} />;\n };\n\n useEffect(() => {\n const handleClickOutside = (event: Event) => {\n if (\n volumeControlRef.current &&\n !volumeControlRef.current.contains(event.target as Node)\n ) {\n setShowVolumeControl(false);\n }\n if (\n speedMenuRef.current &&\n !speedMenuRef.current.contains(event.target as Node)\n ) {\n setShowSpeedMenu(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n 'flex flex-row w-auto h-14 items-center gap-2',\n className\n )}\n {...props}\n >\n {/* Audio element */}\n <audio\n ref={audioRef}\n src={src}\n loop={loop}\n preload={preload}\n onTimeUpdate={handleTimeUpdate}\n onLoadedMetadata={handleLoadedMetadata}\n onEnded={handleEnded}\n data-testid=\"audio-element\"\n aria-label={title}\n >\n {tracks ? (\n tracks.map((track) => (\n <track\n key={track.src}\n kind={track.kind}\n src={track.src}\n srcLang={track.srcLang}\n label={track.label}\n default={track.default}\n />\n ))\n ) : (\n <track\n kind=\"captions\"\n src=\"data:text/vtt;base64,\"\n srcLang=\"pt\"\n label=\"Sem legendas disponíveis\"\n />\n )}\n </audio>\n\n {/* Play/Pause Button */}\n <button\n type=\"button\"\n onClick={handlePlayPause}\n disabled={!src}\n className=\"cursor-pointer text-text-950 hover:text-primary-600 disabled:text-text-400 disabled:cursor-not-allowed\"\n aria-label={isPlaying ? 'Pausar' : 'Reproduzir'}\n >\n {isPlaying ? (\n <div className=\"w-6 h-6 flex items-center justify-center\">\n <div className=\"flex gap-0.5\">\n <div className=\"w-1 h-4 bg-current rounded-sm\"></div>\n <div className=\"w-1 h-4 bg-current rounded-sm\"></div>\n </div>\n </div>\n ) : (\n <Play size={24} />\n )}\n </button>\n\n {/* Current Time */}\n <p className=\"text-text-800 text-md font-medium min-w-[2.5rem]\">\n {formatTime(currentTime)}\n </p>\n\n {/* Progress Bar */}\n <div className=\"flex-1 relative\" data-testid=\"progress-bar\">\n <button\n type=\"button\"\n className=\"w-full h-2 bg-border-100 rounded-full cursor-pointer\"\n onClick={handleProgressClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleProgressClick(\n e as unknown as MouseEvent<HTMLButtonElement>\n );\n }\n }}\n aria-label=\"Barra de progresso do áudio\"\n >\n <div\n className=\"h-full bg-primary-600 rounded-full transition-all duration-100\"\n style={{\n width:\n duration > 0 ? `${(currentTime / duration) * 100}%` : '0%',\n }}\n />\n </button>\n </div>\n\n {/* Duration */}\n <p className=\"text-text-800 text-md font-medium min-w-[2.5rem]\">\n {formatTime(duration)}\n </p>\n\n {/* Volume Control */}\n <div className=\"relative h-6\" ref={volumeControlRef}>\n <button\n type=\"button\"\n onClick={toggleVolumeControl}\n className=\"cursor-pointer text-text-950 hover:text-primary-600\"\n aria-label=\"Controle de volume\"\n >\n <div className=\"w-6 h-6 flex items-center justify-center\">\n {getVolumeIcon()}\n </div>\n </button>\n\n {showVolumeControl && (\n <button\n type=\"button\"\n className=\"absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500\"\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n setShowVolumeControl(false);\n }\n }}\n >\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.1\"\n value={volume}\n onChange={handleVolumeChange}\n onKeyDown={(e) => {\n if (e.key === 'ArrowUp' || e.key === 'ArrowRight') {\n e.preventDefault();\n const newVolume = Math.min(\n 1,\n Math.round((volume + 0.1) * 10) / 10\n );\n setVolume(newVolume);\n if (audioRef.current) audioRef.current.volume = newVolume;\n } else if (e.key === 'ArrowDown' || e.key === 'ArrowLeft') {\n e.preventDefault();\n const newVolume = Math.max(\n 0,\n Math.round((volume - 0.1) * 10) / 10\n );\n setVolume(newVolume);\n if (audioRef.current) audioRef.current.volume = newVolume;\n }\n }}\n className=\"w-20 h-2 bg-border-100 rounded-lg appearance-none cursor-pointer\"\n style={{\n background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${volume * 100}%, #e5e7eb ${volume * 100}%, #e5e7eb 100%)`,\n }}\n aria-label=\"Volume\"\n aria-valuenow={Math.round(volume * 100)}\n aria-valuemin={0}\n aria-valuemax={100}\n />\n </button>\n )}\n </div>\n\n {/* Menu Button */}\n <div className=\"relative h-6\" ref={speedMenuRef}>\n <button\n type=\"button\"\n onClick={toggleSpeedMenu}\n className=\"cursor-pointer text-text-950 hover:text-primary-600\"\n aria-label=\"Opções de velocidade\"\n >\n <DotsThreeVertical size={24} />\n </button>\n\n {showSpeedMenu && (\n <div className=\"absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg min-w-24 z-10\">\n <div className=\"flex flex-col gap-1\">\n {[\n { speed: 1, label: '1x' },\n { speed: 1.5, label: '1.5x' },\n { speed: 2, label: '2x' },\n ].map(({ speed, label }) => (\n <button\n key={speed}\n type=\"button\"\n onClick={() => handleSpeedChange(speed)}\n className={cn(\n 'px-3 py-1 text-sm text-left rounded hover:bg-border-50 transition-colors',\n playbackRate === speed\n ? 'bg-primary-950 text-secondary-100 font-medium'\n : 'text-text-950'\n )}\n >\n {label}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardSimuladoProps extends HTMLAttributes<HTMLDivElement> {\n title: string;\n duration?: string;\n info: string;\n backgroundColor: 'enem' | 'prova' | 'simuladao' | 'vestibular';\n}\n\nconst SIMULADO_BACKGROUND_CLASSES = {\n enem: 'bg-exam-1',\n prova: 'bg-exam-2',\n simuladao: 'bg-exam-3',\n vestibular: 'bg-exam-4',\n};\n\nconst CardSimulado = forwardRef<HTMLDivElement, CardSimuladoProps>(\n ({ title, duration, info, backgroundColor, className, ...props }, ref) => {\n const backgroundClass = SIMULADO_BACKGROUND_CLASSES[backgroundColor];\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n cursor=\"pointer\"\n className={cn(\n `${backgroundClass} hover:shadow-soft-shadow-2 transition-shadow duration-200`,\n className\n )}\n {...props}\n >\n <div className=\"flex justify-between items-center w-full gap-4\">\n <div className=\"flex flex-col gap-1 flex-1 min-w-0\">\n <Text size=\"lg\" weight=\"bold\" className=\"text-text-950 truncate\">\n {title}\n </Text>\n\n <div className=\"flex items-center gap-4 text-text-700\">\n {duration && (\n <div className=\"flex items-center gap-1\">\n <Clock size={16} className=\"flex-shrink-0\" />\n <Text size=\"sm\">{duration}</Text>\n </div>\n )}\n\n <Text size=\"sm\" className=\"truncate\">\n {info}\n </Text>\n </div>\n </div>\n\n <CaretRight\n size={24}\n className=\"text-text-800 flex-shrink-0\"\n data-testid=\"caret-icon\"\n />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardTestProps extends Omit<HTMLAttributes<HTMLElement>, 'onSelect'> {\n title: string;\n duration?: string;\n questionsCount?: number;\n additionalInfo?: string;\n selected?: boolean;\n onSelect?: (selected: boolean) => void;\n}\n\nconst CardTest = forwardRef<HTMLElement, CardTestProps>(\n (\n {\n title,\n duration,\n questionsCount,\n additionalInfo,\n selected = false,\n onSelect,\n className = '',\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (onSelect) {\n onSelect(!selected);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if ((event.key === 'Enter' || event.key === ' ') && onSelect) {\n event.preventDefault();\n onSelect(!selected);\n }\n };\n\n const isSelectable = !!onSelect;\n const getQuestionsText = (count: number) => {\n const singular = count === 1 ? 'questão' : 'questões';\n return `${count} ${singular}`;\n };\n\n const displayInfo = questionsCount\n ? getQuestionsText(questionsCount)\n : additionalInfo || '';\n const baseClasses =\n 'flex flex-row items-center p-4 gap-2 w-full max-w-full bg-background shadow-soft-shadow-1 rounded-xl isolate border-0 text-left';\n const interactiveClasses = isSelectable\n ? 'cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-950 focus:ring-offset-2'\n : '';\n const selectedClasses = selected\n ? 'ring-2 ring-primary-950 ring-offset-2'\n : '';\n\n if (isSelectable) {\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n type=\"button\"\n className={cn(\n `${baseClasses} ${interactiveClasses} ${selectedClasses} ${className}`.trim()\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n aria-pressed={selected}\n {...(props as HTMLAttributes<HTMLButtonElement>)}\n >\n <div className=\"flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0\">\n <Text\n size=\"md\"\n weight=\"bold\"\n className=\"text-text-950 tracking-[0.2px] leading-[19px] truncate\"\n >\n {title}\n </Text>\n\n <div className=\"flex flex-row justify-start items-end gap-4 w-full\">\n {duration && (\n <div className=\"flex flex-row items-center gap-1 flex-shrink-0\">\n <Clock size={16} className=\"text-text-700\" />\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] whitespace-nowrap\"\n >\n {duration}\n </Text>\n </div>\n )}\n\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] flex-grow truncate\"\n >\n {displayInfo}\n </Text>\n </div>\n </div>\n </button>\n );\n }\n\n return (\n <div\n ref={ref as Ref<HTMLDivElement>}\n className={cn(`${baseClasses} ${className}`.trim())}\n {...(props as HTMLAttributes<HTMLDivElement>)}\n >\n <div className=\"flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0\">\n <Text\n size=\"md\"\n weight=\"bold\"\n className=\"text-text-950 tracking-[0.2px] leading-[19px] truncate\"\n >\n {title}\n </Text>\n\n <div className=\"flex flex-row justify-start items-end gap-4 w-full\">\n {duration && (\n <div className=\"flex flex-row items-center gap-1 flex-shrink-0\">\n <Clock size={16} className=\"text-text-700\" />\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] whitespace-nowrap\"\n >\n {duration}\n </Text>\n </div>\n )}\n\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] flex-grow truncate min-w-0\"\n >\n {displayInfo}\n </Text>\n </div>\n </div>\n </div>\n );\n }\n);\n\ninterface SimulationItem {\n id: string;\n title: string;\n type: 'enem' | 'prova' | 'simulado' | 'vestibular';\n info: string;\n}\n\ninterface SimulationHistoryData {\n date: string;\n simulations: SimulationItem[];\n}\n\ninterface CardSimulationHistoryProps extends HTMLAttributes<HTMLDivElement> {\n data: SimulationHistoryData[];\n onSimulationClick?: (simulation: SimulationItem) => void;\n}\n\nconst SIMULATION_TYPE_STYLES = {\n enem: {\n background: 'bg-exam-1',\n badge: 'exam1' as const,\n text: 'Enem',\n },\n prova: {\n background: 'bg-exam-2',\n badge: 'exam2' as const,\n text: 'Prova',\n },\n simulado: {\n background: 'bg-exam-3',\n badge: 'exam3' as const,\n text: 'Simuladão',\n },\n vestibular: {\n background: 'bg-exam-4',\n badge: 'exam4' as const,\n text: 'Vestibular',\n },\n};\n\nconst CardSimulationHistory = forwardRef<\n HTMLDivElement,\n CardSimulationHistoryProps\n>(({ data, onSimulationClick, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('w-full max-w-[992px] h-auto', className)}\n {...props}\n >\n {/* Content */}\n <div className=\"flex flex-col gap-0\">\n {data.map((section, sectionIndex) => (\n <div key={section.date} className=\"flex flex-col\">\n {/* Seção com data */}\n <div\n className={cn(\n 'flex flex-row justify-center items-start px-4 py-6 gap-2 w-full bg-background',\n sectionIndex === 0 ? 'rounded-t-3xl' : ''\n )}\n >\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"text-text-800 w-11 flex-shrink-0\"\n >\n {section.date}\n </Text>\n\n <div className=\"flex flex-col gap-2 flex-1\">\n {section.simulations.map((simulation) => {\n const typeStyles = SIMULATION_TYPE_STYLES[simulation.type];\n\n return (\n <CardBase\n key={simulation.id}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n cursor=\"pointer\"\n className={cn(\n `${typeStyles.background} rounded-xl hover:shadow-soft-shadow-2 \n transition-shadow duration-200 h-auto min-h-[61px]`\n )}\n onClick={() => onSimulationClick?.(simulation)}\n >\n <div className=\"flex justify-between items-center w-full gap-2\">\n <div className=\"flex flex-wrap flex-col justify-between sm:flex-row gap-2 flex-1 min-w-0\">\n <Text\n size=\"lg\"\n weight=\"bold\"\n className=\"text-text-950 truncate\"\n >\n {simulation.title}\n </Text>\n\n <div className=\"flex items-center gap-2\">\n <Badge\n variant=\"examsOutlined\"\n action={typeStyles.badge}\n size=\"medium\"\n >\n {typeStyles.text}\n </Badge>\n\n <Text size=\"sm\" className=\"text-text-800 truncate\">\n {simulation.info}\n </Text>\n </div>\n </div>\n\n <CaretRight\n size={24}\n className=\"text-text-800 flex-shrink-0\"\n data-testid=\"caret-icon\"\n />\n </div>\n </CardBase>\n );\n })}\n </div>\n </div>\n </div>\n ))}\n\n {/* Footer rounded */}\n {data.length > 0 && (\n <div className=\"w-full h-6 bg-background rounded-b-3xl\" />\n )}\n </div>\n </div>\n );\n});\n\nexport {\n CardBase,\n CardActivitiesResults,\n CardQuestions,\n CardProgress,\n CardTopic,\n CardPerformance,\n CardResults,\n CardStatus,\n CardSettings,\n CardSupport,\n CardForum,\n CardAudio,\n CardSimulado,\n CardTest,\n CardSimulationHistory,\n};\n","import { cloneElement, ComponentType, JSX, ReactElement } from 'react';\nimport * as PhosphorIcons from 'phosphor-react';\nimport { ChatPT } from '../../assets/icons/subjects/ChatPT';\nimport { ChatEN } from '../../assets/icons/subjects/ChatEN';\nimport { ChatES } from '../../assets/icons/subjects/ChatES';\n\ntype PhosphorIconName = keyof typeof PhosphorIcons;\ntype PhosphorIconComponent = ComponentType<{\n size?: number;\n color?: string;\n weight?: 'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone';\n}>;\n\nexport interface IconRenderProps {\n /**\n * The name of the icon to render\n */\n iconName: string | ReactElement;\n /**\n * The color of the icon\n * @default '#000000'\n */\n color?: string;\n /**\n * The size of the icon in pixels\n * @default 24\n */\n size?: number;\n /**\n * The weight/style of the icon (for Phosphor icons)\n * @default 'regular'\n */\n weight?: 'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone';\n}\n\n/**\n * Dynamic icon component that renders icons based on name\n * Supports Phosphor icons and custom Chat icons (ChatPT, ChatEN, ChatES)\n *\n * @param iconName - The name of the icon to render\n * @param color - The color of the icon\n * @param size - The size of the icon in pixels\n * @param weight - The weight/style of the icon (for Phosphor icons)\n * @returns JSX element with the corresponding icon\n */\nexport const IconRender = ({\n iconName,\n color = '#000000',\n size = 24,\n weight = 'regular',\n}: IconRenderProps): JSX.Element => {\n if (typeof iconName === 'string') {\n switch (iconName) {\n case 'Chat_PT':\n return <ChatPT size={size} color={color} />;\n case 'Chat_EN':\n return <ChatEN size={size} color={color} />;\n case 'Chat_ES':\n return <ChatES size={size} color={color} />;\n default: {\n const IconComponent = (PhosphorIcons[iconName as PhosphorIconName] ||\n PhosphorIcons.Question) as PhosphorIconComponent;\n\n return <IconComponent size={size} color={color} weight={weight} />;\n }\n }\n } else {\n // Clone the ReactElement with icon props, casting to avoid TypeScript errors\n return cloneElement(iconName, {\n size,\n color: 'currentColor',\n } as Partial<{\n size: number;\n color: string;\n }>);\n }\n};\n\nexport default IconRender;\n","export const ChatPT = ({ size, color }: { size: number; color: string }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z\"\n fill={color}\n />\n <path\n d=\"M21.1758 12V20.5312H19.7168V12H21.1758ZM23.8535 12V13.1719H17.0625V12H23.8535Z\"\n fill={color}\n />\n <path\n d=\"M13.2402 17.3496H11.0195V16.1836H13.2402C13.627 16.1836 13.9395 16.1211 14.1777 15.9961C14.416 15.8711 14.5898 15.6992 14.6992 15.4805C14.8125 15.2578 14.8691 15.0039 14.8691 14.7188C14.8691 14.4492 14.8125 14.1973 14.6992 13.9629C14.5898 13.7246 14.416 13.5332 14.1777 13.3887C13.9395 13.2441 13.627 13.1719 13.2402 13.1719H11.4707V20.5312H10V12H13.2402C13.9004 12 14.4609 12.1172 14.9219 12.3516C15.3867 12.582 15.7402 12.9023 15.9824 13.3125C16.2246 13.7188 16.3457 14.1836 16.3457 14.707C16.3457 15.2578 16.2246 15.7305 15.9824 16.125C15.7402 16.5195 15.3867 16.8223 14.9219 17.0332C14.4609 17.2441 13.9004 17.3496 13.2402 17.3496Z\"\n fill={color}\n />\n </svg>\n);\n","export const ChatEN = ({ size, color }: { size: number; color: string }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z\"\n fill={color}\n />\n <path\n d=\"M22.5488 12V20.5312H21.0781L17.252 14.4199V20.5312H15.7812V12H17.252L21.0898 18.123V12H22.5488Z\"\n fill={color}\n />\n <path\n d=\"M14.584 19.3652V20.5312H10.0547V19.3652H14.584ZM10.4707 12V20.5312H9V12H10.4707ZM13.9922 15.5625V16.7109H10.0547V15.5625H13.9922ZM14.5547 12V13.1719H10.0547V12H14.5547Z\"\n fill={color}\n />\n </svg>\n);\n","export const ChatES = ({ size, color }: { size: number; color: string }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M27 6H5.00004C4.4696 6 3.9609 6.21071 3.58582 6.58579C3.21075 6.96086 3.00004 7.46957 3.00004 8V28C2.99773 28.3814 3.10562 28.7553 3.31074 29.0768C3.51585 29.3984 3.80947 29.6538 4.15629 29.8125C4.42057 29.9356 4.7085 29.9995 5.00004 30C5.46954 29.9989 5.92347 29.8315 6.28129 29.5275L6.29254 29.5187L10.375 26H27C27.5305 26 28.0392 25.7893 28.4142 25.4142C28.7893 25.0391 29 24.5304 29 24V8C29 7.46957 28.7893 6.96086 28.4142 6.58579C28.0392 6.21071 27.5305 6 27 6ZM27 24H10C9.75992 24.0001 9.52787 24.0866 9.34629 24.2437L5.00004 28V8H27V24Z\"\n fill={color}\n />\n <path\n d=\"M21.1426 17.8027C21.1426 17.627 21.1152 17.4707 21.0605 17.334C21.0098 17.1973 20.918 17.0723 20.7852 16.959C20.6523 16.8457 20.4648 16.7363 20.2227 16.6309C19.9844 16.5215 19.6797 16.4102 19.3086 16.2969C18.9023 16.1719 18.5273 16.0332 18.1836 15.8809C17.8438 15.7246 17.5469 15.5449 17.293 15.3418C17.0391 15.1348 16.8418 14.8984 16.7012 14.6328C16.5605 14.3633 16.4902 14.0527 16.4902 13.7012C16.4902 13.3535 16.5625 13.0371 16.707 12.752C16.8555 12.4668 17.0645 12.2207 17.334 12.0137C17.6074 11.8027 17.9297 11.6406 18.3008 11.5273C18.6719 11.4102 19.082 11.3516 19.5312 11.3516C20.1641 11.3516 20.709 11.4688 21.166 11.7031C21.627 11.9375 21.9805 12.252 22.2266 12.6465C22.4766 13.041 22.6016 13.4766 22.6016 13.9531H21.1426C21.1426 13.6719 21.082 13.4238 20.9609 13.209C20.8438 12.9902 20.6641 12.8184 20.4219 12.6934C20.1836 12.5684 19.8809 12.5059 19.5137 12.5059C19.166 12.5059 18.877 12.5586 18.6465 12.6641C18.416 12.7695 18.2441 12.9121 18.1309 13.0918C18.0176 13.2715 17.9609 13.4746 17.9609 13.7012C17.9609 13.8613 17.998 14.0078 18.0723 14.1406C18.1465 14.2695 18.2598 14.3906 18.4121 14.5039C18.5645 14.6133 18.7559 14.7168 18.9863 14.8145C19.2168 14.9121 19.4883 15.0059 19.8008 15.0957C20.2734 15.2363 20.6855 15.3926 21.0371 15.5645C21.3887 15.7324 21.6816 15.9238 21.916 16.1387C22.1504 16.3535 22.3262 16.5977 22.4434 16.8711C22.5605 17.1406 22.6191 17.4473 22.6191 17.791C22.6191 18.1504 22.5469 18.4746 22.4023 18.7637C22.2578 19.0488 22.0508 19.293 21.7812 19.4961C21.5156 19.6953 21.1953 19.8496 20.8203 19.959C20.4492 20.0645 20.0352 20.1172 19.5781 20.1172C19.168 20.1172 18.7637 20.0625 18.3652 19.9531C17.9707 19.8438 17.6113 19.6777 17.2871 19.4551C16.9629 19.2285 16.7051 18.9473 16.5137 18.6113C16.3223 18.2715 16.2266 17.875 16.2266 17.4219H17.6973C17.6973 17.6992 17.7441 17.9355 17.8379 18.1309C17.9355 18.3262 18.0703 18.4863 18.2422 18.6113C18.4141 18.7324 18.6133 18.8223 18.8398 18.8809C19.0703 18.9395 19.3164 18.9688 19.5781 18.9688C19.9219 18.9688 20.209 18.9199 20.4395 18.8223C20.6738 18.7246 20.8496 18.5879 20.9668 18.4121C21.084 18.2363 21.1426 18.0332 21.1426 17.8027Z\"\n fill={color}\n />\n <path\n d=\"M15.4512 18.834V20H10.9219V18.834H15.4512ZM11.3379 11.4688V20H9.86719V11.4688H11.3379ZM14.8594 15.0312V16.1797H10.9219V15.0312H14.8594ZM15.4219 11.4688V12.6406H10.9219V11.4688H15.4219Z\"\n fill={color}\n />\n </svg>\n);\n","import {\n Children,\n cloneElement,\n forwardRef,\n HTMLAttributes,\n isValidElement,\n ReactElement,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { create, StoreApi } from 'zustand';\nimport { CardAccordationProps } from './Accordation';\n\ninterface AccordionGroupStore {\n type: 'single' | 'multiple';\n value: string | string[];\n collapsible: boolean;\n setValue: (value: string | string[]) => void;\n isItemExpanded: (itemValue: string) => boolean;\n}\n\ntype AccordionGroupStoreApi = StoreApi<AccordionGroupStore>;\n\nfunction createAccordionGroupStore(\n type: 'single' | 'multiple',\n initialValue: string | string[],\n collapsible: boolean\n): AccordionGroupStoreApi {\n return create<AccordionGroupStore>((set, get) => ({\n type,\n value: initialValue,\n collapsible,\n setValue: (value) => set({ value }),\n isItemExpanded: (itemValue: string): boolean => {\n const state = get();\n if (state.type === 'single') {\n return state.value === itemValue;\n } else {\n return Array.isArray(state.value) && state.value.includes(itemValue);\n }\n },\n }));\n}\n\ninterface AccordionGroupProps extends HTMLAttributes<HTMLDivElement> {\n type?: 'single' | 'multiple';\n defaultValue?: string | string[];\n value?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n collapsible?: boolean;\n children: ReactNode;\n}\n\n// Helper function to inject store only to CardAccordation components\nconst injectStore = (\n children: ReactNode,\n store: AccordionGroupStoreApi,\n indexRef: { current: number },\n onItemToggle: (itemValue: string, isExpanded: boolean) => void\n): ReactNode => {\n return Children.map(children, (child) => {\n if (!isValidElement(child)) {\n return child;\n }\n\n const typedChild = child as ReactElement<\n CardAccordationProps & {\n children?: ReactNode;\n }\n >;\n\n // Check if it's a CardAccordation component\n const displayName = (typedChild.type as unknown as { displayName?: string })\n ?.displayName;\n\n let newProps: Partial<{\n children: ReactNode;\n value: string;\n expanded: boolean;\n onToggleExpanded: (isExpanded: boolean) => void;\n }> = {};\n\n if (displayName === 'CardAccordation') {\n // Generate value if not provided\n const itemValue =\n typedChild.props.value || `accordion-item-${indexRef.current++}`;\n\n // Get expanded state from store\n const storeState = store.getState();\n const expanded = storeState.isItemExpanded(itemValue);\n\n newProps.value = itemValue;\n newProps.expanded = expanded;\n newProps.onToggleExpanded = (isExpanded: boolean) => {\n onItemToggle(itemValue, isExpanded);\n typedChild.props.onToggleExpanded?.(isExpanded);\n };\n }\n\n // Recursively process children\n if (typedChild.props.children) {\n const processedChildren = injectStore(\n typedChild.props.children,\n store,\n indexRef,\n onItemToggle\n );\n\n // If it's a CardAccordation, add children to newProps\n if (displayName === 'CardAccordation') {\n newProps.children = processedChildren;\n } else if (processedChildren !== typedChild.props.children) {\n // For other elements, only clone if children changed\n return cloneElement(typedChild, { children: processedChildren });\n }\n }\n\n // Only clone if we have props to inject (only for CardAccordation)\n if (Object.keys(newProps).length > 0) {\n return cloneElement(typedChild, newProps);\n }\n\n return child;\n });\n};\n\nconst AccordionGroup = forwardRef<HTMLDivElement, AccordionGroupProps>(\n (\n {\n type = 'single',\n defaultValue,\n value: controlledValue,\n onValueChange,\n collapsible = true,\n children,\n className,\n ...props\n },\n ref\n ) => {\n const [internalValue, setInternalValue] = useState<string | string[]>(\n defaultValue || (type === 'single' ? '' : [])\n );\n\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n // Create store only once using useRef\n const storeRef = useRef<AccordionGroupStoreApi | null>(null);\n if (storeRef.current) {\n // Update store configuration when props change\n storeRef.current.setState((prev) => {\n const nextState: Partial<AccordionGroupStore> = {};\n if (prev.type !== type) {\n nextState.type = type;\n }\n if (prev.collapsible !== collapsible) {\n nextState.collapsible = collapsible;\n }\n return nextState;\n });\n } else {\n // Create store on first render\n storeRef.current = createAccordionGroupStore(\n type,\n currentValue,\n collapsible\n );\n }\n const store = storeRef.current;\n\n // Sync store value when currentValue changes\n useEffect(() => {\n store.setState({ value: currentValue });\n }, [currentValue, store]);\n\n // Normalize internal value when type changes (uncontrolled mode)\n useEffect(() => {\n if (!isControlled) {\n setInternalValue((prev) => {\n if (type === 'single') {\n if (Array.isArray(prev)) {\n return prev[0] ?? '';\n }\n return typeof prev === 'string' ? prev : '';\n }\n if (Array.isArray(prev)) {\n return prev;\n }\n return prev ? [prev] : [];\n });\n }\n }, [isControlled, type]);\n\n const handleItemToggle = (itemValue: string, isExpanded: boolean) => {\n const storeState = store.getState();\n let newValue: string | string[];\n\n if (type === 'single') {\n // Single mode: only one item can be open at a time\n if (isExpanded) {\n newValue = itemValue;\n } else {\n // If collapsible, allow closing the current item\n newValue = collapsible ? '' : (storeState.value as string);\n }\n } else {\n // Multiple mode: multiple items can be open\n const currentArray = Array.isArray(storeState.value)\n ? storeState.value\n : [];\n\n if (isExpanded) {\n newValue = [...currentArray, itemValue];\n } else {\n newValue = currentArray.filter((v) => v !== itemValue);\n }\n }\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n store.setState({ value: newValue });\n onValueChange?.(newValue);\n };\n\n // Use ref to track index across recursive calls\n const indexRef = { current: 0 };\n const enhancedChildren = injectStore(\n children,\n store,\n indexRef,\n handleItemToggle\n );\n\n return (\n <div ref={ref} className={className} {...props}>\n {enhancedChildren}\n </div>\n );\n }\n);\n\nAccordionGroup.displayName = 'AccordionGroup';\n\nexport { AccordionGroup };\n","import React, { useRef } from 'react';\nimport { Paperclip, FileText, X } from 'phosphor-react';\nimport Button from '../Button/Button';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\n\n/**\n * Represents an attached file with unique identifier\n */\nexport interface AttachedFile {\n /** The file object */\n file: File;\n /** Unique identifier for the file */\n id: string;\n}\n\n/**\n * Props for the FileAttachment component\n */\nexport interface FileAttachmentProps {\n /** List of attached files */\n files: AttachedFile[];\n /** Callback when files are added */\n onFilesAdd: (files: File[]) => void;\n /** Callback when a file is removed */\n onFileRemove: (id: string) => void;\n /** Whether the files are read-only (no removal allowed) */\n readOnly?: boolean;\n /** Text for the attach button */\n buttonLabel?: string;\n /** Whether to accept multiple files */\n multiple?: boolean;\n /** Additional CSS class */\n className?: string;\n /** Whether to hide the attach button */\n hideButton?: boolean;\n}\n\n/**\n * Formats file size to human-readable string\n * @param bytes - File size in bytes\n * @returns Formatted string (e.g., \"1.5 MB\")\n */\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n};\n\n/**\n * Generates a unique ID for file tracking\n * @returns Unique string identifier\n */\nconst generateFileId = (): string => {\n return crypto.randomUUID();\n};\n\n/**\n * Reusable file attachment component\n *\n * Allows users to attach multiple files with preview and removal functionality.\n * No file size or type restrictions are applied on the client side.\n *\n * @param props - Component props\n * @returns JSX element\n *\n * @example\n * ```tsx\n * const [files, setFiles] = useState<AttachedFile[]>([]);\n *\n * <FileAttachment\n * files={files}\n * onFilesAdd={(newFiles) => {\n * const attachedFiles = newFiles.map(file => ({\n * file,\n * id: generateFileId()\n * }));\n * setFiles(prev => [...prev, ...attachedFiles]);\n * }}\n * onFileRemove={(id) => setFiles(prev => prev.filter(f => f.id !== id))}\n * multiple\n * />\n * ```\n */\nconst FileAttachment = ({\n files,\n onFilesAdd,\n onFileRemove,\n readOnly = false,\n buttonLabel = 'Anexar',\n multiple = true,\n className,\n hideButton = false,\n}: FileAttachmentProps) => {\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n /**\n * Handle file input change\n * @param event - Input change event\n */\n const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const selectedFiles = event.target.files;\n if (selectedFiles && selectedFiles.length > 0) {\n const filesArray: File[] = Array.from(selectedFiles);\n onFilesAdd(filesArray);\n }\n // Reset input to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n /**\n * Trigger file input click\n */\n const handleAttachClick = () => {\n fileInputRef.current?.click();\n };\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {/* Hidden file input */}\n <input\n type=\"file\"\n ref={fileInputRef}\n className=\"hidden\"\n onChange={handleFileChange}\n multiple={multiple}\n aria-label=\"Selecionar arquivos\"\n />\n\n {/* Attach button */}\n {!readOnly && !hideButton && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={handleAttachClick}\n className=\"self-start flex items-center gap-2\"\n >\n <Paperclip size={16} />\n {buttonLabel}\n </Button>\n )}\n\n {/* Attached files list */}\n {files.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {files.map((attachedFile) => (\n <div\n key={attachedFile.id}\n className=\"flex items-center gap-2 bg-background-50 px-3 py-2 rounded-lg border border-border-100\"\n >\n <FileText size={16} className=\"text-text-500 shrink-0\" />\n <Text className=\"text-sm text-text-700 truncate max-w-[200px]\">\n {attachedFile.file.name}\n </Text>\n <Text className=\"text-xs text-text-400 shrink-0\">\n {formatFileSize(attachedFile.file.size)}\n </Text>\n {!readOnly && (\n <button\n type=\"button\"\n onClick={() => onFileRemove(attachedFile.id)}\n className=\"text-text-400 hover:text-error-500 transition-colors shrink-0\"\n aria-label={`Remover ${attachedFile.file.name}`}\n >\n <X size={14} />\n </button>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n\nexport { generateFileId, formatFileSize };\nexport default FileAttachment;\n","/**\n * Question status enum for student activity correction\n * Maps from ANSWER_STATUS to a simpler status for UI display\n */\nexport const QUESTION_STATUS = {\n CORRETA: 'CORRETA',\n INCORRETA: 'INCORRETA',\n EM_BRANCO: 'EM_BRANCO',\n /** Reserved for future use - pending teacher evaluation for essay questions */\n PENDENTE: 'PENDENTE',\n} as const;\n\nexport type QuestionStatus =\n (typeof QUESTION_STATUS)[keyof typeof QUESTION_STATUS];\n","import { StatusBadgeConfig } from '@/types/activityDetails';\nimport {\n ANSWER_STATUS,\n QUESTION_TYPE,\n} from '../../components/Quiz/useQuizStore';\nimport { QUESTION_STATUS, type QuestionStatus } from './constants';\nimport type { CorrectionQuestionData } from './types';\n\n/**\n * Returns whether the answer is correct, incorrect, or null based on the answer status.\n * @param answerStatus - Answer status from ANSWER_STATUS enum\n * @returns Returns true for correct, false for incorrect, or null if undefined.\n */\nexport const getIsCorrect = (answerStatus: ANSWER_STATUS): boolean | null => {\n if (answerStatus === ANSWER_STATUS.RESPOSTA_CORRETA) return true;\n if (answerStatus === ANSWER_STATUS.RESPOSTA_INCORRETA) return false;\n return null;\n};\n\n/**\n * Map ANSWER_STATUS from Quiz to QUESTION_STATUS for correction modal\n * @param answerStatus - Answer status from QuestionResult\n * @returns QuestionStatus for UI display\n */\nexport const mapAnswerStatusToQuestionStatus = (\n answerStatus: ANSWER_STATUS\n): QuestionStatus => {\n switch (answerStatus) {\n case ANSWER_STATUS.RESPOSTA_CORRETA:\n return QUESTION_STATUS.CORRETA;\n case ANSWER_STATUS.RESPOSTA_INCORRETA:\n return QUESTION_STATUS.INCORRETA;\n case ANSWER_STATUS.NAO_RESPONDIDO:\n return QUESTION_STATUS.EM_BRANCO;\n case ANSWER_STATUS.PENDENTE_AVALIACAO:\n return QUESTION_STATUS.PENDENTE;\n default:\n return QUESTION_STATUS.EM_BRANCO;\n }\n};\n\n/**\n * Get question status badge configuration\n * @param status - Question status\n * @returns Badge configuration with label and colors\n */\nexport const getQuestionStatusBadgeConfig = (status: QuestionStatus) => {\n const configs: Partial<Record<QuestionStatus, StatusBadgeConfig>> = {\n [QUESTION_STATUS.CORRETA]: {\n label: 'Correta',\n bgColor: 'bg-success-background',\n textColor: 'text-success-800',\n },\n [QUESTION_STATUS.INCORRETA]: {\n label: 'Incorreta',\n bgColor: 'bg-error-background',\n textColor: 'text-error-800',\n },\n [QUESTION_STATUS.EM_BRANCO]: {\n label: 'Em branco',\n bgColor: 'bg-gray-100',\n textColor: 'text-gray-600',\n },\n [QUESTION_STATUS.PENDENTE]: {\n label: 'Pendente',\n bgColor: 'bg-warning-background',\n textColor: 'text-warning-800',\n },\n };\n\n const defaultConfig = {\n label: 'Sem categoria',\n bgColor: 'bg-gray-100',\n textColor: 'text-gray-600',\n };\n\n return configs[status] ?? defaultConfig;\n};\n\n/**\n * Check if question can be auto-validated based on options\n * All question types can be auto-validated except DISSERTATIVA (essay questions)\n * @param questionData - Correction question data\n * @returns true if can auto-validate, false otherwise\n */\nexport const canAutoValidate = (\n questionData: CorrectionQuestionData\n): boolean => {\n const { result } = questionData;\n\n // Only dissertative questions require manual evaluation\n if (result.questionType === QUESTION_TYPE.DISSERTATIVA) {\n return false;\n }\n\n return true;\n};\n\ntype Option = {\n id: string;\n option: string;\n isCorrect: boolean;\n};\n\n/**\n * Type predicate to check if an option has isCorrect defined\n */\nconst hasIsCorrect = (op: {\n id: string;\n option: string;\n isCorrect?: boolean | null;\n}): op is Option => {\n return op.isCorrect != null;\n};\n\n/**\n * Validate alternativa (single choice) question\n * Must select exactly one correct option\n */\nconst validateAlternativa = (\n selected: Set<string>,\n options: Option[]\n): ANSWER_STATUS => {\n if (selected.size !== 1) return ANSWER_STATUS.RESPOSTA_INCORRETA;\n\n const [selectedId] = selected;\n return options.find((o) => o.id === selectedId)?.isCorrect\n ? ANSWER_STATUS.RESPOSTA_CORRETA\n : ANSWER_STATUS.RESPOSTA_INCORRETA;\n};\n\n/**\n * Validate multipla escolha (multiple choice) question\n * Each option must match its correct state: selected if correct, not selected if incorrect\n */\nconst validateMultiplaEscolha = (\n selected: Set<string>,\n options: Option[]\n): ANSWER_STATUS => {\n const allMatch = options.every((op) => selected.has(op.id) === op.isCorrect);\n\n return allMatch\n ? ANSWER_STATUS.RESPOSTA_CORRETA\n : ANSWER_STATUS.RESPOSTA_INCORRETA;\n};\n\n/**\n * Validate verdadeiro/falso (true/false) question\n * Each statement is evaluated individually: if statement is true, must be selected;\n * if statement is false, must not be selected\n */\nconst validateVerdadeiroFalso = validateMultiplaEscolha;\n\nconst validators: Partial<\n Record<QUESTION_TYPE, (s: Set<string>, o: Option[]) => ANSWER_STATUS>\n> = {\n [QUESTION_TYPE.ALTERNATIVA]: validateAlternativa,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: validateMultiplaEscolha,\n [QUESTION_TYPE.VERDADEIRO_FALSO]: validateVerdadeiroFalso,\n};\n\n/**\n * Auto-validate question based on selected options vs correct options\n * @param questionData - Correction question data\n * @returns ANSWER_STATUS if can determine, null otherwise\n */\nexport const autoValidateQuestion = (\n questionData: CorrectionQuestionData\n): ANSWER_STATUS | null => {\n const { result } = questionData;\n\n if (!canAutoValidate(questionData) || !result.options) return null;\n\n // Filter options to only include those with isCorrect defined\n const validOptions = result.options.filter(hasIsCorrect);\n if (validOptions.length === 0) return null;\n\n const selected = new Set(\n result.selectedOptions?.map((o) => o.optionId) ?? []\n );\n\n if (selected.size === 0) return ANSWER_STATUS.NAO_RESPONDIDO;\n\n const validator = validators[result.questionType];\n if (!validator) return null;\n\n return validator(selected, validOptions);\n};\n\n/**\n * Get question status from CorrectionQuestionData\n * Maps the result's answerStatus to QuestionStatus\n * If status is PENDENTE_AVALIACAO but can auto-validate, calculates status automatically\n * @param questionData - Correction question data\n * @returns QuestionStatus for UI display\n */\nexport const getQuestionStatusFromData = (\n questionData: CorrectionQuestionData\n): QuestionStatus => {\n const { result } = questionData;\n\n // If pending evaluation, try to auto-validate\n if (\n result.answerStatus === ANSWER_STATUS.PENDENTE_AVALIACAO &&\n canAutoValidate(questionData)\n ) {\n const autoValidatedStatus = autoValidateQuestion(questionData);\n if (autoValidatedStatus !== null) {\n return mapAnswerStatusToQuestionStatus(autoValidatedStatus);\n }\n }\n\n return mapAnswerStatusToQuestionStatus(result.answerStatus);\n};\n","import type { Question } from '../../components/Quiz/useQuizStore';\nimport { QUESTION_TYPE } from '../../components/Quiz/useQuizStore';\nimport type {\n QuestionsAnswersByStudentResponse,\n StudentActivityCorrectionData,\n CorrectionQuestionData,\n EssayQuestionCorrection,\n} from './types';\nimport { getIsCorrect } from './utils';\n\n/**\n * Build Question object from answer data\n * @param answer - Answer data from QuestionResult\n * @returns Question object in Quiz format\n */\nconst buildQuestionFromAnswer = (\n answer: QuestionsAnswersByStudentResponse['data']['answers'][number]\n): Question => {\n return {\n id: answer.questionId,\n statement: answer.statement,\n questionType: answer.questionType,\n difficultyLevel: answer.difficultyLevel,\n description: '',\n examBoard: null,\n examYear: null,\n solutionExplanation: answer.solutionExplanation || null,\n answer: null,\n answerStatus: answer.answerStatus,\n options: answer.options || [],\n knowledgeMatrix: answer.knowledgeMatrix.map((matrix) => ({\n areaKnowledge: matrix.areaKnowledge || {\n id: '',\n name: '',\n },\n subject: matrix.subject || {\n id: '',\n name: '',\n color: '',\n icon: '',\n },\n topic: matrix.topic || {\n id: '',\n name: '',\n },\n subtopic: matrix.subtopic || {\n id: '',\n name: '',\n },\n content: matrix.content || {\n id: '',\n name: '',\n },\n })),\n correctOptionIds:\n answer.options?.filter((opt) => opt.isCorrect).map((opt) => opt.id) || [],\n };\n};\n\n/**\n * Build correction data for essay questions\n * @param answer - Answer data from QuestionResult\n * @returns EssayQuestionCorrection if question is DISSERTATIVA, undefined otherwise\n */\nconst buildEssayCorrection = (\n answer: QuestionsAnswersByStudentResponse['data']['answers'][number]\n): EssayQuestionCorrection | undefined => {\n if (answer.questionType === QUESTION_TYPE.DISSERTATIVA) {\n return {\n isCorrect: getIsCorrect(answer.answerStatus),\n teacherFeedback: answer.teacherFeedback || '',\n };\n }\n return undefined;\n};\n\n/**\n * Convert a single answer to CorrectionQuestionData format\n * @param answer - Answer data from QuestionResult\n * @param index - Index of the answer (0-based)\n * @returns CorrectionQuestionData formatted for the modal\n */\nconst convertAnswerToQuestionData = (\n answer: QuestionsAnswersByStudentResponse['data']['answers'][number],\n index: number\n): CorrectionQuestionData => {\n const question = buildQuestionFromAnswer(answer);\n const correction = buildEssayCorrection(answer);\n\n return {\n question,\n result: answer,\n questionNumber: index + 1,\n correction,\n };\n};\n\n/**\n * Convert QuestionResult from API to StudentActivityCorrectionData\n * This function transforms the API response into the format expected by CorrectActivityModal\n * @param apiResponse - API response with answers and statistics\n * @param studentId - Student ID\n * @param studentName - Student name\n * @param observation - Optional teacher observation\n * @param attachment - Optional attachment URL\n * @returns StudentActivityCorrectionData formatted for the modal\n */\nexport const convertApiResponseToCorrectionData = (\n apiResponse: QuestionsAnswersByStudentResponse,\n studentId: string,\n studentName: string,\n observation?: string,\n attachment?: string\n): StudentActivityCorrectionData => {\n const { answers, statistics } = apiResponse.data;\n\n // Calculate counts from statistics\n const correctCount = statistics.correctAnswers;\n const incorrectCount = statistics.incorrectAnswers;\n const blankCount = statistics.totalAnswered - correctCount - incorrectCount;\n\n // Convert answers to CorrectionQuestionData format\n const questions: CorrectionQuestionData[] = answers.map((answer, index) =>\n convertAnswerToQuestionData(answer, index)\n );\n\n return {\n studentId,\n studentName,\n score: statistics.score ?? null,\n correctCount,\n incorrectCount,\n blankCount,\n questions,\n observation,\n attachment,\n };\n};\n","import { CheckCircle, XCircle } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\nimport { RadioGroup, RadioGroupItem } from '../Radio/Radio';\nimport { forwardRef, HTMLAttributes, useId, useState } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Interface para definir uma alternativa\n */\nexport interface Alternative {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n description?: string;\n}\n\n/**\n * Props do componente AlternativesList\n */\nexport interface AlternativesListProps {\n /** Lista de alternativas */\n alternatives: Alternative[];\n /** Nome do grupo de radio */\n name?: string;\n /** Valor selecionado por padrão */\n defaultValue?: string;\n /** Valor controlado */\n value?: string;\n /** Callback quando uma alternativa é selecionada */\n onValueChange?: (value: string) => void;\n /** Se o componente está desabilitado */\n disabled?: boolean;\n /** Layout das alternativas */\n layout?: 'default' | 'compact' | 'detailed';\n /** Classes CSS adicionais */\n className?: string;\n /** Modo de exibição: interativo (com radios funcionais) ou readonly (apenas visual) */\n mode?: 'interactive' | 'readonly';\n /** Valor selecionado pelo usuário (apenas para modo readonly) */\n selectedValue?: string;\n}\n\n/**\n * Componente reutilizável para exibir lista de alternativas com RadioGroup\n *\n * Suporta dois modos:\n * - `interactive`: Permite interação com radios (padrão)\n * - `readonly`: Apenas exibição visual dos estados\n *\n * @example\n * ```tsx\n * // Modo interativo (padrão)\n * <AlternativesList\n * mode=\"interactive\"\n * alternatives={[\n * { value: \"a\", label: \"Alternativa A\", status: \"correct\" },\n * { value: \"b\", label: \"Alternativa B\", status: \"incorrect\" },\n * { value: \"c\", label: \"Alternativa C\" }\n * ]}\n * defaultValue=\"a\"\n * onValueChange={(value) => console.log(value)}\n * />\n *\n * // Modo readonly - mostra seleção do usuário\n * <AlternativesList\n * mode=\"readonly\"\n * selectedValue=\"b\" // O que o usuário selecionou\n * alternatives={[\n * { value: \"a\", label: \"Resposta A\", status: \"correct\" }, // Mostra como correta\n * { value: \"b\", label: \"Resposta B\" }, // Mostra radio selecionado + badge incorreto\n * { value: \"c\", label: \"Resposta C\" }\n * ]}\n * />\n * ```\n */\nconst AlternativesList = ({\n alternatives,\n name,\n defaultValue,\n value,\n onValueChange,\n disabled = false,\n layout = 'default',\n className = '',\n mode = 'interactive',\n selectedValue,\n}: AlternativesListProps) => {\n // Gerar um ID único para garantir que cada instância tenha seu próprio grupo\n const uniqueId = useId();\n const groupName = name || `alternatives-${uniqueId}`;\n const [actualValue, setActualValue] = useState(value);\n // No modo readonly, não precisamos de interação\n const isReadonly = mode === 'readonly';\n const getStatusStyles = (\n status?: Alternative['status'],\n isReadonly?: boolean\n ) => {\n const hoverClass = isReadonly ? '' : 'hover:bg-background-50';\n\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100 ${hoverClass}`;\n }\n };\n\n const getStatusBadge = (status?: Alternative['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getLayoutClasses = () => {\n switch (layout) {\n case 'compact':\n return 'gap-2';\n case 'detailed':\n return 'gap-4';\n default:\n return 'gap-3.5';\n }\n };\n\n // Componente para renderizar alternativa no modo readonly\n const renderReadonlyAlternative = (alternative: Alternative) => {\n const alternativeId = alternative.value;\n const isUserSelected = selectedValue === alternative.value;\n const isCorrectAnswer = alternative.status === 'correct';\n\n // Determinar o status da alternativa para visualização\n let displayStatus: Alternative['status'] = undefined;\n if (isUserSelected && !isCorrectAnswer) {\n // Usuário selecionou alternativa incorreta\n displayStatus = 'incorrect';\n } else if (isCorrectAnswer) {\n // Alternativa correta (independente se foi selecionada ou não)\n displayStatus = 'correct';\n }\n\n const statusStyles = getStatusStyles(displayStatus, true);\n const statusBadge = getStatusBadge(displayStatus);\n\n // Radio visual - apenas mostra selecionado se o usuário escolheu esta alternativa\n const renderRadio = () => {\n const radioClasses = `w-6 h-6 rounded-full border-2 cursor-default transition-all duration-200 flex items-center justify-center ${\n isUserSelected\n ? 'border-primary-950 bg-background'\n : 'border-border-400 bg-background'\n }`;\n\n const dotClasses =\n 'w-3 h-3 rounded-full bg-primary-950 transition-all duration-200';\n\n return (\n <div className={radioClasses}>\n {isUserSelected && <div className={dotClasses} />}\n </div>\n );\n };\n\n if (layout === 'detailed') {\n return (\n <div\n key={alternativeId}\n className={cn(\n 'border-2 rounded-lg p-4 w-full',\n statusStyles,\n alternative.disabled ? 'opacity-50' : ''\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1\">\n <div className=\"mt-1\">{renderRadio()}</div>\n <div className=\"flex-1\">\n <p\n className={cn(\n 'block font-medium',\n selectedValue === alternative.value || statusBadge\n ? 'text-text-950'\n : 'text-text-600'\n )}\n >\n {alternative.label}\n </p>\n {alternative.description && (\n <p className=\"text-sm text-text-600 mt-1\">\n {alternative.description}\n </p>\n )}\n </div>\n </div>\n {statusBadge && <div className=\"flex-shrink-0\">{statusBadge}</div>}\n </div>\n </div>\n );\n }\n\n return (\n <div\n key={alternativeId}\n className={cn(\n 'flex flex-row justify-between items-start gap-2 p-2 rounded-lg w-full',\n statusStyles,\n alternative.disabled ? 'opacity-50' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderRadio()}\n <span\n className={cn(\n 'flex-1',\n selectedValue === alternative.value || statusBadge\n ? 'text-text-950'\n : 'text-text-600'\n )}\n >\n {alternative.label}\n </span>\n </div>\n {statusBadge && <div className=\"flex-shrink-0\">{statusBadge}</div>}\n </div>\n );\n };\n\n // Se for modo readonly, renderizar sem RadioGroup\n if (isReadonly) {\n return (\n <div\n className={cn('flex flex-col', getLayoutClasses(), 'w-full', className)}\n >\n {alternatives.map((alternative) =>\n renderReadonlyAlternative(alternative)\n )}\n </div>\n );\n }\n\n return (\n <RadioGroup\n name={groupName}\n defaultValue={defaultValue}\n value={value}\n onValueChange={(value) => {\n setActualValue(value);\n onValueChange?.(value);\n }}\n disabled={disabled}\n className={cn('flex flex-col', getLayoutClasses(), className)}\n >\n {alternatives.map((alternative, index) => {\n const alternativeId = alternative.value || `alt-${index}`;\n const statusStyles = getStatusStyles(alternative.status, false);\n const statusBadge = getStatusBadge(alternative.status);\n\n if (layout === 'detailed') {\n return (\n <div\n key={alternativeId}\n className={cn(\n 'border-2 rounded-lg p-4 transition-all',\n statusStyles,\n alternative.disabled\n ? 'opacity-50 cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3 flex-1\">\n <RadioGroupItem\n value={alternative.value}\n id={alternativeId}\n disabled={alternative.disabled}\n className=\"mt-1\"\n />\n <div className=\"flex-1\">\n <label\n htmlFor={alternativeId}\n className={cn(\n 'block font-medium',\n actualValue === alternative.value\n ? 'text-text-950'\n : 'text-text-600',\n alternative.disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {alternative.label}\n </label>\n {alternative.description && (\n <p className=\"text-sm text-text-600 mt-1\">\n {alternative.description}\n </p>\n )}\n </div>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div\n key={alternativeId}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n alternative.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n <RadioGroupItem\n value={alternative.value}\n id={alternativeId}\n disabled={alternative.disabled}\n />\n <label\n htmlFor={alternativeId}\n className={cn(\n 'flex-1',\n actualValue === alternative.value\n ? 'text-text-950'\n : 'text-text-600',\n alternative.disabled ? 'cursor-not-allowed' : 'cursor-pointer'\n )}\n >\n {alternative.label}\n </label>\n </div>\n {statusBadge && <div className=\"flex-shrink-0\">{statusBadge}</div>}\n </div>\n );\n })}\n </RadioGroup>\n );\n};\n\ninterface HeaderAlternativeProps extends HTMLAttributes<HTMLDivElement> {\n title: string;\n subTitle: string;\n content: string;\n}\n\nconst HeaderAlternative = forwardRef<HTMLDivElement, HeaderAlternativeProps>(\n ({ className, title, subTitle, content, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'bg-background p-4 flex flex-col gap-4 rounded-xl',\n className\n )}\n {...props}\n >\n <span className=\"flex flex-col\">\n <p className=\"text-text-950 font-bold text-lg\">{title}</p>\n <p className=\"text-text-700 text-sm \">{subTitle}</p>\n </span>\n\n <p className=\"text-text-950 text-md\">{content}</p>\n </div>\n );\n }\n);\n\nexport { AlternativesList, HeaderAlternative };\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport { AlternativesList } from '../../../components/Alternative/Alternative';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\nimport { Status } from '../types';\n\n/**\n * Render alternative question (single choice)\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionAlternative = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n // Check if options have isCorrect defined (can auto-validate even if pending)\n const hasAutoValidation = result?.options?.some(\n (op) => op.isCorrect !== undefined && op.isCorrect !== null\n );\n\n const alternatives = question.options?.map((option) => {\n const isCorrectOption =\n result?.options?.find((op) => op.id === option.id)?.isCorrect || false;\n\n const isSelected =\n result?.selectedOptions?.some(\n (selectedOption) => selectedOption.optionId === option.id\n ) || false;\n\n // Show correct answers if not pending, OR if we can auto-validate (has isCorrect)\n const shouldShowCorrectAnswers =\n result?.answerStatus !== ANSWER_STATUS.PENDENTE_AVALIACAO ||\n hasAutoValidation;\n\n let status: Status;\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation and no auto-validation, show all options as neutral\n status = Status.NEUTRAL;\n }\n\n return {\n label: option.option,\n value: option.id,\n status: status,\n };\n });\n\n if (!alternatives || alternatives.length === 0) {\n return (\n <div>\n <Text size=\"sm\" weight=\"normal\">\n Não há Alternativas\n </Text>\n </div>\n );\n }\n\n return (\n <div className=\"pt-2\">\n <AlternativesList\n mode=\"readonly\"\n key={`question-${question.id}`}\n name={`question-${question.id}`}\n layout=\"compact\"\n alternatives={alternatives}\n selectedValue={result?.selectedOptions?.[0]?.optionId || ''}\n />\n </div>\n );\n};\n","import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '../../utils/utils';\nimport { CheckCircle, XCircle, Check } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\n\ninterface Choice {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = 'interactive',\n}: MultipleChoiceListProps) => {\n const [actualValue, setActualValue] = useState(selectedValues);\n\n useEffect(() => {\n setActualValue(selectedValues);\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n <div className={checkboxClasses}>\n {isSelected && <Check size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, choice.disabled || disabled)}\n <span\n className={cn(\n 'flex-1',\n isSelected || (choice.status && choice.status != 'neutral')\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-default'\n )}\n >\n {choice.label}\n </span>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className=\"flex flex-row gap-2 items-center\"\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {choice.label}\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport { MultipleChoiceList } from '../../../components/MultipleChoice/MultipleChoice';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\nimport { Status } from '../types';\n\n/**\n * Render multiple choice question\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionMultipleChoice = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n // Check if options have isCorrect defined (can auto-validate even if pending)\n const hasAutoValidation = result?.options?.some(\n (op) => op.isCorrect !== undefined && op.isCorrect !== null\n );\n\n const choices = question.options?.map((option) => {\n const isCorrectOption =\n result?.options?.find((op) => op.id === option.id)?.isCorrect || false;\n\n const isSelected = result?.selectedOptions?.some(\n (op) => op.optionId === option.id\n );\n\n // Show correct/incorrect status if not pending/blank, OR if we can auto-validate (has isCorrect)\n const shouldShowCorrectAnswers =\n (result?.answerStatus !== ANSWER_STATUS.PENDENTE_AVALIACAO &&\n result?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO) ||\n hasAutoValidation;\n\n let status: Status;\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation and no auto-validation, show all options as neutral\n status = Status.NEUTRAL;\n }\n\n return {\n label: option.option,\n value: option.id,\n status,\n };\n });\n\n if (!choices || choices.length === 0) {\n return (\n <div>\n <Text size=\"sm\" weight=\"normal\">\n Não há Escolhas Múltiplas\n </Text>\n </div>\n );\n }\n\n const selectedValues =\n result?.selectedOptions?.map((op) => op.optionId) || [];\n\n return (\n <div className=\"pt-2\">\n <MultipleChoiceList\n mode=\"readonly\"\n key={`question-${question.id}`}\n name={`question-${question.id}`}\n choices={choices}\n selectedValues={selectedValues}\n />\n </div>\n );\n};\n","import {\n forwardRef,\n MouseEvent,\n ReactNode,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { ANSWER_STATUS, useQuizStore } from './useQuizStore';\nimport { cn } from '../../utils/utils';\nimport Select, {\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../Select/Select';\nimport TextArea from '../TextArea/TextArea';\nimport { AlternativesList } from '../Alternative/Alternative';\nimport { MultipleChoiceList } from '../MultipleChoice/MultipleChoice';\nimport Badge from '../Badge/Badge';\nimport { CheckCircle, XCircle } from 'phosphor-react';\nimport ImageQuestion from '../../assets/img/mock-image-question.png';\n\nexport const getStatusBadge = (status?: 'correct' | 'incorrect') => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n};\n\nexport const getStatusStyles = (variantCorrect?: string) => {\n switch (variantCorrect) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return '';\n }\n};\n\nenum Status {\n CORRECT = 'correct',\n INCORRECT = 'incorrect',\n NEUTRAL = 'neutral',\n}\n\ninterface QuizVariantInterface {\n paddingBottom?: string;\n}\n\nconst QuizSubTitle = forwardRef<HTMLDivElement, { subTitle: string }>(\n ({ subTitle, ...props }, ref) => {\n return (\n <div className=\"px-4 pb-2 pt-6\" {...props} ref={ref}>\n <p className=\"font-bold text-lg text-text-950\">{subTitle}</p>\n </div>\n );\n }\n);\n\nconst QuizContainer = forwardRef<\n HTMLDivElement,\n { children: ReactNode; className?: string }\n>(({ children, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'bg-background rounded-t-xl px-4 pt-4 pb-[80px] h-auto flex flex-col gap-4 mb-auto',\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n});\n\nconst QuizAlternative = ({ paddingBottom }: QuizVariantInterface) => {\n const {\n getCurrentQuestion,\n selectAnswer,\n getQuestionResultByQuestionId,\n getCurrentAnswer,\n variant,\n } = useQuizStore();\n const currentQuestion = getCurrentQuestion();\n const currentQuestionResult = getQuestionResultByQuestionId(\n currentQuestion?.id || ''\n );\n\n const currentAnswer = getCurrentAnswer();\n const alternatives = currentQuestion?.options?.map((option) => {\n let status: Status = Status.NEUTRAL;\n if (variant === 'result') {\n const isCorrectOption =\n currentQuestionResult?.options?.find((op) => op.id === option.id)\n ?.isCorrect || false;\n\n const isSelected = currentQuestionResult?.selectedOptions.some(\n (selectedOption) => selectedOption.optionId === option.id\n );\n\n // Only show correct/incorrect status if answer is not pending evaluation\n const shouldShowCorrectAnswers =\n currentQuestionResult?.answerStatus !==\n ANSWER_STATUS.PENDENTE_AVALIACAO &&\n currentQuestionResult?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO;\n\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation, show all options as neutral\n status = Status.NEUTRAL;\n }\n }\n\n return {\n label: option.option,\n value: option.id,\n status: status,\n };\n });\n\n if (!alternatives)\n return (\n <div>\n <p>Não há Alternativas</p>\n </div>\n );\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"space-y-4\">\n <AlternativesList\n mode={variant === 'default' ? 'interactive' : 'readonly'}\n key={`question-${currentQuestion?.id || '1'}`}\n name={`question-${currentQuestion?.id || '1'}`}\n layout=\"compact\"\n alternatives={alternatives}\n value={\n variant === 'result'\n ? currentQuestionResult?.selectedOptions[0]?.optionId || ''\n : currentAnswer?.optionId || ''\n }\n selectedValue={\n variant === 'result'\n ? currentQuestionResult?.selectedOptions[0]?.optionId || ''\n : currentAnswer?.optionId || ''\n }\n onValueChange={(value) => {\n if (currentQuestion) {\n selectAnswer(currentQuestion.id, value);\n }\n }}\n />\n </div>\n </QuizContainer>\n </>\n );\n};\n\nconst QuizMultipleChoice = ({ paddingBottom }: QuizVariantInterface) => {\n const {\n getCurrentQuestion,\n selectMultipleAnswer,\n getAllCurrentAnswer,\n getQuestionResultByQuestionId,\n variant,\n } = useQuizStore();\n const currentQuestion = getCurrentQuestion();\n const allCurrentAnswers = getAllCurrentAnswer();\n const currentQuestionResult = getQuestionResultByQuestionId(\n currentQuestion?.id || ''\n );\n // Use ref to track previous values and prevent unnecessary updates\n const prevSelectedValuesRef = useRef<string[]>([]);\n const prevQuestionIdRef = useRef<string>('');\n\n // Memoize the answer IDs to prevent unnecessary re-renders\n const allCurrentAnswerIds = useMemo(() => {\n return allCurrentAnswers?.map((answer) => answer.optionId) || [];\n }, [allCurrentAnswers]);\n\n // Memoize the selected values to prevent infinite loops\n const selectedValues = useMemo(() => {\n return allCurrentAnswerIds?.filter((id): id is string => id !== null) || [];\n }, [allCurrentAnswerIds]);\n\n // Only update selectedValues if they actually changed or question changed\n const stableSelectedValues = useMemo(() => {\n const currentQuestionId = currentQuestion?.id || '';\n const hasQuestionChanged = prevQuestionIdRef.current !== currentQuestionId;\n\n if (hasQuestionChanged) {\n prevQuestionIdRef.current = currentQuestionId;\n prevSelectedValuesRef.current = selectedValues;\n return selectedValues;\n }\n\n // Only update if values actually changed\n const hasValuesChanged =\n JSON.stringify(prevSelectedValuesRef.current) !==\n JSON.stringify(selectedValues);\n if (hasValuesChanged) {\n prevSelectedValuesRef.current = selectedValues;\n return selectedValues;\n }\n\n if (variant == 'result') {\n return (\n currentQuestionResult?.selectedOptions.map((op) => op.optionId) || []\n );\n } else {\n return prevSelectedValuesRef.current;\n }\n }, [\n selectedValues,\n currentQuestion?.id,\n variant,\n currentQuestionResult?.selectedOptions,\n ]);\n\n // Memoize the callback to prevent unnecessary re-renders\n const handleSelectedValues = useCallback(\n (values: string[]) => {\n if (currentQuestion) {\n selectMultipleAnswer(currentQuestion.id, values);\n }\n },\n [currentQuestion, selectMultipleAnswer]\n );\n\n // Create a stable key to force re-mount when question changes\n const questionKey = useMemo(\n () => `question-${currentQuestion?.id || '1'}`,\n [currentQuestion?.id]\n );\n const choices = currentQuestion?.options?.map((option) => {\n let status: Status = Status.NEUTRAL;\n\n if (variant === 'result') {\n const isCorrectOption =\n currentQuestionResult?.options?.find((op) => op.id === option.id)\n ?.isCorrect || false;\n\n const isSelected = currentQuestionResult?.selectedOptions?.some(\n (op) => op.optionId === option.id\n );\n\n // Only show correct/incorrect status if answer is not pending evaluation\n const shouldShowCorrectAnswers =\n currentQuestionResult?.answerStatus !==\n ANSWER_STATUS.PENDENTE_AVALIACAO &&\n currentQuestionResult?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO;\n\n if (shouldShowCorrectAnswers) {\n if (isCorrectOption) {\n status = Status.CORRECT;\n } else if (isSelected && !isCorrectOption) {\n status = Status.INCORRECT;\n } else {\n status = Status.NEUTRAL;\n }\n } else {\n // When pending evaluation, show all options as neutral\n status = Status.NEUTRAL;\n }\n }\n\n return {\n label: option.option,\n value: option.id,\n status: status,\n };\n });\n\n if (!choices)\n return (\n <div>\n <p>Não há Escolhas Multiplas</p>\n </div>\n );\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"space-y-4\">\n <MultipleChoiceList\n choices={choices}\n key={questionKey}\n name={questionKey}\n selectedValues={stableSelectedValues}\n onHandleSelectedValues={handleSelectedValues}\n mode={variant === 'default' ? 'interactive' : 'readonly'}\n />\n </div>\n </QuizContainer>\n </>\n );\n};\n\nconst QuizDissertative = ({ paddingBottom }: QuizVariantInterface) => {\n const {\n getCurrentQuestion,\n getCurrentAnswer,\n selectDissertativeAnswer,\n getQuestionResultByQuestionId,\n variant,\n getDissertativeCharLimit,\n } = useQuizStore();\n\n const currentQuestion = getCurrentQuestion();\n const currentQuestionResult = getQuestionResultByQuestionId(\n currentQuestion?.id || ''\n );\n\n const currentAnswer = getCurrentAnswer();\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const charLimit = getDissertativeCharLimit();\n\n const handleAnswerChange = (value: string) => {\n if (currentQuestion) {\n selectDissertativeAnswer(currentQuestion.id, value);\n }\n };\n\n // Auto-resize function\n const adjustTextareaHeight = useCallback(() => {\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n const scrollHeight = textareaRef.current.scrollHeight;\n const minHeight = 120; // 120px minimum height\n const maxHeight = 400; // 400px maximum height\n const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight);\n textareaRef.current.style.height = `${newHeight}px`;\n }\n }, []);\n\n // Adjust height when currentAnswer changes\n useEffect(() => {\n adjustTextareaHeight();\n }, [currentAnswer, adjustTextareaHeight]);\n\n if (!currentQuestion) {\n return (\n <div className=\"space-y-4\">\n <p className=\"text-text-600 text-md\">Nenhuma questão disponível</p>\n </div>\n );\n }\n\n const localAnswer =\n (variant == 'result'\n ? currentQuestionResult?.answer\n : currentAnswer?.answer) || '';\n return (\n <>\n <QuizSubTitle subTitle=\"Resposta\" />\n\n <QuizContainer className={cn(variant != 'result' && paddingBottom)}>\n <div className=\"space-y-4 max-h-[600px] overflow-y-auto\">\n {variant === 'default' ? (\n <div className=\"space-y-4\">\n <TextArea\n ref={textareaRef}\n placeholder=\"Escreva sua resposta\"\n value={localAnswer}\n onChange={(e) => handleAnswerChange(e.target.value)}\n rows={4}\n className=\"min-h-[120px] max-h-[400px] resize-none overflow-y-auto\"\n maxLength={charLimit}\n showCharacterCount={!!charLimit}\n />\n </div>\n ) : (\n <div className=\"space-y-4\">\n <p className=\"text-text-600 text-md whitespace-pre-wrap\">\n {localAnswer || 'Nenhuma resposta fornecida'}\n </p>\n </div>\n )}\n </div>\n </QuizContainer>\n\n {variant === 'result' &&\n currentQuestionResult?.answerStatus ==\n ANSWER_STATUS.RESPOSTA_INCORRETA && (\n <>\n <QuizSubTitle subTitle=\"Observação do professor\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <p className=\"text-text-600 text-md whitespace-pre-wrap\">\n {currentQuestionResult?.teacherFeedback}\n </p>\n </QuizContainer>\n </>\n )}\n </>\n );\n};\n\nconst QuizTrueOrFalse = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const options = [\n {\n label: '25 metros',\n isCorrect: true,\n },\n {\n label: '30 metros',\n isCorrect: false,\n },\n {\n label: '40 metros',\n isCorrect: false,\n },\n {\n label: '50 metros',\n isCorrect: false,\n },\n ];\n\n const getLetterByIndex = (index: number) => String.fromCodePoint(97 + index); // 97 = 'a' in ASCII\n\n const isDefaultVariant = variant === 'default';\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"flex flex-col gap-3.5\">\n {options.map((option, index) => {\n const variantCorrect = option.isCorrect ? 'correct' : 'incorrect';\n return (\n <section\n key={option.label.concat(`-${index}`)}\n className=\"flex flex-col gap-2\"\n >\n <div\n className={cn(\n 'flex flex-row justify-between items-center gap-2 p-2 rounded-md',\n isDefaultVariant ? '' : getStatusStyles(variantCorrect)\n )}\n >\n <p className=\"text-text-900 text-sm\">\n {getLetterByIndex(index).concat(') ').concat(option.label)}\n </p>\n\n {isDefaultVariant ? (\n <Select size=\"medium\">\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue placeholder=\"Selecione opcão\" />\n </SelectTrigger>\n\n <SelectContent>\n <SelectItem value=\"V\">Verdadeiro</SelectItem>\n <SelectItem value=\"F\">Falso</SelectItem>\n </SelectContent>\n </Select>\n ) : (\n <div className=\"flex-shrink-0\">\n {getStatusBadge(variantCorrect)}\n </div>\n )}\n </div>\n\n {!isDefaultVariant && (\n <span className=\"flex flex-row gap-2 items-center\">\n <p className=\"text-text-800 text-2xs\">\n Resposta selecionada: V\n </p>\n {!option.isCorrect && (\n <p className=\"text-text-800 text-2xs\">\n Resposta correta: F\n </p>\n )}\n </span>\n )}\n </section>\n );\n })}\n </div>\n </QuizContainer>\n </>\n );\n};\n\ninterface UserAnswer {\n option: string;\n dotOption: string | null;\n correctOption: string;\n isCorrect: boolean | null;\n}\n\nconst QuizConnectDots = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const dotsOptions = [\n { label: 'Ração' },\n { label: 'Rato' },\n { label: 'Grama' },\n { label: 'Peixe' },\n ];\n\n const options = [\n {\n label: 'Cachorro',\n correctOption: 'Ração',\n },\n {\n label: 'Gato',\n correctOption: 'Rato',\n },\n {\n label: 'Cabra',\n correctOption: 'Grama',\n },\n {\n label: 'Baleia',\n correctOption: 'Peixe',\n },\n ];\n\n const mockUserAnswers = [\n {\n option: 'Cachorro',\n dotOption: 'Ração',\n correctOption: 'Ração',\n isCorrect: true,\n },\n {\n option: 'Gato',\n dotOption: 'Rato',\n correctOption: 'Rato',\n isCorrect: true,\n },\n {\n option: 'Cabra',\n dotOption: 'Peixe',\n correctOption: 'Grama',\n isCorrect: false,\n },\n {\n option: 'Baleia',\n dotOption: 'Grama',\n correctOption: 'Peixe',\n isCorrect: false,\n },\n ];\n\n const [userAnswers, setUserAnswers] = useState<UserAnswer[]>(() => {\n if (variant === 'result') {\n return mockUserAnswers;\n }\n return options.map((option) => ({\n option: option.label,\n dotOption: null,\n correctOption: option.correctOption,\n isCorrect: null,\n }));\n });\n\n const handleSelectDot = (optionIndex: number, dotValue: string) => {\n setUserAnswers((prev) => {\n const next = [...prev];\n const { label: optionLabel, correctOption } = options[optionIndex];\n next[optionIndex] = {\n option: optionLabel,\n dotOption: dotValue,\n correctOption,\n isCorrect: dotValue ? dotValue === correctOption : null,\n };\n return next;\n });\n };\n\n const getLetterByIndex = (index: number) => String.fromCodePoint(97 + index); // 'a', 'b', 'c'...\n\n const isDefaultVariant = variant === 'default';\n const assignedDots = new Set(\n userAnswers.map((a) => a.dotOption).filter(Boolean)\n );\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div className=\"flex flex-col gap-3.5\">\n {options.map((option, index) => {\n const answer = userAnswers[index];\n const variantCorrect = answer.isCorrect ? 'correct' : 'incorrect';\n return (\n <section key={option.label} className=\"flex flex-col gap-2\">\n <div\n className={cn(\n 'flex flex-row justify-between items-center gap-2 p-2 rounded-md',\n isDefaultVariant ? '' : getStatusStyles(variantCorrect)\n )}\n >\n <p className=\"text-text-900 text-sm\">\n {getLetterByIndex(index) + ') ' + option.label}\n </p>\n\n {isDefaultVariant ? (\n <Select\n size=\"medium\"\n value={answer.dotOption || undefined}\n onValueChange={(value) => handleSelectDot(index, value)}\n >\n <SelectTrigger className=\"w-[180px]\">\n <SelectValue placeholder=\"Selecione opção\" />\n </SelectTrigger>\n\n <SelectContent>\n {dotsOptions\n .filter(\n (dot) =>\n !assignedDots.has(dot.label) ||\n answer.dotOption === dot.label\n )\n .map((dot) => (\n <SelectItem key={dot.label} value={dot.label}>\n {dot.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <div className=\"flex-shrink-0\">\n {answer.isCorrect === null\n ? null\n : getStatusBadge(variantCorrect)}\n </div>\n )}\n </div>\n\n {!isDefaultVariant && (\n <span className=\"flex flex-row gap-2 items-center\">\n <p className=\"text-text-800 text-2xs\">\n Resposta selecionada: {answer.dotOption || 'Nenhuma'}\n </p>\n {!answer.isCorrect && (\n <p className=\"text-text-800 text-2xs\">\n Resposta correta: {answer.correctOption}\n </p>\n )}\n </span>\n )}\n </section>\n );\n })}\n </div>\n </QuizContainer>\n </>\n );\n};\n\ninterface FillUserAnswer {\n selectId: string;\n userAnswer: string;\n correctAnswer: string;\n isCorrect: boolean;\n}\n\nconst QuizFill = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const options = [\n 'ciência',\n 'disciplina',\n 'área',\n 'especialidade',\n 'variações',\n ];\n\n const exampleText = `A meteorologia é a {{ciencia}} que estuda os fenômenos atmosféricos e suas {{variações}}. Esta disciplina científica tem como objetivo principal {{objetivo}} o comportamento da atmosfera terrestre.\n\n Os meteorologistas utilizam diversos {{instrumentos}} para coletar dados atmosféricos, incluindo termômetros, barômetros e {{equipamentos}} modernos como radares meteorológicos.`;\n\n // Mock data for result variant - simulating user answers\n const mockUserAnswers: FillUserAnswer[] = [\n {\n selectId: 'ciencia',\n userAnswer: 'tecnologia',\n correctAnswer: 'ciência',\n isCorrect: false,\n },\n {\n selectId: 'variações',\n userAnswer: 'variações',\n correctAnswer: 'variações',\n isCorrect: true,\n },\n {\n selectId: 'objetivo',\n userAnswer: 'estudar',\n correctAnswer: 'compreender',\n isCorrect: false,\n },\n {\n selectId: 'instrumentos',\n userAnswer: 'ferramentas',\n correctAnswer: 'instrumentos',\n isCorrect: false,\n },\n {\n selectId: 'equipamentos',\n userAnswer: 'equipamentos',\n correctAnswer: 'equipamentos',\n isCorrect: true,\n },\n ];\n\n const [answers, setAnswers] = useState<Record<string, string>>({});\n const baseId = useId(); // Generate base ID for this component instance\n\n // Get available options for a specific select\n const getAvailableOptionsForSelect = (selectId: string) => {\n const usedOptions = new Set(\n Object.entries(answers)\n .filter(([key]) => key !== selectId) // Exclude the current selection itself\n .map(([, value]) => value)\n );\n\n return options.filter((option) => !usedOptions.has(option));\n };\n\n const handleSelectChange = (selectId: string, value: string) => {\n const newAnswers = { ...answers, [selectId]: value };\n setAnswers(newAnswers);\n };\n\n const renderResolutionElement = (selectId: string) => {\n const mockAnswer = mockUserAnswers.find(\n (answer) => answer.selectId === selectId\n );\n\n return (\n <p className=\"inline-flex mb-2.5 text-success-600 font-semibold text-md border-b-2 border-success-600\">\n {mockAnswer?.correctAnswer}\n </p>\n );\n };\n\n const renderDefaultElement = (\n selectId: string,\n startIndex: number,\n selectedValue: string,\n availableOptionsForThisSelect: string[]\n ) => {\n return (\n <Select\n key={`${selectId}-${startIndex}`}\n value={selectedValue}\n onValueChange={(value) => handleSelectChange(selectId, value)}\n className=\"inline-flex mb-2.5\"\n >\n <SelectTrigger className=\"inline-flex w-auto min-w-[140px] h-8 mx-1 bg-background border-gray-300\">\n <SelectValue placeholder=\"Selecione opção\" />\n </SelectTrigger>\n <SelectContent>\n {availableOptionsForThisSelect.map((option, index) => (\n <SelectItem key={`${option}-${index}`} value={option}>\n {option}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n };\n\n const renderResultElement = (selectId: string) => {\n const mockAnswer = mockUserAnswers.find(\n (answer) => answer.selectId === selectId\n );\n\n if (!mockAnswer) return null;\n\n const action = mockAnswer.isCorrect ? 'success' : 'error';\n const icon = mockAnswer.isCorrect ? <CheckCircle /> : <XCircle />;\n\n return (\n <Badge\n key={selectId}\n variant=\"solid\"\n action={action}\n iconRight={icon}\n size=\"large\"\n className=\"py-3 w-[180px] justify-between mb-2.5\"\n >\n <span className=\"text-text-900\">{mockAnswer.userAnswer}</span>\n </Badge>\n );\n };\n\n const renderTextWithSelects = (text: string, isResolution?: boolean) => {\n const elements: Array<{ element: string | ReactNode; id: string }> = [];\n let lastIndex = 0;\n let elementCounter = 0;\n\n // Support Unicode letters/marks and digits: allows placeholders like {{variações}}\n const regex = /\\{\\{([\\p{L}\\p{M}\\d_]+)\\}\\}/gu;\n let match;\n\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, selectId] = match;\n const startIndex = match.index;\n\n if (startIndex > lastIndex) {\n elements.push({\n element: text.slice(lastIndex, startIndex),\n id: `${baseId}-text-${++elementCounter}`,\n });\n }\n\n const selectedValue = answers[selectId];\n const availableOptionsForThisSelect =\n getAvailableOptionsForSelect(selectId);\n\n if (isResolution) {\n elements.push({\n element: renderResolutionElement(selectId),\n id: `${baseId}-resolution-${++elementCounter}`,\n });\n } else if (variant === 'default') {\n elements.push({\n element: renderDefaultElement(\n selectId,\n startIndex,\n selectedValue,\n availableOptionsForThisSelect\n ),\n id: `${baseId}-select-${++elementCounter}`,\n });\n } else {\n const resultElement = renderResultElement(selectId);\n if (resultElement) {\n elements.push({\n element: resultElement,\n id: `${baseId}-result-${++elementCounter}`,\n });\n }\n }\n\n lastIndex = match.index + fullMatch.length;\n }\n\n if (lastIndex < text.length) {\n elements.push({\n element: text.slice(lastIndex),\n id: `${baseId}-text-${++elementCounter}`,\n });\n }\n\n return elements;\n };\n\n return (\n <>\n <QuizSubTitle subTitle=\"Alternativas\" />\n\n <QuizContainer className=\"h-auto pb-0\">\n <div className=\"space-y-6 px-4 h-auto\">\n <div\n className={cn(\n 'text-lg text-text-900 leading-8 h-auto',\n variant != 'result' && paddingBottom\n )}\n >\n {renderTextWithSelects(exampleText).map((element) => (\n <span key={element.id}>{element.element}</span>\n ))}\n </div>\n </div>\n </QuizContainer>\n\n {variant === 'result' && (\n <>\n <QuizSubTitle subTitle=\"Resultado\" />\n\n <QuizContainer className=\"h-auto pb-0\">\n <div className=\"space-y-6 px-4\">\n <div\n className={cn('text-lg text-text-900 leading-8', paddingBottom)}\n >\n {renderTextWithSelects(exampleText, true).map((element) => (\n <span key={element.id}>{element.element}</span>\n ))}\n </div>\n </div>\n </QuizContainer>\n </>\n )}\n </>\n );\n};\n\nconst QuizImageQuestion = ({ paddingBottom }: QuizVariantInterface) => {\n const { variant } = useQuizStore();\n const correctPositionRelative = { x: 0.48, y: 0.45 };\n\n // Calculate correctRadiusRelative automatically based on the circle dimensions\n const calculateCorrectRadiusRelative = (): number => {\n // The correct answer circle has width: 15% and height: 30%\n // We'll use the average of these as the radius\n const circleWidthRelative = 0.15; // 15%\n const circleHeightRelative = 0.3; // 30%\n\n // Calculate the average radius (half of the average of width and height)\n const averageRadius = (circleWidthRelative + circleHeightRelative) / 4;\n\n // Add a small tolerance for better user experience\n const tolerance = 0.02; // 2% tolerance\n\n return averageRadius + tolerance;\n };\n\n const correctRadiusRelative = calculateCorrectRadiusRelative();\n const mockUserAnswerRelative = { x: 0.72, y: 0.348 };\n\n const [clickPositionRelative, setClickPositionRelative] = useState<{\n x: number;\n y: number;\n } | null>(variant == 'result' ? mockUserAnswerRelative : null);\n\n // Helper function to safely convert click coordinates to relative coordinates\n const convertToRelativeCoordinates = (\n x: number,\n y: number,\n rect: DOMRect\n ): { x: number; y: number } => {\n // Guard against division by zero or extremely small dimensions\n const safeWidth = Math.max(rect.width, 0.001);\n const safeHeight = Math.max(rect.height, 0.001);\n\n // Convert to relative coordinates and clamp to [0, 1] range\n const xRelative = Math.max(0, Math.min(1, x / safeWidth));\n const yRelative = Math.max(0, Math.min(1, y / safeHeight));\n\n return { x: xRelative, y: yRelative };\n };\n\n const handleImageClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (variant === 'result') return;\n\n const rect = event.currentTarget.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n\n // Use helper function for safe conversion\n const positionRelative = convertToRelativeCoordinates(x, y, rect);\n setClickPositionRelative(positionRelative);\n };\n\n const handleKeyboardActivate = () => {\n if (variant === 'result') return;\n // Choose a deterministic position for keyboard activation; center is a reasonable default\n setClickPositionRelative({ x: 0.5, y: 0.5 });\n };\n\n const isCorrect = () => {\n if (!clickPositionRelative) return false;\n\n const distance = Math.sqrt(\n Math.pow(clickPositionRelative.x - correctPositionRelative.x, 2) +\n Math.pow(clickPositionRelative.y - correctPositionRelative.y, 2)\n );\n\n return distance <= correctRadiusRelative;\n };\n\n const getUserCircleColorClasses = () => {\n if (variant === 'default') {\n return 'bg-indicator-primary/70 border-[#F8CC2E]';\n }\n\n if (variant === 'result') {\n return isCorrect()\n ? 'bg-success-600/70 border-white' // Green for correct answer\n : 'bg-indicator-error/70 border-white'; // Red for incorrect answer\n }\n\n return 'bg-success-600/70 border-white';\n };\n\n return (\n <>\n <QuizSubTitle subTitle=\"Clique na área correta\" />\n\n <QuizContainer className={cn('', paddingBottom)}>\n <div\n data-testid=\"quiz-image-container\"\n className=\"space-y-6 p-3 relative inline-block\"\n >\n {variant == 'result' && (\n <div\n data-testid=\"quiz-legend\"\n className=\"flex items-center gap-4 text-xs\"\n >\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-primary/70 border border-[#F8CC2E]\"></div>\n <span className=\"text-text-600 font-medium text-sm\">\n Área correta\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-success-600/70 border border-white\"></div>\n <span className=\"text-text-600 font-medium text-sm\">\n Resposta correta\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-error/70 border border-white\"></div>\n <span className=\"text-text-600 font-medium text-sm\">\n Resposta incorreta\n </span>\n </div>\n </div>\n )}\n\n <button\n data-testid=\"quiz-image-button\"\n type=\"button\"\n className=\"relative cursor-pointer w-full h-full border-0 bg-transparent p-0\"\n onClick={handleImageClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleKeyboardActivate();\n }\n }}\n aria-label=\"Área da imagem interativa\"\n >\n <img\n data-testid=\"quiz-image\"\n src={ImageQuestion}\n alt=\"Question\"\n className=\"w-full h-auto rounded-md\"\n />\n\n {/* Correct answer circle - only show in result variant */}\n {variant === 'result' && (\n <div\n data-testid=\"quiz-correct-circle\"\n className=\"absolute rounded-full bg-indicator-primary/70 border-4 border-[#F8CC2E] pointer-events-none\"\n style={{\n minWidth: '50px',\n maxWidth: '160px',\n width: '15%',\n aspectRatio: '1 / 1',\n left: `calc(${correctPositionRelative.x * 100}% - 7.5%)`,\n top: `calc(${correctPositionRelative.y * 100}% - 15%)`,\n }}\n />\n )}\n\n {/* User's answer circle */}\n {clickPositionRelative && (\n <div\n data-testid=\"quiz-user-circle\"\n className={`absolute rounded-full border-4 pointer-events-none ${getUserCircleColorClasses()}`}\n style={{\n minWidth: '30px',\n maxWidth: '52px',\n width: '5%',\n aspectRatio: '1 / 1',\n left: `calc(${clickPositionRelative.x * 100}% - 2.5%)`,\n top: `calc(${clickPositionRelative.y * 100}% - 2.5%)`,\n }}\n />\n )}\n </button>\n </div>\n </QuizContainer>\n </>\n );\n};\n\nexport {\n QuizSubTitle,\n QuizContainer,\n QuizMultipleChoice,\n QuizDissertative,\n QuizTrueOrFalse,\n QuizConnectDots,\n QuizFill,\n QuizImageQuestion,\n QuizAlternative,\n};\n","import { useId, type ReactNode } from 'react';\nimport Badge from '../../../components/Badge/Badge';\nimport { CheckCircle, XCircle } from 'phosphor-react';\nimport { cn } from '../../utils';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\n\n/**\n * Get status badge component\n */\nexport const getStatusBadge = (status?: 'correct' | 'incorrect'): ReactNode => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n};\n\n/**\n * Container component for question content\n */\nexport const QuestionContainer = ({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) => {\n return (\n <div\n className={cn(\n 'bg-background rounded-t-xl px-4 pt-4 pb-[80px] h-auto flex flex-col gap-4 mb-auto',\n className\n )}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Subtitle component for question sections\n */\nexport const QuestionSubTitle = ({ subTitle }: { subTitle: string }) => {\n return (\n <div className=\"px-4 pb-2 pt-6\">\n <Text size=\"md\" weight=\"bold\" color=\"text-text-950\">\n {subTitle}\n </Text>\n </div>\n );\n};\n\n/**\n * Internal component for fill in the blanks question\n * Uses useId hook to generate unique IDs\n */\nexport const FillQuestionContent = ({\n question,\n result,\n}: QuestionRendererProps) => {\n // Extract text from statement - it should contain {{placeholders}}\n const text = question.statement || '';\n const baseId = useId();\n\n // Parse student answer - assuming it's stored in result.answer as JSON or structured data\n // For now, we'll need to extract from the answer field\n // The answer might be structured or we need to parse placeholders from the statement\n const studentAnswers: Record<\n string,\n { answer: string; isCorrect: boolean; correctAnswer: string }\n > = {};\n\n // Try to parse answer if it's JSON, otherwise use empty object\n try {\n if (result?.answer) {\n const parsed =\n typeof result.answer === 'string'\n ? JSON.parse(result.answer)\n : result.answer;\n if (typeof parsed === 'object') {\n Object.assign(studentAnswers, parsed);\n }\n }\n } catch (error) {\n console.error('Error parsing answer:', error);\n }\n\n // Extract placeholders from text\n const regex = /\\{\\{([\\p{L}\\p{M}\\d_]+)\\}\\}/gu;\n const placeholders: string[] = [];\n let match;\n while ((match = regex.exec(text)) !== null) {\n placeholders.push(match[1]);\n }\n\n // Build correct answers from studentAnswers - use the already-parsed correctAnswer field\n const correctAnswers: Record<string, string> = {};\n placeholders.forEach((placeholder) => {\n correctAnswers[placeholder] =\n studentAnswers[placeholder]?.correctAnswer || `[${placeholder}]`;\n });\n\n /**\n * Add text element to elements array\n */\n const addTextElement = (\n elements: Array<{ element: string | ReactNode; id: string }>,\n textContent: string,\n elementCounter: { current: number }\n ) => {\n if (textContent) {\n elements.push({\n element: textContent,\n id: `${baseId}-text-${++elementCounter.current}`,\n });\n }\n };\n\n /**\n * Render placeholder for gabarito (correct answer)\n */\n const renderGabaritoPlaceholder = (\n selectId: string,\n elementCounter: { current: number }\n ): { element: ReactNode; id: string } => {\n const correctAnswer = correctAnswers[selectId] || `[${selectId}]`;\n return {\n element: (\n <Text\n key={`${baseId}-gabarito-${selectId}`}\n size=\"md\"\n weight=\"semibold\"\n color=\"text-success-600\"\n className=\"inline-flex mb-2.5 border-b-2 border-success-600\"\n >\n {correctAnswer}\n </Text>\n ),\n id: `${baseId}-gabarito-${++elementCounter.current}`,\n };\n };\n\n /**\n * Render placeholder for student answer\n */\n const renderStudentPlaceholder = (\n selectId: string,\n elementCounter: { current: number }\n ): { element: ReactNode; id: string } => {\n const studentAnswer = studentAnswers[selectId];\n if (!studentAnswer) {\n return {\n element: (\n <Text\n key={`${baseId}-no-answer-${selectId}`}\n size=\"md\"\n weight=\"normal\"\n color=\"text-text-400\"\n className=\"inline-flex mb-2.5 border-b-2 border-text-300\"\n >\n [Não respondido]\n </Text>\n ),\n id: `${baseId}-no-answer-${++elementCounter.current}`,\n };\n }\n\n const isCorrect = studentAnswer.isCorrect;\n const colorClass = isCorrect\n ? 'text-success-600 border-success-600'\n : 'text-error-600 border-error-600';\n\n return {\n element: (\n <Badge\n key={`${baseId}-answer-${selectId}`}\n variant=\"solid\"\n action={isCorrect ? 'success' : 'error'}\n iconRight={isCorrect ? <CheckCircle /> : <XCircle />}\n size=\"large\"\n className={`py-3 w-[180px] justify-between mb-2.5 ${colorClass}`}\n >\n <span className=\"text-text-900\">{studentAnswer.answer}</span>\n </Badge>\n ),\n id: `${baseId}-answer-${++elementCounter.current}`,\n };\n };\n\n /**\n * Render text with answers or gabarito\n */\n const renderTextWithAnswers = (isGabarito = false) => {\n const elements: Array<{ element: string | ReactNode; id: string }> = [];\n let lastIndex = 0;\n const elementCounter = { current: 0 };\n\n regex.lastIndex = 0; // Reset regex\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, selectId] = match;\n const startIndex = match.index;\n\n // Add text before placeholder\n if (startIndex > lastIndex) {\n addTextElement(\n elements,\n text.slice(lastIndex, startIndex),\n elementCounter\n );\n }\n\n // Add placeholder element\n const placeholderElement = isGabarito\n ? renderGabaritoPlaceholder(selectId, elementCounter)\n : renderStudentPlaceholder(selectId, elementCounter);\n elements.push(placeholderElement);\n\n lastIndex = match.index + fullMatch.length;\n }\n\n // Add remaining text after last placeholder\n if (lastIndex < text.length) {\n addTextElement(elements, text.slice(lastIndex), elementCounter);\n }\n\n return elements;\n };\n\n return (\n <div className=\"pt-2 space-y-4\">\n <div className=\"space-y-2\">\n <Text size=\"xs\" weight=\"normal\" color=\"text-text-500\">\n Resposta do aluno:\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <div className=\"leading-8\">\n {renderTextWithAnswers(false).map((element) => (\n <Text\n key={element.id}\n size=\"md\"\n weight=\"normal\"\n color=\"text-text-900\"\n >\n {element.element}\n </Text>\n ))}\n </div>\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Text size=\"xs\" weight=\"normal\" color=\"text-text-500\">\n Gabarito:\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <div className=\"leading-8\">\n {renderTextWithAnswers(true).map((element) => (\n <Text\n key={element.id}\n size=\"md\"\n weight=\"normal\"\n color=\"text-text-900\"\n >\n {element.element}\n </Text>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport { getStatusStyles } from '../../../components/Quiz/QuizContent';\nimport Text from '../../../components/Text/Text';\nimport { cn } from '../../../utils/utils';\nimport type { QuestionRendererProps } from '../types';\nimport { getStatusBadge } from '../components';\n\n/**\n * Render true or false question\n * Each option has a statement, and student marks V or F for each\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionTrueOrFalse = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n const options = question.options || [];\n const getLetterByIndex = (index: number) => String.fromCodePoint(97 + index); // 97 = 'a' in ASCII\n\n const shouldShowStatus =\n result?.answerStatus !== ANSWER_STATUS.PENDENTE_AVALIACAO &&\n result?.answerStatus !== ANSWER_STATUS.NAO_RESPONDIDO;\n\n return (\n <div className=\"pt-2\">\n <div className=\"flex flex-col gap-3.5\">\n {options.map((option, index) => {\n // In true/false, isCorrect indicates if the statement is TRUE\n const statementIsTrue =\n result?.options?.find((op) => op.id === option.id)?.isCorrect ||\n false;\n const isSelected = result?.selectedOptions?.some(\n (op) => op.optionId === option.id\n );\n\n // Determine if student's answer is correct\n // If statement is true and selected, or statement is false and not selected\n const isStudentCorrect = statementIsTrue === isSelected;\n\n const variantCorrect = statementIsTrue ? 'correct' : 'incorrect';\n const studentAnswer = isSelected ? 'V' : 'F';\n const correctAnswer = statementIsTrue ? 'V' : 'F';\n\n return (\n <section\n key={option.id || `option-${index}`}\n className=\"flex flex-col gap-2\"\n >\n <div\n className={cn(\n 'flex flex-row justify-between items-center gap-2 p-2 rounded-md border',\n shouldShowStatus ? getStatusStyles(variantCorrect) : ''\n )}\n >\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-900\">\n {getLetterByIndex(index).concat(') ').concat(option.option)}\n </Text>\n\n {shouldShowStatus && (\n <div className=\"flex-shrink-0\">\n {getStatusBadge(isStudentCorrect ? 'correct' : 'incorrect')}\n </div>\n )}\n </div>\n\n {shouldShowStatus && (\n <span className=\"flex flex-row gap-2 items-center\">\n <Text size=\"2xs\" weight=\"normal\" color=\"text-text-800\">\n Resposta selecionada: {studentAnswer}\n </Text>\n {!isStudentCorrect && (\n <Text size=\"2xs\" weight=\"normal\" color=\"text-text-800\">\n Resposta correta: {correctAnswer}\n </Text>\n )}\n </span>\n )}\n </section>\n );\n })}\n </div>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport { ANSWER_STATUS } from '../../../components/Quiz/useQuizStore';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\n\n/**\n * Render essay/dissertative question (readonly mode for correction)\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionDissertative = ({\n result,\n}: Omit<QuestionRendererProps, 'question'>): ReactNode => {\n const localAnswer = result?.answer || '';\n\n return (\n <div className=\"pt-2 space-y-4\">\n <div className=\"space-y-2\">\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-950\">\n Resposta do aluno\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-700\">\n {localAnswer || 'Nenhuma resposta fornecida'}\n </Text>\n </div>\n </div>\n\n {result?.answerStatus === ANSWER_STATUS.RESPOSTA_INCORRETA &&\n result?.teacherFeedback && (\n <div className=\"space-y-2\">\n <Text size=\"xs\" weight=\"normal\" color=\"text-text-500\">\n Observação do professor:\n </Text>\n <div className=\"p-3 bg-background-50 rounded-lg border border-border-100\">\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-700\">\n {result.teacherFeedback}\n </Text>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport type { QuestionRendererProps } from '../types';\nimport { FillQuestionContent } from '../components';\n\n/**\n * Render fill in the blanks question\n * Shows text with student answers highlighted (green if correct, red if wrong)\n * Also shows a \"gabarito\" section with correct answers\n * Returns content without wrapper (for accordion use)\n */\nexport const renderQuestionFill = ({\n question,\n result,\n}: QuestionRendererProps): ReactNode => {\n return <FillQuestionContent question={question} result={result} />;\n};\n","import type { ReactNode } from 'react';\nimport ImageQuestion from '../../../assets/img/mock-image-question.png';\nimport Text from '../../../components/Text/Text';\nimport type { QuestionRendererProps } from '../types';\n\n/**\n * Render image question\n * Shows image with clickable area, correct answer circle, and user's answer circle\n */\nexport const renderQuestionImage = ({\n result,\n}: Omit<QuestionRendererProps, 'question'>): ReactNode => {\n // Extract position data from result or question\n // Assuming correct position is stored in question metadata or result\n const correctPositionRelative = { x: 0.48, y: 0.45 }; // Default, should come from question data\n const correctRadiusRelative = 0.1; // Default radius\n\n // Get user's answer position from result\n // This would typically be stored in result.answer as coordinates\n let userPositionRelative: { x: number; y: number } | null = null;\n try {\n if (result?.answer) {\n const parsed =\n typeof result.answer === 'string'\n ? JSON.parse(result.answer)\n : result.answer;\n if (\n parsed &&\n typeof parsed.x === 'number' &&\n typeof parsed.y === 'number'\n ) {\n userPositionRelative = { x: parsed.x, y: parsed.y };\n }\n }\n } catch {\n userPositionRelative = null;\n }\n\n // Determine if answer is correct (within radius)\n const isCorrect = userPositionRelative\n ? Math.sqrt(\n Math.pow(userPositionRelative.x - correctPositionRelative.x, 2) +\n Math.pow(userPositionRelative.y - correctPositionRelative.y, 2)\n ) <= correctRadiusRelative\n : false;\n\n const getUserCircleColorClasses = () => {\n if (!userPositionRelative) return '';\n return isCorrect\n ? 'bg-success-600/70 border-white'\n : 'bg-indicator-error/70 border-white';\n };\n\n // Calculate position descriptions for accessibility\n const getPositionDescription = (x: number, y: number): string => {\n const xPercent = Math.round(x * 100);\n const yPercent = Math.round(y * 100);\n return `${xPercent}% da esquerda, ${yPercent}% do topo`;\n };\n\n const getSpatialRelationship = (): string => {\n if (!userPositionRelative) {\n return `Área correta localizada em ${getPositionDescription(\n correctPositionRelative.x,\n correctPositionRelative.y\n )}. Nenhuma resposta do aluno fornecida.`;\n }\n\n const deltaX = userPositionRelative.x - correctPositionRelative.x;\n const deltaY = userPositionRelative.y - correctPositionRelative.y;\n const distance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));\n const distancePercent = Math.round(distance * 100);\n\n let direction = '';\n if (Math.abs(deltaX) > Math.abs(deltaY)) {\n direction = deltaX > 0 ? 'à direita' : 'à esquerda';\n } else {\n direction = deltaY > 0 ? 'abaixo' : 'acima';\n }\n\n const correctPos = getPositionDescription(\n correctPositionRelative.x,\n correctPositionRelative.y\n );\n const userPos = getPositionDescription(\n userPositionRelative.x,\n userPositionRelative.y\n );\n\n return `Área correta localizada em ${correctPos}. Resposta do aluno em ${userPos}. A resposta do aluno está ${distancePercent}% de distância ${direction} da área correta. ${isCorrect ? 'A resposta está dentro da área de tolerância e é considerada correta.' : 'A resposta está fora da área de tolerância e é considerada incorreta.'}`;\n };\n\n const correctPositionDescription = getPositionDescription(\n correctPositionRelative.x,\n correctPositionRelative.y\n );\n const imageAltText = `Questão de imagem com área correta localizada em ${correctPositionDescription}`;\n\n return (\n <div className=\"pt-2 space-y-4\">\n {/* Legend */}\n <div className=\"flex items-center gap-4 text-xs\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-primary/70 border border-[#F8CC2E]\"></div>\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-600\">\n Área correta\n </Text>\n </div>\n {userPositionRelative && (\n <>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-success-600/70 border border-white\"></div>\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-600\">\n Resposta correta\n </Text>\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"w-3 h-3 rounded-full bg-indicator-error/70 border border-white\"></div>\n <Text size=\"sm\" weight=\"normal\" color=\"text-text-600\">\n Resposta incorreta\n </Text>\n </div>\n </>\n )}\n </div>\n\n {/* Image container */}\n <div className=\"relative w-full\">\n {/* Hidden text summary for screen readers */}\n <div className=\"sr-only\">{getSpatialRelationship()}</div>\n\n <img\n src={ImageQuestion}\n alt={imageAltText}\n className=\"w-full h-auto rounded-md\"\n />\n\n {/* Correct answer circle */}\n <div\n role=\"img\"\n aria-label={`Área correta marcada em ${correctPositionDescription}`}\n className=\"absolute rounded-full bg-indicator-primary/70 border-4 border-[#F8CC2E] pointer-events-none\"\n style={{\n minWidth: '50px',\n maxWidth: '160px',\n width: '15%',\n aspectRatio: '1 / 1',\n left: `calc(${correctPositionRelative.x * 100}% - 7.5%)`,\n top: `calc(${correctPositionRelative.y * 100}% - 15%)`,\n }}\n >\n <Text\n size=\"sm\"\n weight=\"normal\"\n color=\"text-text-600\"\n className=\"sr-only\"\n >\n Círculo amarelo indicando a área correta da resposta, posicionado em{' '}\n {correctPositionDescription}\n </Text>\n </div>\n\n {/* User's answer circle */}\n {userPositionRelative && (\n <div\n role=\"img\"\n aria-label={`Resposta do aluno marcada em ${getPositionDescription(\n userPositionRelative.x,\n userPositionRelative.y\n )}, ${isCorrect ? 'correta' : 'incorreta'}`}\n className={`absolute rounded-full border-4 pointer-events-none ${getUserCircleColorClasses()}`}\n style={{\n minWidth: '30px',\n maxWidth: '52px',\n width: '5%',\n aspectRatio: '1 / 1',\n left: `calc(${userPositionRelative.x * 100}% - 2.5%)`,\n top: `calc(${userPositionRelative.y * 100}% - 2.5%)`,\n }}\n >\n <Text\n size=\"sm\"\n weight=\"normal\"\n color=\"text-text-600\"\n className=\"sr-only\"\n >\n Círculo {isCorrect ? 'verde' : 'vermelho'} indicando a resposta do\n aluno, posicionado em{' '}\n {getPositionDescription(\n userPositionRelative.x,\n userPositionRelative.y\n )}\n . A resposta está{' '}\n {Math.round(\n Math.sqrt(\n Math.pow(\n userPositionRelative.x - correctPositionRelative.x,\n 2\n ) +\n Math.pow(\n userPositionRelative.y - correctPositionRelative.y,\n 2\n )\n ) * 100\n )}\n % de distância da área correta e é considerada{' '}\n {isCorrect ? 'correta' : 'incorreta'}.\n </Text>\n </div>\n )}\n </div>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\nimport { cn } from '../../../utils/utils';\nimport Text from '../../../components/Text/Text';\nimport { QuestionSubTitle, QuestionContainer } from '../components';\n\n/**\n * Render connect dots question (not implemented)\n */\nexport const renderQuestionConnectDots = ({\n paddingBottom,\n}: {\n paddingBottom?: string;\n} = {}): ReactNode => {\n return (\n <>\n <QuestionSubTitle subTitle=\"Tipo de questão: Ligar Pontos\" />\n <QuestionContainer className={cn('', paddingBottom)}>\n <div className=\"space-y-4\">\n <Text size=\"md\" weight=\"normal\" color=\"text-text-600\">\n Tipo de questão: Ligar Pontos (não implementado)\n </Text>\n </div>\n </QuestionContainer>\n </>\n );\n};\n","import type { ReactNode } from 'react';\nimport { QUESTION_TYPE } from '../../components/Quiz/useQuizStore';\nimport { renderQuestionAlternative } from './alternative';\nimport { renderQuestionMultipleChoice } from './multipleChoice';\nimport { renderQuestionTrueOrFalse } from './trueOrFalse';\nimport { renderQuestionDissertative } from './dissertative';\nimport { renderQuestionFill } from './fill';\nimport { renderQuestionImage } from './image';\nimport { renderQuestionConnectDots } from './connectDots';\nimport type { QuestionRendererProps } from './types';\n\n// Re-export types\nexport type { QuestionRendererProps } from './types';\nexport { Status } from './types';\n\n// Re-export components\nexport {\n getStatusBadge,\n QuestionContainer,\n QuestionSubTitle,\n FillQuestionContent,\n} from './components';\n\n// Re-export individual renderers\nexport { renderQuestionAlternative } from './alternative';\nexport { renderQuestionMultipleChoice } from './multipleChoice';\nexport { renderQuestionTrueOrFalse } from './trueOrFalse';\nexport { renderQuestionDissertative } from './dissertative';\nexport { renderQuestionFill } from './fill';\nexport { renderQuestionImage } from './image';\nexport { renderQuestionConnectDots } from './connectDots';\n\n/**\n * Map question types to their render functions\n */\nconst questionRendererMap = {\n [QUESTION_TYPE.ALTERNATIVA]: renderQuestionAlternative,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: renderQuestionMultipleChoice,\n [QUESTION_TYPE.VERDADEIRO_FALSO]: renderQuestionTrueOrFalse,\n [QUESTION_TYPE.DISSERTATIVA]: renderQuestionDissertative,\n [QUESTION_TYPE.PREENCHER]: renderQuestionFill,\n [QUESTION_TYPE.IMAGEM]: renderQuestionImage,\n [QUESTION_TYPE.LIGAR_PONTOS]: renderQuestionConnectDots,\n};\n\n/**\n * Render question based on question type\n * @param props - Question renderer props\n * @returns Rendered question content\n */\nexport const renderQuestion = (props: QuestionRendererProps): ReactNode => {\n const { question } = props;\n const renderer = questionRendererMap[question.questionType];\n\n if (!renderer) {\n // Fallback: try to render based on options presence\n if (question.options && question.options.length > 0) {\n return renderQuestionAlternative(props);\n }\n return renderQuestionDissertative({ result: props.result });\n }\n\n // Handle renderers with different prop requirements\n switch (question.questionType) {\n case QUESTION_TYPE.DISSERTATIVA:\n return renderQuestionDissertative({ result: props.result });\n case QUESTION_TYPE.IMAGEM:\n return renderQuestionImage({ result: props.result });\n case QUESTION_TYPE.LIGAR_PONTOS:\n return renderQuestionConnectDots({ paddingBottom: '' });\n case QUESTION_TYPE.ALTERNATIVA:\n case QUESTION_TYPE.MULTIPLA_ESCOLHA:\n case QUESTION_TYPE.VERDADEIRO_FALSO:\n case QUESTION_TYPE.PREENCHER:\n return renderer(props);\n default:\n return null;\n }\n};\n\n/**\n * Type for question renderer map\n */\nexport type QuestionRendererMap = Record<QUESTION_TYPE, () => ReactNode>;\n\n/**\n * Render from a map of renderers\n * @param renderers - Map of question type to render function\n * @param questionType - Type of question to render\n * @returns Rendered content or null\n */\nexport const renderFromMap = (\n renderers: QuestionRendererMap,\n questionType?: QUESTION_TYPE\n) => {\n if (!questionType) return null;\n const renderer = renderers[questionType];\n return renderer ? renderer() : null;\n};\n","import { useState, useEffect } from 'react';\n\n// Mobile width in pixels\nconst MOBILE_WIDTH = 500;\n// Tablet width in pixels\nconst TABLET_WIDTH = 931;\n// Video responsive breakpoints\nconst SMALL_MOBILE_WIDTH = 425;\nconst EXTRA_SMALL_MOBILE_WIDTH = 375;\nconst ULTRA_SMALL_MOBILE_WIDTH = 375; // For video controls\nconst TINY_MOBILE_WIDTH = 320;\n// Default desktop width for SSR\nconst DEFAULT_WIDTH = 1200;\n\n/**\n * Device type based on screen width\n */\nexport type DeviceType = 'responsive' | 'desktop';\n\n/**\n * Gets the window width safely (SSR compatible)\n * @returns {number} window width or default value for SSR\n */\nconst getWindowWidth = (): number => {\n if (typeof window === 'undefined') {\n return DEFAULT_WIDTH;\n }\n return window.innerWidth;\n};\n\n/**\n * Gets the current device type based on screen width\n * @returns {DeviceType} 'responsive' for mobile/tablet (width < 931px), 'desktop' for larger screens\n */\nexport const getDeviceType = (): DeviceType => {\n const width = getWindowWidth();\n return width < TABLET_WIDTH ? 'responsive' : 'desktop';\n};\n\n/**\n * Hook to detect screen size and get responsive classes\n * @returns object with isMobile, isTablet, responsive class functions and getDeviceType\n */\nexport const useMobile = () => {\n const [isMobile, setIsMobile] = useState(false);\n const [isTablet, setIsTablet] = useState(false);\n const [isSmallMobile, setIsSmallMobile] = useState(false);\n const [isExtraSmallMobile, setIsExtraSmallMobile] = useState(false);\n const [isUltraSmallMobile, setIsUltraSmallMobile] = useState(false);\n const [isTinyMobile, setIsTinyMobile] = useState(false);\n\n useEffect(() => {\n const checkScreenSize = () => {\n const width = getWindowWidth();\n setIsMobile(width < MOBILE_WIDTH);\n setIsTablet(width < TABLET_WIDTH);\n setIsSmallMobile(width < SMALL_MOBILE_WIDTH);\n setIsExtraSmallMobile(width < EXTRA_SMALL_MOBILE_WIDTH);\n setIsUltraSmallMobile(width < ULTRA_SMALL_MOBILE_WIDTH);\n setIsTinyMobile(width < TINY_MOBILE_WIDTH);\n };\n\n checkScreenSize();\n\n window.addEventListener('resize', checkScreenSize);\n\n return () => window.removeEventListener('resize', checkScreenSize);\n }, []);\n\n /**\n * Get responsive classes for the form container\n * @returns className string for form container based on screen size\n */\n const getFormContainerClasses = (): string => {\n if (isMobile) {\n return 'w-full px-4';\n }\n if (isTablet) {\n return 'w-full px-6';\n }\n return 'w-full max-w-[992px] mx-auto px-0';\n };\n\n /**\n * Get mobile-specific classes for the header\n * @returns className string for mobile header layout\n */\n const getMobileHeaderClasses = (): string => {\n return 'flex flex-col items-start gap-4 mb-6';\n };\n\n /**\n * Get desktop-specific classes for the header\n * @returns className string for desktop header layout\n */\n const getDesktopHeaderClasses = (): string => {\n return 'flex flex-row justify-between items-center gap-6 mb-8';\n };\n\n /**\n * Get responsive classes for the header\n * @returns className string for header based on screen size\n */\n const getHeaderClasses = (): string => {\n return isMobile ? getMobileHeaderClasses() : getDesktopHeaderClasses();\n };\n\n /**\n * Get responsive classes for video container\n * @returns className string for video container aspect ratio based on screen size\n */\n const getVideoContainerClasses = (): string => {\n if (isTinyMobile) return 'aspect-square'; // 1:1 ratio for screens < 320px\n if (isExtraSmallMobile) return 'aspect-[4/3]'; // 4:3 ratio for screens < 375px\n if (isSmallMobile) return 'aspect-[16/12]'; // 16:12 ratio for screens < 425px\n return 'aspect-video'; // 16:9 ratio for larger screens\n };\n\n return {\n isMobile,\n isTablet,\n isSmallMobile,\n isExtraSmallMobile,\n isUltraSmallMobile,\n isTinyMobile,\n getFormContainerClasses,\n getHeaderClasses,\n getMobileHeaderClasses,\n getDesktopHeaderClasses,\n getVideoContainerClasses,\n getDeviceType,\n };\n};\n","export const BookOpenText = ({\n size,\n color,\n}: {\n size: number;\n color: string;\n}) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M29 6H20C19.2238 6 18.4582 6.18073 17.7639 6.52786C17.0697 6.875 16.4657 7.37902 16 8C15.5343 7.37902 14.9303 6.875 14.2361 6.52786C13.5418 6.18073 12.7762 6 12 6H3C2.73478 6 2.48043 6.10536 2.29289 6.29289C2.10536 6.48043 2 6.73478 2 7V25C2 25.2652 2.10536 25.5196 2.29289 25.7071C2.48043 25.8946 2.73478 26 3 26H12C12.7956 26 13.5587 26.3161 14.1213 26.8787C14.6839 27.4413 15 28.2044 15 29C15 29.2652 15.1054 29.5196 15.2929 29.7071C15.4804 29.8946 15.7348 30 16 30C16.2652 30 16.5196 29.8946 16.7071 29.7071C16.8946 29.5196 17 29.2652 17 29C17 28.2044 17.3161 27.4413 17.8787 26.8787C18.4413 26.3161 19.2044 26 20 26H29C29.2652 26 29.5196 25.8946 29.7071 25.7071C29.8946 25.5196 30 25.2652 30 25V7C30 6.73478 29.8946 6.48043 29.7071 6.29289C29.5196 6.10536 29.2652 6 29 6ZM12 24H4V8H12C12.7956 8 13.5587 8.31607 14.1213 8.87868C14.6839 9.44129 15 10.2044 15 11V25C14.1353 24.3493 13.0821 23.9983 12 24ZM28 24H20C18.9179 23.9983 17.8647 24.3493 17 25V11C17 10.2044 17.3161 9.44129 17.8787 8.87868C18.4413 8.31607 19.2044 8 20 8H28V24ZM20 11H25C25.2652 11 25.5196 11.1054 25.7071 11.2929C25.8946 11.4804 26 11.7348 26 12C26 12.2652 25.8946 12.5196 25.7071 12.7071C25.5196 12.8946 25.2652 13 25 13H20C19.7348 13 19.4804 12.8946 19.2929 12.7071C19.1054 12.5196 19 12.2652 19 12C19 11.7348 19.1054 11.4804 19.2929 11.2929C19.4804 11.1054 19.7348 11 20 11ZM26 16C26 16.2652 25.8946 16.5196 25.7071 16.7071C25.5196 16.8946 25.2652 17 25 17H20C19.7348 17 19.4804 16.8946 19.2929 16.7071C19.1054 16.5196 19 16.2652 19 16C19 15.7348 19.1054 15.4804 19.2929 15.2929C19.4804 15.1054 19.7348 15 20 15H25C25.2652 15 25.5196 15.1054 25.7071 15.2929C25.8946 15.4804 26 15.7348 26 16ZM26 20C26 20.2652 25.8946 20.5196 25.7071 20.7071C25.5196 20.8946 25.2652 21 25 21H20C19.7348 21 19.4804 20.8946 19.2929 20.7071C19.1054 20.5196 19 20.2652 19 20C19 19.7348 19.1054 19.4804 19.2929 19.2929C19.4804 19.1054 19.7348 19 20 19H25C25.2652 19 25.5196 19.1054 25.7071 19.2929C25.8946 19.4804 26 19.7348 26 20Z\"\n fill={color}\n />\n </svg>\n);\n","export const HeadCircuit = ({\n size,\n color,\n}: {\n size: number;\n color: string;\n}) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M24.0625 21.4338C25.327 20.3715 26.3372 19.0392 27.0187 17.5348C27.7001 16.0304 28.0354 14.3924 28 12.7413C27.875 7.02751 23.2987 2.31626 17.595 2.01626C16.1233 1.93616 14.6506 2.15261 13.2642 2.65277C11.8778 3.15293 10.6061 3.92659 9.52453 4.92781C8.44297 5.92903 7.57365 7.13739 6.96819 8.48112C6.36272 9.82485 6.03347 11.2766 5.99997 12.75L3.19372 18.1475C3.18247 18.17 3.17122 18.1925 3.16122 18.215C2.96003 18.6839 2.94569 19.212 3.12114 19.6912C3.29659 20.1704 3.64855 20.5644 4.10497 20.7925L4.13622 20.8063L6.99997 22.1175V26C6.99997 26.5304 7.21068 27.0392 7.58576 27.4142C7.96083 27.7893 8.46954 28 8.99997 28H15C15.2652 28 15.5195 27.8947 15.7071 27.7071C15.8946 27.5196 16 27.2652 16 27C16 26.7348 15.8946 26.4804 15.7071 26.2929C15.5195 26.1054 15.2652 26 15 26H8.99997V21.4763C9.00011 21.2846 8.94517 21.0969 8.84168 20.9356C8.73818 20.7742 8.5905 20.646 8.41622 20.5663L4.99997 19L7.88372 13.4575C7.95889 13.3166 7.99878 13.1597 7.99997 13C7.99968 10.9604 8.69216 8.98124 9.96395 7.38674C11.2357 5.79224 13.0114 4.677 15 4.22376V6.17251C14.3328 6.4084 13.7704 6.87258 13.4123 7.48299C13.0543 8.0934 12.9235 8.81075 13.0432 9.50824C13.1628 10.2057 13.5252 10.8385 14.0663 11.2946C14.6074 11.7508 15.2923 12.0009 16 12.0009C16.7077 12.0009 17.3926 11.7508 17.9336 11.2946C18.4747 10.8385 18.8371 10.2057 18.9568 9.50824C19.0764 8.81075 18.9457 8.0934 18.5876 7.48299C18.2295 6.87258 17.6672 6.4084 17 6.17251V4.00001C17.1625 4.00001 17.325 4.00001 17.4875 4.01251C19.2608 4.11409 20.9649 4.73627 22.3864 5.80124C23.808 6.86621 24.8841 8.32669 25.48 10H23C22.8533 9.99995 22.7084 10.0322 22.5755 10.0944C22.4426 10.1566 22.3251 10.2473 22.2312 10.36L19.0425 14.1875C18.3774 13.9397 17.6462 13.9351 16.9781 14.1744C16.3099 14.4138 15.748 14.8817 15.3916 15.4954C15.0352 16.1092 14.9073 16.8292 15.0306 17.5281C15.1538 18.227 15.5203 18.8598 16.0652 19.3146C16.61 19.7694 17.2981 20.0168 18.0078 20.0132C18.7175 20.0095 19.4031 19.755 19.9432 19.2947C20.4834 18.8343 20.8433 18.1977 20.9594 17.4976C21.0754 16.7974 20.9402 16.0788 20.5775 15.4688L23.4687 12H25.9425C25.9725 12.26 25.9908 12.5225 25.9975 12.7875C26.0286 14.2198 25.7187 15.639 25.0931 16.9278C24.4676 18.2167 23.5445 19.3383 22.4 20.2C22.2589 20.3057 22.1484 20.4469 22.0794 20.6091C22.0105 20.7713 21.9857 20.9489 22.0075 21.1238L23.0075 29.1238C23.0379 29.3653 23.1554 29.5874 23.3379 29.7485C23.5203 29.9095 23.7553 29.9985 23.9987 29.9988C24.0405 29.9988 24.0822 29.9962 24.1237 29.9913C24.2541 29.975 24.3799 29.9333 24.4942 29.8684C24.6084 29.8035 24.7087 29.7168 24.7893 29.6131C24.87 29.5094 24.9295 29.3909 24.9643 29.2643C24.9992 29.1376 25.0087 29.0054 24.9925 28.875L24.0625 21.4338ZM16 10C15.8022 10 15.6088 9.94136 15.4444 9.83148C15.28 9.7216 15.1518 9.56542 15.0761 9.38269C15.0004 9.19997 14.9806 8.9989 15.0192 8.80492C15.0578 8.61094 15.153 8.43275 15.2929 8.2929C15.4327 8.15305 15.6109 8.05781 15.8049 8.01922C15.9989 7.98064 16.1999 8.00044 16.3827 8.07613C16.5654 8.15182 16.7216 8.27999 16.8314 8.44444C16.9413 8.60889 17 8.80223 17 9.00001C17 9.26523 16.8946 9.51958 16.7071 9.70712C16.5195 9.89465 16.2652 10 16 10ZM18 18C17.8022 18 17.6088 17.9414 17.4444 17.8315C17.28 17.7216 17.1518 17.5654 17.0761 17.3827C17.0004 17.2 16.9806 16.9989 17.0192 16.8049C17.0578 16.6109 17.153 16.4328 17.2929 16.2929C17.4327 16.153 17.6109 16.0578 17.8049 16.0192C17.9989 15.9806 18.1999 16.0004 18.3827 16.0761C18.5654 16.1518 18.7216 16.28 18.8314 16.4444C18.9413 16.6089 19 16.8022 19 17C19 17.2652 18.8946 17.5196 18.7071 17.7071C18.5195 17.8947 18.2652 18 18 18Z\"\n fill={color}\n />\n </svg>\n);\n","export const Microscope = ({\n size,\n color,\n}: {\n size: number;\n color: string;\n}) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M28 26H25.4925C26.7637 24.4552 27.5898 22.5932 27.882 20.6142C28.1743 18.6351 27.9216 16.6138 27.1511 14.7676C26.3806 12.9213 25.1215 11.32 23.5092 10.1358C21.8968 8.95153 19.9922 8.22913 18 8.04625V4C18 3.46957 17.7893 2.96086 17.4142 2.58579C17.0391 2.21071 16.5304 2 16 2H10C9.46957 2 8.96086 2.21071 8.58579 2.58579C8.21071 2.96086 8 3.46957 8 4V17C8 17.5304 8.21071 18.0391 8.58579 18.4142C8.96086 18.7893 9.46957 19 10 19H16C16.5304 19 17.0391 18.7893 17.4142 18.4142C17.7893 18.0391 18 17.5304 18 17V10.0575C19.7643 10.2552 21.4306 10.9703 22.7895 12.1128C24.1483 13.2553 25.1389 14.7742 25.6366 16.4783C26.1343 18.1824 26.1169 19.9957 25.5866 21.69C25.0563 23.3842 24.0368 24.8838 22.6562 26H4C3.73478 26 3.48043 26.1054 3.29289 26.2929C3.10536 26.4804 3 26.7348 3 27C3 27.2652 3.10536 27.5196 3.29289 27.7071C3.48043 27.8946 3.73478 28 4 28H28C28.2652 28 28.5196 27.8946 28.7071 27.7071C28.8946 27.5196 29 27.2652 29 27C29 26.7348 28.8946 26.4804 28.7071 26.2929C28.5196 26.1054 28.2652 26 28 26ZM16 17H10V4H16V17ZM9 23C8.73478 23 8.48043 22.8946 8.29289 22.7071C8.10536 22.5196 8 22.2652 8 22C8 21.7348 8.10536 21.4804 8.29289 21.2929C8.48043 21.1054 8.73478 21 9 21H17C17.2652 21 17.5196 21.1054 17.7071 21.2929C17.8946 21.4804 18 21.7348 18 22C18 22.2652 17.8946 22.5196 17.7071 22.7071C17.5196 22.8946 17.2652 23 17 23H9Z\"\n fill={color}\n />\n </svg>\n);\n","import { BookOpenText } from '../../assets/icons/subjects/BookOpenText';\nimport { ChatEN } from '../../assets/icons/subjects/ChatEN';\nimport { ChatES } from '../../assets/icons/subjects/ChatES';\nimport { ChatPT } from '../../assets/icons/subjects/ChatPT';\nimport { HeadCircuit } from '../../assets/icons/subjects/HeadCircuit';\nimport { Microscope } from '../../assets/icons/subjects/Microscope';\nimport { SubjectEnum } from '../../enums/SubjectEnum';\nimport {\n ArticleNyTimes,\n Atom,\n Book,\n BookBookmark,\n DribbbleLogo,\n Flask,\n GlobeHemisphereWest,\n MathOperations,\n Palette,\n Person,\n Scroll,\n} from 'phosphor-react';\nimport { ReactElement } from 'react';\nexport interface IconProps {\n size?: number;\n color?: string;\n}\n\nexport interface SubjectData {\n icon: ReactElement<IconProps>;\n colorClass: string;\n name: string;\n}\n\nexport const SubjectInfo: Record<SubjectEnum, SubjectData> = {\n [SubjectEnum.FISICA]: {\n icon: <Atom size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-1',\n name: SubjectEnum.FISICA,\n },\n [SubjectEnum.HISTORIA]: {\n icon: <Scroll size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-2',\n name: SubjectEnum.HISTORIA,\n },\n [SubjectEnum.LITERATURA]: {\n icon: <BookOpenText size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-3',\n name: SubjectEnum.LITERATURA,\n },\n [SubjectEnum.GEOGRAFIA]: {\n icon: <GlobeHemisphereWest size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-4',\n name: SubjectEnum.GEOGRAFIA,\n },\n [SubjectEnum.BIOLOGIA]: {\n icon: <Microscope size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-5',\n name: SubjectEnum.BIOLOGIA,\n },\n [SubjectEnum.PORTUGUES]: {\n icon: <ChatPT size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-6',\n name: SubjectEnum.PORTUGUES,\n },\n [SubjectEnum.QUIMICA]: {\n icon: <Flask size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-7',\n name: SubjectEnum.QUIMICA,\n },\n [SubjectEnum.ARTES]: {\n icon: <Palette size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-8',\n name: SubjectEnum.ARTES,\n },\n [SubjectEnum.MATEMATICA]: {\n icon: <MathOperations size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-9',\n name: SubjectEnum.MATEMATICA,\n },\n [SubjectEnum.FILOSOFIA]: {\n icon: <HeadCircuit size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-10',\n name: SubjectEnum.FILOSOFIA,\n },\n [SubjectEnum.ESPANHOL]: {\n icon: <ChatES size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-11',\n name: SubjectEnum.ESPANHOL,\n },\n [SubjectEnum.REDACAO]: {\n icon: <ArticleNyTimes size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-12',\n name: SubjectEnum.REDACAO,\n },\n [SubjectEnum.SOCIOLOGIA]: {\n icon: <Person size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-13',\n name: SubjectEnum.SOCIOLOGIA,\n },\n [SubjectEnum.INGLES]: {\n icon: <ChatEN size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-14',\n name: SubjectEnum.INGLES,\n },\n [SubjectEnum.EDUCACAO_FISICA]: {\n icon: <DribbbleLogo size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-15',\n name: SubjectEnum.EDUCACAO_FISICA,\n },\n [SubjectEnum.TRILHAS]: {\n icon: <BookBookmark size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-16',\n name: SubjectEnum.TRILHAS,\n },\n};\n\nexport const getSubjectInfo = (subject: SubjectEnum): SubjectData => {\n return (\n SubjectInfo[subject] || {\n icon: <Book size={17} color=\"currentColor\" />,\n colorClass: 'bg-subject-16',\n name: subject,\n }\n );\n};\n\nexport const getSubjectIcon = (subject: SubjectEnum): ReactElement => {\n return SubjectInfo[subject].icon;\n};\n\nexport const getSubjectColorClass = (subject: SubjectEnum): string => {\n return SubjectInfo[subject].colorClass;\n};\n\nexport const getSubjectName = (subject: SubjectEnum): string => {\n return SubjectInfo[subject].name;\n};\n","import { useState, useCallback } from 'react';\nimport type { BaseApiClient } from '../types/api';\nimport type {\n QuestionsFilterBody,\n QuestionsListResponseActivity,\n QuestionsByIdsBody,\n QuestionsByIdsResponse,\n Question,\n Pagination,\n PaginationActivity,\n} from '../types/questions';\n\n// ============================================================================\n// Hook State Types\n// ============================================================================\n\n/**\n * Hook state interface\n */\ninterface UseQuestionsListState {\n questions: Question[];\n pagination: Pagination | null;\n loading: boolean;\n loadingMore: boolean;\n error: string | null;\n currentFilters: Partial<QuestionsFilterBody> | null;\n}\n\n// ============================================================================\n// Hook Return Type\n// ============================================================================\n\n/**\n * Hook return type\n */\nexport interface UseQuestionsListReturn extends UseQuestionsListState {\n fetchQuestions: (\n filters?: Partial<QuestionsFilterBody>,\n append?: boolean\n ) => Promise<void>;\n fetchRandomQuestions: (\n count: number,\n filters?: Partial<QuestionsFilterBody>\n ) => Promise<Question[]>;\n fetchQuestionsByIds: (questionIds: string[]) => Promise<Question[]>;\n loadMore: () => Promise<void>;\n reset: () => void;\n}\n\n// ============================================================================\n// Main Hook Implementation\n// ============================================================================\n\nconst useQuestionsListImpl = (\n apiClient: BaseApiClient\n): UseQuestionsListReturn => {\n const [state, setState] = useState<UseQuestionsListState>({\n questions: [],\n pagination: null,\n loading: false,\n loadingMore: false,\n error: null,\n currentFilters: null,\n });\n\n const updateState = useCallback((updates: Partial<UseQuestionsListState>) => {\n setState((prev) => ({ ...prev, ...updates }));\n }, []);\n\n const handleError = useCallback(\n (error: unknown) => {\n console.error('Erro ao carregar questões:', error);\n let errorMessage = 'Erro ao carregar questões';\n\n if (error && typeof error === 'object' && 'response' in error) {\n const axiosError = error as {\n response?: { data?: { message?: string } };\n message?: string;\n };\n errorMessage =\n axiosError?.response?.data?.message ||\n axiosError?.message ||\n errorMessage;\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n updateState({\n loading: false,\n loadingMore: false,\n error: errorMessage,\n });\n },\n [updateState]\n );\n\n /**\n * Convert PaginationActivity to Pagination format\n */\n const convertPagination = (\n pagination: PaginationActivity | undefined\n ): Pagination | null => {\n if (!pagination) return null;\n return {\n page: pagination.page,\n pageSize: pagination.limit,\n total: pagination.total,\n totalPages: pagination.totalPages,\n hasNext: pagination.hasNext,\n hasPrevious: pagination.hasPrev,\n };\n };\n\n /**\n * Fetch questions from API with filters\n * @param filters - Filters to apply\n * @param append - If true, appends results to existing questions; if false, replaces them\n */\n const fetchQuestions = useCallback(\n async (filters?: Partial<QuestionsFilterBody>, append: boolean = false) => {\n if (append) {\n setState((prev) => ({ ...prev, loadingMore: true, error: null }));\n } else {\n updateState({ loading: true, error: null, questions: [] });\n }\n\n try {\n const validatedFilters: QuestionsFilterBody = {\n ...filters,\n };\n\n const response = await apiClient.post<QuestionsListResponseActivity>(\n '/questions/list',\n validatedFilters\n );\n\n setState((prev) => ({\n loading: false,\n loadingMore: false,\n questions: append\n ? [...prev.questions, ...response.data.data.questions]\n : response.data.data.questions,\n pagination: convertPagination(response.data.data.pagination),\n error: null,\n currentFilters: validatedFilters,\n }));\n } catch (error) {\n setState((prev) => ({\n ...prev,\n loading: false,\n loadingMore: false,\n }));\n handleError(error);\n }\n },\n [apiClient, updateState, handleError]\n );\n\n /**\n * Fetch random questions from API\n * @param count - Number of random questions to fetch\n * @param filters - Optional filters to apply\n * @returns Promise with array of questions\n */\n const fetchRandomQuestions = useCallback(\n async (\n count: number,\n filters?: Partial<QuestionsFilterBody>\n ): Promise<Question[]> => {\n try {\n const validatedFilters: QuestionsFilterBody = {\n ...filters,\n randomQuestions: count,\n };\n\n const response = await apiClient.post<QuestionsListResponseActivity>(\n '/questions/list',\n validatedFilters\n );\n\n return response.data.data.questions;\n } catch (error) {\n handleError(error);\n return [];\n }\n },\n [apiClient, handleError]\n );\n\n /**\n * Fetch questions by their IDs\n * @param questionIds - Array of question IDs to fetch\n * @returns Promise with array of questions\n */\n const fetchQuestionsByIds = useCallback(\n async (questionIds: string[]): Promise<Question[]> => {\n try {\n const body: QuestionsByIdsBody & Record<string, unknown> = {\n questionsIds: questionIds,\n };\n\n const response = await apiClient.post<QuestionsByIdsResponse>(\n '/questions/by-ids',\n body\n );\n\n return response.data.data.questions;\n } catch (error) {\n handleError(error);\n return [];\n }\n },\n [apiClient, handleError]\n );\n\n const loadMore = useCallback(async () => {\n setState((prev) => {\n const { currentFilters, pagination, loadingMore: isLoadingMore } = prev;\n\n if (isLoadingMore || !currentFilters || !pagination?.hasNext) {\n return prev;\n }\n\n const nextPageFilters = {\n ...currentFilters,\n page: pagination.page + 1,\n };\n\n fetchQuestions(nextPageFilters, true).catch((error) => {\n console.error('Erro ao carregar mais questões:', error);\n });\n\n return {\n ...prev,\n loadingMore: true,\n };\n });\n }, [fetchQuestions]);\n\n /**\n * Reset questions list\n */\n const reset = useCallback(() => {\n setState({\n questions: [],\n pagination: null,\n loading: false,\n loadingMore: false,\n error: null,\n currentFilters: null,\n });\n }, []);\n\n return {\n ...state,\n fetchQuestions,\n fetchRandomQuestions,\n fetchQuestionsByIds,\n loadMore,\n reset,\n };\n};\n\n// ============================================================================\n// Hook Factory\n// ============================================================================\n\n/**\n * Create a questions list hook with API client injection.\n * @param apiClient - API client instance\n * @returns Pre-configured useQuestionsList hook\n *\n * @example\n * // In your app setup\n * import { createUseQuestionsList } from 'analytica-frontend-lib';\n * import api from './services/api';\n *\n * export const useQuestionsList = createUseQuestionsList(api);\n *\n * // Then use directly in components\n * const { questions, fetchQuestions, loadMore } = useQuestionsList();\n */\nexport const createUseQuestionsList = (apiClient: BaseApiClient) => {\n return (): UseQuestionsListReturn => useQuestionsListImpl(apiClient);\n};\n\n/**\n * Create a pre-configured questions list hook\n * This is a convenience function that returns a hook ready to use\n *\n * @param apiClient - API client instance\n * @returns Pre-configured useQuestionsList hook\n *\n * @example\n * // In your app setup\n * import { createQuestionsListHook } from 'analytica-frontend-lib';\n * import api from './services/api';\n *\n * export const useQuestionsList = createQuestionsListHook(api);\n *\n * // Then use directly in components\n * const { questions, fetchQuestions, loadMore } = useQuestionsList();\n */\nexport const createQuestionsListHook = (apiClient: BaseApiClient) => {\n return createUseQuestionsList(apiClient);\n};\n","import type {\n ActivityFiltersData,\n PreviewQuestion,\n QuestionActivity as Question,\n} from '../..';\nimport { QUESTION_TYPE } from '../Quiz/useQuizStore';\nimport type {\n BackendFiltersFormat,\n School,\n SchoolYear,\n Class,\n Student,\n} from './ActivityCreate.types';\nimport { ActivityType } from './ActivityCreate.types';\nimport type { BaseApiClient } from '../../types/api';\nimport type { CategoryConfig } from '../CheckBoxGroup/CheckBoxGroup';\n\n/**\n * Set of valid QUESTION_TYPE enum values for runtime validation\n */\nconst VALID_QUESTION_TYPES = new Set(Object.values(QUESTION_TYPE));\n\n/**\n * Type guard to validate if a string is a valid QUESTION_TYPE\n * @param type - String to validate\n * @returns True if type is a valid QUESTION_TYPE enum value\n */\nconst isValidQuestionType = (type: string): type is QUESTION_TYPE => {\n return VALID_QUESTION_TYPES.has(type as QUESTION_TYPE);\n};\n\n/**\n * Knowledge area interface for subject lookup\n */\nexport interface KnowledgeArea {\n id: string;\n name: string;\n}\n\n/**\n * Convert ActivityFiltersData to backend format\n *\n * @param filters - ActivityFiltersData to convert, can be null\n * @returns BackendFiltersFormat object with converted filter data\n *\n * @example\n * ```ts\n * const backendFilters = convertFiltersToBackendFormat({\n * types: ['ALTERNATIVA'],\n * subjectIds: ['math'],\n * // ...\n * });\n * ```\n */\nexport function convertFiltersToBackendFormat(\n filters: ActivityFiltersData | null\n): BackendFiltersFormat {\n if (!filters) {\n return {\n questionTypes: [],\n questionBanks: [],\n subjects: [],\n topics: [],\n subtopics: [],\n contents: [],\n };\n }\n\n return {\n questionTypes: filters.types,\n questionBanks: filters.bankIds,\n subjects: filters.subjectIds,\n topics: filters.topicIds,\n subtopics: filters.subtopicIds,\n contents: filters.contentIds,\n };\n}\n\n/**\n * Convert backend filters format to ActivityFiltersData\n *\n * @param backendFilters - BackendFiltersFormat to convert, can be null\n * @returns ActivityFiltersData object with converted filter data, or null if input is null\n *\n * @example\n * ```ts\n * const activityFilters = convertBackendFiltersToActivityFiltersData({\n * questionTypes: ['ALTERNATIVA'],\n * subjects: ['math'],\n * // ...\n * });\n * ```\n */\nexport function convertBackendFiltersToActivityFiltersData(\n backendFilters: BackendFiltersFormat | null\n): ActivityFiltersData | null {\n if (!backendFilters) {\n return null;\n }\n\n return {\n types: (backendFilters.questionTypes || []).filter(isValidQuestionType),\n bankIds: backendFilters.questionBanks || [],\n subjectIds: backendFilters.subjects || [],\n topicIds: backendFilters.topics || [],\n subtopicIds: backendFilters.subtopics || [],\n contentIds: backendFilters.contents || [],\n yearIds: [],\n };\n}\n\n/**\n * Get subject name from subjectId by searching in knowledge areas\n *\n * @param subjectId - The subject ID to look up\n * @param knowledgeAreas - Array of knowledge areas to search in\n * @returns The subject name if found, null otherwise\n *\n * @example\n * ```ts\n * const subjectName = getSubjectName('math', [\n * { id: 'math', name: 'Matemática' }\n * ]);\n * // Returns: 'Matemática'\n * ```\n */\nexport function getSubjectName(\n subjectId: string | null,\n knowledgeAreas: KnowledgeArea[]\n): string | null {\n if (!subjectId || !knowledgeAreas.length) {\n return null;\n }\n const subject = knowledgeAreas.find((area) => area.id === subjectId);\n return subject?.name || null;\n}\n\n/**\n * Get activity type label using object literal mapping\n *\n * @param type - Activity type (ActivityType enum)\n * @returns Label string for the activity type\n *\n * @example\n * ```ts\n * const label = getActivityTypeLabel(ActivityType.RASCUNHO);\n * // Returns: 'Rascunho'\n * ```\n */\nexport function getActivityTypeLabel(type: ActivityType): string {\n const activityTypeLabels: Record<ActivityType, string> = {\n [ActivityType.RASCUNHO]: 'Rascunho',\n [ActivityType.MODELO]: 'Modelo',\n [ActivityType.ATIVIDADE]: 'Atividade',\n };\n return activityTypeLabels[type];\n}\n\n/**\n * Generate activity title based on type and subject\n *\n * @param type - Activity type (ActivityType enum)\n * @param subjectId - Subject ID to get name from\n * @param knowledgeAreas - Array of knowledge areas for subject lookup\n * @returns Generated title string\n *\n * @example\n * ```ts\n * const title = generateTitle(ActivityType.RASCUNHO, 'math', [\n * { id: 'math', name: 'Matemática' }\n * ]);\n * // Returns: 'Rascunho - Matemática'\n * ```\n */\nexport function generateTitle(\n type: ActivityType,\n subjectId: string | null,\n knowledgeAreas: KnowledgeArea[]\n): string {\n const typeLabel = getActivityTypeLabel(type);\n const subjectName = getSubjectName(subjectId, knowledgeAreas);\n return subjectName ? `${typeLabel} - ${subjectName}` : typeLabel;\n}\n\n/**\n * Format time for display (HH:mm format)\n *\n * @param date - Date object to format\n * @returns Formatted time string in HH:mm format\n *\n * @example\n * ```ts\n * const time = formatTime(new Date('2025-01-01T14:30:00'));\n * // Returns: '14:30'\n * ```\n */\nexport function formatTime(date: Date): string {\n const hours = date.getHours().toString().padStart(2, '0');\n const minutes = date.getMinutes().toString().padStart(2, '0');\n return `${hours}:${minutes}`;\n}\n\n/**\n * Converte ActivityType para o formato usado na URL\n *\n * @param type - ActivityType enum value\n * @returns String representation for URL (rascunho or modelo)\n *\n * @example\n * ```ts\n * const urlType = getTypeFromUrl(ActivityType.RASCUNHO);\n * // Returns: 'rascunho'\n * ```\n */\nexport function getTypeFromUrl(type: ActivityType): string {\n switch (type) {\n case ActivityType.RASCUNHO:\n return 'rascunho';\n case ActivityType.MODELO:\n return 'modelo';\n default:\n return 'rascunho';\n }\n}\n\n/**\n * Converte string da URL para ActivityType\n *\n * @param type - String from URL (rascunho or modelo)\n * @returns ActivityType enum value\n *\n * @example\n * ```ts\n * const activityType = getTypeFromUrlString('rascunho');\n * // Returns: ActivityType.RASCUNHO\n * ```\n */\nexport function getTypeFromUrlString(type: string | undefined): ActivityType {\n switch (type) {\n case 'rascunho':\n return ActivityType.RASCUNHO;\n case 'modelo':\n return ActivityType.MODELO;\n default:\n return ActivityType.RASCUNHO;\n }\n}\n\n/**\n * Convert Question to PreviewQuestion format\n *\n * @param question - Question object to convert\n * @returns PreviewQuestion object with converted data\n *\n * @example\n * ```ts\n * const previewQuestion = convertQuestionToPreview({\n * id: 'q1',\n * statement: 'Test question',\n * questionType: 'ALTERNATIVA',\n * options: [{ id: 'opt1', option: 'Option 1' }],\n * knowledgeMatrix: [{\n * subject: { name: 'Math', color: '#000', icon: 'Math' }\n * }]\n * });\n * ```\n */\nexport function convertQuestionToPreview(question: Question): PreviewQuestion {\n const subjectInfo =\n question.knowledgeMatrix && question.knowledgeMatrix.length > 0\n ? {\n subjectName: question.knowledgeMatrix[0].subject?.name || undefined,\n subjectColor: question.knowledgeMatrix[0].subject?.color || undefined,\n iconName: question.knowledgeMatrix[0].subject?.icon || undefined,\n }\n : {};\n\n return {\n id: question.id,\n enunciado: question.statement,\n questionType: question.questionType,\n question: question.options\n ? {\n options: question.options.map(\n (opt: { id: string; option: string }) => ({\n id: opt.id,\n option: opt.option,\n })\n ),\n correctOptionIds: [],\n }\n : undefined,\n ...subjectInfo,\n };\n}\n\n/**\n * Fetch all students by paginating through all pages\n *\n * @param apiClient - API client instance\n * @returns Promise resolving to array of all students\n *\n * @example\n * ```ts\n * const students = await fetchAllStudents(apiClient);\n * ```\n */\nexport async function fetchAllStudents(\n apiClient: BaseApiClient\n): Promise<Student[]> {\n const allStudents: Student[] = [];\n let currentPage = 1;\n let totalPages = 1;\n const limit = 100;\n\n do {\n const response = await apiClient.get<{\n message: string;\n data: {\n students: Student[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n };\n }>(`/students?page=${currentPage}&limit=${limit}`);\n\n const { students, pagination } = response.data.data;\n allStudents.push(...students);\n totalPages = pagination.totalPages;\n currentPage++;\n } while (currentPage <= totalPages);\n\n return allStudents;\n}\n\n/**\n * Load categories data from API and transform to CategoryConfig format\n *\n * @param apiClient - API client instance\n * @param existingCategories - Current categories array to check if already loaded\n * @returns Promise resolving to array of CategoryConfig\n *\n * @example\n * ```ts\n * const categories = await loadCategoriesData(apiClient, []);\n * ```\n */\nexport async function loadCategoriesData(\n apiClient: BaseApiClient,\n existingCategories: CategoryConfig[]\n): Promise<CategoryConfig[]> {\n if (existingCategories.length > 0) {\n return existingCategories;\n }\n\n const [schoolsResponse, schoolYearsResponse, classesResponse, allStudents] =\n await Promise.all([\n apiClient.get<{ message: string; data: { schools: School[] } }>(\n '/school'\n ),\n apiClient.get<{\n message: string;\n data: { schoolYears: SchoolYear[] };\n }>('/schoolYear'),\n apiClient.get<{\n message: string;\n data: { classes: Class[] };\n }>('/classes'),\n fetchAllStudents(apiClient),\n ]);\n\n const schools = schoolsResponse.data.data.schools;\n const schoolYears = schoolYearsResponse.data.data.schoolYears;\n const classes = classesResponse.data.data.classes;\n const students = allStudents;\n\n const transformedCategories: CategoryConfig[] = [\n {\n key: 'escola',\n label: 'Escola',\n itens: schools.map((s) => ({ id: s.id, name: s.companyName })),\n selectedIds: [],\n },\n {\n key: 'serie',\n label: 'Série',\n dependsOn: ['escola'],\n filteredBy: [{ key: 'escola', internalField: 'schoolId' }],\n itens: schoolYears.map((sy) => ({\n id: sy.id,\n name: sy.name,\n schoolId: sy.schoolId,\n })),\n selectedIds: [],\n },\n {\n key: 'turma',\n label: 'Turma',\n dependsOn: ['serie'],\n filteredBy: [{ key: 'serie', internalField: 'schoolYearId' }],\n itens: classes.map((c) => ({\n id: c.id,\n name: c.name,\n schoolYearId: c.schoolYearId,\n })),\n selectedIds: [],\n },\n {\n key: 'alunos',\n label: 'Alunos',\n dependsOn: ['turma'],\n filteredBy: [{ key: 'turma', internalField: 'classId' }],\n itens: students.map((s) => ({\n id: s.id,\n name: s.name,\n classId: s.classId,\n studentId: s.id,\n userInstitutionId: s.userInstitutionId,\n })),\n selectedIds: [],\n },\n ];\n\n return transformedCategories;\n}\n","import React, { forwardRef, useRef, useCallback } from 'react';\nimport { QUESTION_TYPE } from '../Quiz/useQuizStore';\nimport LatexRenderer from '../LatexRenderer/LatexRenderer';\nimport type { PreviewQuestion } from '../ActivityPreview/ActivityPreview';\n\ninterface QuestionsPdfGeneratorProps {\n questions: PreviewQuestion[];\n onPrint?: () => void;\n onPrintError?: (error: Error) => void;\n /**\n * Optional render prop to access the handlePrint function.\n * If not provided, the component will render the hidden PDF content only.\n * Consumers can use the hook directly (useQuestionsPdfPrint) for more control.\n */\n children?: (handlePrint: () => void) => React.ReactNode;\n}\n\n/**\n * Component that renders questions in a format suitable for PDF printing\n * This component is hidden from view and only used for printing\n */\nexport const QuestionsPdfContent = forwardRef<\n HTMLDivElement,\n { questions: PreviewQuestion[] }\n>(({ questions }, ref) => {\n const getLetterByIndex = (index: number): string => {\n return String.fromCodePoint(97 + index);\n };\n\n const renderAlternative = (question: PreviewQuestion) => {\n if (!question.question?.options || question.question.options.length === 0) {\n return null;\n }\n\n return (\n <ol\n type=\"a\"\n style={{\n marginTop: '12px',\n marginBottom: '12px',\n paddingLeft: '24px',\n }}\n >\n {question.question.options.map((option) => (\n <li\n key={option.id}\n style={{\n marginBottom: '8px',\n lineHeight: '1.6',\n }}\n >\n <LatexRenderer content={option.option} />\n </li>\n ))}\n </ol>\n );\n };\n\n const renderMultipleChoice = (question: PreviewQuestion) => {\n if (!question.question?.options || question.question.options.length === 0) {\n return null;\n }\n\n return (\n <div\n style={{\n marginTop: '12px',\n marginBottom: '12px',\n }}\n >\n {question.question.options.map((option, index) => {\n const letter = getLetterByIndex(index);\n return (\n <div\n key={option.id}\n style={{\n marginBottom: '12px',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n lineHeight: '1.6',\n }}\n >\n <span\n style={{\n marginTop: '2px',\n minWidth: '20px',\n fontSize: '16px',\n }}\n >\n ☐\n </span>\n <span\n style={{\n fontWeight: 'bold',\n marginRight: '4px',\n }}\n >\n {letter})\n </span>\n <div style={{ flex: 1 }}>\n <LatexRenderer content={option.option} />\n </div>\n </div>\n );\n })}\n </div>\n );\n };\n\n const renderDissertative = () => {\n return (\n <div\n style={{\n marginTop: '12px',\n marginBottom: '12px',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n }}\n >\n <span\n style={{\n fontWeight: 'bold',\n marginTop: '2px',\n }}\n >\n R:\n </span>\n <div\n style={{\n minHeight: '150px',\n flex: 1,\n }}\n />\n </div>\n </div>\n );\n };\n\n const renderTrueOrFalse = (question: PreviewQuestion) => {\n if (!question.question?.options || question.question.options.length === 0) {\n return null;\n }\n\n return (\n <div style={{ marginTop: '12px', marginBottom: '12px' }}>\n {question.question.options.map((option, index) => (\n <div\n key={option.id}\n style={{\n marginBottom: '16px',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '12px',\n }}\n >\n <span\n style={{\n fontWeight: 'bold',\n minWidth: '20px',\n }}\n >\n {getLetterByIndex(index)})\n </span>\n <div style={{ flex: 1 }}>\n <LatexRenderer content={option.option} />\n </div>\n <span\n style={{\n marginLeft: '8px',\n whiteSpace: 'nowrap',\n fontSize: '14px',\n }}\n >\n ( ) V ( ) F\n </span>\n </div>\n ))}\n </div>\n );\n };\n\n const renderQuestionTypeContent = (question: PreviewQuestion) => {\n type RenderFunction = (\n question: PreviewQuestion\n ) => ReturnType<typeof renderAlternative> | null;\n\n const renderMap: Record<QUESTION_TYPE, RenderFunction> = {\n [QUESTION_TYPE.ALTERNATIVA]: renderAlternative,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: renderMultipleChoice,\n [QUESTION_TYPE.DISSERTATIVA]: () => renderDissertative(),\n [QUESTION_TYPE.VERDADEIRO_FALSO]: renderTrueOrFalse,\n [QUESTION_TYPE.LIGAR_PONTOS]: () => null,\n [QUESTION_TYPE.PREENCHER]: () => null,\n [QUESTION_TYPE.IMAGEM]: () => null,\n };\n\n if (!question.questionType) {\n return null;\n }\n\n const renderFunction = renderMap[question.questionType];\n return renderFunction ? renderFunction(question) : null;\n };\n\n const renderQuestionContent = (question: PreviewQuestion, index: number) => {\n const questionNumber = index + 1;\n\n return (\n <div\n key={question.id}\n style={{\n marginBottom: '32px',\n pageBreakInside: 'avoid',\n }}\n >\n <h3\n style={{\n fontSize: '16px',\n fontWeight: 'bold',\n marginBottom: '12px',\n color: '#000',\n }}\n >\n Questão {questionNumber}\n </h3>\n\n {question.enunciado && (\n <div\n style={{\n marginBottom: '12px',\n lineHeight: '1.6',\n color: '#000',\n }}\n >\n <LatexRenderer content={question.enunciado} />\n </div>\n )}\n\n {renderQuestionTypeContent(question)}\n </div>\n );\n };\n\n return (\n <div\n ref={ref}\n className=\"questions-pdf-container\"\n style={{\n position: 'fixed',\n left: 0,\n top: 0,\n width: '210mm',\n minHeight: '297mm',\n visibility: 'hidden',\n pointerEvents: 'none',\n zIndex: -1,\n }}\n >\n <style>\n {`\n @media print {\n @page {\n margin: 20mm;\n size: A4;\n }\n \n body {\n margin: 0;\n padding: 0;\n }\n \n .questions-pdf-container {\n position: static !important;\n left: auto !important;\n top: auto !important;\n visibility: visible !important;\n pointer-events: auto !important;\n z-index: auto !important;\n padding: 0;\n margin: 0;\n font-family: Arial, sans-serif;\n font-size: 14px;\n line-height: 1.6;\n color: #000;\n width: auto;\n min-height: auto;\n }\n \n .questions-pdf-container h3 {\n page-break-after: avoid;\n }\n \n .questions-pdf-container > div {\n page-break-inside: avoid;\n }\n }\n `}\n </style>\n <div style={{ padding: '20px' }}>\n {questions.map((question, index) =>\n renderQuestionContent(question, index)\n )}\n </div>\n </div>\n );\n});\n\nQuestionsPdfContent.displayName = 'QuestionsPdfContent';\n\n/**\n * Collects relevant CSS styles from document stylesheets\n */\nconst collectRelevantStyles = (): string[] => {\n const styles: string[] = [];\n const styleSheets = Array.from(document.styleSheets);\n\n styleSheets.forEach((styleSheet) => {\n try {\n const cssRules = styleSheet.cssRules || [];\n Array.from(cssRules).forEach((rule) => {\n const ruleText = rule.cssText;\n if (ruleText.includes('katex') || ruleText.includes('questions-pdf')) {\n styles.push(ruleText);\n }\n });\n } catch (error) {\n if (typeof console !== 'undefined' && console.debug) {\n console.debug('Could not access stylesheet (likely CORS):', error);\n }\n }\n });\n\n return styles;\n};\n\n/**\n * Generates the HTML content for the print window\n *\n * Security note: contentHTML is already sanitized via DOMPurify in LatexRenderer\n * before reaching this function, so it's safe to inject into the template string.\n *\n * CSP note: This function loads KaTeX CSS from CDN. Ensure your Content Security Policy\n * allows: style-src 'self' https://cdn.jsdelivr.net;\n * Or consider serving KaTeX CSS locally for stricter CSP compliance.\n */\nconst generatePrintHTML = (contentHTML: string, styles: string[]): string => {\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Questões</title>\n <meta charset=\"utf-8\">\n <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/katex@0.16.27/dist/katex.min.css\">\n <style>\n @page {\n margin: 20mm;\n size: A4;\n }\n \n * {\n box-sizing: border-box;\n }\n \n body {\n margin: 0;\n padding: 0;\n font-family: Arial, sans-serif;\n font-size: 14px;\n line-height: 1.6;\n color: #000;\n }\n \n .questions-pdf-container {\n position: static !important;\n visibility: visible !important;\n pointer-events: auto !important;\n z-index: auto !important;\n left: auto !important;\n top: auto !important;\n width: auto !important;\n min-height: auto !important;\n padding: 0;\n margin: 0;\n }\n \n .questions-pdf-container h3 {\n page-break-after: avoid;\n font-size: 16px;\n font-weight: bold;\n margin-bottom: 12px;\n color: #000;\n }\n \n .questions-pdf-container > div {\n page-break-inside: avoid;\n }\n \n ol {\n margin-top: 12px;\n margin-bottom: 12px;\n padding-left: 24px;\n }\n \n li {\n margin-bottom: 8px;\n line-height: 1.6;\n }\n \n ${styles.join('\\n')}\n </style>\n </head>\n <body>\n <div class=\"questions-pdf-container\">\n ${contentHTML}\n </div>\n </body>\n </html>\n `;\n};\n\n/**\n * Sets up the print window onload handler with improved timing and cleanup\n */\nconst setupPrintWindowHandler = (printWindow: Window): void => {\n printWindow.onload = () => {\n const printAndCleanup = () => {\n try {\n printWindow.print();\n } finally {\n setTimeout(() => {\n if (printWindow && !printWindow.closed) {\n printWindow.close();\n }\n }, 1000);\n }\n };\n\n const fonts = printWindow.document.fonts;\n if (fonts && 'ready' in fonts) {\n fonts.ready\n .then(() => {\n setTimeout(printAndCleanup, 100);\n })\n .catch(() => {\n setTimeout(printAndCleanup, 500);\n });\n } else {\n setTimeout(printAndCleanup, 500);\n }\n };\n};\n\n/**\n * Hook to generate PDF from questions using native browser print API\n * Returns the content ref and print handler\n *\n * Security: Content is sanitized via DOMPurify in LatexRenderer before rendering.\n * CSP: Ensure your Content Security Policy allows loading KaTeX CSS from cdn.jsdelivr.net\n * or serve KaTeX CSS locally for stricter CSP compliance.\n */\nexport const useQuestionsPdfPrint = (\n questions: PreviewQuestion[],\n onPrint?: () => void,\n onPrintError?: (error: Error) => void\n) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n const handlePrint = useCallback(() => {\n try {\n onPrint?.();\n\n if (!contentRef.current) {\n throw new Error('Elemento de PDF não encontrado no DOM');\n }\n\n const printWindow = window.open('', '_blank');\n if (!printWindow) {\n throw new Error(\n 'Não foi possível abrir a janela de impressão. Verifique se os pop-ups estão bloqueados.'\n );\n }\n printWindow.opener = null;\n\n const contentHTML = contentRef.current.innerHTML;\n const styles = collectRelevantStyles();\n const htmlContent = generatePrintHTML(contentHTML, styles);\n\n const doc = printWindow.document;\n doc.open();\n doc.write(htmlContent);\n doc.close();\n\n setupPrintWindowHandler(printWindow);\n } catch (error) {\n const errorObj =\n error instanceof Error ? error : new Error(String(error));\n onPrintError?.(errorObj);\n console.error('Erro ao gerar PDF:', errorObj);\n }\n }, [onPrint, onPrintError]);\n\n return {\n contentRef,\n handlePrint,\n };\n};\n\n/**\n * QuestionsPdfGenerator Component\n *\n * Isolated and reusable component for generating PDFs of questions without answers.\n * Formats questions for school printing with specific layouts for each question type.\n *\n * This component renders hidden content and optionally exposes handlePrint via render prop.\n * For more control, consumers can use the hook directly (useQuestionsPdfPrint).\n *\n * @param questions - Array of questions to render in PDF\n * @param onPrint - Optional callback when print is triggered\n * @param onPrintError - Optional callback when print error occurs\n * @param children - Optional render prop function that receives handlePrint\n * @returns Component with hidden PDF content and optionally rendered children\n *\n * @example\n * // Without render prop (hidden content only)\n * <QuestionsPdfGenerator questions={questions} />\n *\n * @example\n * // With render prop (expose handlePrint)\n * <QuestionsPdfGenerator questions={questions}>\n * {(handlePrint) => <button onClick={handlePrint}>Print</button>}\n * </QuestionsPdfGenerator>\n */\nexport const QuestionsPdfGenerator = ({\n questions,\n onPrint,\n onPrintError,\n children,\n}: QuestionsPdfGeneratorProps) => {\n const { contentRef, handlePrint } = useQuestionsPdfPrint(\n questions,\n onPrint,\n onPrintError\n );\n\n return (\n <>\n {children?.(handlePrint)}\n <div style={{ display: 'none' }}>\n <QuestionsPdfContent ref={contentRef} questions={questions} />\n </div>\n </>\n );\n};\n\nexport type { QuestionsPdfGeneratorProps };\n","import { useCallback } from 'react';\nimport type { BaseApiClient } from '../types/api';\nimport type {\n ActivityDetailsData,\n ActivityDetailsQueryParams,\n ActivityDetailsApiResponse,\n QuizResponse,\n PresignedUrlResponse,\n} from '../types/activityDetails';\nimport type {\n QuestionsAnswersByStudentResponse,\n SaveQuestionCorrectionPayload,\n} from '../utils/studentActivityCorrection';\n\n/**\n * Hook return type for activity details\n */\nexport interface UseActivityDetailsReturn {\n /**\n * Fetch activity details from API\n * @param id - Activity ID\n * @param params - Query parameters for pagination\n * @returns Activity details data\n */\n fetchActivityDetails: (\n id: string,\n params?: ActivityDetailsQueryParams\n ) => Promise<ActivityDetailsData>;\n /**\n * Fetch student correction data from API\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @returns Student answers response data\n */\n fetchStudentCorrection: (\n activityId: string,\n studentId: string\n ) => Promise<QuestionsAnswersByStudentResponse>;\n /**\n * Submit observation for student activity\n * @param actId - Activity ID\n * @param studentId - Student ID\n * @param observation - Observation text\n * @param file - Attached file (optional)\n */\n submitObservation: (\n actId: string,\n studentId: string,\n observation: string,\n file: File | null\n ) => Promise<void>;\n /**\n * Submit question correction for student activity\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @param payload - Question correction payload\n */\n submitQuestionCorrection: (\n activityId: string,\n studentId: string,\n payload: SaveQuestionCorrectionPayload\n ) => Promise<void>;\n}\n\n/**\n * Build query parameters for API request\n */\nconst buildQueryParams = (\n params?: ActivityDetailsQueryParams\n): Record<string, unknown> => {\n const paramsObj: Record<string, unknown> = {};\n if (params?.page) paramsObj.page = params.page;\n if (params?.limit) paramsObj.limit = params.limit;\n if (params?.sortBy) paramsObj.sortBy = params.sortBy;\n if (params?.sortOrder) paramsObj.sortOrder = params.sortOrder;\n if (params?.status) paramsObj.status = params.status;\n return paramsObj;\n};\n\n/**\n * Hook for managing activity details API calls\n * Provides functions to fetch activity details, student corrections, and submit observations/corrections\n *\n * @param apiClient - API client instance for making requests\n * @returns Hook return object with API functions\n *\n * @example\n * ```tsx\n * import { useActivityDetails } from 'analytica-frontend-lib';\n * import { useApi } from './services/apiService';\n *\n * function ActivityDetailsPage() {\n * const api = useApi();\n * const { fetchActivityDetails, fetchStudentCorrection } = useActivityDetails(api);\n *\n * // Use functions...\n * }\n * ```\n */\nexport const useActivityDetails = (\n apiClient: BaseApiClient\n): UseActivityDetailsReturn => {\n /**\n * Fetch activity details from API\n * @param id - Activity ID\n * @param params - Query parameters for pagination\n * @returns Activity details data\n */\n const fetchActivityDetails = useCallback(\n async (\n id: string,\n params?: ActivityDetailsQueryParams\n ): Promise<ActivityDetailsData> => {\n const queryParams = buildQueryParams(params);\n\n const [detailsResponse, quizResponse] = await Promise.all([\n apiClient.get<ActivityDetailsApiResponse>(`/activities/${id}/details`, {\n params: queryParams,\n }),\n apiClient.get<QuizResponse>(`/activities/${id}/quiz`).catch(() => null),\n ]);\n\n return {\n ...detailsResponse.data.data,\n activity: quizResponse?.data?.data,\n };\n },\n [apiClient]\n );\n\n /**\n * Fetch student correction data from API\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @returns Student answers response data\n */\n const fetchStudentCorrection = useCallback(\n async (\n activityId: string,\n studentId: string\n ): Promise<QuestionsAnswersByStudentResponse> => {\n const response = await apiClient.get<QuestionsAnswersByStudentResponse>(\n `/questions/activity/${activityId}/user/${studentId}/answers`\n );\n return response.data;\n },\n [apiClient]\n );\n\n /**\n * Submit observation for student activity\n * @param actId - Activity ID\n * @param studentId - Student ID\n * @param observation - Observation text\n * @param file - Attached file (optional)\n */\n const submitObservation = useCallback(\n async (\n actId: string,\n studentId: string,\n observation: string,\n file: File | null\n ): Promise<void> => {\n let attachmentUrl: string | null = null;\n\n if (file) {\n const presignedRes = await apiClient.post<PresignedUrlResponse>(\n '/user/get-pre-signed-url',\n {\n fileName: file.name,\n fileType: file.type,\n fileSize: file.size,\n }\n );\n\n const { url, fields } = presignedRes.data.data;\n const formData = new FormData();\n\n for (const [key, value] of Object.entries(fields)) {\n formData.append(key, value);\n }\n formData.append('file', file);\n\n await fetch(url, {\n method: 'POST',\n body: formData,\n }).then((response) => {\n if (!response.ok) {\n throw new Error('Falha ao fazer upload do arquivo');\n }\n });\n\n // Ensure proper URL construction\n const baseUrl = url.endsWith('/') ? url.slice(0, -1) : url;\n const key = fields.key.startsWith('/')\n ? fields.key.slice(1)\n : fields.key;\n attachmentUrl = `${baseUrl}/${key}`;\n }\n\n await apiClient.post(\n `/activities/${actId}/students/${studentId}/feedback/observation`,\n {\n observation,\n attachmentUrl,\n }\n );\n },\n [apiClient]\n );\n\n /**\n * Submit question correction for student activity\n * @param activityId - Activity ID\n * @param studentId - Student ID\n * @param payload - Question correction payload\n */\n const submitQuestionCorrection = useCallback(\n async (\n activityId: string,\n studentId: string,\n payload: SaveQuestionCorrectionPayload\n ): Promise<void> => {\n await apiClient.post(\n `/activities/${activityId}/students/${studentId}/questions/correction`,\n payload\n );\n },\n [apiClient]\n );\n\n return {\n fetchActivityDetails,\n fetchStudentCorrection,\n submitObservation,\n submitQuestionCorrection,\n };\n};\n","import type { CategoryConfig, Item } from './CheckBoxGroup';\n\n/**\n * Helper function to efficiently compare selectedIds arrays\n */\nexport const areSelectedIdsEqual = (\n ids1?: string[],\n ids2?: string[]\n): boolean => {\n if (ids1 === ids2) return true;\n if (!ids1 || !ids2) return ids1 === ids2;\n if (ids1.length !== ids2.length) return false;\n\n for (let i = 0; i < ids1.length; i++) {\n if (ids1[i] !== ids2[i]) return false;\n }\n return true;\n};\n\n/**\n * Helper function to check if category is enabled based on dependencies\n */\nexport const isCategoryEnabled = (\n category: CategoryConfig,\n allCategories: CategoryConfig[]\n): boolean => {\n if (!category.dependsOn || category.dependsOn.length === 0) {\n return true;\n }\n return category.dependsOn.every((depKey) => {\n const depCat = allCategories.find((c) => c.key === depKey);\n return depCat?.selectedIds && depCat.selectedIds.length > 0;\n });\n};\n\n/**\n * Helper function to check if an item matches a filter\n */\nexport const isItemMatchingFilter = (\n item: Item,\n filter: { key: string; internalField: string },\n allCategories: CategoryConfig[]\n): boolean => {\n const parentCat = allCategories.find((c) => c.key === filter.key);\n const parentSelectedIds = parentCat?.selectedIds || [];\n const itemFieldValue = item[filter.internalField];\n return parentSelectedIds.includes(String(itemFieldValue));\n};\n\n/**\n * Helper function to get badge text for category\n */\nexport const getBadgeText = (\n category: CategoryConfig,\n formattedItems: { groupLabel?: string; itens: Item[] }[]\n): string => {\n const visibleIds = formattedItems\n .flatMap((group) => group.itens || [])\n .map((i) => i.id);\n const selectedVisibleCount = visibleIds.filter((id) =>\n category.selectedIds?.includes(id)\n ).length;\n const totalVisible = visibleIds.length;\n return `${selectedVisibleCount} de ${totalVisible} ${\n selectedVisibleCount === 1 ? 'selecionado' : 'selecionados'\n }`;\n};\n\n/**\n * Helper function to handle accordion value change logic\n * Returns the new accordion value or null if should not change\n */\nexport const handleAccordionValueChange = (\n value: string | string[] | undefined,\n categories: CategoryConfig[],\n isCategoryEnabledFn: (category: CategoryConfig) => boolean\n): string | null => {\n if (typeof value !== 'string') {\n if (!value) {\n return '';\n }\n return null; // Don't change for array values\n }\n\n if (!value) {\n return '';\n }\n\n // Prevent opening disabled categories\n const category = categories.find((c) => c.key === value);\n if (!category) {\n return null; // Category not found, don't change\n }\n\n const isEnabled = isCategoryEnabledFn(category);\n if (!isEnabled) {\n return null; // Don't allow opening disabled accordions\n }\n\n return value;\n};\n\n/**\n * Helper function to calculate filtered items for auto-selection\n * This function determines which items are visible/filtered for a category\n */\nexport const calculateFormattedItemsForAutoSelection = (\n category: CategoryConfig,\n allCategories: CategoryConfig[]\n): Item[] => {\n if (!category?.dependsOn || category.dependsOn.length === 0) {\n return category?.itens || [];\n }\n\n // Check if category is enabled based on dependencies\n const isEnabled = isCategoryEnabled(category, allCategories);\n\n // If category is disabled, return empty items array\n if (!isEnabled) {\n return [];\n }\n\n const filters =\n (category.filteredBy as {\n key: string;\n internalField: string;\n label?: string;\n }[]) || [];\n\n if (filters.length === 0) {\n return category?.itens || [];\n }\n\n const selectedIdsArr = filters.map((f) => {\n const parentCat = allCategories.find((c) => c.key === f.key);\n if (!parentCat?.selectedIds?.length) {\n return [];\n }\n return parentCat.selectedIds;\n });\n\n if (selectedIdsArr.some((arr) => arr.length === 0)) {\n return [];\n }\n\n // Filter items based on selected parent IDs\n const filteredItems = (category.itens || []).filter((item) =>\n filters.every((filter) => isItemMatchingFilter(item, filter, allCategories))\n );\n\n return filteredItems;\n};\n","import Modal from '../Modal/Modal';\nimport { CheckboxGroup } from '../CheckBoxGroup/CheckBoxGroup';\nimport Button from '../Button/Button';\nimport type { FilterConfig } from './useTableFilter';\n\nexport type FilterModalProps = {\n /**\n * Controls modal visibility\n */\n isOpen: boolean;\n\n /**\n * Callback when modal should close\n */\n onClose: () => void;\n\n /**\n * Filter configurations with categories\n */\n filterConfigs: FilterConfig[];\n\n /**\n * Callback when filters change (temporary, before applying)\n */\n onFiltersChange: (configs: FilterConfig[]) => void;\n\n /**\n * Callback when \"Aplicar\" button is clicked\n */\n onApply: () => void;\n\n /**\n * Callback when \"Limpar filtros\" button is clicked\n */\n onClear: () => void;\n\n /**\n * Modal title\n * @default \"Filtros\"\n */\n title?: string;\n\n /**\n * Modal size\n * @default \"md\"\n */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n /**\n * Apply button label\n * @default \"Aplicar\"\n */\n applyLabel?: string;\n\n /**\n * Clear button label\n * @default \"Limpar filtros\"\n */\n clearLabel?: string;\n};\n\n/**\n * FilterModal component - A modal for table filtering with CheckboxGroup\n *\n * Integrates Modal, CheckboxGroup, and Button components to create a\n * complete filtering interface. Works with useTableFilter hook for URL synchronization.\n *\n * @example\n * ```tsx\n * const { filterConfigs, updateFilters, applyFilters, clearFilters } = useTableFilter(\n * initialConfigs,\n * { syncWithUrl: true }\n * );\n *\n * <FilterModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * filterConfigs={filterConfigs}\n * onFiltersChange={updateFilters}\n * onApply={() => {\n * applyFilters();\n * setIsOpen(false);\n * }}\n * onClear={clearFilters}\n * />\n * ```\n */\nexport const FilterModal = ({\n isOpen,\n onClose,\n filterConfigs,\n onFiltersChange,\n onApply,\n onClear,\n title = 'Filtros',\n size = 'md',\n applyLabel = 'Aplicar',\n clearLabel = 'Limpar filtros',\n}: FilterModalProps) => {\n const handleCategoryChange = (\n configIndex: number,\n updatedCategories: (typeof filterConfigs)[0]['categories']\n ) => {\n const newConfigs = [...filterConfigs];\n newConfigs[configIndex] = {\n ...newConfigs[configIndex],\n categories: updatedCategories,\n };\n onFiltersChange(newConfigs);\n };\n\n const handleApply = () => {\n onApply();\n onClose();\n };\n\n const handleClear = () => {\n onClear();\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size={size}\n footer={\n <div className=\"flex gap-3 justify-end w-full\">\n <Button variant=\"outline\" onClick={handleClear}>\n {clearLabel}\n </Button>\n <Button onClick={handleApply}>{applyLabel}</Button>\n </div>\n }\n >\n <div className=\"flex flex-col gap-6\">\n {filterConfigs.map((config, index) => (\n <div key={config.key} className=\"flex flex-col gap-4\">\n {/* Section Header */}\n <div className=\"flex items-center gap-2 text-text-400 text-sm font-medium uppercase\">\n {config.key === 'academic' && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-text-400\"\n >\n <path\n d=\"M8 2L2 5.33333L8 8.66667L14 5.33333L8 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M2 10.6667L8 14L14 10.6667\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M2 8L8 11.3333L14 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n {config.key === 'content' && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-text-400\"\n >\n <path\n d=\"M3.33333 2H12.6667C13.403 2 14 2.59695 14 3.33333V12.6667C14 13.403 13.403 14 12.6667 14H3.33333C2.59695 14 2 13.403 2 12.6667V3.33333C2 2.59695 2.59695 2 3.33333 2Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M2 6H14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M6 2V14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n <span>{config.label}</span>\n </div>\n\n {/* CheckboxGroup */}\n <CheckboxGroup\n categories={config.categories}\n onCategoriesChange={(updatedCategories) =>\n handleCategoryChange(index, updatedCategories)\n }\n />\n </div>\n ))}\n </div>\n </Modal>\n );\n};\n"],"mappings":"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","names":["useState","useMemo","useCallback","useEffect","useRef","Medal","Star","CaretRight","WarningCircle","QUESTION_TYPE","answer","jsx","jsx","jsxs","VARIANT_ACTION_CLASSES","SIZE_CLASSES","jsx","jsxs","jsx","jsxs","_","useState","useEffect","useMemo","useCallback","forwardRef","CaretDown","jsx","jsxs","jsx","jsxs","jsx","jsxs","forwardRef","CaretDown","useEffect","useState","useMemo","X","forwardRef","useState","useId","useMemo","useEffect","useRef","CaretRight","forwardRef","useEffect","isValidElement","Children","useState","create","useEffect","jsx","jsxs","SIZE_CLASSES","useEffect","useState","useEffect","forwardRef","jsx","jsxs","forwardRef","useEffect","create","devtools","useEffect","jsx","useState","useEffect","jsx","jsxs","create","Children","isValidElement","useEffect","forwardRef","useState","CaretRight","jsx","jsxs","forwardRef","useState","useRef","useMemo","useEffect","useId","disabled","readOnly","X","useEffect","useMemo","useRef","useState","Element","Fragment","jsx","jsxs","Element","forwardRef","useState","useId","jsx","jsxs","SIZE_CLASSES","forwardRef","useId","useState","forwardRef","useId","useEffect","useRef","Children","cloneElement","isValidElement","create","useStore","jsx","create","injectStore","Children","isValidElement","cloneElement","forwardRef","useId","useRef","useStore","useEffect","forwardRef","useState","useId","jsx","jsxs","SIZE_CLASSES","STATE_CLASSES","forwardRef","useId","useState","jsx","forwardRef","useState","useId","useEffect","useRef","Children","cloneElement","isValidElement","create","useStore","jsx","jsxs","SIZE_CLASSES","STATE_CLASSES","forwardRef","useId","useRef","useState","create","injectStore","Children","isValidElement","cloneElement","useStore","useEffect","create","Fragment","jsx","jsxs","SIZE_CLASSES","useState","useRef","useEffect","useCallback","Paperclip","X","WarningCircle","forwardRef","useId","useState","useEffect","forwardRef","Fragment","useState","useRef","useEffect","CaretRight","cloneElement","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","cloneElement","Fragment","jsx","jsxs","forwardRef","CaretRight","status","useState","useRef","useEffect","CaretRight","jsx","jsxs","forwardRef","useState","useId","useEffect","CaretRight","Children","cloneElement","forwardRef","isValidElement","useEffect","useRef","useState","create","jsx","injectStore","useRef","X","jsx","jsxs","CheckCircle","XCircle","forwardRef","useId","useState","jsx","jsxs","useId","useState","getStatusStyles","isReadonly","getStatusBadge","CheckCircle","XCircle","value","forwardRef","jsx","useEffect","useState","CheckCircle","XCircle","Check","jsx","jsxs","useState","useEffect","getStatusBadge","CheckCircle","XCircle","getStatusStyles","Check","jsx","forwardRef","useCallback","useEffect","useId","useMemo","useRef","useState","CheckCircle","XCircle","Fragment","jsx","jsxs","forwardRef","jsx","useId","CheckCircle","XCircle","jsx","jsxs","CheckCircle","XCircle","useId","jsx","jsxs","jsx","jsxs","jsx","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","WarningCircle","useState","useRef","useEffect","useCallback","Paperclip","X","useState","useEffect","jsx","jsx","jsx","jsx","useState","useCallback","forwardRef","useRef","useCallback","Fragment","jsx","jsxs","forwardRef","useRef","useCallback","useCallback","key","jsx","jsxs","useState","useRef","useEffect","useMemo","formattedItemsMap","getBadgeText","isCategoryEnabled","handleAccordionValueChange","jsx","jsxs","Fragment","jsx","jsxs","useState","useMemo","useEffect","useCallback","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useMemo","error","CaretRight","WarningCircle","Star","Medal"]}
|