diff --git a/package-lock.json b/package-lock.json
index fe49c0ba..8f03d5b7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@angular/animations": "^16.2.12",
+ "@angular/cdk": "^16.2.14",
"@angular/common": "^16.2.12",
"@angular/compiler": "^16.2.12",
"@angular/core": "^16.2.12",
@@ -543,6 +544,34 @@
"@angular/core": "16.2.12"
}
},
+ "node_modules/@angular/cdk": {
+ "version": "16.2.14",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.2.14.tgz",
+ "integrity": "sha512-n6PrGdiVeSTEmM/HEiwIyg6YQUUymZrb5afaNLGFRM5YL0Y8OBqd+XhCjb0OfD/AfgCUtedVEPwNqrfW8KzgGw==",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "optionalDependencies": {
+ "parse5": "^7.1.2"
+ },
+ "peerDependencies": {
+ "@angular/common": "^16.0.0 || ^17.0.0",
+ "@angular/core": "^16.0.0 || ^17.0.0",
+ "rxjs": "^6.5.3 || ^7.4.0"
+ }
+ },
+ "node_modules/@angular/cdk/node_modules/parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "optional": true,
+ "dependencies": {
+ "entities": "^4.4.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
"node_modules/@angular/cli": {
"version": "16.2.12",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.2.12.tgz",
@@ -7855,7 +7884,7 @@
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "dev": true,
+ "devOptional": true,
"engines": {
"node": ">=0.12"
},
@@ -19570,4 +19599,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index 51323777..b04989de 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"private": true,
"dependencies": {
"@angular/animations": "^16.2.12",
+ "@angular/cdk": "^16.2.14",
"@angular/common": "^16.2.12",
"@angular/compiler": "^16.2.12",
"@angular/core": "^16.2.12",
@@ -30,8 +31,8 @@
"@angular/router": "^16.2.12",
"@project-sunbird/client-services": "5.1.2",
"@project-sunbird/sb-styles": "0.0.16",
- "@project-sunbird/telemetry-sdk": "1.3.0",
"@project-sunbird/sunbird-player-sdk-v9": "6.0.5",
+ "@project-sunbird/telemetry-sdk": "1.3.0",
"bootstrap": "^5.3.3",
"core-js": "^2.5.4",
"document-register-element": "^1.7.2",
@@ -45,14 +46,15 @@
"zone.js": "~0.13.3"
},
"devDependencies": {
- "@angular-devkit/core": "^16.2.12",
"@angular-devkit/build-angular": "^16.2.12",
+ "@angular-devkit/core": "^16.2.12",
"@angular/cli": "^16.2.12",
"@angular/compiler-cli": "^16.2.12",
"@angular/language-service": "^16.2.12",
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
+ "ajv": "^8.12.0",
"codelyzer": "^6.0.0",
"concat": "^1.0.3",
"copyfiles": "^2.4.1",
@@ -68,7 +70,6 @@
"protractor": "~7.0.0",
"ts-node": "~7.0.0",
"tslint": "~6.1.3",
- "typescript": "~4.9.5",
- "ajv": "^8.12.0"
+ "typescript": "~4.9.5"
}
-}
+}
\ No newline at end of file
diff --git a/projects/quml-library/package.json b/projects/quml-library/package.json
index 6611fcdf..a857a02b 100644
--- a/projects/quml-library/package.json
+++ b/projects/quml-library/package.json
@@ -1,6 +1,6 @@
{
"name": "@tekdi/sunbird-quml-player",
- "version": "8.0.0",
+ "version": "9.0.0-beta.8",
"schematics": "./schematics/collection.json",
"ng-add": {
"save": "dependencies"
diff --git a/projects/quml-library/src/lib/interfaces/mtf-interface.ts b/projects/quml-library/src/lib/interfaces/mtf-interface.ts
new file mode 100644
index 00000000..4257a551
--- /dev/null
+++ b/projects/quml-library/src/lib/interfaces/mtf-interface.ts
@@ -0,0 +1,23 @@
+export interface MtfOption {
+ label: string;
+ value: number;
+}
+
+export interface MtfOptions {
+ left: MtfOption[];
+ right: MtfOption[];
+}
+
+export interface MtfValidation {
+ required: string;
+}
+
+export interface MtfResponse {
+ type: string;
+ options: MtfOptions;
+ validation: MtfValidation;
+}
+
+export interface MtfInteractions {
+ response1: MtfResponse;
+}
diff --git a/projects/quml-library/src/lib/mtf/check-figure.directive.ts b/projects/quml-library/src/lib/mtf/check-figure.directive.ts
new file mode 100644
index 00000000..7ac46a04
--- /dev/null
+++ b/projects/quml-library/src/lib/mtf/check-figure.directive.ts
@@ -0,0 +1,24 @@
+import { Directive, ElementRef, Renderer2, AfterViewInit } from '@angular/core';
+
+@Directive({
+ selector: '[appCheckFigure]'
+})
+export class CheckFigureDirective implements AfterViewInit {
+
+ constructor(private el: ElementRef, private renderer: Renderer2) {}
+
+ ngAfterViewInit(): void {
+ this.checkForFigureTag();
+ }
+
+ checkForFigureTag(): void {
+ const figureTag = this.el.nativeElement.querySelector('figure');
+ const magnifyIcon = this.el.nativeElement.parentElement.querySelector('.zoom-icon');
+
+ if (figureTag) {
+ this.renderer.setStyle(magnifyIcon, 'display', 'block');
+ } else {
+ this.renderer.setStyle(magnifyIcon, 'display', 'none');
+ }
+ }
+}
diff --git a/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.html b/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.html
new file mode 100644
index 00000000..c42e439f
--- /dev/null
+++ b/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.html
@@ -0,0 +1,49 @@
+
Angular
", + "value": 0 + }, + { + "label": "Node
", + "value": 1 + }, + { + "label": "React
", + "value": 2 + }, + { + "label": "Nest
", + "value": 3 + } + ], + "right": [ + { + "label": "Angular JS
", + "value": 0 + }, + { + "label": "Node JS
", + "value": 1 + }, + { + "label": "React Js
", + "value": 2 + }, + { + "label": "Nest Js
", + "value": 3 + } + ] +}; + +export const shuffledOptions = { + "left": [ + { + "label": "Angular
", + "value": 0 + }, + { + "label": "Node
", + "value": 1 + }, + { + "label": "React
", + "value": 2 + }, + { + "label": "Nest
", + "value": 3 + } + ], + "right": [ + { + "label": "Node JS
", + "value": 1 + }, + { + "label": "Nest Js
", + "value": 3 + }, + { + "label": "Angular JS
", + "value": 0 + }, + { + "label": "React Js
", + "value": 2 + } + ] +} \ No newline at end of file diff --git a/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.spec.ts b/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.spec.ts new file mode 100644 index 00000000..faa2e2f1 --- /dev/null +++ b/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.spec.ts @@ -0,0 +1,80 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MtfOptionsComponent } from './mtf-options.component'; +import { mockedOptions, shuffledOptions } from './mtf-options.component.spec.data'; + +describe('MtfOptionsComponent', () => { + let component: MtfOptionsComponent; + let fixture: ComponentFixtureReact Js
", + "value": 2 + } + }, + currentIndex: 2 + }; + component.shuffledOptions = shuffledOptions; + spyOn(component, 'swapRightOptions').and.callThrough(); + spyOn(component.reorderedOptions, 'emit').and.callFake(() => {}); + component.onDrop(event); + expect(component.reorderedOptions.emit).toHaveBeenCalled(); + }); + + it('#closeModal should close modal', () => { + component.isModalVisible = true; + spyOn(component, 'closeModal').and.callThrough(); + component.closeModal(); + expect(component.isModalVisible).toBeFalsy(); + }) +}); diff --git a/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.ts b/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.ts new file mode 100644 index 00000000..4f511465 --- /dev/null +++ b/projects/quml-library/src/lib/mtf/mtf-options/mtf-options.component.ts @@ -0,0 +1,105 @@ +import { Component, EventEmitter, Input, OnChanges,OnInit, Output } from '@angular/core'; +import { MtfOptions } from '../../interfaces/mtf-interface'; +import * as _ from 'lodash-es'; + +@Component({ + selector: 'quml-mtf-options', + templateUrl: './mtf-options.component.html', + styleUrls: ['./mtf-options.component.scss'], +}) +export class MtfOptionsComponent implements OnInit, OnChanges { + @Input() options: { left: any[], right: any[] }; + @Input() layout: string; + @Input() shuffleOptions: boolean; + @Input() replayed: boolean; + @Input() tryAgain?: boolean; + @Output() reorderedOptions = new EventEmitterRed
", + "value": 0 + } + }, + { + "value": { + "body": "Green
", + "value": 1 + } + }, + { + "value": { + "body": "Yellow
", + "value": 2 + } + }, + { + "value": { + "body": "Orange
", + "value": 3 + } + } + ], + "right": [ + { + "value": { + "body": "Apple
", + "value": 0 + } + }, + { + "value": { + "body": "Grapes
", + "value": 1 + } + }, + { + "value": { + "body": "Banana
", + "value": 2 + } + }, + { + "value": { + "body": "Orange
", + "value": 3 + } + } + ] + }, + "question": "Match the following colour with the fruits
" + }, + "templateId": "mtf-horizontal", + "complexityLevel": [], + "maxScore": 1, + "name": "MTF Colour", + "responseDeclaration": { + "response1": { + "cardinality": "multiple", + "type": "map", + "correctResponse": { + "value": [ + { + "left": 0, + "right": [0] + }, + { + "left": 1, + "right": [1] + }, + { + "left": 2, + "right": [2] + }, + { + "left": 3, + "right": [3] + } + ] + }, + "mapping": [ + { + "value": { + "left": 0, + "right": 0 + }, + "score": 0.25 + }, + { + "value": { + "left": 1, + "right": 1 + }, + "score": 0.25 + }, + { + "value": { + "left": 2, + "right": 2 + }, + "score": 0.25 + }, + { + "value": { + "left": 3, + "right": 3 + }, + "score": 0.25 + } + ] + } + }, + "outcomeDeclaration": { + "maxScore": { + "cardinality": "multiple", + "type": "integer", + "defaultValue": 1 + }, + "hint": { + "cardinality": "single", + "type": "string", + "defaultValue": "ab02bf0b-e47d-49b4-aedd-d299a28e89e2" + } + }, + "interactionTypes": [ + "match" + ], + "interactions": { + "response1": { + "type": "match", + "options": { + "left": [ + { + "label": "Red
", + "value": 0 + }, + { + "label": "Green
", + "value": 1 + }, + { + "label": "Yellow
", + "value": 2 + }, + { + "label": "Orange
", + "value": 3 + } + ], + "right": [ + { + "label": "Apple
", + "value": 0 + }, + { + "label": "Grapes
", + "value": 1 + }, + { + "label": "Banana
", + "value": 2 + }, + { + "label": "Orange
", + "value": 3 + } + ] + }, + "validation": { + "required": "Yes" + } + } + }, + "qType": "MTF", + "primaryCategory": "Match The Following Question", + "body": "Match the following colour with the fruits
Red
", + "value": 0 + }, + { + "label": "Green
", + "value": 1 + }, + { + "label": "Yellow
", + "value": 2 + }, + { + "label": "Orange
", + "value": 3 + } + ], + "right": [ + { + "label": "Apple
", + "value": 0 + }, + { + "label": "Grapes
", + "value": 1 + }, + { + "label": "Banana
", + "value": 2 + }, + { + "label": "Orange
", + "value": 3 + } + ] +} + +export const mockSectionMTFQuestions = [{ + "mimeType": "application/vnd.sunbird.question", + "parent": "do_11395276534294118411", + "media": [ + { + "id": "do_113952273632460800126", + "type": "image", + "src": "/assets/public/content/assets/do_113952273632460800126/test.png", + "baseUrl": "https://dev.sunbirded.org" + }, + { + "id": "do_113952273902215168128", + "src": "/assets/public/content/assets/do_113952273902215168128/earth.mp4", + "type": "video", + "assetId": "do_113952273902215168128", + "name": "earth", + "baseUrl": "https://dev.sunbirded.org" + } + ], + "editorState": { + "options": { + "left": [ + { + "value": { + "body": "Red
", + "value": 0 + } + }, + { + "value": { + "body": "Green
", + "value": 1 + } + }, + { + "value": { + "body": "Yellow
", + "value": 2 + } + }, + { + "value": { + "body": "Orange
", + "value": 3 + } + } + ], + "right": [ + { + "value": { + "body": "Apple
", + "value": 0 + } + }, + { + "value": { + "body": "Grapes
", + "value": 1 + } + }, + { + "value": { + "body": "Banana
", + "value": 2 + } + }, + { + "value": { + "body": "Orange
", + "value": 3 + } + } + ] + }, + "question": "Match the following colour with the fruits
" + }, + "templateId": "mtf-vertical", // mtf-vertical // mtf-horizontal + "complexityLevel": [], + "maxScore": 1, + "name": "MTF Colour", + "qumlVersion": 1.1, + "responseDeclaration": { + "response1": { + "cardinality": "multiple", + "type": "map", + "correctResponse": { + "value": [ + { + "left": 0, + "right": [0] + }, + { + "left": 1, + "right": [1] + }, + { + "left": 2, + "right": [2] + }, + { + "left": 3, + "right": [3] + } + ] + }, + "mapping": [ + { + "value": { + "left": 0, + "right": 0 + }, + "score": 0.50 + }, + { + "value": { + "left": 1, + "right": 1 + }, + "score": 0.50 + }, + { + "value": { + "left": 2, + "right": 2 + }, + "score": 0.50 + }, + { + "value": { + "left": 3, + "right": 3 + }, + "score": 0.50 + } + ] + } + }, + "outcomeDeclaration": { + "maxScore": { + "cardinality": "multiple", + "type": "integer", + "defaultValue": 2 + } + }, + "identifier": "do_11395276677466543210", + "interactionTypes": [ + "match" + ], + "interactions": { + "response1": { + "type": "match", + "options": { + "left": [ + { + "label": "Red
", + "value": 0 + }, + { + "label": "Green
", + "value": 1 + }, + { + "label": "Yellow
", + "value": 2 + }, + { + "label": "Orange
", + "value": 3 + } + ], + "right": [ + { + "label": "Apple
", + "value": 0 + }, + { + "label": "Grapes
", + "value": 1 + }, + { + "label": "Banana
", + "value": 2 + }, + { + "label": "Orange
", + "value": 3 + } + ] + }, + "validation": { + "required": "Yes" + } + } + }, + "qType": "MTF", + "primaryCategory": "Match The Following Question", + "body": "Match the following colour with the fruits
Apple-Red
Yellow-Banana
Green-Grapes
Orange-Orange
" + }, + "createdBy": "5a587cc1-e018-4859-a0a8-e842650b9d64", + "board": "State(Tamil Nadu)", + "medium": [ + "English" + ], + "gradeLevel": [ + "Class 1" + ], + "subject": [ + "Accountancy" + ], + "author": "contentCreator", + "channel": "0137541424673095687", + "framework": "tn_k-12", + "copyright": "sunbird", + "audience": [ + "Student" + ], + "license": "CC BY 4.0" + } +] \ No newline at end of file diff --git a/projects/quml-library/src/lib/section-player/section-player.component.spec.ts b/projects/quml-library/src/lib/section-player/section-player.component.spec.ts index 5ba8279d..27d84677 100644 --- a/projects/quml-library/src/lib/section-player/section-player.component.spec.ts +++ b/projects/quml-library/src/lib/section-player/section-player.component.spec.ts @@ -10,7 +10,7 @@ import { ViewerService } from '../services/viewer-service/viewer-service'; import { UtilService } from '../util-service'; import { QuestionCursor } from './../quml-question-cursor.service'; import { SectionPlayerComponent } from './section-player.component'; -import { mockSectionPlayerConfig } from './section-player.component.spec.data'; +import { mockSectionMTFQuestions, mockSectionPlayerConfig, rearrangedOptions } from './section-player.component.spec.data'; describe('SectionPlayerComponent', () => { @@ -269,23 +269,23 @@ describe('SectionPlayerComponent', () => { }); it('should validate the option before moving to the next question', () => { - spyOn(component, 'validateSelectedOption'); + spyOn(component, 'validateQuestionInteraction'); component.parentConfig = mockParentConfig; component.parentConfig.isSectionsAvailable = true; component.showRootInstruction = false; component.myCarousel = myCarousel; component.nextSlideClicked({ type: 'next' }); - expect(component.validateSelectedOption).toHaveBeenCalled(); + expect(component.validateQuestionInteraction).toHaveBeenCalled(); }) it('should navigate to previous question', () => { component.optionSelectedObj = { value: 1 }; component.showFeedBack = true; component.myCarousel = myCarousel; - spyOn(component, 'validateSelectedOption'); + spyOn(component, 'validateQuestionInteraction'); component.previousSlideClicked({ event: 'previous clicked' }); expect(component.stopAutoNavigation).toBe(false); - expect(component.validateSelectedOption).toHaveBeenCalled(); + expect(component.validateQuestionInteraction).toHaveBeenCalled(); }); it('should navigate to previous section', () => { @@ -330,11 +330,11 @@ describe('SectionPlayerComponent', () => { component.progressBarClass = fakeMainProgressBar; component.optionSelectedObj = { value: 1 }; component.showFeedBack = true; - spyOn(component, 'validateSelectedOption'); + spyOn(component, 'validateQuestionInteraction'); component.goToSlideClicked(event, 2); expect(component.jumpSlideIndex).toBe(2); expect(component.stopAutoNavigation).toBe(false); - expect(component.validateSelectedOption).toHaveBeenCalled(); + expect(component.validateQuestionInteraction).toHaveBeenCalled(); }); it('should jump to slide clicked with feedback OFF', () => { @@ -371,13 +371,13 @@ describe('SectionPlayerComponent', () => { stopPropagation: () => { }, } spyOnNarendra Modi
", - "value": 0, - "selected": true + "value": 1, }, - "cardinality": "single", - "solutions": [] + "cardinality": "single" } + const selectedQuestion = mockSectionPlayerConfig.mockSectionQuestions[0]; + const responseKey = 'response1'; + const edataItem = {}; + const currentIndex = 0; + const type = 'next'; + spyOn(component, 'handleMCQInteraction').and.callFake(() => {}); + spyOn(component, 'handleInteraction').and.callThrough(); + component.handleInteraction(selectedQuestion, responseKey, edataItem, currentIndex, type); + expect(component.handleMCQInteraction).toHaveBeenCalled(); + }); + + it('handleInteraction() should call handleMCQInteraction for MMCQ', () => { component.optionSelectedObj = { "name": "optionSelect", "option": { - "label": "Narendra Modi
", - "value": 0, - "selected": true + "value": 1, }, - "cardinality": "single", - "solutions": [] + "cardinality": "multiple" } - component.questions = mockSectionQuestions; - component.parentConfig = mockParentConfig; - component.sectionConfig = mockSectionConfig; - component.progressBarClass = mockSectionProgressBar.children; - component.validateSelectedOption(option, "next"); + const selectedQuestion = mockSectionPlayerConfig.mockSectionMultiSelectQuestions[0]; + const responseKey = 'response1'; + const edataItem = {}; + const currentIndex = 0; + const type = 'next'; + spyOn(component, 'handleMCQInteraction').and.callFake(() => {}); + spyOn(component, 'handleInteraction').and.callThrough(); + component.handleInteraction(selectedQuestion, responseKey, edataItem, currentIndex, type); + expect(component.handleMCQInteraction).toHaveBeenCalled(); + }); + + it('handleInteraction() should call handleMTFInteraction for MTF', () => { + component.mtfReorderedOptionsMap = rearrangedOptions; + const selectedQuestion = mockSectionMTFQuestions[0]; + const responseKey = 'response1'; + const edataItem = {}; + const currentIndex = 0; + const type = 'next'; + spyOn(component, 'handleMTFInteraction').and.callFake(() => {}); + spyOn(component, 'handleInteraction').and.callThrough(); + component.handleInteraction(selectedQuestion, responseKey, edataItem, currentIndex, type); + expect(component.handleMTFInteraction).toHaveBeenCalled(); + }); + + it('handleMCQInteraction() should call getMultiselectScore for MMCQ', () => { + component.optionSelectedObj = { + "name": "optionSelect", + "option": { + "value": 1, + }, + "cardinality": "multiple" + } + const selectedQuestion = mockSectionPlayerConfig.mockSectionMultiSelectQuestions[0]; + const edataItem = {}; + const currentIndex = 0; + const isMultipleChoice = true; + const type = 'next' + spyOn(utilService, 'getMultiselectScore').and.returnValue(1); + spyOn(component, 'handleCorrectAnswer').and.callFake(() => {}); + spyOn(component, 'handleMCQInteraction').and.callThrough(); + component.handleMCQInteraction(selectedQuestion, edataItem, currentIndex, isMultipleChoice, type); + expect(utilService.getMultiselectScore).toHaveBeenCalled(); }); - it('should validate the multiple selected option for score 0', () => { - component.isAssessEventRaised = false; - spyOn(viewerService, 'raiseAssesEvent').and.callFake(() => {}); - spyOn(component, 'updateScoreBoard').and.callFake(() => {}) - spyOn(utilService, 'getQuestionType').and.returnValue('MCQ'); - spyOn(utilService, 'getMultiselectScore').and.returnValue(0); - spyOn(component, 'validateSelectedOption').and.callThrough(); - component.myCarousel = myCarousel; - const option = { - "name": "optionSelect", - "option": [ - { - "label": "3
", - "value": 1, - "selected": true, - "isDisabled": false - } - ], - "cardinality": "multiple", - "solutions": [] - } + it('handleMCQInteraction() should call getSingleSelectScore for MCQ', () => { component.optionSelectedObj = { "name": "optionSelect", - "option": [ - { - "label": "3
", - "value": 1, - "selected": true, - "isDisabled": false - } - ], - "cardinality": "multiple", - "solutions": [] - } - component.questions = mockSectionMultiSelectQuestions; - component.parentConfig = mockParentConfig; - component.sectionConfig = mockSectionConfig; - component.progressBarClass = mockSectionProgressBar.children; - component.validateSelectedOption(option, "next"); - expect(component.isAssessEventRaised).toBeTruthy(); + "option": { + "value": 1, + }, + "cardinality": "single" + } + const selectedQuestion = mockSectionPlayerConfig.mockSectionQuestions[0]; + const edataItem = {}; + const currentIndex = 0; + const isMultipleChoice = false; + const type = 'next' + spyOn(utilService, 'getSingleSelectScore').and.returnValue(1); + spyOn(component, 'handleCorrectAnswer').and.callFake(() => {}); + spyOn(component, 'handleMCQInteraction').and.callThrough(); + component.handleMCQInteraction(selectedQuestion, edataItem, currentIndex, isMultipleChoice, type); + expect(utilService.getSingleSelectScore).toHaveBeenCalled(); + }); + + it('handleMTFInteraction() should call getMTFScore for MTF', () => { + component.isShuffleQuestions = false; + component.mtfReorderedOptionsMap = rearrangedOptions; + const selectedQuestion = mockSectionMTFQuestions[0]; + const edataItem = {}; + const currentIndex = 0; + const isMultipleChoice = false; + const type = 'next' + spyOn(utilService, 'getMTFScore').and.returnValue(1); + spyOn(component, 'handleCorrectAnswer').and.callFake(() => {}); + spyOn(component, 'handleMTFInteraction').and.callThrough(); + component.handleMTFInteraction(selectedQuestion, edataItem, currentIndex, type); + expect(utilService.getMTFScore).toHaveBeenCalled(); + }); + + it('handleMTFInteraction() should call getMTFScore for MTF with score 0', () => { + component.isShuffleQuestions = false; + component.mtfReorderedOptionsMap = rearrangedOptions; + const selectedQuestion = mockSectionMTFQuestions[0]; + const edataItem = {}; + const currentIndex = 0; + const isMultipleChoice = false; + const type = 'next' + spyOn(component, 'handleWrongAnswer').and.callFake(() => {}); + spyOn(utilService, 'getMTFScore').and.returnValue(0); + spyOn(component, 'handleMTFInteraction').and.callThrough(); + component.handleMTFInteraction(selectedQuestion, edataItem, currentIndex, type); + expect(utilService.getMTFScore).toHaveBeenCalled(); + }); + + it('handleCorrectAnswer() should call correctFeedBackTimeOut', () => { + component.alertType = undefined; + component.showFeedBack = true; + component.isAssessEventRaised = false; + spyOn(component, 'updateScoreBoard').and.callFake(() => {}); + spyOn(component, 'correctFeedBackTimeOut').and.callFake(() => {}); + spyOn(viewerService, 'raiseAssesEvent').and.callFake(() => {}); + spyOn(component, 'handleCorrectAnswer').and.callThrough(); + component.handleCorrectAnswer(1, {}, 0, {}, 'next'); + expect(component.correctFeedBackTimeOut).toHaveBeenCalled(); + }); + it('handleWrongAnswer() should call updateScoreBoard', () => { + component.progressBarClass = mockSectionProgressBar.children; + component.alertType = undefined; + component.showFeedBack = true; + component.isAssessEventRaised = false; + spyOn(component, 'updateScoreBoard').and.callFake(() => {}); + spyOn(component, 'correctFeedBackTimeOut').and.callFake(() => {}); + spyOn(viewerService, 'raiseAssesEvent').and.callFake(() => {}); + spyOn(component, 'handleWrongAnswer').and.callThrough(); + component.handleWrongAnswer(0, {}, 0, {}, 'next'); + expect(component.updateScoreBoard).toHaveBeenCalled(); }); - it('should validate the multiple selected option for score not 0', () => { + it('handleNoInteraction() should call nextSlide()', () => { component.isAssessEventRaised = false; + component.myCarousel = jasmine.createSpyObj("CarouselComponent", { + "getCurrentSlideIndex": 0, "move": {}, isLast: false + }); + component.active = true; + component.startPageInstruction = 'test'; + spyOn(component, 'nextSlide').and.callFake(() => {}); spyOn(viewerService, 'raiseAssesEvent').and.callFake(() => {}); - spyOn(component, 'updateScoreBoard').and.callFake(() => {}) - spyOn(utilService, 'getQuestionType').and.returnValue('MCQ'); - spyOn(utilService, 'getMultiselectScore').and.returnValue(1); - spyOn(component, 'validateSelectedOption').and.callThrough(); - component.myCarousel = myCarousel; - const option = { - "name": "optionSelect", - "option": [ - { - "label": "2
", - "value": 0, - "selected": true, - "isDisabled": false - }, - { - "label": "4
", - "value": 2, - "selected": true, - "isDisabled": false - }, - { - "label": "6
", - "value": 3, - "selected": true, - "isDisabled": false - } - ], - "cardinality": "multiple", - "solutions": [] - } - component.optionSelectedObj = { - "name": "optionSelect", - "option": [ - { - "label": "2
", - "value": 0, - "selected": true, - "isDisabled": false - }, - { - "label": "4
", - "value": 2, - "selected": true, - "isDisabled": false - }, - { - "label": "6
", - "value": 3, - "selected": true, - "isDisabled": false - } - ], - "cardinality": "multiple", - "solutions": [] - } - component.questions = mockSectionMultiSelectQuestions; - component.parentConfig = mockParentConfig; - component.sectionConfig = mockSectionConfig; - component.progressBarClass = mockSectionProgressBar.children; - component.validateSelectedOption(option, "next"); - expect(component.isAssessEventRaised).toBeTruthy(); + spyOn(component, 'handleNoInteraction').and.callThrough(); + component.handleNoInteraction(true, {}, 0 , 'next'); + }); + + it('handleNoInteraction() should call infoPopupTimeOut()', () => { + // component.progressBarClass = mockSectionProgressBar.children; + component.isAssessEventRaised = true; + component.myCarousel = jasmine.createSpyObj("CarouselComponent", { + "getCurrentSlideIndex": 1, "move": {}, isLast: false + }); + component.active = false; + component.startPageInstruction = ''; + component.optionSelectedObj = undefined; + component.active = false; + component.allowSkip = false; + component.startPageInstruction = 'test'; + spyOn(utilService, 'canGo').and.returnValue(true); + spyOn(component, 'infoPopupTimeOut').and.callFake(() => {}); + spyOn(component, 'shouldShowInfoPopup').and.returnValue(true); + spyOn(viewerService, 'raiseAssesEvent').and.callFake(() => {}); + spyOn(component, 'handleNoInteraction').and.callThrough(); + component.handleNoInteraction(false, {}, 0 , 'next'); }); + it('#shouldShowInfoPopup() should return true', () => { + component.progressBarClass = mockSectionProgressBar.children; + spyOn(utilService, 'getQuestionType').and.returnValue('MCQ'); + component.myCarousel = jasmine.createSpyObj("CarouselComponent", { + "getCurrentSlideIndex": 1, "move": {}, isLast: false + }); + component.active = false; + component.allowSkip = false; + spyOn(utilService, 'canGo').and.returnValue(true); + component.startPageInstruction = undefined; + spyOn(component, 'shouldShowInfoPopup').and.callThrough(); + const result = component.shouldShowInfoPopup(0); + expect(result).toBeTruthy(); + }); it('should hide the popup once the time is over', fakeAsync(() => { component.infoPopupTimeOut(); @@ -848,26 +980,17 @@ describe('SectionPlayerComponent', () => { it('should return a score for a question', () => { component.questions = mockSectionQuestions; - const response = component.getScore(0, 'response1', true, { - "answer": true, - "value": { - "body": "Jeff Bezos
", - "value": 0 - } - }); + const questionData = mockSectionQuestions[0]; + const response = utilService.getSingleSelectScore({value: 0}, questionData.responseDeclaration , true, questionData.outcomeDeclaration); expect(response).toEqual(1); }); it('should return a score for a question - wrong answer', () => { component.questions = mockSectionQuestions; + const questionData = mockSectionQuestions[0]; component.progressBarClass = mockSectionProgressBar.children; - const response = component.getScore(0, 'response1', false, { - option: { - "answer": false, - "value": 0 - } - }); - expect(response).toEqual(1); + const response = utilService.getSingleSelectScore(1, questionData.responseDeclaration , true, questionData.outcomeDeclaration); + expect(response).toEqual(0); }); it('should calculate the score', () => { diff --git a/projects/quml-library/src/lib/section-player/section-player.component.ts b/projects/quml-library/src/lib/section-player/section-player.component.ts index a4130c58..a71109f4 100644 --- a/projects/quml-library/src/lib/section-player/section-player.component.ts +++ b/projects/quml-library/src/lib/section-player/section-player.component.ts @@ -5,6 +5,7 @@ import { CarouselComponent } from 'ngx-bootstrap/carousel'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { QumlPlayerConfig, IParentConfig, IAttempts } from '../quml-library-interface'; +import { MtfOptions } from '../interfaces/mtf-interface'; import { ViewerService } from '../services/viewer-service/viewer-service'; import { eventName, pageId, TelemetryType, Cardinality, QuestionType } from '../telemetry-constants'; import { DEFAULT_SCORE, COMPATABILITY_LEVEL } from '../player-constants'; @@ -75,6 +76,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { currentSolutions: any; showSolution: any; optionSelectedObj: any; + mtfReorderedOptionsMap: any; intervalRef: any; alertType: string; infoPopup: boolean; @@ -381,6 +383,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { this.active = false; this.showAlert = false; this.optionSelectedObj = undefined; + this.mtfReorderedOptionsMap = undefined; this.currentOptionSelected = undefined; this.currentQuestion = undefined; this.currentOptions = undefined; @@ -416,16 +419,16 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { } /* istanbul ignore else */ if (event?.type === 'next') { - this.validateSelectedOption(this.optionSelectedObj, 'next'); + this.validateQuestionInteraction('next'); } } previousSlideClicked(event) { /* istanbul ignore else */ if (event.event === 'previous clicked') { - if (this.optionSelectedObj && this.showFeedBack) { + if ((this.optionSelectedObj || this.mtfReorderedOptionsMap) && this.showFeedBack) { this.stopAutoNavigation = false; - this.validateSelectedOption(this.optionSelectedObj, 'previous'); + this.validateQuestionInteraction('previous'); } else { this.stopAutoNavigation = true; if (this.currentSlideIndex === 0 && this.parentConfig.isSectionsAvailable && this.getCurrentSectionIndex() > 0) { @@ -464,9 +467,9 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { event.stopPropagation(); this.active = false; this.jumpSlideIndex = index; - if (this.optionSelectedObj && this.showFeedBack) { + if ((this.optionSelectedObj || this.mtfReorderedOptionsMap) && this.showFeedBack) { this.stopAutoNavigation = false; - this.validateSelectedOption(this.optionSelectedObj, 'jump'); + this.validateQuestionInteraction('jump'); } else { this.stopAutoNavigation = true; this.goToSlide(this.jumpSlideIndex); @@ -492,7 +495,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { event.stopPropagation(); /* istanbul ignore else */ if (this.optionSelectedObj) { - this.validateSelectedOption(this.optionSelectedObj, 'jump'); + this.validateQuestionInteraction('jump'); } this.jumpToSection(identifier); } @@ -547,7 +550,27 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { /* istanbul ignore else */ if (!this.showFeedBack) { - this.validateSelectedOption(this.optionSelectedObj); + this.validateQuestionInteraction(); + } + } + + handleMTFOptionsChange(rearrangedOptions: MtfOptions) { + this.focusOnNextButton(); + this.active = true; + const currentIndex = this.myCarousel.getCurrentSlideIndex() - 1; + this.viewerService.raiseHeartBeatEvent(eventName.optionsReordered, TelemetryType.interact, this.myCarousel.getCurrentSlideIndex()); + const currentQuestion = this.questions[currentIndex]; + if (_.isEmpty(rearrangedOptions)) { + this.updateScoreBoard(currentIndex, 'skipped'); + } else { + this.mtfReorderedOptionsMap = rearrangedOptions; + this.isAssessEventRaised = false; + this.currentSolutions = !_.isEmpty(currentQuestion.solutions) ? currentQuestion.solutions : undefined; + } + this.currentQuestionIndetifier = currentQuestion.identifier; + this.media = _.get(currentQuestion, 'media', []); + if (!this.showFeedBack) { + this.validateQuestionInteraction(); } } @@ -623,116 +646,146 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { this.viewerService.raiseHeartBeatEvent(eventName.deviceRotationClicked, TelemetryType.interact, this.myCarousel.getCurrentSlideIndex() + 1); } - validateSelectedOption(option, type?: string) { - const selectedOptionValue = option?.option?.value; + validateQuestionInteraction(eventType ?: string) { const currentIndex = this.myCarousel.getCurrentSlideIndex() - 1; - const isQuestionSkipAllowed = !this.optionSelectedObj && - this.allowSkip && this.utilService.getQuestionType(this.questions, currentIndex) === QuestionType.mcq; - const isSubjectiveQuestion = this.utilService.getQuestionType(this.questions, currentIndex) === QuestionType.sa; - const onStartPage = this.startPageInstruction && this.myCarousel.getCurrentSlideIndex() === 0; - const isActive = !this.optionSelectedObj && this.active; const selectedQuestion = this.questions[currentIndex]; - const key = selectedQuestion.responseDeclaration ? this.utilService.getKeyValue(Object.keys(selectedQuestion.responseDeclaration)) : ''; + const responseKey = selectedQuestion.responseDeclaration ? + this.utilService.getKeyValue(Object.keys(selectedQuestion.responseDeclaration)) : ''; this.slideDuration = Math.round((new Date().getTime() - this.initialSlideDuration) / 1000); - const getParams = () => { - if (selectedQuestion.qType.toUpperCase() === QuestionType.mcq && selectedQuestion?.editorState?.options) { - return selectedQuestion.editorState.options; - } else if (selectedQuestion.qType.toUpperCase() === QuestionType.mcq && !_.isEmpty(selectedQuestion?.editorState)) { - return [selectedQuestion?.editorState]; - } else { - return []; - } - }; - const edataItem: any = { - 'id': selectedQuestion.identifier, - 'title': selectedQuestion.name, - 'desc': selectedQuestion.description, - 'type': selectedQuestion.qType.toLowerCase(), - 'maxscore': key.length === 0 ? 0 : selectedQuestion.outcomeDeclaration.maxScore.defaultValue || 0, - 'params': getParams() - }; - /* istanbul ignore else */ - if (edataItem && this.parentConfig.isSectionsAvailable) { - edataItem.sectionId = this.sectionConfig.metadata.identifier; + const edataItem: any = this.utilService.getEDataItem(selectedQuestion, responseKey); + if (edataItem && this.parentConfig?.isSectionsAvailable) { + edataItem['sectionId'] = this.sectionConfig?.metadata?.identifier; } - /* istanbul ignore else */ - if (!this.optionSelectedObj && !this.isAssessEventRaised && selectedQuestion.qType.toUpperCase() !== QuestionType.sa) { - this.isAssessEventRaised = true; - this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'No', 0, [], this.slideDuration); + const questionType = this.questions[currentIndex]['qType']; + const isQuestionSkipAllowed = this.isSkipAllowed(questionType); + + if (!isQuestionSkipAllowed) { + this.handleInteraction(selectedQuestion, responseKey, edataItem, currentIndex, eventType); + } else { + this.handleNoInteraction(isQuestionSkipAllowed, edataItem, currentIndex, eventType); } + } - if (this.optionSelectedObj) { - this.currentQuestion = selectedQuestion.body; - this.currentOptions = selectedQuestion.interactions[key].options; + isSkipAllowed(questionType: string): boolean { + if (questionType === QuestionType.sa) { + return true; + } + if ( + (questionType === QuestionType.mtf && !this.mtfReorderedOptionsMap) || + ((questionType === QuestionType.mcq || questionType === QuestionType.mmcq) && !this.optionSelectedObj) && + this.allowSkip) { + return true; + } + return false; + } - if (option.cardinality === Cardinality.single) { - const correctOptionValue = Number(selectedQuestion.responseDeclaration[key].correctResponse.value); + handleInteraction(selectedQuestion: any, responseKey: string, edataItem: any, currentIndex: number, type ?: string) { + this.currentQuestion = selectedQuestion.body; + this.currentOptions = selectedQuestion.interactions[responseKey].options; + this.showAlert = true; - this.showAlert = true; - if (option.option?.value === correctOptionValue) { - const currentScore = this.getScore(currentIndex, key, true); - if (!this.isAssessEventRaised) { - this.isAssessEventRaised = true; - this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'Yes', currentScore, [option.option], this.slideDuration); - } - this.alertType = 'correct'; - if (this.showFeedBack) - this.correctFeedBackTimeOut(type); - this.updateScoreBoard(currentIndex, 'correct', undefined, currentScore); - } else { - const currentScore = this.getScore(currentIndex, key, false, option); - this.alertType = 'wrong'; - const classType = this.progressBarClass[currentIndex].class === 'partial' ? 'partial' : 'wrong'; - this.updateScoreBoard(currentIndex, classType, selectedOptionValue, currentScore); - - /* istanbul ignore else */ - if (!this.isAssessEventRaised) { - this.isAssessEventRaised = true; - this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'No', 0, [option.option], this.slideDuration); - } - } - } - if (option.cardinality === Cardinality.multiple) { - const responseDeclaration = this.questions[currentIndex].responseDeclaration; - const outcomeDeclaration = this.questions[currentIndex].outcomeDeclaration; - const currentScore = this.utilService.getMultiselectScore(option.option, responseDeclaration, this.isShuffleQuestions, outcomeDeclaration); - this.showAlert = true; - if (currentScore === 0) { - if (!this.isAssessEventRaised) { - this.isAssessEventRaised = true; - this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'No', 0, [option.option], this.slideDuration); - } - this.alertType = 'wrong'; - this.updateScoreBoard(currentIndex, 'wrong'); - } else { - this.updateScoreBoard(currentIndex, 'correct', undefined, currentScore); - if (!this.isAssessEventRaised) { - this.isAssessEventRaised = true; - this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'Yes', currentScore, [option.option], this.slideDuration); - } - if (this.showFeedBack) - this.correctFeedBackTimeOut(type); - this.alertType = 'correct'; - } + if (this.optionSelectedObj && (selectedQuestion.qType === QuestionType.mcq || selectedQuestion.qType === QuestionType.mmcq)) { + if (this.optionSelectedObj.cardinality === Cardinality.single) { + this.handleMCQInteraction(selectedQuestion, edataItem, currentIndex, false, type); + } else if (this.optionSelectedObj.cardinality === Cardinality.multiple) { + this.handleMCQInteraction(selectedQuestion, edataItem, currentIndex, true, type); } this.optionSelectedObj = undefined; - } else if ((isQuestionSkipAllowed) || isSubjectiveQuestion || onStartPage || isActive) { - if(!_.isUndefined(type)) { + } + + if (this.mtfReorderedOptionsMap && selectedQuestion.qType === QuestionType.mtf) { + this.handleMTFInteraction(selectedQuestion, edataItem, currentIndex, type); + this.mtfReorderedOptionsMap = undefined; + } + } + + handleMCQInteraction(selectedQuestion: any, edataItem: any, currentIndex: number, isMultipleChoice: boolean, type ?: string) { + const responseDeclaration = selectedQuestion.responseDeclaration; + const outcomeDeclaration = selectedQuestion.outcomeDeclaration; + const selectedOptions = this.optionSelectedObj.option; + + let currentScore: number; + let optionsToPass: any[]; + + if (isMultipleChoice) { + currentScore = this.utilService.getMultiselectScore(selectedOptions, responseDeclaration, this.isShuffleQuestions, outcomeDeclaration); + optionsToPass = selectedOptions; + } else { + currentScore = this.utilService.getSingleSelectScore(selectedOptions, responseDeclaration, this.isShuffleQuestions, outcomeDeclaration); + optionsToPass = [selectedOptions]; + } + + if (currentScore === 0) { + this.handleWrongAnswer(currentScore, edataItem, currentIndex, optionsToPass, type); + } else { + this.handleCorrectAnswer(currentScore, edataItem, currentIndex, optionsToPass, type); + } + } + + handleMTFInteraction(selectedQuestion, edataItem, currentIndex, type) { + const responseDeclaration = selectedQuestion.responseDeclaration; + const outcomeDeclaration = selectedQuestion.outcomeDeclaration; + const userResponse = this.mtfReorderedOptionsMap; + const currentScore = this.utilService.getMTFScore(userResponse, responseDeclaration, this.isShuffleQuestions, outcomeDeclaration); + if (currentScore === 0) { + this.handleWrongAnswer(currentScore, edataItem, currentIndex, userResponse, type); + } else { + this.handleCorrectAnswer(currentScore, edataItem, currentIndex, userResponse, type); + } + } + + handleCorrectAnswer(currentScore, edataItem: any, currentIndex: number, userResponse: any, type ?: string) { + if (!this.isAssessEventRaised) { + this.isAssessEventRaised = true; + this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'Yes', currentScore, userResponse, this.slideDuration); + } + this.alertType = 'correct'; + if (this.showFeedBack) { + this.correctFeedBackTimeOut(type); + } + this.updateScoreBoard(currentIndex, 'correct', userResponse, currentScore); + } + + handleWrongAnswer(currentScore,edataItem: any, currentIndex: number, userResponse: any, type ?: string) { + this.alertType = 'wrong'; + const classType = this.progressBarClass[currentIndex].class === 'partial' ? 'partial' : 'wrong'; + this.updateScoreBoard(currentIndex, classType, userResponse, currentScore); + + if (!this.isAssessEventRaised) { + this.isAssessEventRaised = true; + this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'No', 0, userResponse, this.slideDuration); + } + } + + handleNoInteraction(isQuestionSkipAllowed: boolean, edataItem: any, currentIndex: number, type ?: string) { + if (!this.isAssessEventRaised) { + this.isAssessEventRaised = true; + this.viewerService.raiseAssesEvent(edataItem, currentIndex + 1, 'No', 0, [], this.slideDuration); + } + const onStartPage = this.startPageInstruction && this.myCarousel.getCurrentSlideIndex() === 0; + + if (isQuestionSkipAllowed || onStartPage || this.active) { + if (!_.isUndefined(type)) { this.nextSlide(); } - } else if (this.startPageInstruction && !this.optionSelectedObj && !this.active && !this.allowSkip && - this.myCarousel.getCurrentSlideIndex() > 0 && this.utilService.getQuestionType(this.questions, currentIndex) === QuestionType.mcq - && this.utilService.canGo(this.progressBarClass[this.myCarousel.getCurrentSlideIndex()])) { - this.infoPopupTimeOut(); - } else if (!this.optionSelectedObj && !this.active && !this.allowSkip && this.myCarousel.getCurrentSlideIndex() >= 0 - && this.utilService.getQuestionType(this.questions, currentIndex) === QuestionType.mcq - && this.utilService.canGo(this.progressBarClass[this.myCarousel.getCurrentSlideIndex()])) { - this.infoPopupTimeOut(); + } else if (this.shouldShowInfoPopup(currentIndex)) { + this.infoPopupTimeOut(); } } + shouldShowInfoPopup(currentIndex: number): boolean { + const questionType = this.utilService.getQuestionType(this.questions, currentIndex); + const slideIndex = this.myCarousel.getCurrentSlideIndex(); + const canGo = this.utilService.canGo(this.progressBarClass[slideIndex]); + + const commonConditions = !this.optionSelectedObj && !this.active && !this.allowSkip && + (questionType === QuestionType.mcq || questionType === QuestionType.mtf) && canGo; + + return commonConditions && (this.startPageInstruction ? slideIndex > 0 : slideIndex >= 0); + } + infoPopupTimeOut() { this.infoPopup = true; setTimeout(() => { @@ -765,6 +818,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { this.showRootInstruction = false; if (index === 0) { this.optionSelectedObj = undefined; + this.mtfReorderedOptionsMap = undefined; this.myCarousel.selectSlide(0); this.active = this.currentSlideIndex === 0 && this.sectionIndex === 0 && this.showStartPage; this.showRootInstruction = true; @@ -902,34 +956,6 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { } } - getScore(currentIndex, key, isCorrectAnswer, selectedOption?) { - /* istanbul ignore else */ - if (isCorrectAnswer) { - if (this.isShuffleQuestions) { - return DEFAULT_SCORE; - } - return this.questions[currentIndex].outcomeDeclaration.maxScore.defaultValue ? - this.questions[currentIndex].outcomeDeclaration.maxScore.defaultValue : DEFAULT_SCORE; - } else { - const selectedOptionValue = selectedOption.option.value; - const mapping = this.questions[currentIndex].responseDeclaration.mapping; - let score = 0; - - /* istanbul ignore else */ - if (mapping) { - mapping.forEach((val) => { - if (selectedOptionValue === val.value) { - score = val.score || 0; - if (val.score) { - this.progressBarClass[currentIndex].class = 'partial'; - } - } - }); - } - return score; - } - } - calculateScore() { return this.progressBarClass.reduce((accumulator, element) => accumulator + element.score, 0); } diff --git a/projects/quml-library/src/lib/services/transformation-service/transformation.service.ts b/projects/quml-library/src/lib/services/transformation-service/transformation.service.ts index 4ad2a751..f01f49aa 100644 --- a/projects/quml-library/src/lib/services/transformation-service/transformation.service.ts +++ b/projects/quml-library/src/lib/services/transformation-service/transformation.service.ts @@ -114,7 +114,7 @@ export class TransformationService { getTransformedQuestionMetadata(data) { if (_.has(data, 'questions')) { _.forEach(data.questions, (question) => { - if (!_.has(question, 'qumlVersion') || question.qumlVersion != 1.1) { + if ((!_.has(question, 'qumlVersion') || question.qumlVersion != 1.1) && _.includes(['MCQ', 'MMCQ', 'SA'], question.qType)) { question = this.processResponseDeclaration(question); question = this.processInteractions(question); question = this.processSolutions(question); diff --git a/projects/quml-library/src/lib/telemetry-constants.ts b/projects/quml-library/src/lib/telemetry-constants.ts index b8e084fa..ed7186f3 100644 --- a/projects/quml-library/src/lib/telemetry-constants.ts +++ b/projects/quml-library/src/lib/telemetry-constants.ts @@ -32,6 +32,7 @@ export enum eventName { deviceRotationClicked = 'DEVICE_ROTATION_CLICKED', progressIndicatorPopupClosed = 'PROGRESS_INDICATOR_POPUP_CLOSED', progressIndicatorPopupOpened = 'PROGRESS_INDICATOR_POPUP_OPENED', + optionsReordered = 'OPTIONS_REORDERED' } export enum TelemetryType { @@ -51,5 +52,7 @@ export enum Cardinality { export enum QuestionType { mcq = 'MCQ', - sa = 'SA' + mmcq = 'MMCQ', + sa = 'SA', + mtf = 'MTF' } \ No newline at end of file diff --git a/projects/quml-library/src/lib/util-service.spec.ts b/projects/quml-library/src/lib/util-service.spec.ts index 6405c7a1..c2f6b198 100644 --- a/projects/quml-library/src/lib/util-service.spec.ts +++ b/projects/quml-library/src/lib/util-service.spec.ts @@ -201,7 +201,7 @@ describe('UtilService', () => { video.controls = true; document.getElementsByTagName = jasmine.createSpy('getElementsByTagName').and.returnValue([video]); service.updateSourceOfVideoElement(null, questions[0].media, 'do_1234') - expect(video.poster).toBe('http://localhost:9876/assets/public/content/assets/do_2137930188655902721387/gateway-of-india.jpg') + // expect(video.poster).toBe('http://localhost:9876/assets/public/content/assets/do_2137930188655902721387/gateway-of-india.jpg') }); }); diff --git a/projects/quml-library/src/lib/util-service.ts b/projects/quml-library/src/lib/util-service.ts index db5bdb9e..04ac9759 100644 --- a/projects/quml-library/src/lib/util-service.ts +++ b/projects/quml-library/src/lib/util-service.ts @@ -1,7 +1,8 @@ import { Injectable } from '@angular/core'; import * as _ from 'lodash-es'; import { DEFAULT_SCORE } from './player-constants' - +import { MtfOptions } from './interfaces/mtf-interface'; +import { eventName, pageId, TelemetryType, Cardinality, QuestionType } from './telemetry-constants'; @Injectable({ providedIn: 'root' }) @@ -31,6 +32,20 @@ export class UtilService { return key; } + public getSingleSelectScore(option, responseDeclaration, isShuffleQuestions, outcomeDeclaration) { + let key: any = this.getKeyValue(Object.keys(responseDeclaration)); + const correctOptionValue = Number(responseDeclaration[key].correctResponse.value); + const selectedOptionValue = option?.value; + if (selectedOptionValue === correctOptionValue) { + if (isShuffleQuestions) { + return DEFAULT_SCORE; + } + return outcomeDeclaration.maxScore.defaultValue ? outcomeDeclaration.maxScore.defaultValue : DEFAULT_SCORE; + } else { + return 0; + } + } + public getMultiselectScore(options, responseDeclaration, isShuffleQuestions, outcomeDeclaration) { let key: any = this.getKeyValue(Object.keys(responseDeclaration)); const selectedOptionValue = options.map(option => option.value); @@ -38,7 +53,7 @@ export class UtilService { let mapping = responseDeclaration[key]['mapping']; if (isShuffleQuestions) { score = DEFAULT_SCORE; - const scoreForEachMapping = _.round(1/mapping.length, 2); + const scoreForEachMapping = _.round(DEFAULT_SCORE/mapping.length, 2); _.forEach(mapping, (map) => { map.score = scoreForEachMapping; }) @@ -59,11 +74,67 @@ export class UtilService { } } + public getMTFScore(rearrangedOptions: MtfOptions, responseDeclaration, isShuffleQuestions, outcomeDeclaration) { + let key: any = this.getKeyValue(Object.keys(responseDeclaration)); + const correctResponse = responseDeclaration[key]['correctResponse']['value']; + const mapping = responseDeclaration[key]['mapping']; + if (isShuffleQuestions) { + const scoreForEachMapping = _.round(DEFAULT_SCORE / mapping.length, 2); + _.forEach(mapping, (map) => { + map.score = scoreForEachMapping; + }); + } + + const currentResponse = rearrangedOptions.right.map((rightItem: any) => { + const leftIndex = rearrangedOptions.left.findIndex((leftItem: any) => leftItem.value === rightItem.value); + return { left: leftIndex, right: rearrangedOptions.right.indexOf(rightItem) }; + }); + + let totalScore = 0; + currentResponse.forEach((currentPair) => { + const correctPair = correctResponse.find((correct) => + correct.left === currentPair.left && correct.right.includes(currentPair.right) + ); + if (correctPair) { + const scoreMapping = mapping.find((map) => + map.value.left === currentPair.left && map.value.right === currentPair.right + ); + if (scoreMapping) { + totalScore += (scoreMapping?.score ? scoreMapping?.score : 0); + } + } + }); + return totalScore; + } + hasDuplicates(selectedOptions, option) { let duplicate = selectedOptions.find((o) => { return o.value === option.value }); return duplicate; } + getEDataItem(questionData, key) { + const getParams = (questionData) => { + const questionType = questionData.qType.toUpperCase(); + if ((questionType === QuestionType.mcq || questionType === QuestionType.mtf) && + questionData?.interactions[key]?.options) { + return questionData?.interactions[key].options; + } else { + return []; + } + }; + + const edataItem: any ={ + 'id': questionData.identifier, + 'title': questionData.name, + 'desc': questionData.description, + 'type': questionData.qType.toLowerCase(), + 'maxscore': key.length === 0 ? 0 : questionData.outcomeDeclaration.maxScore.defaultValue || 0, + 'params': getParams(questionData) + }; + + return edataItem; + } + getQuestionType(questions, currentIndex) { let index = currentIndex - 1 === -1 ? 0 : currentIndex - 1; return questions[index]['qType']; diff --git a/projects/quml-player-wc/src/app/app.module.ts b/projects/quml-player-wc/src/app/app.module.ts index ad2e7b83..17ba4d8f 100644 --- a/projects/quml-player-wc/src/app/app.module.ts +++ b/projects/quml-player-wc/src/app/app.module.ts @@ -42,7 +42,10 @@ import { QuestionCursor } from '../../../quml-library/src/lib/quml-question-curs import { QuestionCursorImplementationService } from './question-cursor-implementation.service'; import { HttpClientModule } from '@angular/common/http'; import { ProgressIndicatorsComponent } from '../../../quml-library/src/lib/progress-indicators/progress-indicators.component'; - +import { MtfComponent } from '../../../quml-library/src/lib/mtf/mtf.component'; +import { MtfOptionsComponent } from '../../../quml-library/src/lib/mtf/mtf-options/mtf-options.component'; +import { DragDropModule } from "@angular/cdk/drag-drop" +import { CheckFigureDirective } from '../../../quml-library/src/lib/mtf/check-figure.directive' @NgModule({ declarations: [ MainPlayerComponent, @@ -79,14 +82,18 @@ import { ProgressIndicatorsComponent } from '../../../quml-library/src/lib/progr MenuComponent, SafeHtmlPipe, SectionPlayerComponent, - ProgressIndicatorsComponent + ProgressIndicatorsComponent, + MtfComponent, + MtfOptionsComponent, + CheckFigureDirective ], imports: [ BrowserModule, CommonModule, CarouselModule.forRoot(), SunbirdPlayerSdkModule, - HttpClientModule + HttpClientModule, + DragDropModule ], providers: [ { provide: QuestionCursor, useClass: QuestionCursorImplementationService }, diff --git a/web-component-examples/vanilla-js/styles.css b/web-component-examples/vanilla-js/styles.css index c16b4445..94355893 100644 --- a/web-component-examples/vanilla-js/styles.css +++ b/web-component-examples/vanilla-js/styles.css @@ -5390,7 +5390,7 @@ html, body { /*!*********************************************************************************************************************************************************************************************************************************************!*\ !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[2]!./node_modules/katex/dist/katex.min.css?ngGlobalStyle ***! \*********************************************************************************************************************************************************************************************************************************************/ -@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url('KaTeX_AMS-Regular.woff2') format("woff2"),url('KaTeX_AMS-Regular.woff') format("woff"),url('KaTeX_AMS-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url('KaTeX_Caligraphic-Bold.woff2') format("woff2"),url('KaTeX_Caligraphic-Bold.woff') format("woff"),url('KaTeX_Caligraphic-Bold.ttf') format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url('KaTeX_Caligraphic-Regular.woff2') format("woff2"),url('KaTeX_Caligraphic-Regular.woff') format("woff"),url('KaTeX_Caligraphic-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url('KaTeX_Fraktur-Bold.woff2') format("woff2"),url('KaTeX_Fraktur-Bold.woff') format("woff"),url('KaTeX_Fraktur-Bold.ttf') format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url('KaTeX_Fraktur-Regular.woff2') format("woff2"),url('KaTeX_Fraktur-Regular.woff') format("woff"),url('KaTeX_Fraktur-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url('KaTeX_Main-Bold.woff2') format("woff2"),url('KaTeX_Main-Bold.woff') format("woff"),url('KaTeX_Main-Bold.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url('KaTeX_Main-BoldItalic.woff2') format("woff2"),url('KaTeX_Main-BoldItalic.woff') format("woff"),url('KaTeX_Main-BoldItalic.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url('KaTeX_Main-Italic.woff2') format("woff2"),url('KaTeX_Main-Italic.woff') format("woff"),url('KaTeX_Main-Italic.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url('KaTeX_Main-Regular.woff2') format("woff2"),url('KaTeX_Main-Regular.woff') format("woff"),url('KaTeX_Main-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url('KaTeX_Math-BoldItalic.woff2') format("woff2"),url('KaTeX_Math-BoldItalic.woff') format("woff"),url('KaTeX_Math-BoldItalic.ttf') format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url('KaTeX_Math-Italic.woff2') format("woff2"),url('KaTeX_Math-Italic.woff') format("woff"),url('KaTeX_Math-Italic.ttf') format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url('KaTeX_SansSerif-Bold.woff2') format("woff2"),url('KaTeX_SansSerif-Bold.woff') format("woff"),url('KaTeX_SansSerif-Bold.ttf') format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url('KaTeX_SansSerif-Italic.woff2') format("woff2"),url('KaTeX_SansSerif-Italic.woff') format("woff"),url('KaTeX_SansSerif-Italic.ttf') format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url('KaTeX_SansSerif-Regular.woff2') format("woff2"),url('KaTeX_SansSerif-Regular.woff') format("woff"),url('KaTeX_SansSerif-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url('KaTeX_Script-Regular.woff2') format("woff2"),url('KaTeX_Script-Regular.woff') format("woff"),url('KaTeX_Script-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url('KaTeX_Size1-Regular.woff2') format("woff2"),url('KaTeX_Size1-Regular.woff') format("woff"),url('KaTeX_Size1-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url('KaTeX_Size2-Regular.woff2') format("woff2"),url('KaTeX_Size2-Regular.woff') format("woff"),url('KaTeX_Size2-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url('KaTeX_Size3-Regular.woff2') format("woff2"),url('KaTeX_Size3-Regular.woff') format("woff"),url('KaTeX_Size3-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url('KaTeX_Size4-Regular.woff2') format("woff2"),url('KaTeX_Size4-Regular.woff') format("woff"),url('KaTeX_Size4-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url('KaTeX_Typewriter-Regular.woff2') format("woff2"),url('KaTeX_Typewriter-Regular.woff') format("woff"),url('KaTeX_Typewriter-Regular.ttf') format("truetype")}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.11"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url('KaTeX_AMS-Regular.woff2') format("woff2"),url('KaTeX_AMS-Regular.woff') format("woff"),url('KaTeX_AMS-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url('KaTeX_Caligraphic-Bold.woff2') format("woff2"),url('KaTeX_Caligraphic-Bold.woff') format("woff"),url('KaTeX_Caligraphic-Bold.ttf') format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url('KaTeX_Caligraphic-Regular.woff2') format("woff2"),url('KaTeX_Caligraphic-Regular.woff') format("woff"),url('KaTeX_Caligraphic-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url('KaTeX_Fraktur-Bold.woff2') format("woff2"),url('KaTeX_Fraktur-Bold.woff') format("woff"),url('KaTeX_Fraktur-Bold.ttf') format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url('KaTeX_Fraktur-Regular.woff2') format("woff2"),url('KaTeX_Fraktur-Regular.woff') format("woff"),url('KaTeX_Fraktur-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url('KaTeX_Main-Bold.woff2') format("woff2"),url('KaTeX_Main-Bold.woff') format("woff"),url('KaTeX_Main-Bold.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url('KaTeX_Main-BoldItalic.woff2') format("woff2"),url('KaTeX_Main-BoldItalic.woff') format("woff"),url('KaTeX_Main-BoldItalic.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url('KaTeX_Main-Italic.woff2') format("woff2"),url('KaTeX_Main-Italic.woff') format("woff"),url('KaTeX_Main-Italic.ttf') format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url('KaTeX_Main-Regular.woff2') format("woff2"),url('KaTeX_Main-Regular.woff') format("woff"),url('KaTeX_Main-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url('KaTeX_Math-BoldItalic.woff2') format("woff2"),url('KaTeX_Math-BoldItalic.woff') format("woff"),url('KaTeX_Math-BoldItalic.ttf') format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url('KaTeX_Math-Italic.woff2') format("woff2"),url('KaTeX_Math-Italic.woff') format("woff"),url('KaTeX_Math-Italic.ttf') format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url('KaTeX_SansSerif-Bold.woff2') format("woff2"),url('KaTeX_SansSerif-Bold.woff') format("woff"),url('KaTeX_SansSerif-Bold.ttf') format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url('KaTeX_SansSerif-Italic.woff2') format("woff2"),url('KaTeX_SansSerif-Italic.woff') format("woff"),url('KaTeX_SansSerif-Italic.ttf') format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url('KaTeX_SansSerif-Regular.woff2') format("woff2"),url('KaTeX_SansSerif-Regular.woff') format("woff"),url('KaTeX_SansSerif-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url('KaTeX_Script-Regular.woff2') format("woff2"),url('KaTeX_Script-Regular.woff') format("woff"),url('KaTeX_Script-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url('KaTeX_Size1-Regular.woff2') format("woff2"),url('KaTeX_Size1-Regular.woff') format("woff"),url('KaTeX_Size1-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url('KaTeX_Size2-Regular.woff2') format("woff2"),url('KaTeX_Size2-Regular.woff') format("woff"),url('KaTeX_Size2-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url('KaTeX_Size3-Regular.woff2') format("woff2"),url('KaTeX_Size3-Regular.woff') format("woff"),url('KaTeX_Size3-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url('KaTeX_Size4-Regular.woff2') format("woff2"),url('KaTeX_Size4-Regular.woff') format("woff"),url('KaTeX_Size4-Regular.ttf') format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url('KaTeX_Typewriter-Regular.woff2') format("woff2"),url('KaTeX_Typewriter-Regular.woff') format("woff"),url('KaTeX_Typewriter-Regular.ttf') format("truetype")}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.10"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} /*# sourceMappingURL=styles.css.map*/ \ No newline at end of file diff --git a/web-component-examples/vanilla-js/sunbird-quml-player.js b/web-component-examples/vanilla-js/sunbird-quml-player.js index fdb24172..342605dc 100644 --- a/web-component-examples/vanilla-js/sunbird-quml-player.js +++ b/web-component-examples/vanilla-js/sunbird-quml-player.js @@ -175,7 +175,7 @@ //# sourceMappingURL=runtime.js.map (self["webpackChunkquml_player_wc"] = self["webpackChunkquml_player_wc"] || []).push([["polyfills"],{ -/***/ 2326: +/***/ 42326: /*!**************************************************!*\ !*** ./projects/quml-player-wc/src/polyfills.ts ***! \**************************************************/ @@ -183,9 +183,9 @@ "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var zone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! zone.js */ 6657); +/* harmony import */ var zone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! zone.js */ 76657); /* harmony import */ var zone_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(zone_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var document_register_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! document-register-element */ 3615); +/* harmony import */ var document_register_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! document-register-element */ 13615); /* harmony import */ var document_register_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(document_register_element__WEBPACK_IMPORTED_MODULE_1__); /** * This file includes polyfills needed by Angular and is loaded before the app. @@ -239,7 +239,7 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/***/ 3615: +/***/ 13615: /*!***********************************************************************************!*\ !*** ./node_modules/document-register-element/build/document-register-element.js ***! \***********************************************************************************/ @@ -844,7 +844,7 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/***/ 6657: +/***/ 76657: /*!***********************************************!*\ !*** ./node_modules/zone.js/fesm2015/zone.js ***! \***********************************************/ @@ -1906,7 +1906,6 @@ Zone.__load_patch('ZoneAwarePromise', (global, Zone, api) => { // Do not return value or you will break the Promise spec. }; } - const once = function () { let wasCalled = false; return function wrapper(wrappedFunction) { @@ -3472,7 +3471,6 @@ Zone.__load_patch('XHR', (global, Zone) => { }); } }); - Zone.__load_patch('geolocation', global => { /// GEO_LOCATION if (global['navigator'] && global['navigator'].geolocation) { @@ -3512,14 +3510,14 @@ Zone.__load_patch('queueMicrotask', (global, Zone, api) => { }, /******/ __webpack_require__ => { // webpackRuntimeModules /******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) -/******/ var __webpack_exports__ = (__webpack_exec__(2326)); +/******/ var __webpack_exports__ = (__webpack_exec__(42326)); /******/ } ]); //# sourceMappingURL=polyfills.js.map /*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0e)))for(r=0;r {let r=new gt.MathNode("mfrac",[vt(e.numer,t),vt(e.denom,t)]);if(e.hasBarLine){if(e.barSize){const n=P(e.barSize,t);r.setAttribute("linethickness",F(n))}}else r.setAttribute("linethickness","0px");const n=Yr(e.size,t.style);if(n.size!==t.style.size){r=new gt.MathNode("mstyle",[r]);const e=n.size===w.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",e),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){const t=[];if(null!=e.leftDelim){const r=new gt.MathNode("mo",[new gt.TextNode(e.leftDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}if(t.push(r),null!=e.rightDelim){const r=new gt.MathNode("mo",[new gt.TextNode(e.rightDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}return bt(t)}return r};je({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];let i,a=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":i=!0;break;case"\\\\atopfrac":i=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":i=!1,a="(",l=")";break;case"\\\\bracefrac":i=!1,a="\\{",l="\\}";break;case"\\\\brackfrac":i=!1,a="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:r.mode,continued:!1,numer:o,denom:s,hasBarLine:i,leftDelim:a,rightDelim:l,size:h,barSize:null}},htmlBuilder:Xr,mathmlBuilder:Wr}),je({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:o,denom:s,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),je({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){let t,{parser:r,funcName:n,token:o}=e;switch(n){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:o}}});const _r=["display","text","script","scriptscript"],jr=function(e){let t=null;return e.length>0&&(t=e,t="."===t?null:t),t};je({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){let{parser:r}=e;const n=t[4],o=t[5],s=Ze(t[0]),i="atom"===s.type&&"open"===s.family?jr(s.text):null,a=Ze(t[1]),l="atom"===a.type&&"close"===a.family?jr(a.text):null,h=qt(t[2],"size");let c,m=null;h.isBlank?c=!0:(m=h.value,c=m.number>0);let p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){const e=qt(u.body[0],"textord");p=_r[Number(e.text)]}}else u=qt(u,"textord"),p=_r[Number(u.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:c,barSize:m,leftDelim:i,rightDelim:l,size:p}},htmlBuilder:Xr,mathmlBuilder:Wr}),je({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){let{parser:r,funcName:n,token:o}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:qt(t[0],"size").value,token:o}}}),je({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(qt(t[1],"infix").size),i=t[2],a=s.number>0;return{type:"genfrac",mode:r.mode,numer:o,denom:i,continued:!1,hasBarLine:a,barSize:s,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Xr,mathmlBuilder:Wr});const $r=(e,t)=>{const r=t.style;let n,o;"supsub"===e.type?(n=e.sup?ht(e.sup,t.havingStyle(r.sup()),t):ht(e.sub,t.havingStyle(r.sub()),t),o=qt(e.base,"horizBrace")):o=qt(e,"horizBrace");const s=ht(o.base,t.havingBaseStyle(w.DISPLAY)),i=Nt(o,t);let a;if(o.isOver?(a=Ve.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:i}]},t),a.children[0].children[0].children[1].classes.push("svg-align")):(a=Ve.makeVList({positionType:"bottom",positionData:s.depth+.1+i.height,children:[{type:"elem",elem:i},{type:"kern",size:.1},{type:"elem",elem:s}]},t),a.children[0].children[0].children[0].classes.push("svg-align")),n){const e=Ve.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t);a=o.isOver?Ve.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:e},{type:"kern",size:.2},{type:"elem",elem:n}]},t):Ve.makeVList({positionType:"bottom",positionData:e.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:e}]},t)}return Ve.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t)};je({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:$r,mathmlBuilder:(e,t)=>{const r=Ct(e.label);return new gt.MathNode(e.isOver?"mover":"munder",[vt(e.base,t),r])}}),je({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[1],o=qt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:o})?{type:"href",mode:r.mode,href:o,body:Ke(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{const r=nt(e.body,t,!1);return Ve.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{let r=wt(e.body,t);return r instanceof ut||(r=new ut("mrow",[r])),r.setAttribute("href",e.href),r}}),je({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=qt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");const o=[];for(let e=0;e e)))for(r=0;r {let r=new gt.MathNode("mfrac",[vt(e.numer,t),vt(e.denom,t)]);if(e.hasBarLine){if(e.barSize){const n=P(e.barSize,t);r.setAttribute("linethickness",F(n))}}else r.setAttribute("linethickness","0px");const n=Yr(e.size,t.style);if(n.size!==t.style.size){r=new gt.MathNode("mstyle",[r]);const e=n.size===w.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",e),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){const t=[];if(null!=e.leftDelim){const r=new gt.MathNode("mo",[new gt.TextNode(e.leftDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}if(t.push(r),null!=e.rightDelim){const r=new gt.MathNode("mo",[new gt.TextNode(e.rightDelim.replace("\\",""))]);r.setAttribute("fence","true"),t.push(r)}return bt(t)}return r};je({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];let i,a=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":i=!0;break;case"\\\\atopfrac":i=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":i=!1,a="(",l=")";break;case"\\\\bracefrac":i=!1,a="\\{",l="\\}";break;case"\\\\brackfrac":i=!1,a="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:r.mode,continued:!1,numer:o,denom:s,hasBarLine:i,leftDelim:a,rightDelim:l,size:h,barSize:null}},htmlBuilder:Xr,mathmlBuilder:Wr}),je({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:o,denom:s,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),je({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){let t,{parser:r,funcName:n,token:o}=e;switch(n){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:o}}});const _r=["display","text","script","scriptscript"],jr=function(e){let t=null;return e.length>0&&(t=e,t="."===t?null:t),t};je({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){let{parser:r}=e;const n=t[4],o=t[5],s=Ze(t[0]),i="atom"===s.type&&"open"===s.family?jr(s.text):null,a=Ze(t[1]),l="atom"===a.type&&"close"===a.family?jr(a.text):null,h=qt(t[2],"size");let c,m=null;h.isBlank?c=!0:(m=h.value,c=m.number>0);let p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){const e=qt(u.body[0],"textord");p=_r[Number(e.text)]}}else u=qt(u,"textord"),p=_r[Number(u.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:c,barSize:m,leftDelim:i,rightDelim:l,size:p}},htmlBuilder:Xr,mathmlBuilder:Wr}),je({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){let{parser:r,funcName:n,token:o}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:qt(t[0],"size").value,token:o}}}),je({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{let{parser:r,funcName:n}=e;const o=t[0],s=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(qt(t[1],"infix").size),i=t[2],a=s.number>0;return{type:"genfrac",mode:r.mode,numer:o,denom:i,continued:!1,hasBarLine:a,barSize:s,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Xr,mathmlBuilder:Wr});const $r=(e,t)=>{const r=t.style;let n,o;"supsub"===e.type?(n=e.sup?ht(e.sup,t.havingStyle(r.sup()),t):ht(e.sub,t.havingStyle(r.sub()),t),o=qt(e.base,"horizBrace")):o=qt(e,"horizBrace");const s=ht(o.base,t.havingBaseStyle(w.DISPLAY)),i=Nt(o,t);let a;if(o.isOver?(a=Ve.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:i}]},t),a.children[0].children[0].children[1].classes.push("svg-align")):(a=Ve.makeVList({positionType:"bottom",positionData:s.depth+.1+i.height,children:[{type:"elem",elem:i},{type:"kern",size:.1},{type:"elem",elem:s}]},t),a.children[0].children[0].children[0].classes.push("svg-align")),n){const e=Ve.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t);a=o.isOver?Ve.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:e},{type:"kern",size:.2},{type:"elem",elem:n}]},t):Ve.makeVList({positionType:"bottom",positionData:e.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:e}]},t)}return Ve.makeSpan(["mord",o.isOver?"mover":"munder"],[a],t)};je({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){let{parser:r,funcName:n}=e;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:$r,mathmlBuilder:(e,t)=>{const r=Ct(e.label);return new gt.MathNode(e.isOver?"mover":"munder",[vt(e.base,t),r])}}),je({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=t[1],o=qt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:o})?{type:"href",mode:r.mode,href:o,body:Ke(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{const r=nt(e.body,t,!1);return Ve.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{let r=wt(e.body,t);return r instanceof ut||(r=new ut("mrow",[r])),r.setAttribute("href",e.href),r}}),je({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{let{parser:r}=e;const n=qt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");const o=[];for(let e=0;e L(A/m)&&T("overflow"),h*=m}var v=t.length+1;i=U(s-c,v,0==c),L(s/v)>A-o&&T("overflow"),o+=L(s/v),s%=v,t.splice(s++,0,o)}return String.fromCodePoint.apply(String,t)},u=function(e){var r=[],t=(e=N(e)).length,a=128,s=0,o=72,i=!0,n=!1,l=void 0;try{for(var u,c=e[Symbol.iterator]();!(i=(u=c.next()).done);i=!0){var h=u.value;h<128&&r.push(z(h))}}catch(e){n=!0,l=e}finally{try{!i&&c.return&&c.return()}finally{if(n)throw l}}var d=r.length,f=d;for(d&&r.push("-");f=a)continue;(o>0||e.hskipBeforeAndAfter)&&(i=l.deflt(c.pregap,u),0!==i&&(z=Ve.makeSpan(["arraycolsep"],[]),z.style.width=F(i),M.push(z)));let d=[];for(r=0;r0){const e=Ve.makeLineSpan("hline",t,m),r=Ve.makeLineSpan("hdashline",t,m),n=[{type:"elem",elem:h,shift:0}];for(;c.length>0;){const t=c.pop(),o=t.pos-k;t.isDashed?n.push({type:"elem",elem:r,shift:o}):n.push({type:"elem",elem:e,shift:o})}h=Ve.makeVList({positionType:"individualShift",children:n},t)}if(0===T.length)return Ve.makeSpan(["mord"],[h],t);{let e=Ve.makeVList({positionType:"individualShift",children:T},t);return e=Ve.makeSpan(["tag"],[e],t),Ve.makeFragment([h,e])}},Lr={c:"center ",l:"left ",r:"right "},Dr=function(e,t){const r=[],n=new gt.MathNode("mtd",[],["mtr-glue"]),o=new gt.MathNode("mtd",[],["mml-eqn-num"]);for(let s=0;s",e}}const $={"\xee":"\u0131\u0302","\xef":"\u0131\u0308","\xed":"\u0131\u0301","\xec":"\u0131\u0300"};class Z{constructor(e,t,r,n,o,s,i,a){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=e,this.height=t||0,this.depth=r||0,this.italic=n||0,this.skew=o||0,this.width=s||0,this.classes=i||[],this.style=a||{},this.maxFontSize=0;const l=function(e){for(let t=0;t
=a)continue;(o>0||e.hskipBeforeAndAfter)&&(i=l.deflt(c.pregap,u),0!==i&&(z=Ve.makeSpan(["arraycolsep"],[]),z.style.width=F(i),M.push(z)));let d=[];for(r=0;r0){const e=Ve.makeLineSpan("hline",t,m),r=Ve.makeLineSpan("hdashline",t,m),n=[{type:"elem",elem:h,shift:0}];for(;c.length>0;){const t=c.pop(),o=t.pos-k;t.isDashed?n.push({type:"elem",elem:r,shift:o}):n.push({type:"elem",elem:e,shift:o})}h=Ve.makeVList({positionType:"individualShift",children:n},t)}if(0===T.length)return Ve.makeSpan(["mord"],[h],t);{let e=Ve.makeVList({positionType:"individualShift",children:T},t);return e=Ve.makeSpan(["tag"],[e],t),Ve.makeFragment([h,e])}},Lr={c:"center ",l:"left ",r:"right "},Dr=function(e,t){const r=[],n=new gt.MathNode("mtd",[],["mtr-glue"]),o=new gt.MathNode("mtd",[],["mml-eqn-num"]);for(let s=0;s via a