@tinyweb_dev/oe-exam-sdk 0.1.24 → 0.1.27

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.
Files changed (133) hide show
  1. package/README.md +5 -4
  2. package/dist/components/exams/ExamPreviewDialog.d.ts +7 -6
  3. package/dist/components/exams/ExamPreviewDialog.js +1 -1
  4. package/dist/components/exams/index.d.ts +0 -1
  5. package/dist/components/exams/take/components/QuestionRenderer.js +1 -1
  6. package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +1 -1
  7. package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +1 -1
  8. package/dist/components/exams/take/exam-taking.utils.d.ts +0 -13
  9. package/dist/components/exams/take/exam-taking.utils.js +1 -1
  10. package/dist/components/exams/take/utils/answer-transformers.js +1 -1
  11. package/dist/components/exams/take/utils/question-transformers.d.ts +7 -17
  12. package/dist/components/exams/take/utils/question-transformers.js +1 -1
  13. package/dist/components/questions/_shared/config/question-types.config.js +1 -1
  14. package/dist/components/questions/_shared/types/choose-the-correct-answer-group.type.d.ts +36 -0
  15. package/dist/components/questions/_shared/types/cross-out-word-group.type.d.ts +40 -0
  16. package/dist/components/questions/_shared/types/index.d.ts +1 -0
  17. package/dist/components/questions/_shared/types/index.js +1 -1
  18. package/dist/components/questions/_shared/types/true-false-group.type.d.ts +31 -0
  19. package/dist/components/questions/_shared/types/true-false-group.type.js +1 -0
  20. package/dist/components/questions/_shared/types/word-fill-structured-form.type.d.ts +29 -26
  21. package/dist/components/questions/creator/question-type-registry.js +1 -1
  22. package/dist/components/questions/index.d.ts +0 -1
  23. package/dist/components/questions/index.js +1 -1
  24. package/dist/components/questions/types/choose-the-correct-answer/ChooseTheCorrectAnswerClient.js +1 -1
  25. package/dist/components/questions/types/choose-the-correct-answer/transform.js +1 -1
  26. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient.d.ts +2 -0
  27. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupClient.js +1 -0
  28. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupCreator.d.ts +2 -0
  29. package/dist/components/questions/types/choose-the-correct-answer-group/ChooseTheCorrectAnswerGroupCreator.js +1 -0
  30. package/dist/components/questions/types/choose-the-correct-answer-group/index.d.ts +2 -0
  31. package/dist/components/questions/types/choose-the-correct-answer-group/index.js +1 -0
  32. package/dist/components/questions/types/choose-the-correct-answer-group/register.d.ts +2 -0
  33. package/dist/components/questions/types/choose-the-correct-answer-group/register.js +1 -0
  34. package/dist/components/questions/types/choose-the-correct-answer-group/transform.d.ts +2 -0
  35. package/dist/components/questions/types/choose-the-correct-answer-group/transform.js +1 -0
  36. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupClient.d.ts +2 -0
  37. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupClient.js +1 -0
  38. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupCreator.d.ts +2 -0
  39. package/dist/components/questions/types/cross-out-word-group/CrossOutWordGroupCreator.js +1 -0
  40. package/dist/components/questions/types/cross-out-word-group/index.d.ts +4 -0
  41. package/dist/components/questions/types/cross-out-word-group/index.js +1 -0
  42. package/dist/components/questions/types/cross-out-word-group/register.d.ts +2 -0
  43. package/dist/components/questions/types/cross-out-word-group/register.js +1 -0
  44. package/dist/components/questions/types/cross-out-word-group/transform.d.ts +2 -0
  45. package/dist/components/questions/types/cross-out-word-group/transform.js +1 -0
  46. package/dist/components/questions/types/true-false-group/TrueFalseGroupClient.d.ts +2 -0
  47. package/dist/components/questions/types/true-false-group/TrueFalseGroupClient.js +1 -0
  48. package/dist/components/questions/types/true-false-group/TrueFalseGroupCreator.d.ts +2 -0
  49. package/dist/components/questions/types/true-false-group/TrueFalseGroupCreator.js +1 -0
  50. package/dist/components/questions/types/true-false-group/index.d.ts +4 -0
  51. package/dist/components/questions/types/true-false-group/index.js +1 -0
  52. package/dist/components/questions/types/true-false-group/register.d.ts +2 -0
  53. package/dist/components/questions/types/true-false-group/register.js +1 -0
  54. package/dist/components/questions/types/true-false-group/transform.d.ts +2 -0
  55. package/dist/components/questions/types/true-false-group/transform.js +1 -0
  56. package/dist/components/questions/types/word-fill-structured-form/WfsfWordBankEditor.d.ts +14 -0
  57. package/dist/components/questions/types/word-fill-structured-form/WfsfWordBankEditor.js +1 -0
  58. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.d.ts +1 -1
  59. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormClient.js +1 -1
  60. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.d.ts +1 -1
  61. package/dist/components/questions/types/word-fill-structured-form/WordFillStructuredFormCreator.js +1 -1
  62. package/dist/components/questions/types/word-fill-structured-form/register.js +1 -1
  63. package/dist/components/questions/types/word-fill-structured-form/transform.d.ts +5 -2
  64. package/dist/components/questions/types/word-fill-structured-form/transform.js +1 -1
  65. package/dist/components/questions/types/word-fill-structured-form/wfsf-word-bank.utils.d.ts +24 -0
  66. package/dist/components/questions/types/word-fill-structured-form/wfsf-word-bank.utils.js +1 -0
  67. package/dist/components/questions/viewer/QuestionViewer.js +1 -1
  68. package/dist/components/results/renderers/review-question-body-dedicated.js +1 -1
  69. package/dist/components/results/review-data.js +1 -1
  70. package/dist/components/themes/english-certification/EcWordFillStructuredForm.js +1 -1
  71. package/dist/index.d.ts +1 -2
  72. package/dist/index.js +1 -1
  73. package/dist/mcp/config.d.ts +12 -0
  74. package/dist/mcp/config.js +1 -0
  75. package/dist/mcp/http-client.d.ts +6 -0
  76. package/dist/mcp/http-client.js +1 -0
  77. package/dist/mcp/index.d.ts +6 -0
  78. package/dist/mcp/index.js +2 -0
  79. package/dist/mcp/tools/_helpers.d.ts +4 -0
  80. package/dist/mcp/tools/_helpers.js +1 -0
  81. package/dist/mcp/tools/exams.d.ts +2 -0
  82. package/dist/mcp/tools/exams.js +1 -0
  83. package/dist/mcp/tools/index.d.ts +2 -0
  84. package/dist/mcp/tools/index.js +1 -0
  85. package/dist/mcp/tools/results.d.ts +2 -0
  86. package/dist/mcp/tools/results.js +1 -0
  87. package/dist/shared/constants/question-skills.js +1 -1
  88. package/dist/shared/lib/i18n/messages/en/admin.d.ts +4 -11
  89. package/dist/shared/lib/i18n/messages/en/admin.js +1 -1
  90. package/dist/shared/lib/i18n/messages/en.d.ts +4 -11
  91. package/dist/shared/lib/i18n/messages/vi/admin.d.ts +4 -11
  92. package/dist/shared/lib/i18n/messages/vi/admin.js +1 -1
  93. package/dist/shared/lib/i18n/messages/vi.d.ts +4 -11
  94. package/dist/shared/lib/utils/question-reverse-transform.js +1 -1
  95. package/dist/shared/lib/utils/question-transform.js +1 -1
  96. package/dist/shared/types/common.types.d.ts +1 -1
  97. package/dist/shared/types/questions/choose-the-correct-answer-group.d.ts +41 -0
  98. package/dist/shared/types/questions/choose-the-correct-answer-group.js +1 -0
  99. package/dist/shared/types/questions/cross-out-word-group.d.ts +41 -0
  100. package/dist/shared/types/questions/cross-out-word-group.js +1 -0
  101. package/dist/shared/types/questions/index.d.ts +2 -0
  102. package/dist/shared/types/questions/index.js +1 -1
  103. package/package.json +165 -163
  104. package/dist/components/exams/ExamPreviewPartContent.d.ts +0 -18
  105. package/dist/components/exams/ExamPreviewPartContent.js +0 -1
  106. package/dist/components/exams/ExamPreviewSidebar.d.ts +0 -17
  107. package/dist/components/exams/ExamPreviewSidebar.js +0 -1
  108. package/dist/components/exams/exam-preview.types.d.ts +0 -34
  109. package/dist/components/exams/exam-preview.types.js +0 -1
  110. package/dist/components/questions/_shared/utils/parseFillBlankStem.d.ts +0 -30
  111. package/dist/components/questions/_shared/utils/parseFillBlankStem.js +0 -1
  112. package/dist/components/questions/question-bank/EditQuestionBankDialog.d.ts +0 -2
  113. package/dist/components/questions/question-bank/EditQuestionBankDialog.js +0 -1
  114. package/dist/components/questions/question-bank/QuestionEditorRenderer.d.ts +0 -23
  115. package/dist/components/questions/question-bank/QuestionEditorRenderer.js +0 -1
  116. package/dist/components/questions/question-bank/difficulty.d.ts +0 -15
  117. package/dist/components/questions/question-bank/difficulty.js +0 -1
  118. package/dist/components/questions/question-bank/editor-adapters/choice-adapters.d.ts +0 -5
  119. package/dist/components/questions/question-bank/editor-adapters/choice-adapters.js +0 -1
  120. package/dist/components/questions/question-bank/editor-adapters/index.d.ts +0 -5
  121. package/dist/components/questions/question-bank/editor-adapters/index.js +0 -1
  122. package/dist/components/questions/question-bank/editor-adapters/media-adapters.d.ts +0 -6
  123. package/dist/components/questions/question-bank/editor-adapters/media-adapters.js +0 -1
  124. package/dist/components/questions/question-bank/editor-adapters/types.d.ts +0 -1
  125. package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.d.ts +0 -8
  126. package/dist/components/questions/question-bank/editor-adapters/unsupported-fallback.js +0 -1
  127. package/dist/components/questions/question-bank/editor-adapters/writing-adapters.d.ts +0 -5
  128. package/dist/components/questions/question-bank/editor-adapters/writing-adapters.js +0 -1
  129. package/dist/components/questions/question-bank/index.d.ts +0 -4
  130. package/dist/components/questions/question-bank/index.js +0 -1
  131. package/dist/components/questions/question-bank/types.d.ts +0 -59
  132. /package/dist/components/questions/{question-bank/editor-adapters/types.js → _shared/types/choose-the-correct-answer-group.type.js} +0 -0
  133. /package/dist/components/questions/{question-bank/types.js → _shared/types/cross-out-word-group.type.js} +0 -0
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerResultTools(server: McpServer): void;
@@ -0,0 +1 @@
1
+ import{z as t}from"zod";import{mcpRequest as e}from"../http-client.js";import{buildToolResult as n,wrapHandler as o}from"./_helpers.js";export function registerResultTools(r){r.registerTool("exam_result_get",{title:"Get exam result review",description:"Fetch student exam result review by attemptId. Optional token supports public result review links.",inputSchema:{attemptId:t.string().min(1),token:t.string().min(1).optional(),includeAttempt:t.boolean().default(!0)}},o("exam_result_get",async({attemptId:t,token:o,includeAttempt:r})=>{const i=o?`?token=${encodeURIComponent(String(o))}`:"",s=await e({method:"GET",url:`/api/v1/student/results/${encodeURIComponent(String(t))}${i}`}),l=!1===r?null:await e({method:"GET",url:`/api/v1/student/attempts/${encodeURIComponent(String(t))}${i}`});return n({result:s,attempt:l})}))}
@@ -1 +1 @@
1
- import{SkillEnum as E}from"../types/common.types";export const QUESTION_TYPE_SKILLS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:E.LISTENING,LISTEN_AND_TICK_ANSWER:E.LISTENING,LISTEN_AND_FILL_NAME_NUMBER:E.LISTENING,LISTENING_FILL_BLANK:E.LISTENING,LISTENING_COLOR:E.LISTENING,LISTENING:E.LISTENING,LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:E.SPEAKING,LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:E.SPEAKING,LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:E.SPEAKING,LISTEN_AND_SPEAK_ANSWER:E.SPEAKING,LISTEN_AND_SPEAK_IMAGE_GROUP:E.SPEAKING,LISTEN_AND_SPEAK_QUESTION_LIST:E.SPEAKING,LISTEN_AND_SPEAK_COMPARE_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_WITH_STORY_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_ODD_ONE_OUT:E.SPEAKING,LISTEN_AND_SPEAK_INFO_EXCHANGE:E.SPEAKING,READ_DISPLAYED_CONTENT:E.SPEAKING,SPEAKING_DESCRIBE_IMAGE:E.SPEAKING,SPONTANEOUS_QA:E.SPEAKING,SPEAKING_CONVERSATION:E.SPEAKING,SPEAKING_CUE_CARD:E.SPEAKING,GN_SPEAKING_INTERVIEW:E.SPEAKING,CHOOSE_THE_CORRECT_ANSWER:E.READING,CHOOSE_CORRECT_ADJECTIVE:E.READING,FILL_IN_BLANK:E.READING,FILL_MISSING_WORDS_IN_GRID:E.READING,READ_PASSAGE_AND_ANSWER_QUESTIONS:E.READING,ANSWER_THE_QUESTION:E.READING,WORD_ORDERING:E.READING,WORD_FILL_PARAGRAPH:E.READING,MATCH_BY_WRITING_ANSWER:E.READING,LABEL_THE_PICTURE:E.READING,LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:E.READING,LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:E.READING,LOOK_PICTURE_FILL_WORD_HINT:E.READING,READ_AND_COLOR_OBJECTS:E.READING,IMAGE_OBJECT_MATCHING:E.READING,TRUE_FALSE:E.READING,MATCHING:E.READING,ORDERING:E.READING,TICK_TRUE_OR_FALSE:E.READING,TICK_YES_OR_NO:E.READING,READING_TICK_CROSS:E.READING,ARRANGE_LETTERS_INTO_WORDS:E.READING,READ_PASSAGE_AND_COMPLETE_STORY:E.READING,CLOZE_TEST_WITH_TICK_BOX:E.READING,READ_AND_CHOOSE_APPROPRIATE_WORD:E.READING,READING_LETTER_ARRANGE:E.READING,READING_PASSAGE_FILL:E.READING,FILL_BLANK:E.READING,WORD_FILL_STRUCTURED_FORM:E.READING,WRITE_A_SHORT_LETTER:E.WRITING,WRITE_CORRECT_VERB_FORM:E.WRITING,WRITE_SHORT_PARAGRAPH:E.WRITING,WRITE_SENTENCES:E.WRITING,ESSAY:E.WRITING,COLORING:E.WRITING};export function getQuestionTypeSkill(E){return QUESTION_TYPE_SKILLS[E]||"READING"}export function getQuestionTypesBySkill(E){return Object.entries(QUESTION_TYPE_SKILLS).filter(([_,N])=>N===E).map(([E,_])=>E)}export const QUESTION_TYPES_BY_SKILL={LISTENING:getQuestionTypesBySkill("LISTENING"),SPEAKING:getQuestionTypesBySkill("SPEAKING"),READING:getQuestionTypesBySkill("READING"),WRITING:getQuestionTypesBySkill("WRITING")};export const MARKETING_QUESTION_TYPES_BY_SKILL={[E.LISTENING]:[],[E.SPEAKING]:[],[E.READING]:["CHOOSE_THE_CORRECT_ANSWER","CHOOSE_CORRECT_ADJECTIVE","FILL_IN_BLANK","FILL_MISSING_WORDS_IN_GRID","LABEL_THE_PICTURE","LOOK_PICTURE_CHOOSE_CORRECT_ANSWER","LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER","LOOK_PICTURE_FILL_WORD_HINT","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING","READ_PASSAGE_AND_ANSWER_QUESTIONS"],[E.WRITING]:["WRITE_A_SHORT_LETTER","WRITE_CORRECT_VERB_FORM","WRITE_SENTENCES"]};export function isMarketingQuestionType(E){return Object.values(MARKETING_QUESTION_TYPES_BY_SKILL).flat().includes(E)}export const QUESTION_TYPE_LABELS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:"Nghe - Điền từ có hình",LISTEN_AND_TICK_ANSWER:"Nghe - Đánh dấu",LISTEN_AND_FILL_NAME_NUMBER:"Nghe - Điền tên/số",LISTENING_FILL_BLANK:"Nghe - Điền chỗ trống",LISTENING_COLOR:"Nghe - Tô màu",LISTENING:"Nghe",CHOOSE_THE_CORRECT_ANSWER:"Chọn đáp án đúng",CHOOSE_CORRECT_ADJECTIVE:"Chọn tính từ",FILL_IN_BLANK:"Điền vào chỗ trống",FILL_MISSING_WORDS_IN_GRID:"Điền từ vào lưới",READ_PASSAGE_AND_ANSWER_QUESTIONS:"Đọc hiểu - Trả lời",LABEL_THE_PICTURE:"Gắn nhãn hình ảnh",LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:"Nhìn ảnh - Chọn đáp án",LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:"Nhìn ảnh - Điền và chọn",LOOK_PICTURE_FILL_WORD_HINT:"Nhìn ảnh - Điền từ gợi ý",READ_AND_COLOR_OBJECTS:"Đọc - Tô màu",IMAGE_OBJECT_MATCHING:"Ghép hình ảnh - Đối tượng",TRUE_FALSE:"Đúng/Sai",MATCHING:"Ghép nối",ORDERING:"Sắp xếp",TICK_TRUE_OR_FALSE:"Đánh dấu Đúng/Sai",TICK_YES_OR_NO:"Đánh dấu Có/Không",READING_TICK_CROSS:"Đọc - Đánh dấu",ARRANGE_LETTERS_INTO_WORDS:"Sắp xếp chữ cái thành từ",READ_PASSAGE_AND_COMPLETE_STORY:"Đọc - Hoàn thành câu chuyện",CLOZE_TEST_WITH_TICK_BOX:"Điền từ - Đánh dấu",READ_AND_CHOOSE_APPROPRIATE_WORD:"Đọc - Chọn từ phù hợp",READING_LETTER_ARRANGE:"Đọc - Sắp xếp chữ cái",READING_PASSAGE_FILL:"Đọc - Điền đoạn văn",FILL_BLANK:"Điền chỗ trống",ANSWER_THE_QUESTION:"Nghe - Đọc câu hỏi và viết đáp án",WORD_ORDERING:"Sắp xếp từ",WORD_FILL_PARAGRAPH:"Điền từ vào đoạn văn",MATCH_BY_WRITING_ANSWER:"Ghép đáp án bằng cách viết",WORD_FILL_STRUCTURED_FORM:"Điền từ vào biểu mẫu có cấu trúc",WRITE_A_SHORT_LETTER:"Viết thư",WRITE_CORRECT_VERB_FORM:"Chia động từ",WRITE_SHORT_PARAGRAPH:"Viết đoạn văn ngắn",WRITE_SENTENCES:"Viết câu",ESSAY:"Viết luận",COLORING:"Tô màu",LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:"Nghe và chọn trong nhóm đáp án",LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:"Nghe và chọn đối tượng trong cảnh",LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:"Nghe và kéo thả đối tượng vào cảnh",LISTEN_AND_SPEAK_ANSWER:"Nghe và trả lời (Speaking)",LISTEN_AND_SPEAK_IMAGE_GROUP:"Nghe, nhìn nhóm ảnh và trả lời (Speaking)",LISTEN_AND_SPEAK_QUESTION_LIST:"Nghe, chọn câu hỏi và trả lời (Speaking)",LISTEN_AND_SPEAK_COMPARE_IMAGES:"Nghe và so sánh ảnh (Speaking)",LISTEN_AND_SPEAK_WITH_STORY_IMAGES:"Nghe, nhìn ảnh truyện và kể lại (Speaking)",LISTEN_AND_SPEAK_ODD_ONE_OUT:"Nghe, chọn hình khác loại và giải thích (Speaking)",LISTEN_AND_SPEAK_INFO_EXCHANGE:"Trao đổi thông tin (Speaking)",READ_DISPLAYED_CONTENT:"Đọc nội dung hiển thị (Speaking)",SPEAKING_DESCRIBE_IMAGE:"Nhìn tranh và mô tả (Speaking Part 2)",SPONTANEOUS_QA:"Hỏi đáp tự phát (Speaking Part 3)",SPEAKING_CONVERSATION:"Hội thoại Speaking (KFS Speaking)",GN_SPEAKING_INTERVIEW:"GN Speaking - Hỏi đáp (Virtual + Real)"};export function getQuestionTypeLabel(E){return QUESTION_TYPE_LABELS[E]||E}export const SKILL_METADATA={[E.LISTENING]:{name:"Nghe",emoji:"🎧",color:"text-blue-600",bgColor:"bg-blue-50",borderColor:"border-blue-200",description:"Kỹ năng nghe hiểu"},[E.SPEAKING]:{name:"Nói",emoji:"🗣️",color:"text-green-600",bgColor:"bg-green-50",borderColor:"border-green-200",description:"Kỹ năng giao tiếp"},[E.READING]:{name:"Đọc",emoji:"📖",color:"text-purple-600",bgColor:"bg-purple-50",borderColor:"border-purple-200",description:"Kỹ năng đọc hiểu"},[E.WRITING]:{name:"Viết",emoji:"✏️",color:"text-orange-600",bgColor:"bg-orange-50",borderColor:"border-orange-200",description:"Kỹ năng viết"}};
1
+ import{SkillEnum as E}from"../types/common.types";export const QUESTION_TYPE_SKILLS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:E.LISTENING,LISTEN_AND_TICK_ANSWER:E.LISTENING,LISTEN_AND_FILL_NAME_NUMBER:E.LISTENING,LISTENING_FILL_BLANK:E.LISTENING,LISTENING_COLOR:E.LISTENING,LISTENING:E.LISTENING,LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:E.SPEAKING,LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:E.SPEAKING,LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:E.SPEAKING,LISTEN_AND_SPEAK_ANSWER:E.SPEAKING,LISTEN_AND_SPEAK_IMAGE_GROUP:E.SPEAKING,LISTEN_AND_SPEAK_QUESTION_LIST:E.SPEAKING,LISTEN_AND_SPEAK_COMPARE_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_WITH_STORY_IMAGES:E.SPEAKING,LISTEN_AND_SPEAK_ODD_ONE_OUT:E.SPEAKING,LISTEN_AND_SPEAK_INFO_EXCHANGE:E.SPEAKING,READ_DISPLAYED_CONTENT:E.SPEAKING,SPEAKING_DESCRIBE_IMAGE:E.SPEAKING,SPONTANEOUS_QA:E.SPEAKING,SPEAKING_CONVERSATION:E.SPEAKING,SPEAKING_CUE_CARD:E.SPEAKING,GN_SPEAKING_INTERVIEW:E.SPEAKING,CHOOSE_THE_CORRECT_ANSWER:E.READING,CHOOSE_THE_CORRECT_ANSWER_GROUP:E.READING,CHOOSE_CORRECT_ADJECTIVE:E.READING,FILL_IN_BLANK:E.READING,FILL_MISSING_WORDS_IN_GRID:E.READING,READ_PASSAGE_AND_ANSWER_QUESTIONS:E.READING,ANSWER_THE_QUESTION:E.READING,WORD_ORDERING:E.READING,WORD_FILL_PARAGRAPH:E.READING,MATCH_BY_WRITING_ANSWER:E.READING,LABEL_THE_PICTURE:E.READING,LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:E.READING,LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:E.READING,LOOK_PICTURE_FILL_WORD_HINT:E.READING,READ_AND_COLOR_OBJECTS:E.READING,IMAGE_OBJECT_MATCHING:E.READING,TRUE_FALSE:E.READING,TRUE_FALSE_GROUP:E.READING,CROSS_OUT_WORD_GROUP:E.READING,MATCHING:E.READING,ORDERING:E.READING,TICK_TRUE_OR_FALSE:E.READING,TICK_YES_OR_NO:E.READING,READING_TICK_CROSS:E.READING,ARRANGE_LETTERS_INTO_WORDS:E.READING,READ_PASSAGE_AND_COMPLETE_STORY:E.READING,CLOZE_TEST_WITH_TICK_BOX:E.READING,READ_AND_CHOOSE_APPROPRIATE_WORD:E.READING,READING_LETTER_ARRANGE:E.READING,READING_PASSAGE_FILL:E.READING,FILL_BLANK:E.READING,WORD_FILL_STRUCTURED_FORM:E.READING,WRITE_A_SHORT_LETTER:E.WRITING,WRITE_CORRECT_VERB_FORM:E.WRITING,WRITE_SHORT_PARAGRAPH:E.WRITING,WRITE_SENTENCES:E.WRITING,ESSAY:E.WRITING,COLORING:E.WRITING};export function getQuestionTypeSkill(E){return QUESTION_TYPE_SKILLS[E]||"READING"}export function getQuestionTypesBySkill(E){return Object.entries(QUESTION_TYPE_SKILLS).filter(([_,N])=>N===E).map(([E,_])=>E)}export const QUESTION_TYPES_BY_SKILL={LISTENING:getQuestionTypesBySkill("LISTENING"),SPEAKING:getQuestionTypesBySkill("SPEAKING"),READING:getQuestionTypesBySkill("READING"),WRITING:getQuestionTypesBySkill("WRITING")};export const MARKETING_QUESTION_TYPES_BY_SKILL={[E.LISTENING]:[],[E.SPEAKING]:[],[E.READING]:["CHOOSE_THE_CORRECT_ANSWER","CHOOSE_CORRECT_ADJECTIVE","FILL_IN_BLANK","FILL_MISSING_WORDS_IN_GRID","LABEL_THE_PICTURE","LOOK_PICTURE_CHOOSE_CORRECT_ANSWER","LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER","LOOK_PICTURE_FILL_WORD_HINT","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING","READ_PASSAGE_AND_ANSWER_QUESTIONS"],[E.WRITING]:["WRITE_A_SHORT_LETTER","WRITE_CORRECT_VERB_FORM","WRITE_SENTENCES"]};export function isMarketingQuestionType(E){return Object.values(MARKETING_QUESTION_TYPES_BY_SKILL).flat().includes(E)}export const QUESTION_TYPE_LABELS={LISTEN_AND_FILL_IN_THE_BLANK_WITH_IMAGE:"Nghe - Điền từ có hình",LISTEN_AND_TICK_ANSWER:"Nghe - Đánh dấu",LISTEN_AND_FILL_NAME_NUMBER:"Nghe - Điền tên/số",LISTENING_FILL_BLANK:"Nghe - Điền chỗ trống",LISTENING_COLOR:"Nghe - Tô màu",LISTENING:"Nghe",CHOOSE_THE_CORRECT_ANSWER:"Chọn đáp án đúng",CHOOSE_THE_CORRECT_ANSWER_GROUP:"Chọn đáp án đúng (nhóm)",CHOOSE_CORRECT_ADJECTIVE:"Chọn tính từ",FILL_IN_BLANK:"Điền vào chỗ trống",FILL_MISSING_WORDS_IN_GRID:"Điền từ vào lưới",READ_PASSAGE_AND_ANSWER_QUESTIONS:"Đọc hiểu - Trả lời",LABEL_THE_PICTURE:"Gắn nhãn hình ảnh",LOOK_PICTURE_CHOOSE_CORRECT_ANSWER:"Nhìn ảnh - Chọn đáp án",LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER:"Nhìn ảnh - Điền và chọn",LOOK_PICTURE_FILL_WORD_HINT:"Nhìn ảnh - Điền từ gợi ý",READ_AND_COLOR_OBJECTS:"Đọc - Tô màu",IMAGE_OBJECT_MATCHING:"Ghép hình ảnh - Đối tượng",TRUE_FALSE:"Đúng/Sai",TRUE_FALSE_GROUP:"Đúng/Sai (nhóm)",CROSS_OUT_WORD_GROUP:"Gạch từ / sửa từ (nhóm)",MATCHING:"Ghép nối",ORDERING:"Sắp xếp",TICK_TRUE_OR_FALSE:"Đánh dấu Đúng/Sai",TICK_YES_OR_NO:"Đánh dấu Có/Không",READING_TICK_CROSS:"Đọc - Đánh dấu",ARRANGE_LETTERS_INTO_WORDS:"Sắp xếp chữ cái thành từ",READ_PASSAGE_AND_COMPLETE_STORY:"Đọc - Hoàn thành câu chuyện",CLOZE_TEST_WITH_TICK_BOX:"Điền từ - Đánh dấu",READ_AND_CHOOSE_APPROPRIATE_WORD:"Đọc - Chọn từ phù hợp",READING_LETTER_ARRANGE:"Đọc - Sắp xếp chữ cái",READING_PASSAGE_FILL:"Đọc - Điền đoạn văn",FILL_BLANK:"Điền chỗ trống",ANSWER_THE_QUESTION:"Nghe - Đọc câu hỏi và viết đáp án",WORD_ORDERING:"Sắp xếp từ",WORD_FILL_PARAGRAPH:"Điền từ vào đoạn văn",MATCH_BY_WRITING_ANSWER:"Ghép đáp án bằng cách viết",WORD_FILL_STRUCTURED_FORM:"Điền từ vào biểu mẫu có cấu trúc",WRITE_A_SHORT_LETTER:"Viết thư",WRITE_CORRECT_VERB_FORM:"Chia động từ",WRITE_SHORT_PARAGRAPH:"Viết đoạn văn ngắn",WRITE_SENTENCES:"Viết câu",ESSAY:"Viết luận",COLORING:"Tô màu",LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP:"Nghe và chọn trong nhóm đáp án",LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE:"Nghe và chọn đối tượng trong cảnh",LISTEN_AND_DRAG_OBJECTS_INTO_SCENE:"Nghe và kéo thả đối tượng vào cảnh",LISTEN_AND_SPEAK_ANSWER:"Nghe và trả lời (Speaking)",LISTEN_AND_SPEAK_IMAGE_GROUP:"Nghe, nhìn nhóm ảnh và trả lời (Speaking)",LISTEN_AND_SPEAK_QUESTION_LIST:"Nghe, chọn câu hỏi và trả lời (Speaking)",LISTEN_AND_SPEAK_COMPARE_IMAGES:"Nghe và so sánh ảnh (Speaking)",LISTEN_AND_SPEAK_WITH_STORY_IMAGES:"Nghe, nhìn ảnh truyện và kể lại (Speaking)",LISTEN_AND_SPEAK_ODD_ONE_OUT:"Nghe, chọn hình khác loại và giải thích (Speaking)",LISTEN_AND_SPEAK_INFO_EXCHANGE:"Trao đổi thông tin (Speaking)",READ_DISPLAYED_CONTENT:"Đọc nội dung hiển thị (Speaking)",SPEAKING_DESCRIBE_IMAGE:"Nhìn tranh và mô tả (Speaking Part 2)",SPONTANEOUS_QA:"Hỏi đáp tự phát (Speaking Part 3)",SPEAKING_CONVERSATION:"Hội thoại Speaking (KFS Speaking)",GN_SPEAKING_INTERVIEW:"GN Speaking - Hỏi đáp (Virtual + Real)"};export function getQuestionTypeLabel(E){return QUESTION_TYPE_LABELS[E]||E}export const SKILL_METADATA={[E.LISTENING]:{name:"Nghe",emoji:"🎧",color:"text-blue-600",bgColor:"bg-blue-50",borderColor:"border-blue-200",description:"Kỹ năng nghe hiểu"},[E.SPEAKING]:{name:"Nói",emoji:"🗣️",color:"text-green-600",bgColor:"bg-green-50",borderColor:"border-green-200",description:"Kỹ năng giao tiếp"},[E.READING]:{name:"Đọc",emoji:"📖",color:"text-purple-600",bgColor:"bg-purple-50",borderColor:"border-purple-200",description:"Kỹ năng đọc hiểu"},[E.WRITING]:{name:"Viết",emoji:"✏️",color:"text-orange-600",bgColor:"bg-orange-50",borderColor:"border-orange-200",description:"Kỹ năng viết"}};
@@ -118,12 +118,6 @@ declare const admin: {
118
118
  readonly 'admin.questionBank.dialog.edit.save': "Save changes";
119
119
  readonly 'admin.questionBank.dialog.edit.codeError': "Please enter question code";
120
120
  readonly 'admin.questionBank.dialog.edit.titleError': "Please enter title";
121
- readonly 'admin.questionBank.dialog.edit.loading': "Loading...";
122
- readonly 'admin.questionBank.dialog.edit.unsupportedNote': "Note:";
123
- readonly 'admin.questionBank.dialog.edit.unsupportedType': "Question type \"{type}\" is not editable in this UI. Please use the exam creator to edit this question.";
124
- readonly 'admin.questionBank.dialog.edit.contentLabel': "Question content";
125
- readonly 'admin.questionBank.dialog.edit.answerLabel': "Correct answer";
126
- readonly 'admin.questionBank.dialog.edit.explanationLabel': "Explanation";
127
121
  readonly 'admin.questionBank.dialog.delete.title': "Confirm Delete Question";
128
122
  readonly 'admin.questionBank.dialog.delete.message': "Are you sure you want to delete question";
129
123
  readonly 'admin.questionBank.dialog.delete.warning': "This action cannot be undone.";
@@ -1393,6 +1387,9 @@ declare const admin: {
1393
1387
  readonly 'admin.exams.shuffle.info3': "Questions within the same Part are randomly shuffled";
1394
1388
  readonly 'admin.exams.shuffle.info4': "Variants are linked to the parent exam for management";
1395
1389
  readonly 'admin.exams.shuffle.countLabel': "Number of variants to create";
1390
+ readonly 'admin.exams.shuffle.strategyLabel': "Existing exam handling option";
1391
+ readonly 'admin.exams.shuffle.keepOld': "Keep existing exams and add new ones";
1392
+ readonly 'admin.exams.shuffle.replaceAll': "Create a completely new set";
1396
1393
  readonly 'admin.exams.shuffle.existingVariants': "Existing exams ({count})";
1397
1394
  readonly 'admin.exams.shuffle.deleteAll': "Delete all ({count})";
1398
1395
  readonly 'admin.exams.shuffle.loading': "Loading...";
@@ -1483,25 +1480,21 @@ declare const admin: {
1483
1480
  readonly 'admin.exams.preview.totalPoints': "Total Points:";
1484
1481
  readonly 'admin.exams.preview.progress': "Progress";
1485
1482
  readonly 'admin.exams.preview.loading': "Loading...";
1486
- readonly 'admin.exams.preview.questionNavigation': "Part Navigation";
1483
+ readonly 'admin.exams.preview.questionNavigation': "Question Navigation";
1487
1484
  readonly 'admin.exams.preview.all': "All";
1488
1485
  readonly 'admin.exams.preview.allQuestions': "All {count} questions";
1489
1486
  readonly 'admin.exams.preview.partQuestions': "Part {part}: {count} questions";
1490
1487
  readonly 'admin.exams.preview.collapse': "Collapse";
1491
1488
  readonly 'admin.exams.preview.detail': "Details";
1492
1489
  readonly 'admin.exams.preview.questionIndex': "Question {index} / {total}";
1493
- readonly 'admin.exams.preview.partIndex': "Part {index} / {total}";
1494
1490
  readonly 'admin.exams.preview.noQuestions': "No questions yet";
1495
1491
  readonly 'admin.exams.preview.loadingQuestions': "Loading questions...";
1496
1492
  readonly 'admin.exams.preview.retry': "Retry";
1497
1493
  readonly 'admin.exams.preview.examNoQuestions': "This exam has no questions yet.";
1498
1494
  readonly 'admin.exams.preview.prevQuestion': "Previous Question";
1499
- readonly 'admin.exams.preview.prevPart': "Previous Part";
1500
1495
  readonly 'admin.exams.preview.prev': "Prev";
1501
1496
  readonly 'admin.exams.preview.nextQuestion': "Next Question";
1502
- readonly 'admin.exams.preview.nextPart': "Next Part";
1503
1497
  readonly 'admin.exams.preview.next': "Next";
1504
- readonly 'admin.exams.preview.questionLabel': "Question {number}";
1505
1498
  readonly 'admin.exams.preview.footerNote': "This is a preview mode to check the layout and content of the exam.";
1506
1499
  readonly 'admin.exams.preview.close': "Close";
1507
1500
  readonly 'admin.exams.preview.loadError': "Unable to load questions. Please try again.";