UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

1 lines 5.77 kB
{"version":3,"sources":["../src/components/Quiz/Quiz.utils.ts"],"sourcesContent":["import {\n QuizVariant,\n type QuestionAnswerResult,\n type TrueOrFalseOptionState,\n} from './Quiz.types';\nimport { TrueFalseEnum } from '../../enums/Quiz';\nimport { OptionStatus } from '../../enums/Options';\n\n/**\n * Helper function to format exam info (bank - year)\n * @param examBoard - The exam board/bank name\n * @param examYear - The exam year\n * @returns Formatted string like \"(ENEM - 2023)\" or empty string if no info\n */\nexport const formatExamInfo = (\n examBoard: string | null | undefined,\n examYear: string | null | undefined\n): string => {\n if (examBoard && examYear) {\n return `(${examBoard} - ${examYear})`;\n }\n if (examBoard) {\n return `(${examBoard})`;\n }\n if (examYear) {\n return `(${examYear})`;\n }\n return '';\n};\n\n/**\n * Shuffle array using a seed for consistent ordering per question\n * Uses Fisher-Yates shuffle with seeded random for deterministic results\n */\nexport const shuffleWithSeed = <T>(array: T[], seed: string): T[] => {\n const shuffled = [...array];\n // Simple hash function to convert string seed to number\n let hash = 0;\n for (let i = 0; i < seed.length; i++) {\n const char = seed.codePointAt(i) ?? 0;\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n // Fisher-Yates shuffle with seeded random\n const seededRandom = (max: number) => {\n hash = (hash * 1103515245 + 12345) & 0x7fffffff;\n return hash % max;\n };\n for (let i = shuffled.length - 1; i > 0; i--) {\n const j = seededRandom(i + 1);\n [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];\n }\n return shuffled;\n};\n\n/**\n * Helper to prepend letter to HTML content (handles <p> tags)\n * @example prependLetterToHtml('a', '<p>Text</p>') => '<p>a) Text</p>'\n * @example prependLetterToHtml('a', 'Text') => 'a) Text'\n */\nexport const prependLetterToHtml = (letter: string, html: string): string => {\n if (html.trim().startsWith('<p>')) {\n return html.replace(/^(\\s*<p>)/, `$1${letter}) `);\n }\n return `${letter}) ${html}`;\n};\n\n/**\n * Compute state for a true/false option\n * Handles both interactive (default) and result modes\n */\nexport const getTrueOrFalseOptionState = (\n optionId: string,\n variant: string,\n currentQuestionResult: QuestionAnswerResult | null | undefined,\n localAnswers: Record<string, string>\n): TrueOrFalseOptionState => {\n // Get whether the statement is TRUE or FALSE from persisted result\n const correctAnswerOption = currentQuestionResult?.options?.find(\n (op) => op.id === optionId\n );\n const isStatementTrue =\n variant === QuizVariant.RESULT\n ? (correctAnswerOption?.isCorrect ?? false)\n : false;\n\n // Get student's selection from selectedOptions\n const studentSelection =\n variant === QuizVariant.RESULT\n ? currentQuestionResult?.selectedOptions?.find(\n (op) => op.optionId === optionId\n )\n : undefined;\n\n // Determine if answered and what was marked\n const hasAnswered =\n variant === QuizVariant.RESULT\n ? studentSelection !== undefined\n : !!localAnswers[optionId];\n\n const studentMarkedTrue =\n variant === QuizVariant.RESULT\n ? (studentSelection?.isCorrect ?? false)\n : localAnswers[optionId] === TrueFalseEnum.VERDADEIRO;\n\n // Compute display values\n const getStudentAnswerDisplay = (): string => {\n if (variant !== QuizVariant.RESULT) {\n return localAnswers[optionId] || '-';\n }\n if (!hasAnswered) {\n return '-';\n }\n return studentMarkedTrue ? TrueFalseEnum.VERDADEIRO : TrueFalseEnum.FALSO;\n };\n const studentAnswer = getStudentAnswerDisplay();\n\n const correctAnswer = isStatementTrue\n ? TrueFalseEnum.VERDADEIRO\n : TrueFalseEnum.FALSO;\n const isStudentCorrect = hasAnswered && studentMarkedTrue === isStatementTrue;\n const variantCorrect = isStudentCorrect\n ? OptionStatus.CORRECT\n : OptionStatus.INCORRECT;\n\n return {\n isStatementTrue,\n hasAnswered,\n studentMarkedTrue,\n studentAnswer,\n correctAnswer,\n isStudentCorrect,\n variantCorrect,\n };\n};\n"],"mappings":";AAcO,IAAM,iBAAiB,CAC5B,WACA,aACW;AACX,MAAI,aAAa,UAAU;AACzB,WAAO,IAAI,SAAS,MAAM,QAAQ;AAAA,EACpC;AACA,MAAI,WAAW;AACb,WAAO,IAAI,SAAS;AAAA,EACtB;AACA,MAAI,UAAU;AACZ,WAAO,IAAI,QAAQ;AAAA,EACrB;AACA,SAAO;AACT;AAMO,IAAM,kBAAkB,CAAI,OAAY,SAAsB;AACnE,QAAM,WAAW,CAAC,GAAG,KAAK;AAE1B,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,OAAO,KAAK,YAAY,CAAC,KAAK;AACpC,YAAQ,QAAQ,KAAK,OAAO;AAC5B,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,eAAe,CAAC,QAAgB;AACpC,WAAQ,OAAO,aAAa,QAAS;AACrC,WAAO,OAAO;AAAA,EAChB;AACA,WAAS,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;AAC5C,UAAM,IAAI,aAAa,IAAI,CAAC;AAC5B,KAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;AAAA,EACxD;AACA,SAAO;AACT;AAOO,IAAM,sBAAsB,CAAC,QAAgB,SAAyB;AAC3E,MAAI,KAAK,KAAK,EAAE,WAAW,KAAK,GAAG;AACjC,WAAO,KAAK,QAAQ,aAAa,KAAK,MAAM,IAAI;AAAA,EAClD;AACA,SAAO,GAAG,MAAM,KAAK,IAAI;AAC3B;AAMO,IAAM,4BAA4B,CACvC,UACA,SACA,uBACA,iBAC2B;AAE3B,QAAM,sBAAsB,uBAAuB,SAAS;AAAA,IAC1D,CAAC,OAAO,GAAG,OAAO;AAAA,EACpB;AACA,QAAM,kBACJ,oCACK,qBAAqB,aAAa,QACnC;AAGN,QAAM,mBACJ,oCACI,uBAAuB,iBAAiB;AAAA,IACtC,CAAC,OAAO,GAAG,aAAa;AAAA,EAC1B,IACA;AAGN,QAAM,cACJ,oCACI,qBAAqB,SACrB,CAAC,CAAC,aAAa,QAAQ;AAE7B,QAAM,oBACJ,oCACK,kBAAkB,aAAa,QAChC,aAAa,QAAQ;AAG3B,QAAM,0BAA0B,MAAc;AAC5C,QAAI,mCAAgC;AAClC,aAAO,aAAa,QAAQ,KAAK;AAAA,IACnC;AACA,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,wBAAwB;AAE9C,QAAM,gBAAgB;AAGtB,QAAM,mBAAmB,eAAe,sBAAsB;AAC9D,QAAM,iBAAiB;AAIvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}