analytica-frontend-lib 1.0.83 → 1.0.85
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/Accordation/index.js +163 -74
- package/dist/Accordation/index.js.map +1 -1
- package/dist/Accordation/index.mjs +163 -74
- package/dist/Accordation/index.mjs.map +1 -1
- package/dist/Alert/index.js +32 -32
- package/dist/Alert/index.js.map +1 -1
- package/dist/Alert/index.mjs +32 -32
- package/dist/Alert/index.mjs.map +1 -1
- package/dist/AlertDialog/index.js +13 -2
- package/dist/AlertDialog/index.js.map +1 -1
- package/dist/AlertDialog/index.mjs +13 -2
- package/dist/AlertDialog/index.mjs.map +1 -1
- package/dist/Alternative/index.js +86 -25
- package/dist/Alternative/index.js.map +1 -1
- package/dist/Alternative/index.mjs +86 -25
- package/dist/Alternative/index.mjs.map +1 -1
- package/dist/Badge/index.js +13 -4
- package/dist/Badge/index.js.map +1 -1
- package/dist/Badge/index.mjs +13 -4
- package/dist/Badge/index.mjs.map +1 -1
- package/dist/Button/index.js +10 -1
- package/dist/Button/index.js.map +1 -1
- package/dist/Button/index.mjs +8 -1
- package/dist/Button/index.mjs.map +1 -1
- package/dist/Calendar/index.js +11 -2
- package/dist/Calendar/index.js.map +1 -1
- package/dist/Calendar/index.mjs +11 -2
- package/dist/Calendar/index.mjs.map +1 -1
- package/dist/Card/index.js +154 -71
- package/dist/Card/index.js.map +1 -1
- package/dist/Card/index.mjs +154 -71
- package/dist/Card/index.mjs.map +1 -1
- package/dist/CheckBox/index.js +28 -5
- package/dist/CheckBox/index.js.map +1 -1
- package/dist/CheckBox/index.mjs +28 -5
- package/dist/CheckBox/index.mjs.map +1 -1
- package/dist/Chips/index.js +10 -1
- package/dist/Chips/index.js.map +1 -1
- package/dist/Chips/index.mjs +10 -1
- package/dist/Chips/index.mjs.map +1 -1
- package/dist/Divider/index.js +10 -1
- package/dist/Divider/index.js.map +1 -1
- package/dist/Divider/index.mjs +8 -1
- package/dist/Divider/index.mjs.map +1 -1
- package/dist/DropdownMenu/index.js +18 -22
- package/dist/DropdownMenu/index.js.map +1 -1
- package/dist/DropdownMenu/index.mjs +18 -22
- package/dist/DropdownMenu/index.mjs.map +1 -1
- package/dist/IconButton/index.js +10 -1
- package/dist/IconButton/index.js.map +1 -1
- package/dist/IconButton/index.mjs +10 -1
- package/dist/IconButton/index.mjs.map +1 -1
- package/dist/IconRoundedButton/index.js +10 -1
- package/dist/IconRoundedButton/index.js.map +1 -1
- package/dist/IconRoundedButton/index.mjs +8 -1
- package/dist/IconRoundedButton/index.mjs.map +1 -1
- package/dist/Menu/index.js +22 -10
- package/dist/Menu/index.js.map +1 -1
- package/dist/Menu/index.mjs +22 -10
- package/dist/Menu/index.mjs.map +1 -1
- package/dist/Modal/index.js +15 -1
- package/dist/Modal/index.js.map +1 -1
- package/dist/Modal/index.mjs +15 -1
- package/dist/Modal/index.mjs.map +1 -1
- package/dist/NavButton/index.js +10 -1
- package/dist/NavButton/index.js.map +1 -1
- package/dist/NavButton/index.mjs +10 -1
- package/dist/NavButton/index.mjs.map +1 -1
- package/dist/NotFound/index.js +13 -3
- package/dist/NotFound/index.js.map +1 -1
- package/dist/NotFound/index.mjs +13 -3
- package/dist/NotFound/index.mjs.map +1 -1
- package/dist/ProgressBar/index.js +63 -15
- package/dist/ProgressBar/index.js.map +1 -1
- package/dist/ProgressBar/index.mjs +63 -15
- package/dist/ProgressBar/index.mjs.map +1 -1
- package/dist/ProgressCircle/index.js +34 -7
- package/dist/ProgressCircle/index.js.map +1 -1
- package/dist/ProgressCircle/index.mjs +34 -7
- package/dist/ProgressCircle/index.mjs.map +1 -1
- package/dist/Quiz/index.d.mts +25 -2
- package/dist/Quiz/index.d.ts +25 -2
- package/dist/Quiz/index.js +972 -260
- package/dist/Quiz/index.js.map +1 -1
- package/dist/Quiz/index.mjs +968 -261
- package/dist/Quiz/index.mjs.map +1 -1
- package/dist/Quiz/useQuizStore/index.d.mts +44 -12
- package/dist/Quiz/useQuizStore/index.d.ts +44 -12
- package/dist/Quiz/useQuizStore/index.js +206 -85
- package/dist/Quiz/useQuizStore/index.js.map +1 -1
- package/dist/Quiz/useQuizStore/index.mjs +203 -85
- package/dist/Quiz/useQuizStore/index.mjs.map +1 -1
- package/dist/Radio/index.js +36 -6
- package/dist/Radio/index.js.map +1 -1
- package/dist/Radio/index.mjs +36 -6
- package/dist/Radio/index.mjs.map +1 -1
- package/dist/Select/index.js +20 -4
- package/dist/Select/index.js.map +1 -1
- package/dist/Select/index.mjs +20 -4
- package/dist/Select/index.mjs.map +1 -1
- package/dist/SelectionButton/index.js +10 -1
- package/dist/SelectionButton/index.js.map +1 -1
- package/dist/SelectionButton/index.mjs +10 -1
- package/dist/SelectionButton/index.mjs.map +1 -1
- package/dist/Skeleton/index.js +18 -6
- package/dist/Skeleton/index.js.map +1 -1
- package/dist/Skeleton/index.mjs +18 -6
- package/dist/Skeleton/index.mjs.map +1 -1
- package/dist/Stepper/index.js +27 -18
- package/dist/Stepper/index.js.map +1 -1
- package/dist/Stepper/index.mjs +27 -18
- package/dist/Stepper/index.mjs.map +1 -1
- package/dist/Table/index.js +37 -13
- package/dist/Table/index.js.map +1 -1
- package/dist/Table/index.mjs +37 -13
- package/dist/Table/index.mjs.map +1 -1
- package/dist/Text/index.js +10 -1
- package/dist/Text/index.js.map +1 -1
- package/dist/Text/index.mjs +8 -1
- package/dist/Text/index.mjs.map +1 -1
- package/dist/TextArea/index.js +17 -3
- package/dist/TextArea/index.js.map +1 -1
- package/dist/TextArea/index.mjs +17 -3
- package/dist/TextArea/index.mjs.map +1 -1
- package/dist/Toast/Toaster/index.js +15 -1
- package/dist/Toast/Toaster/index.js.map +1 -1
- package/dist/Toast/Toaster/index.mjs +15 -1
- package/dist/Toast/Toaster/index.mjs.map +1 -1
- package/dist/Toast/index.js +15 -1
- package/dist/Toast/index.js.map +1 -1
- package/dist/Toast/index.mjs +15 -1
- package/dist/Toast/index.mjs.map +1 -1
- package/dist/index.css +8 -9
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +903 -325
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +901 -326
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +8 -9
- package/dist/styles.css.map +1 -1
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Quiz/useQuizStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { devtools } from 'zustand/middleware';\n\ninterface Question {\n id: string;\n questionText: string;\n correctOptionId: string;\n description: string;\n type: 'ALTERNATIVA' | 'DISSERTATIVA' | 'MULTIPLA_CHOICE';\n status: 'APROVADO' | 'REPROVADO';\n difficulty: 'FACIL' | 'MEDIO' | 'DIFICIL';\n examBoard: string | null;\n examYear: string | null;\n answerKey: string | null;\n createdAt: string;\n updatedAt: string;\n knowledgeMatrix: {\n areaKnowledgeId: string;\n subjectId: string;\n topicId: string;\n subtopicId: string;\n contentId: string;\n }[];\n options: {\n id: string;\n option: string;\n }[];\n createdBy: string;\n}\n\ninterface Simulado {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface Atividade {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface Aula {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface UserAnswer extends Question {\n isSkipped: boolean;\n}\n\ninterface QuizState {\n // Data\n bySimulado?: Simulado;\n byAtividade?: Atividade;\n byAula?: Aula;\n\n // UI State\n currentQuestionIndex: number;\n selectedAnswers: Record<string, string>;\n skippedQuestions: string[];\n userAnswers: UserAnswer[];\n timeElapsed: number;\n isStarted: boolean;\n isFinished: boolean;\n\n // Actions\n setBySimulado: (simulado: Simulado) => void;\n setByAtividade: (atividade: Atividade) => void;\n setByAula: (aula: Aula) => void;\n\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 skipQuestion: () => 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 // 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: () => string | undefined;\n getQuizTitle: () => string;\n formatTime: (seconds: number) => string;\n getUserAnswers: () => UserAnswer[];\n getUnansweredQuestionsFromUserAnswers: () => number[];\n getQuestionsGroupedBySubject: () => { [key: string]: Question[] };\n}\n\nexport const useQuizStore = create<QuizState>()(\n devtools(\n (set, get) => {\n let timerInterval: ReturnType<typeof setInterval> | null = null;\n\n const startTimer = () => {\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 return {\n // Initial State\n currentQuestionIndex: 0,\n selectedAnswers: {},\n skippedQuestions: [],\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n\n // Setters\n setBySimulado: (simulado) => set({ bySimulado: simulado }),\n setByAtividade: (atividade) => set({ byAtividade: atividade }),\n setByAula: (aula) => set({ byAula: aula }),\n\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 // Quiz Actions\n selectAnswer: (questionId, answerId) => {\n const { selectedAnswers, skippedQuestions, addUserAnswer } = get();\n // Remove from skipped questions if it was skipped\n const newSkippedQuestions = skippedQuestions.filter(\n (id) => id !== questionId\n );\n set({\n selectedAnswers: {\n ...selectedAnswers,\n [questionId]: answerId,\n },\n skippedQuestions: newSkippedQuestions,\n });\n // Add to user answers\n addUserAnswer(questionId, answerId);\n },\n\n skipQuestion: () => {\n const { getCurrentQuestion, skippedQuestions, addUserAnswer } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (currentQuestion) {\n set({\n skippedQuestions: [...skippedQuestions, currentQuestion.id],\n });\n // Add to user answers as skipped\n addUserAnswer(currentQuestion.id);\n }\n },\n\n addUserAnswer: (questionId, answerId) => {\n const { userAnswers, bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\n const question = quiz?.questions.find((q) => q.id === questionId);\n\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.id === questionId\n );\n\n if (existingAnswerIndex !== -1) {\n // Update existing answer\n const updatedAnswers = [...userAnswers];\n updatedAnswers[existingAnswerIndex] = {\n ...question,\n answerKey: answerId || '',\n isSkipped: !answerId,\n };\n set({ userAnswers: updatedAnswers });\n } else {\n // Add new answer\n set({\n userAnswers: [\n ...userAnswers,\n {\n ...question,\n answerKey: answerId || '',\n isSkipped: !answerId,\n },\n ],\n });\n }\n },\n\n startQuiz: () => {\n set({ isStarted: true, timeElapsed: 0 });\n startTimer();\n },\n\n finishQuiz: () => {\n set({ isFinished: true });\n stopTimer();\n },\n\n resetQuiz: () => {\n stopTimer();\n set({\n currentQuestionIndex: 0,\n selectedAnswers: {},\n skippedQuestions: [],\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n });\n },\n\n // Timer\n updateTime: (time) => set({ timeElapsed: time }),\n startTimer,\n stopTimer,\n\n // Getters\n getCurrentQuestion: () => {\n const { bySimulado, byAtividade, byAula, currentQuestionIndex } =\n get();\n const quiz = bySimulado || byAtividade || byAula;\n\n if (!quiz) {\n return null;\n }\n\n return quiz.questions[currentQuestionIndex];\n },\n\n getTotalQuestions: () => {\n const { bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\n\n return quiz?.questions?.length || 0;\n },\n\n getAnsweredQuestions: () => {\n const { selectedAnswers } = get();\n return Object.keys(selectedAnswers).length;\n },\n\n getUnansweredQuestions: () => {\n const {\n bySimulado,\n byAtividade,\n byAula,\n selectedAnswers,\n skippedQuestions,\n } = get();\n const quiz = bySimulado || byAtividade || byAula;\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const isAnswered = question.id in selectedAnswers;\n const isSkipped = skippedQuestions.includes(question.id);\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 { skippedQuestions } = get();\n return skippedQuestions.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 { selectedAnswers } = get();\n return questionId in selectedAnswers;\n },\n\n isQuestionSkipped: (questionId) => {\n const { skippedQuestions } = get();\n return skippedQuestions.includes(questionId);\n },\n\n getCurrentAnswer: () => {\n const { getCurrentQuestion, selectedAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n return selectedAnswers[currentQuestion?.id || ''];\n },\n\n getQuizTitle: () => {\n const { bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\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 { bySimulado, byAtividade, byAula, userAnswers } = get();\n const quiz = bySimulado || byAtividade || byAula;\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.id === question.id\n );\n\n // Se não há resposta do usuário OU se a questão foi pulada (isSkipped = true)\n if (!userAnswer || userAnswer.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 { bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\n if (!quiz) return {};\n\n const groupedQuestions: { [key: string]: Question[] } = {};\n\n quiz.questions.forEach((question) => {\n const subjectId =\n question.knowledgeMatrix?.[0]?.subjectId || '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 },\n {\n name: 'quiz-store',\n }\n )\n);\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Quiz/useQuizStore.ts"],"sourcesContent":["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\nexport enum QUESTION_TYPE {\n ALTERNATIVA = 'ALTERNATIVA',\n DISSERTATIVA = 'DISSERTATIVA',\n MULTIPLA_CHOICE = 'MULTIPLA_CHOICE',\n}\n\nexport enum QUESTION_STATUS {\n APROVADO = 'APROVADO',\n REPROVADO = 'REPROVADO',\n}\n\nexport interface Question {\n id: string;\n questionText: string;\n correctOptionId: string;\n description: string;\n type: QUESTION_TYPE;\n status: QUESTION_STATUS;\n difficulty: QUESTION_DIFFICULTY;\n examBoard: string | null;\n examYear: string | null;\n answerKey: string | null;\n createdAt: string;\n updatedAt: string;\n knowledgeMatrix: {\n areaKnowledgeId: string;\n subjectId: string;\n topicId: string;\n subtopicId: string;\n contentId: string;\n }[];\n options: {\n id: string;\n option: string;\n }[];\n createdBy: string;\n}\n\ninterface Simulado {\n id: string;\n title: string;\n category: string;\n questions: Question[];\n}\n\ninterface Atividade {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface Aula {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface UserAnswerItem {\n questionId: string;\n activityId: string;\n userId: string;\n answer: string | null;\n optionId: string | null;\n}\n\ninterface UserAnswer extends Question {\n isSkipped: boolean;\n}\n\ninterface QuizState {\n // Data\n bySimulated?: Simulado;\n byActivity?: Atividade;\n byQuestionary?: Aula;\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\n // Actions\n setBySimulated: (simulado: Simulado) => void;\n setByActivity: (atividade: Atividade) => void;\n setByQuestionary: (aula: Aula) => void;\n setUserId: (userId: string) => void;\n\n // Quiz Navigation\n goToNextQuestion: () => void;\n goToPreviousQuestion: () => void;\n goToQuestion: (index: number) => void;\n getActiveQuiz: () => {\n quiz: Simulado | Atividade | Aula;\n type: 'bySimulated' | 'byActivity' | 'byQuestionary';\n } | null;\n\n // Quiz Actions\n selectAnswer: (questionId: string, answerId: string) => void;\n skipQuestion: () => 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 // 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: () => string | undefined;\n getQuizTitle: () => string;\n formatTime: (seconds: number) => string;\n getUserAnswers: () => UserAnswer[];\n getUnansweredQuestionsFromUserAnswers: () => number[];\n getQuestionsGroupedBySubject: () => { [key: string]: Question[] };\n getUserId: () => string;\n\n // New methods for userAnswers\n getUserAnswerByQuestionId: (questionId: string) => UserAnswerItem | null;\n isQuestionAnsweredByUserAnswers: (questionId: string) => boolean;\n getQuestionStatusFromUserAnswers: (\n questionId: string\n ) => 'answered' | 'unanswered' | 'skipped';\n getUserAnswersForActivity: () => UserAnswerItem[];\n}\n\nexport const useQuizStore = create<QuizState>()(\n devtools(\n (set, get) => {\n let timerInterval: 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 return {\n // Initial State\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n\n // Setters\n setBySimulated: (simulado) => set({ bySimulated: simulado }),\n setByActivity: (atividade) => set({ byActivity: atividade }),\n setByQuestionary: (aula) => set({ byQuestionary: aula }),\n setUserId: (userId) => set({ userId }),\n getUserId: () => get().userId,\n\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 getActiveQuiz: () => {\n const { bySimulated, byActivity, byQuestionary } = get();\n if (bySimulated)\n return { quiz: bySimulated, type: 'bySimulated' as const };\n if (byActivity)\n return { quiz: byActivity, type: 'byActivity' as const };\n if (byQuestionary)\n return { quiz: byQuestionary, type: 'byQuestionary' as const };\n return null;\n },\n\n selectAnswer: (questionId, answerId) => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return;\n\n const updatedQuestions = activeQuiz.quiz.questions.map((question) =>\n question.id === questionId\n ? { ...question, answerKey: answerId }\n : question\n );\n\n const updatedQuiz = {\n ...activeQuiz.quiz,\n questions: updatedQuestions,\n };\n\n const activityId = activeQuiz.quiz.id;\n const userId = get().getUserId();\n\n if (!userId) {\n console.warn('selectAnswer called before userId is set');\n return;\n }\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: answerId,\n optionId: answerId,\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 [activeQuiz.type]: updatedQuiz,\n userAnswers: updatedUserAnswers,\n });\n },\n\n skipQuestion: () => {\n const { getCurrentQuestion, userAnswers, getActiveQuiz } = get();\n const currentQuestion = getCurrentQuestion();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return;\n\n if (currentQuestion) {\n const activityId = activeQuiz.quiz.id;\n const userId = get().getUserId();\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 };\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 addUserAnswer: (questionId, answerId) => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return;\n\n // Add to userAnswers array with new structure\n const activityId = activeQuiz.quiz.id;\n const userId = get().getUserId();\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: answerId || null,\n optionId: answerId || null,\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 },\n\n finishQuiz: () => {\n set({ isFinished: true });\n stopTimer();\n },\n\n resetQuiz: () => {\n stopTimer();\n set({\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n });\n },\n\n // Timer\n updateTime: (time) => set({ timeElapsed: time }),\n startTimer,\n stopTimer,\n\n // Getters\n getCurrentQuestion: () => {\n const { currentQuestionIndex, getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) {\n return null;\n }\n\n return activeQuiz.quiz.questions[currentQuestionIndex];\n },\n\n getTotalQuestions: () => {\n const { getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n\n return activeQuiz?.quiz?.questions?.length || 0;\n },\n\n getAnsweredQuestions: () => {\n const { userAnswers } = get();\n return userAnswers.filter((answer) => answer.answer !== null).length;\n },\n\n getUnansweredQuestions: () => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n if (!activeQuiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n activeQuiz.quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const isAnswered = userAnswer && userAnswer.answer !== null;\n const isSkipped = userAnswer && 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((answer) => answer.answer === null).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 ? userAnswer.answer !== null : false;\n },\n\n isQuestionSkipped: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer ? userAnswer.answer === null : 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 return userAnswer?.answer;\n },\n\n getQuizTitle: () => {\n const { getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n\n return activeQuiz?.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 { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return [];\n\n return activeQuiz.quiz.questions.map((question) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n return {\n ...question,\n isSkipped: userAnswer ? userAnswer.answer === null : false,\n };\n });\n },\n\n getUnansweredQuestionsFromUserAnswers: () => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n if (!activeQuiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n activeQuiz.quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const hasAnswer = userAnswer && userAnswer.answer !== null;\n const isSkipped = userAnswer && 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 { getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n if (!activeQuiz) return {};\n\n const groupedQuestions: { [key: string]: Question[] } = {};\n\n activeQuiz.quiz.questions.forEach((question) => {\n const subjectId =\n question.knowledgeMatrix?.[0]?.subjectId || '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 ? answer.answer !== null : 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.answer === null) return 'skipped';\n return 'answered';\n },\n getUserAnswersForActivity: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n };\n },\n {\n name: 'quiz-store',\n }\n )\n);\n"],"mappings":"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","names":["QUESTION_DIFFICULTY","QUESTION_TYPE","QUESTION_STATUS","answer"]}
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
// src/components/Quiz/useQuizStore.ts
|
|
2
2
|
import { create } from "zustand";
|
|
3
3
|
import { devtools } from "zustand/middleware";
|
|
4
|
+
var QUESTION_DIFFICULTY = /* @__PURE__ */ ((QUESTION_DIFFICULTY2) => {
|
|
5
|
+
QUESTION_DIFFICULTY2["FACIL"] = "FACIL";
|
|
6
|
+
QUESTION_DIFFICULTY2["MEDIO"] = "MEDIO";
|
|
7
|
+
QUESTION_DIFFICULTY2["DIFICIL"] = "DIFICIL";
|
|
8
|
+
return QUESTION_DIFFICULTY2;
|
|
9
|
+
})(QUESTION_DIFFICULTY || {});
|
|
10
|
+
var QUESTION_TYPE = /* @__PURE__ */ ((QUESTION_TYPE2) => {
|
|
11
|
+
QUESTION_TYPE2["ALTERNATIVA"] = "ALTERNATIVA";
|
|
12
|
+
QUESTION_TYPE2["DISSERTATIVA"] = "DISSERTATIVA";
|
|
13
|
+
QUESTION_TYPE2["MULTIPLA_CHOICE"] = "MULTIPLA_CHOICE";
|
|
14
|
+
return QUESTION_TYPE2;
|
|
15
|
+
})(QUESTION_TYPE || {});
|
|
16
|
+
var QUESTION_STATUS = /* @__PURE__ */ ((QUESTION_STATUS2) => {
|
|
17
|
+
QUESTION_STATUS2["APROVADO"] = "APROVADO";
|
|
18
|
+
QUESTION_STATUS2["REPROVADO"] = "REPROVADO";
|
|
19
|
+
return QUESTION_STATUS2;
|
|
20
|
+
})(QUESTION_STATUS || {});
|
|
4
21
|
var useQuizStore = create()(
|
|
5
22
|
devtools(
|
|
6
23
|
(set, get) => {
|
|
7
24
|
let timerInterval = null;
|
|
8
25
|
const startTimer = () => {
|
|
26
|
+
if (get().isFinished) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
9
29
|
if (timerInterval) {
|
|
10
30
|
clearInterval(timerInterval);
|
|
11
31
|
}
|
|
@@ -24,15 +44,17 @@ var useQuizStore = create()(
|
|
|
24
44
|
// Initial State
|
|
25
45
|
currentQuestionIndex: 0,
|
|
26
46
|
selectedAnswers: {},
|
|
27
|
-
skippedQuestions: [],
|
|
28
47
|
userAnswers: [],
|
|
29
48
|
timeElapsed: 0,
|
|
30
49
|
isStarted: false,
|
|
31
50
|
isFinished: false,
|
|
51
|
+
userId: "",
|
|
32
52
|
// Setters
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
53
|
+
setBySimulated: (simulado) => set({ bySimulated: simulado }),
|
|
54
|
+
setByActivity: (atividade) => set({ byActivity: atividade }),
|
|
55
|
+
setByQuestionary: (aula) => set({ byQuestionary: aula }),
|
|
56
|
+
setUserId: (userId) => set({ userId }),
|
|
57
|
+
getUserId: () => get().userId,
|
|
36
58
|
// Navigation
|
|
37
59
|
goToNextQuestion: () => {
|
|
38
60
|
const { currentQuestionIndex, getTotalQuestions } = get();
|
|
@@ -54,58 +76,107 @@ var useQuizStore = create()(
|
|
|
54
76
|
set({ currentQuestionIndex: index });
|
|
55
77
|
}
|
|
56
78
|
},
|
|
57
|
-
|
|
79
|
+
getActiveQuiz: () => {
|
|
80
|
+
const { bySimulated, byActivity, byQuestionary } = get();
|
|
81
|
+
if (bySimulated)
|
|
82
|
+
return { quiz: bySimulated, type: "bySimulated" };
|
|
83
|
+
if (byActivity)
|
|
84
|
+
return { quiz: byActivity, type: "byActivity" };
|
|
85
|
+
if (byQuestionary)
|
|
86
|
+
return { quiz: byQuestionary, type: "byQuestionary" };
|
|
87
|
+
return null;
|
|
88
|
+
},
|
|
58
89
|
selectAnswer: (questionId, answerId) => {
|
|
59
|
-
const {
|
|
60
|
-
const
|
|
61
|
-
|
|
90
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
91
|
+
const activeQuiz = getActiveQuiz();
|
|
92
|
+
if (!activeQuiz) return;
|
|
93
|
+
const updatedQuestions = activeQuiz.quiz.questions.map(
|
|
94
|
+
(question) => question.id === questionId ? { ...question, answerKey: answerId } : question
|
|
95
|
+
);
|
|
96
|
+
const updatedQuiz = {
|
|
97
|
+
...activeQuiz.quiz,
|
|
98
|
+
questions: updatedQuestions
|
|
99
|
+
};
|
|
100
|
+
const activityId = activeQuiz.quiz.id;
|
|
101
|
+
const userId = get().getUserId();
|
|
102
|
+
if (!userId) {
|
|
103
|
+
console.warn("selectAnswer called before userId is set");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const existingAnswerIndex = userAnswers.findIndex(
|
|
107
|
+
(answer) => answer.questionId === questionId
|
|
62
108
|
);
|
|
109
|
+
const newUserAnswer = {
|
|
110
|
+
questionId,
|
|
111
|
+
activityId,
|
|
112
|
+
userId,
|
|
113
|
+
answer: answerId,
|
|
114
|
+
optionId: answerId
|
|
115
|
+
};
|
|
116
|
+
let updatedUserAnswers;
|
|
117
|
+
if (existingAnswerIndex !== -1) {
|
|
118
|
+
updatedUserAnswers = [...userAnswers];
|
|
119
|
+
updatedUserAnswers[existingAnswerIndex] = newUserAnswer;
|
|
120
|
+
} else {
|
|
121
|
+
updatedUserAnswers = [...userAnswers, newUserAnswer];
|
|
122
|
+
}
|
|
63
123
|
set({
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
[questionId]: answerId
|
|
67
|
-
},
|
|
68
|
-
skippedQuestions: newSkippedQuestions
|
|
124
|
+
[activeQuiz.type]: updatedQuiz,
|
|
125
|
+
userAnswers: updatedUserAnswers
|
|
69
126
|
});
|
|
70
|
-
addUserAnswer(questionId, answerId);
|
|
71
127
|
},
|
|
72
128
|
skipQuestion: () => {
|
|
73
|
-
const { getCurrentQuestion,
|
|
129
|
+
const { getCurrentQuestion, userAnswers, getActiveQuiz } = get();
|
|
74
130
|
const currentQuestion = getCurrentQuestion();
|
|
131
|
+
const activeQuiz = getActiveQuiz();
|
|
132
|
+
if (!activeQuiz) return;
|
|
75
133
|
if (currentQuestion) {
|
|
134
|
+
const activityId = activeQuiz.quiz.id;
|
|
135
|
+
const userId = get().getUserId();
|
|
136
|
+
const existingAnswerIndex = userAnswers.findIndex(
|
|
137
|
+
(answer) => answer.questionId === currentQuestion.id
|
|
138
|
+
);
|
|
139
|
+
const newUserAnswer = {
|
|
140
|
+
questionId: currentQuestion.id,
|
|
141
|
+
activityId,
|
|
142
|
+
userId,
|
|
143
|
+
answer: null,
|
|
144
|
+
optionId: null
|
|
145
|
+
};
|
|
146
|
+
let updatedUserAnswers;
|
|
147
|
+
if (existingAnswerIndex !== -1) {
|
|
148
|
+
updatedUserAnswers = [...userAnswers];
|
|
149
|
+
updatedUserAnswers[existingAnswerIndex] = newUserAnswer;
|
|
150
|
+
} else {
|
|
151
|
+
updatedUserAnswers = [...userAnswers, newUserAnswer];
|
|
152
|
+
}
|
|
76
153
|
set({
|
|
77
|
-
|
|
154
|
+
userAnswers: updatedUserAnswers
|
|
78
155
|
});
|
|
79
|
-
addUserAnswer(currentQuestion.id);
|
|
80
156
|
}
|
|
81
157
|
},
|
|
82
158
|
addUserAnswer: (questionId, answerId) => {
|
|
83
|
-
const {
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
159
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
160
|
+
const activeQuiz = getActiveQuiz();
|
|
161
|
+
if (!activeQuiz) return;
|
|
162
|
+
const activityId = activeQuiz.quiz.id;
|
|
163
|
+
const userId = get().getUserId();
|
|
87
164
|
const existingAnswerIndex = userAnswers.findIndex(
|
|
88
|
-
(answer) => answer.
|
|
165
|
+
(answer) => answer.questionId === questionId
|
|
89
166
|
);
|
|
167
|
+
const newUserAnswer = {
|
|
168
|
+
questionId,
|
|
169
|
+
activityId,
|
|
170
|
+
userId,
|
|
171
|
+
answer: answerId || null,
|
|
172
|
+
optionId: answerId || null
|
|
173
|
+
};
|
|
90
174
|
if (existingAnswerIndex !== -1) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
answerKey: answerId || "",
|
|
95
|
-
isSkipped: !answerId
|
|
96
|
-
};
|
|
97
|
-
set({ userAnswers: updatedAnswers });
|
|
175
|
+
const updatedUserAnswers = [...userAnswers];
|
|
176
|
+
updatedUserAnswers[existingAnswerIndex] = newUserAnswer;
|
|
177
|
+
set({ userAnswers: updatedUserAnswers });
|
|
98
178
|
} else {
|
|
99
|
-
set({
|
|
100
|
-
userAnswers: [
|
|
101
|
-
...userAnswers,
|
|
102
|
-
{
|
|
103
|
-
...question,
|
|
104
|
-
answerKey: answerId || "",
|
|
105
|
-
isSkipped: !answerId
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
});
|
|
179
|
+
set({ userAnswers: [...userAnswers, newUserAnswer] });
|
|
109
180
|
}
|
|
110
181
|
},
|
|
111
182
|
startQuiz: () => {
|
|
@@ -121,11 +192,11 @@ var useQuizStore = create()(
|
|
|
121
192
|
set({
|
|
122
193
|
currentQuestionIndex: 0,
|
|
123
194
|
selectedAnswers: {},
|
|
124
|
-
skippedQuestions: [],
|
|
125
195
|
userAnswers: [],
|
|
126
196
|
timeElapsed: 0,
|
|
127
197
|
isStarted: false,
|
|
128
|
-
isFinished: false
|
|
198
|
+
isFinished: false,
|
|
199
|
+
userId: ""
|
|
129
200
|
});
|
|
130
201
|
},
|
|
131
202
|
// Timer
|
|
@@ -134,36 +205,33 @@ var useQuizStore = create()(
|
|
|
134
205
|
stopTimer,
|
|
135
206
|
// Getters
|
|
136
207
|
getCurrentQuestion: () => {
|
|
137
|
-
const {
|
|
138
|
-
const
|
|
139
|
-
if (!
|
|
208
|
+
const { currentQuestionIndex, getActiveQuiz } = get();
|
|
209
|
+
const activeQuiz = getActiveQuiz();
|
|
210
|
+
if (!activeQuiz) {
|
|
140
211
|
return null;
|
|
141
212
|
}
|
|
142
|
-
return quiz.questions[currentQuestionIndex];
|
|
213
|
+
return activeQuiz.quiz.questions[currentQuestionIndex];
|
|
143
214
|
},
|
|
144
215
|
getTotalQuestions: () => {
|
|
145
|
-
const {
|
|
146
|
-
const
|
|
147
|
-
return quiz?.questions?.length || 0;
|
|
216
|
+
const { getActiveQuiz } = get();
|
|
217
|
+
const activeQuiz = getActiveQuiz();
|
|
218
|
+
return activeQuiz?.quiz?.questions?.length || 0;
|
|
148
219
|
},
|
|
149
220
|
getAnsweredQuestions: () => {
|
|
150
|
-
const {
|
|
151
|
-
return
|
|
221
|
+
const { userAnswers } = get();
|
|
222
|
+
return userAnswers.filter((answer) => answer.answer !== null).length;
|
|
152
223
|
},
|
|
153
224
|
getUnansweredQuestions: () => {
|
|
154
|
-
const {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
byAula,
|
|
158
|
-
selectedAnswers,
|
|
159
|
-
skippedQuestions
|
|
160
|
-
} = get();
|
|
161
|
-
const quiz = bySimulado || byAtividade || byAula;
|
|
162
|
-
if (!quiz) return [];
|
|
225
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
226
|
+
const activeQuiz = getActiveQuiz();
|
|
227
|
+
if (!activeQuiz) return [];
|
|
163
228
|
const unansweredQuestions = [];
|
|
164
|
-
quiz.questions.forEach((question, index) => {
|
|
165
|
-
const
|
|
166
|
-
|
|
229
|
+
activeQuiz.quiz.questions.forEach((question, index) => {
|
|
230
|
+
const userAnswer = userAnswers.find(
|
|
231
|
+
(answer) => answer.questionId === question.id
|
|
232
|
+
);
|
|
233
|
+
const isAnswered = userAnswer && userAnswer.answer !== null;
|
|
234
|
+
const isSkipped = userAnswer && userAnswer.answer === null;
|
|
167
235
|
if (!isAnswered && !isSkipped) {
|
|
168
236
|
unansweredQuestions.push(index + 1);
|
|
169
237
|
}
|
|
@@ -171,8 +239,8 @@ var useQuizStore = create()(
|
|
|
171
239
|
return unansweredQuestions;
|
|
172
240
|
},
|
|
173
241
|
getSkippedQuestions: () => {
|
|
174
|
-
const {
|
|
175
|
-
return
|
|
242
|
+
const { userAnswers } = get();
|
|
243
|
+
return userAnswers.filter((answer) => answer.answer === null).length;
|
|
176
244
|
},
|
|
177
245
|
getProgress: () => {
|
|
178
246
|
const { getTotalQuestions, getAnsweredQuestions } = get();
|
|
@@ -181,22 +249,32 @@ var useQuizStore = create()(
|
|
|
181
249
|
return total > 0 ? answered / total * 100 : 0;
|
|
182
250
|
},
|
|
183
251
|
isQuestionAnswered: (questionId) => {
|
|
184
|
-
const {
|
|
185
|
-
|
|
252
|
+
const { userAnswers } = get();
|
|
253
|
+
const userAnswer = userAnswers.find(
|
|
254
|
+
(answer) => answer.questionId === questionId
|
|
255
|
+
);
|
|
256
|
+
return userAnswer ? userAnswer.answer !== null : false;
|
|
186
257
|
},
|
|
187
258
|
isQuestionSkipped: (questionId) => {
|
|
188
|
-
const {
|
|
189
|
-
|
|
259
|
+
const { userAnswers } = get();
|
|
260
|
+
const userAnswer = userAnswers.find(
|
|
261
|
+
(answer) => answer.questionId === questionId
|
|
262
|
+
);
|
|
263
|
+
return userAnswer ? userAnswer.answer === null : false;
|
|
190
264
|
},
|
|
191
265
|
getCurrentAnswer: () => {
|
|
192
|
-
const { getCurrentQuestion,
|
|
266
|
+
const { getCurrentQuestion, userAnswers } = get();
|
|
193
267
|
const currentQuestion = getCurrentQuestion();
|
|
194
|
-
|
|
268
|
+
if (!currentQuestion) return void 0;
|
|
269
|
+
const userAnswer = userAnswers.find(
|
|
270
|
+
(answer) => answer.questionId === currentQuestion.id
|
|
271
|
+
);
|
|
272
|
+
return userAnswer?.answer;
|
|
195
273
|
},
|
|
196
274
|
getQuizTitle: () => {
|
|
197
|
-
const {
|
|
198
|
-
const
|
|
199
|
-
return quiz?.title || "Quiz";
|
|
275
|
+
const { getActiveQuiz } = get();
|
|
276
|
+
const activeQuiz = getActiveQuiz();
|
|
277
|
+
return activeQuiz?.quiz?.title || "Quiz";
|
|
200
278
|
},
|
|
201
279
|
formatTime: (seconds) => {
|
|
202
280
|
const minutes = Math.floor(seconds / 60);
|
|
@@ -204,30 +282,42 @@ var useQuizStore = create()(
|
|
|
204
282
|
return `${minutes.toString().padStart(2, "0")}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
205
283
|
},
|
|
206
284
|
getUserAnswers: () => {
|
|
207
|
-
const { userAnswers } = get();
|
|
208
|
-
|
|
285
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
286
|
+
const activeQuiz = getActiveQuiz();
|
|
287
|
+
if (!activeQuiz) return [];
|
|
288
|
+
return activeQuiz.quiz.questions.map((question) => {
|
|
289
|
+
const userAnswer = userAnswers.find(
|
|
290
|
+
(answer) => answer.questionId === question.id
|
|
291
|
+
);
|
|
292
|
+
return {
|
|
293
|
+
...question,
|
|
294
|
+
isSkipped: userAnswer ? userAnswer.answer === null : false
|
|
295
|
+
};
|
|
296
|
+
});
|
|
209
297
|
},
|
|
210
298
|
getUnansweredQuestionsFromUserAnswers: () => {
|
|
211
|
-
const {
|
|
212
|
-
const
|
|
213
|
-
if (!
|
|
299
|
+
const { getActiveQuiz, userAnswers } = get();
|
|
300
|
+
const activeQuiz = getActiveQuiz();
|
|
301
|
+
if (!activeQuiz) return [];
|
|
214
302
|
const unansweredQuestions = [];
|
|
215
|
-
quiz.questions.forEach((question, index) => {
|
|
303
|
+
activeQuiz.quiz.questions.forEach((question, index) => {
|
|
216
304
|
const userAnswer = userAnswers.find(
|
|
217
|
-
(answer) => answer.
|
|
305
|
+
(answer) => answer.questionId === question.id
|
|
218
306
|
);
|
|
219
|
-
|
|
307
|
+
const hasAnswer = userAnswer && userAnswer.answer !== null;
|
|
308
|
+
const isSkipped = userAnswer && userAnswer.answer === null;
|
|
309
|
+
if (!hasAnswer || isSkipped) {
|
|
220
310
|
unansweredQuestions.push(index + 1);
|
|
221
311
|
}
|
|
222
312
|
});
|
|
223
313
|
return unansweredQuestions;
|
|
224
314
|
},
|
|
225
315
|
getQuestionsGroupedBySubject: () => {
|
|
226
|
-
const {
|
|
227
|
-
const
|
|
228
|
-
if (!
|
|
316
|
+
const { getActiveQuiz } = get();
|
|
317
|
+
const activeQuiz = getActiveQuiz();
|
|
318
|
+
if (!activeQuiz) return {};
|
|
229
319
|
const groupedQuestions = {};
|
|
230
|
-
quiz.questions.forEach((question) => {
|
|
320
|
+
activeQuiz.quiz.questions.forEach((question) => {
|
|
231
321
|
const subjectId = question.knowledgeMatrix?.[0]?.subjectId || "Sem mat\xE9ria";
|
|
232
322
|
if (!groupedQuestions[subjectId]) {
|
|
233
323
|
groupedQuestions[subjectId] = [];
|
|
@@ -235,6 +325,31 @@ var useQuizStore = create()(
|
|
|
235
325
|
groupedQuestions[subjectId].push(question);
|
|
236
326
|
});
|
|
237
327
|
return groupedQuestions;
|
|
328
|
+
},
|
|
329
|
+
// New methods for userAnswers
|
|
330
|
+
getUserAnswerByQuestionId: (questionId) => {
|
|
331
|
+
const { userAnswers } = get();
|
|
332
|
+
return userAnswers.find((answer) => answer.questionId === questionId) || null;
|
|
333
|
+
},
|
|
334
|
+
isQuestionAnsweredByUserAnswers: (questionId) => {
|
|
335
|
+
const { userAnswers } = get();
|
|
336
|
+
const answer = userAnswers.find(
|
|
337
|
+
(answer2) => answer2.questionId === questionId
|
|
338
|
+
);
|
|
339
|
+
return answer ? answer.answer !== null : false;
|
|
340
|
+
},
|
|
341
|
+
getQuestionStatusFromUserAnswers: (questionId) => {
|
|
342
|
+
const { userAnswers } = get();
|
|
343
|
+
const answer = userAnswers.find(
|
|
344
|
+
(answer2) => answer2.questionId === questionId
|
|
345
|
+
);
|
|
346
|
+
if (!answer) return "unanswered";
|
|
347
|
+
if (answer.answer === null) return "skipped";
|
|
348
|
+
return "answered";
|
|
349
|
+
},
|
|
350
|
+
getUserAnswersForActivity: () => {
|
|
351
|
+
const { userAnswers } = get();
|
|
352
|
+
return userAnswers;
|
|
238
353
|
}
|
|
239
354
|
};
|
|
240
355
|
},
|
|
@@ -244,6 +359,9 @@ var useQuizStore = create()(
|
|
|
244
359
|
)
|
|
245
360
|
);
|
|
246
361
|
export {
|
|
362
|
+
QUESTION_DIFFICULTY,
|
|
363
|
+
QUESTION_STATUS,
|
|
364
|
+
QUESTION_TYPE,
|
|
247
365
|
useQuizStore
|
|
248
366
|
};
|
|
249
367
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Quiz/useQuizStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { devtools } from 'zustand/middleware';\n\ninterface Question {\n id: string;\n questionText: string;\n correctOptionId: string;\n description: string;\n type: 'ALTERNATIVA' | 'DISSERTATIVA' | 'MULTIPLA_CHOICE';\n status: 'APROVADO' | 'REPROVADO';\n difficulty: 'FACIL' | 'MEDIO' | 'DIFICIL';\n examBoard: string | null;\n examYear: string | null;\n answerKey: string | null;\n createdAt: string;\n updatedAt: string;\n knowledgeMatrix: {\n areaKnowledgeId: string;\n subjectId: string;\n topicId: string;\n subtopicId: string;\n contentId: string;\n }[];\n options: {\n id: string;\n option: string;\n }[];\n createdBy: string;\n}\n\ninterface Simulado {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface Atividade {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface Aula {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface UserAnswer extends Question {\n isSkipped: boolean;\n}\n\ninterface QuizState {\n // Data\n bySimulado?: Simulado;\n byAtividade?: Atividade;\n byAula?: Aula;\n\n // UI State\n currentQuestionIndex: number;\n selectedAnswers: Record<string, string>;\n skippedQuestions: string[];\n userAnswers: UserAnswer[];\n timeElapsed: number;\n isStarted: boolean;\n isFinished: boolean;\n\n // Actions\n setBySimulado: (simulado: Simulado) => void;\n setByAtividade: (atividade: Atividade) => void;\n setByAula: (aula: Aula) => void;\n\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 skipQuestion: () => 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 // 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: () => string | undefined;\n getQuizTitle: () => string;\n formatTime: (seconds: number) => string;\n getUserAnswers: () => UserAnswer[];\n getUnansweredQuestionsFromUserAnswers: () => number[];\n getQuestionsGroupedBySubject: () => { [key: string]: Question[] };\n}\n\nexport const useQuizStore = create<QuizState>()(\n devtools(\n (set, get) => {\n let timerInterval: ReturnType<typeof setInterval> | null = null;\n\n const startTimer = () => {\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 return {\n // Initial State\n currentQuestionIndex: 0,\n selectedAnswers: {},\n skippedQuestions: [],\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n\n // Setters\n setBySimulado: (simulado) => set({ bySimulado: simulado }),\n setByAtividade: (atividade) => set({ byAtividade: atividade }),\n setByAula: (aula) => set({ byAula: aula }),\n\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 // Quiz Actions\n selectAnswer: (questionId, answerId) => {\n const { selectedAnswers, skippedQuestions, addUserAnswer } = get();\n // Remove from skipped questions if it was skipped\n const newSkippedQuestions = skippedQuestions.filter(\n (id) => id !== questionId\n );\n set({\n selectedAnswers: {\n ...selectedAnswers,\n [questionId]: answerId,\n },\n skippedQuestions: newSkippedQuestions,\n });\n // Add to user answers\n addUserAnswer(questionId, answerId);\n },\n\n skipQuestion: () => {\n const { getCurrentQuestion, skippedQuestions, addUserAnswer } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (currentQuestion) {\n set({\n skippedQuestions: [...skippedQuestions, currentQuestion.id],\n });\n // Add to user answers as skipped\n addUserAnswer(currentQuestion.id);\n }\n },\n\n addUserAnswer: (questionId, answerId) => {\n const { userAnswers, bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\n const question = quiz?.questions.find((q) => q.id === questionId);\n\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.id === questionId\n );\n\n if (existingAnswerIndex !== -1) {\n // Update existing answer\n const updatedAnswers = [...userAnswers];\n updatedAnswers[existingAnswerIndex] = {\n ...question,\n answerKey: answerId || '',\n isSkipped: !answerId,\n };\n set({ userAnswers: updatedAnswers });\n } else {\n // Add new answer\n set({\n userAnswers: [\n ...userAnswers,\n {\n ...question,\n answerKey: answerId || '',\n isSkipped: !answerId,\n },\n ],\n });\n }\n },\n\n startQuiz: () => {\n set({ isStarted: true, timeElapsed: 0 });\n startTimer();\n },\n\n finishQuiz: () => {\n set({ isFinished: true });\n stopTimer();\n },\n\n resetQuiz: () => {\n stopTimer();\n set({\n currentQuestionIndex: 0,\n selectedAnswers: {},\n skippedQuestions: [],\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n });\n },\n\n // Timer\n updateTime: (time) => set({ timeElapsed: time }),\n startTimer,\n stopTimer,\n\n // Getters\n getCurrentQuestion: () => {\n const { bySimulado, byAtividade, byAula, currentQuestionIndex } =\n get();\n const quiz = bySimulado || byAtividade || byAula;\n\n if (!quiz) {\n return null;\n }\n\n return quiz.questions[currentQuestionIndex];\n },\n\n getTotalQuestions: () => {\n const { bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\n\n return quiz?.questions?.length || 0;\n },\n\n getAnsweredQuestions: () => {\n const { selectedAnswers } = get();\n return Object.keys(selectedAnswers).length;\n },\n\n getUnansweredQuestions: () => {\n const {\n bySimulado,\n byAtividade,\n byAula,\n selectedAnswers,\n skippedQuestions,\n } = get();\n const quiz = bySimulado || byAtividade || byAula;\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const isAnswered = question.id in selectedAnswers;\n const isSkipped = skippedQuestions.includes(question.id);\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 { skippedQuestions } = get();\n return skippedQuestions.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 { selectedAnswers } = get();\n return questionId in selectedAnswers;\n },\n\n isQuestionSkipped: (questionId) => {\n const { skippedQuestions } = get();\n return skippedQuestions.includes(questionId);\n },\n\n getCurrentAnswer: () => {\n const { getCurrentQuestion, selectedAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n return selectedAnswers[currentQuestion?.id || ''];\n },\n\n getQuizTitle: () => {\n const { bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\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 { bySimulado, byAtividade, byAula, userAnswers } = get();\n const quiz = bySimulado || byAtividade || byAula;\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.id === question.id\n );\n\n // Se não há resposta do usuário OU se a questão foi pulada (isSkipped = true)\n if (!userAnswer || userAnswer.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 { bySimulado, byAtividade, byAula } = get();\n const quiz = bySimulado || byAtividade || byAula;\n if (!quiz) return {};\n\n const groupedQuestions: { [key: string]: Question[] } = {};\n\n quiz.questions.forEach((question) => {\n const subjectId =\n question.knowledgeMatrix?.[0]?.subjectId || '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 },\n {\n name: 'quiz-store',\n }\n )\n);\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Quiz/useQuizStore.ts"],"sourcesContent":["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\nexport enum QUESTION_TYPE {\n ALTERNATIVA = 'ALTERNATIVA',\n DISSERTATIVA = 'DISSERTATIVA',\n MULTIPLA_CHOICE = 'MULTIPLA_CHOICE',\n}\n\nexport enum QUESTION_STATUS {\n APROVADO = 'APROVADO',\n REPROVADO = 'REPROVADO',\n}\n\nexport interface Question {\n id: string;\n questionText: string;\n correctOptionId: string;\n description: string;\n type: QUESTION_TYPE;\n status: QUESTION_STATUS;\n difficulty: QUESTION_DIFFICULTY;\n examBoard: string | null;\n examYear: string | null;\n answerKey: string | null;\n createdAt: string;\n updatedAt: string;\n knowledgeMatrix: {\n areaKnowledgeId: string;\n subjectId: string;\n topicId: string;\n subtopicId: string;\n contentId: string;\n }[];\n options: {\n id: string;\n option: string;\n }[];\n createdBy: string;\n}\n\ninterface Simulado {\n id: string;\n title: string;\n category: string;\n questions: Question[];\n}\n\ninterface Atividade {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface Aula {\n id: string;\n title: string;\n questions: Question[];\n}\n\ninterface UserAnswerItem {\n questionId: string;\n activityId: string;\n userId: string;\n answer: string | null;\n optionId: string | null;\n}\n\ninterface UserAnswer extends Question {\n isSkipped: boolean;\n}\n\ninterface QuizState {\n // Data\n bySimulated?: Simulado;\n byActivity?: Atividade;\n byQuestionary?: Aula;\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\n // Actions\n setBySimulated: (simulado: Simulado) => void;\n setByActivity: (atividade: Atividade) => void;\n setByQuestionary: (aula: Aula) => void;\n setUserId: (userId: string) => void;\n\n // Quiz Navigation\n goToNextQuestion: () => void;\n goToPreviousQuestion: () => void;\n goToQuestion: (index: number) => void;\n getActiveQuiz: () => {\n quiz: Simulado | Atividade | Aula;\n type: 'bySimulated' | 'byActivity' | 'byQuestionary';\n } | null;\n\n // Quiz Actions\n selectAnswer: (questionId: string, answerId: string) => void;\n skipQuestion: () => 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 // 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: () => string | undefined;\n getQuizTitle: () => string;\n formatTime: (seconds: number) => string;\n getUserAnswers: () => UserAnswer[];\n getUnansweredQuestionsFromUserAnswers: () => number[];\n getQuestionsGroupedBySubject: () => { [key: string]: Question[] };\n getUserId: () => string;\n\n // New methods for userAnswers\n getUserAnswerByQuestionId: (questionId: string) => UserAnswerItem | null;\n isQuestionAnsweredByUserAnswers: (questionId: string) => boolean;\n getQuestionStatusFromUserAnswers: (\n questionId: string\n ) => 'answered' | 'unanswered' | 'skipped';\n getUserAnswersForActivity: () => UserAnswerItem[];\n}\n\nexport const useQuizStore = create<QuizState>()(\n devtools(\n (set, get) => {\n let timerInterval: 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 return {\n // Initial State\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n\n // Setters\n setBySimulated: (simulado) => set({ bySimulated: simulado }),\n setByActivity: (atividade) => set({ byActivity: atividade }),\n setByQuestionary: (aula) => set({ byQuestionary: aula }),\n setUserId: (userId) => set({ userId }),\n getUserId: () => get().userId,\n\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 getActiveQuiz: () => {\n const { bySimulated, byActivity, byQuestionary } = get();\n if (bySimulated)\n return { quiz: bySimulated, type: 'bySimulated' as const };\n if (byActivity)\n return { quiz: byActivity, type: 'byActivity' as const };\n if (byQuestionary)\n return { quiz: byQuestionary, type: 'byQuestionary' as const };\n return null;\n },\n\n selectAnswer: (questionId, answerId) => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return;\n\n const updatedQuestions = activeQuiz.quiz.questions.map((question) =>\n question.id === questionId\n ? { ...question, answerKey: answerId }\n : question\n );\n\n const updatedQuiz = {\n ...activeQuiz.quiz,\n questions: updatedQuestions,\n };\n\n const activityId = activeQuiz.quiz.id;\n const userId = get().getUserId();\n\n if (!userId) {\n console.warn('selectAnswer called before userId is set');\n return;\n }\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: answerId,\n optionId: answerId,\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 [activeQuiz.type]: updatedQuiz,\n userAnswers: updatedUserAnswers,\n });\n },\n\n skipQuestion: () => {\n const { getCurrentQuestion, userAnswers, getActiveQuiz } = get();\n const currentQuestion = getCurrentQuestion();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return;\n\n if (currentQuestion) {\n const activityId = activeQuiz.quiz.id;\n const userId = get().getUserId();\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 };\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 addUserAnswer: (questionId, answerId) => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return;\n\n // Add to userAnswers array with new structure\n const activityId = activeQuiz.quiz.id;\n const userId = get().getUserId();\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: answerId || null,\n optionId: answerId || null,\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 },\n\n finishQuiz: () => {\n set({ isFinished: true });\n stopTimer();\n },\n\n resetQuiz: () => {\n stopTimer();\n set({\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n });\n },\n\n // Timer\n updateTime: (time) => set({ timeElapsed: time }),\n startTimer,\n stopTimer,\n\n // Getters\n getCurrentQuestion: () => {\n const { currentQuestionIndex, getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) {\n return null;\n }\n\n return activeQuiz.quiz.questions[currentQuestionIndex];\n },\n\n getTotalQuestions: () => {\n const { getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n\n return activeQuiz?.quiz?.questions?.length || 0;\n },\n\n getAnsweredQuestions: () => {\n const { userAnswers } = get();\n return userAnswers.filter((answer) => answer.answer !== null).length;\n },\n\n getUnansweredQuestions: () => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n if (!activeQuiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n activeQuiz.quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const isAnswered = userAnswer && userAnswer.answer !== null;\n const isSkipped = userAnswer && 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((answer) => answer.answer === null).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 ? userAnswer.answer !== null : false;\n },\n\n isQuestionSkipped: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer ? userAnswer.answer === null : 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 return userAnswer?.answer;\n },\n\n getQuizTitle: () => {\n const { getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n\n return activeQuiz?.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 { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n\n if (!activeQuiz) return [];\n\n return activeQuiz.quiz.questions.map((question) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n return {\n ...question,\n isSkipped: userAnswer ? userAnswer.answer === null : false,\n };\n });\n },\n\n getUnansweredQuestionsFromUserAnswers: () => {\n const { getActiveQuiz, userAnswers } = get();\n const activeQuiz = getActiveQuiz();\n if (!activeQuiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n activeQuiz.quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const hasAnswer = userAnswer && userAnswer.answer !== null;\n const isSkipped = userAnswer && 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 { getActiveQuiz } = get();\n const activeQuiz = getActiveQuiz();\n if (!activeQuiz) return {};\n\n const groupedQuestions: { [key: string]: Question[] } = {};\n\n activeQuiz.quiz.questions.forEach((question) => {\n const subjectId =\n question.knowledgeMatrix?.[0]?.subjectId || '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 ? answer.answer !== null : 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.answer === null) return 'skipped';\n return 'answered';\n },\n getUserAnswersForActivity: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n };\n },\n {\n name: 'quiz-store',\n }\n )\n);\n"],"mappings":";AAAA,SAAS,cAAc;AACvB,SAAS,gBAAgB;AAElB,IAAK,sBAAL,kBAAKA,yBAAL;AACL,EAAAA,qBAAA,WAAQ;AACR,EAAAA,qBAAA,WAAQ;AACR,EAAAA,qBAAA,aAAU;AAHA,SAAAA;AAAA,GAAA;AAML,IAAK,gBAAL,kBAAKC,mBAAL;AACL,EAAAA,eAAA,iBAAc;AACd,EAAAA,eAAA,kBAAe;AACf,EAAAA,eAAA,qBAAkB;AAHR,SAAAA;AAAA,GAAA;AAML,IAAK,kBAAL,kBAAKC,qBAAL;AACL,EAAAA,iBAAA,cAAW;AACX,EAAAA,iBAAA,eAAY;AAFF,SAAAA;AAAA,GAAA;AAoIL,IAAM,eAAe,OAAkB;AAAA,EAC5C;AAAA,IACE,CAAC,KAAK,QAAQ;AACZ,UAAI,gBAAuD;AAE3D,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,aAAO;AAAA;AAAA,QAEL,sBAAsB;AAAA,QACtB,iBAAiB,CAAC;AAAA,QAClB,aAAa,CAAC;AAAA,QACd,aAAa;AAAA,QACb,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,QAAQ;AAAA;AAAA,QAGR,gBAAgB,CAAC,aAAa,IAAI,EAAE,aAAa,SAAS,CAAC;AAAA,QAC3D,eAAe,CAAC,cAAc,IAAI,EAAE,YAAY,UAAU,CAAC;AAAA,QAC3D,kBAAkB,CAAC,SAAS,IAAI,EAAE,eAAe,KAAK,CAAC;AAAA,QACvD,WAAW,CAAC,WAAW,IAAI,EAAE,OAAO,CAAC;AAAA,QACrC,WAAW,MAAM,IAAI,EAAE;AAAA;AAAA,QAGvB,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,eAAe,MAAM;AACnB,gBAAM,EAAE,aAAa,YAAY,cAAc,IAAI,IAAI;AACvD,cAAI;AACF,mBAAO,EAAE,MAAM,aAAa,MAAM,cAAuB;AAC3D,cAAI;AACF,mBAAO,EAAE,MAAM,YAAY,MAAM,aAAsB;AACzD,cAAI;AACF,mBAAO,EAAE,MAAM,eAAe,MAAM,gBAAyB;AAC/D,iBAAO;AAAA,QACT;AAAA,QAEA,cAAc,CAAC,YAAY,aAAa;AACtC,gBAAM,EAAE,eAAe,YAAY,IAAI,IAAI;AAC3C,gBAAM,aAAa,cAAc;AAEjC,cAAI,CAAC,WAAY;AAEjB,gBAAM,mBAAmB,WAAW,KAAK,UAAU;AAAA,YAAI,CAAC,aACtD,SAAS,OAAO,aACZ,EAAE,GAAG,UAAU,WAAW,SAAS,IACnC;AAAA,UACN;AAEA,gBAAM,cAAc;AAAA,YAClB,GAAG,WAAW;AAAA,YACd,WAAW;AAAA,UACb;AAEA,gBAAM,aAAa,WAAW,KAAK;AACnC,gBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,cAAI,CAAC,QAAQ;AACX,oBAAQ,KAAK,0CAA0C;AACvD;AAAA,UACF;AAEA,gBAAM,sBAAsB,YAAY;AAAA,YACtC,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AAEA,gBAAM,gBAAgC;AAAA,YACpC;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR,UAAU;AAAA,UACZ;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,CAAC,WAAW,IAAI,GAAG;AAAA,YACnB,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,QAEA,cAAc,MAAM;AAClB,gBAAM,EAAE,oBAAoB,aAAa,cAAc,IAAI,IAAI;AAC/D,gBAAM,kBAAkB,mBAAmB;AAC3C,gBAAM,aAAa,cAAc;AAEjC,cAAI,CAAC,WAAY;AAEjB,cAAI,iBAAiB;AACnB,kBAAM,aAAa,WAAW,KAAK;AACnC,kBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,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,YACZ;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,eAAe,CAAC,YAAY,aAAa;AACvC,gBAAM,EAAE,eAAe,YAAY,IAAI,IAAI;AAC3C,gBAAM,aAAa,cAAc;AAEjC,cAAI,CAAC,WAAY;AAGjB,gBAAM,aAAa,WAAW,KAAK;AACnC,gBAAM,SAAS,IAAI,EAAE,UAAU;AAE/B,gBAAM,sBAAsB,YAAY;AAAA,YACtC,CAAC,WAAW,OAAO,eAAe;AAAA,UACpC;AAEA,gBAAM,gBAAgC;AAAA,YACpC;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ,YAAY;AAAA,YACpB,UAAU,YAAY;AAAA,UACxB;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;AAAA,QACb;AAAA,QAEA,YAAY,MAAM;AAChB,cAAI,EAAE,YAAY,KAAK,CAAC;AACxB,oBAAU;AAAA,QACZ;AAAA,QAEA,WAAW,MAAM;AACf,oBAAU;AACV,cAAI;AAAA,YACF,sBAAsB;AAAA,YACtB,iBAAiB,CAAC;AAAA,YAClB,aAAa,CAAC;AAAA,YACd,aAAa;AAAA,YACb,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA;AAAA,QAGA,YAAY,CAAC,SAAS,IAAI,EAAE,aAAa,KAAK,CAAC;AAAA,QAC/C;AAAA,QACA;AAAA;AAAA,QAGA,oBAAoB,MAAM;AACxB,gBAAM,EAAE,sBAAsB,cAAc,IAAI,IAAI;AACpD,gBAAM,aAAa,cAAc;AAEjC,cAAI,CAAC,YAAY;AACf,mBAAO;AAAA,UACT;AAEA,iBAAO,WAAW,KAAK,UAAU,oBAAoB;AAAA,QACvD;AAAA,QAEA,mBAAmB,MAAM;AACvB,gBAAM,EAAE,cAAc,IAAI,IAAI;AAC9B,gBAAM,aAAa,cAAc;AAEjC,iBAAO,YAAY,MAAM,WAAW,UAAU;AAAA,QAChD;AAAA,QAEA,sBAAsB,MAAM;AAC1B,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,iBAAO,YAAY,OAAO,CAAC,WAAW,OAAO,WAAW,IAAI,EAAE;AAAA,QAChE;AAAA,QAEA,wBAAwB,MAAM;AAC5B,gBAAM,EAAE,eAAe,YAAY,IAAI,IAAI;AAC3C,gBAAM,aAAa,cAAc;AACjC,cAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,gBAAM,sBAAgC,CAAC;AAEvC,qBAAW,KAAK,UAAU,QAAQ,CAAC,UAAU,UAAU;AACrD,kBAAM,aAAa,YAAY;AAAA,cAC7B,CAAC,WAAW,OAAO,eAAe,SAAS;AAAA,YAC7C;AACA,kBAAM,aAAa,cAAc,WAAW,WAAW;AACvD,kBAAM,YAAY,cAAc,WAAW,WAAW;AAEtD,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,OAAO,CAAC,WAAW,OAAO,WAAW,IAAI,EAAE;AAAA,QAChE;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,aAAa,WAAW,WAAW,OAAO;AAAA,QACnD;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,aAAa,WAAW,WAAW,OAAO;AAAA,QACnD;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;AACA,iBAAO,YAAY;AAAA,QACrB;AAAA,QAEA,cAAc,MAAM;AAClB,gBAAM,EAAE,cAAc,IAAI,IAAI;AAC9B,gBAAM,aAAa,cAAc;AAEjC,iBAAO,YAAY,MAAM,SAAS;AAAA,QACpC;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,eAAe,YAAY,IAAI,IAAI;AAC3C,gBAAM,aAAa,cAAc;AAEjC,cAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,iBAAO,WAAW,KAAK,UAAU,IAAI,CAAC,aAAa;AACjD,kBAAM,aAAa,YAAY;AAAA,cAC7B,CAAC,WAAW,OAAO,eAAe,SAAS;AAAA,YAC7C;AACA,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,WAAW,aAAa,WAAW,WAAW,OAAO;AAAA,YACvD;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QAEA,uCAAuC,MAAM;AAC3C,gBAAM,EAAE,eAAe,YAAY,IAAI,IAAI;AAC3C,gBAAM,aAAa,cAAc;AACjC,cAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,gBAAM,sBAAgC,CAAC;AAEvC,qBAAW,KAAK,UAAU,QAAQ,CAAC,UAAU,UAAU;AACrD,kBAAM,aAAa,YAAY;AAAA,cAC7B,CAAC,WAAW,OAAO,eAAe,SAAS;AAAA,YAC7C;AACA,kBAAM,YAAY,cAAc,WAAW,WAAW;AACtD,kBAAM,YAAY,cAAc,WAAW,WAAW;AAGtD,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,cAAc,IAAI,IAAI;AAC9B,gBAAM,aAAa,cAAc;AACjC,cAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,gBAAM,mBAAkD,CAAC;AAEzD,qBAAW,KAAK,UAAU,QAAQ,CAAC,aAAa;AAC9C,kBAAM,YACJ,SAAS,kBAAkB,CAAC,GAAG,aAAa;AAE9C,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,SAAS,OAAO,WAAW,OAAO;AAAA,QAC3C;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,WAAW,KAAM,QAAO;AACnC,iBAAO;AAAA,QACT;AAAA,QACA,2BAA2B,MAAM;AAC/B,gBAAM,EAAE,YAAY,IAAI,IAAI;AAC5B,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EACF;AACF;","names":["QUESTION_DIFFICULTY","QUESTION_TYPE","QUESTION_STATUS","answer"]}
|