import { CabriIntegration } from "./cabri-integration";
import { CabriDataService } from "../services/cabri-data.service";
import { GlobalService } from "../services/global.service";
import { Platform } from "@ionic/angular";
import { NgZone, Renderer2 } from "@angular/core";
import { Subject } from "rxjs";
import { AccountService } from "../services/account.service";
import { AppUtils, Fraction } from "../app-utils";
declare var window: {
store: any;
document: any;
innerWidth: any;
innerHeight: any;
outerWidth: any;
outerHeight: any;
dispatchEvent: any;
};
declare var MathJax: {
startup: any;
svg: any;
tex: any;
tex2svg: any;
tex2svgPromise: any;
loader: any;
Hub: any;
config: any;
tex2mml: any;
defsGlobalCaching: any;
};
declare var BABYLON;
export class CabriIntegrationCalculmental extends CabriIntegration {
public operationWrapperID: string;
public paramDisplayMode;
public currentNumberOperations = new Array();
public exerciseOptionNumbers = new Array();
public operationWrapperMethods = {
paramCollections: new Subject(),
paramSimpleImg: new Subject()
};
public collectionsImgs = {
firstNumber: new Array(),
secondNumber: new Array()
};
mode: string = "";
currentOperator: any;
cduHilighted = false;
constructor(
public cabriService: CabriDataService,
public accountService: AccountService,
public globalService: GlobalService,
public _ngZone: NgZone,
public page,
public platform: Platform,
public renderer: Renderer2
) {
super(cabriService, globalService, _ngZone, page, renderer);
this.page = page;
this.cabriRenderStarted = true;
this.platform.ready().then(() => {
this.operationWrapperID = this.globalService.isCordova ? "#operationWrapperCordova" : "#operationWrapper";
});
}
onBabylonReady(): Promise<void> {
return new Promise(async (resolve, reject) => {
await super.onBabylonReady();
await this.importMascotteMeshes();
this.scene.onAfterRenderObservable.addOnce(() => {
this.unlockRotation();
this.camera.alpha = -Math.PI / 2;
window.store.getters.cps.setPageOrientation(this.camera.alpha, this.camera.beta);
this.replaceCabriLights();
resolve();
});
});
}
/**
* RESIZE CABRI -> Update DOM Cabri elements
* @param holoMode Holo mode
* @param platform Platform
*/
updateCabriPosition(holoMode: string = null): Promise<void> {
const promise = super.updateCabriPosition(holoMode, "calculmental");
promise.then(() => {
if (this.cabriService.currentActivity.id === "10") {
// update font size for resolution de probleme
this.setMaxFontSize();
}
});
return promise;
}
async updateCabriBackground(renderCanvas, condition) {
let backgroundMeshFound = false;
window.store.getters.cabri.Scene.meshes.forEach(async m => {
if (m.id === "background") {
backgroundMeshFound = true;
// background width proportion = 4096/3072 = 1.333333:
if (condition === 2) {
m.scaling.x = 1.1;
m.scaling.z = 1.1;
}
this.checkFlatHoloMode(m);
await this.switchBackgroundLauncher(m, renderCanvas.clientHeight, renderCanvas.clientWidth);
// for testing / screenshots:
// this.switchBackgroundLauncher(m, false, "assignationMap");
console.log("cabri background resized");
}
});
if (!this.page.environment.production && !backgroundMeshFound) {
console.error("no background mesh ?");
// tslint:disable-next-line: no-debugger
debugger;
}
}
/**
* Calculates the height of cabri help depending of context / device
*/
async calculateHelpHeight() {
// help height compute:
if (this.globalService.inIframe) {
// TRALA
this.smallHelpHeight = 8.4;
this.bigHelpHeight = 6.5;
} else if (this.globalService.isTablet && !this.globalService.isIos) {
// TABLET Android
if (this.globalService.isCordova) {
// native:
if (this.cabriService.coinsModeInCM) {
this.smallHelpHeight = 7.3;
} else {
this.smallHelpHeight = 7.5;
}
} else {
// webapp:
this.smallHelpHeight = 7.7;
}
this.bigHelpHeight = 6.2;
} else if (this.globalService.isTablet && this.globalService.isIos) {
// TABLET IOS
this.smallHelpHeight = 7.3;
this.bigHelpHeight = 5.5;
} else if (this.globalService.isMobile) {
// MOBILE (TODO adjust different formats?)
this.smallHelpHeight = 8.1;
this.bigHelpHeight = 6.9;
} else {
if (
!this.cabriService.mirrorMode &&
(this.cabriService.inputMethod === "numpad" ||
(this.cabriService.inputMethod === "stt" && this.cabriService.cabriInputNumpadStatus))
) {
this.smallHelpHeight = 8;
console.log("smallHelp numpad = ", this.smallHelpHeight);
} else if (
this.cabriService.mirrorMode &&
(this.cabriService.inputMethod === "numpad" ||
(this.cabriService.inputMethod === "stt" && this.cabriService.cabriInputNumpadStatus))
) {
this.smallHelpHeight = 7.3;
console.log("smallHelp numpad mirror = ", this.smallHelpHeight);
} else {
this.smallHelpHeight = 8;
console.log("smallHelp stt draw = ", this.smallHelpHeight);
}
this.bigHelpHeight = 6.9;
console.log("this.smallHelpHeight = " + this.smallHelpHeight + " 3rd cond");
console.log("this.bigHelpHeight = " + this.bigHelpHeight + " 3rd cond");
if (this.globalService.isFullscreen) {
let arrondi = this.smallHelpHeight * 100;
arrondi = Math.round(arrondi);
arrondi = arrondi / 100;
this.smallHelpHeight = arrondi;
this.bigHelpHeight = this.bigHelpHeight - 0.4;
}
}
if (
(this.cabriService.inputMethod === "stt" || this.cabriService.inputMethod === "drawing") &&
!this.cabriService.cabriInputNumpadStatus &&
!this.cabriService.mirrorMode &&
!this.page.writeOperationOutEnabled
) {
this.smallHelpHeight = this.smallHelpHeight + 0.5;
console.log("smallHelp stt draw mobile cond= ", this.smallHelpHeight);
}
if (this.cabriService.smallOperationHelp) {
await this.toggleOperationSmallHelp(false, true);
await this.toggleOperationSmallHelp(true);
}
}
getOperationNumber() {
const currentOperation = this.getCurrentOperation();
this.currentNumberOperations = new Array();
const tmp = currentOperation.split(" ");
tmp.forEach((element: any) => {
if (Number(element) === Number(element)) {
this.currentNumberOperations.push(element);
}
});
return this.currentNumberOperations;
}
toggleOperationWrapperPosition(pos: string) {
try {
if (this.page.isActivePage()) {
let ow;
const collectionActivity =
this.paramDisplayMode && this.paramDisplayMode.value && this.paramDisplayMode.value === "collection";
if (this.globalService.isCordova) {
if (this.paramDisplayMode) {
if (collectionActivity) {
ow = window.document.querySelectorAll("#operationWrapper");
} else {
ow = window.document.querySelectorAll(this.operationWrapperID);
}
} else {
ow = window.document.querySelectorAll(this.operationWrapperID);
}
} else {
ow = window.document.querySelectorAll(this.operationWrapperID);
}
if (this.globalService.isCordova && !(collectionActivity && this.globalService.isDesktop)) {
if (pos === "up") {
if (this.accountService.team.length === 1) {
Array.from(ow).forEach((currentData: any) => {
// TODO: erase after iOS testing:
if (this.cabriService.mirrorMode) {
if (collectionActivity) {
currentData.className = "numpadCordova1PlayerCollection";
} else {
currentData.className = "numpadCordova1PlayerMirror";
}
} else if (collectionActivity) {
currentData.className = "numpadCordova1PlayerCollection";
} else {
currentData.className = "numpadCordova1Player";
}
// }
});
} else if (this.accountService.team.length > 1) {
Array.from(ow).forEach((currentData: any) => {
// TODO: erase after iOS testing:
// if (currentData.className.includes("normal") || !currentData.className) {
if (collectionActivity) {
currentData.className = "numpadCollectionTeam";
} else if (this.cabriService.coinsModeInCM) {
currentData.className = "numpadCordovaTeamCoinsMode";
} else if (this.cabriService.mirrorMode) {
currentData.className = "numpadCordovaTeamMirror";
} else {
currentData.className = "numpadCordovaTeam";
}
// }
});
}
} else if (pos === "down") {
Array.from(ow).forEach((currentData: any) => {
// TODO: erase after iOS testing:
// if (
// currentData.className.includes("numpadCordovaTeam") ||
// currentData.className.includes("numpad") ||
// currentData.className.includes("numpadCordovaTeamMirror") ||
// currentData.className.includes("numpadCordova1Player") ||
// currentData.className.includes("numpadCordova1PlayerMirror") ||
// !currentData.className
// ) {
if (this.cabriService.coinsModeInCM) {
currentData.className = "downCoinsMode";
} else {
currentData.className = "normal";
}
// }
});
}
} else {
if (collectionActivity && this.globalService.isDesktop) {
Array.from(ow).forEach((currentData: any) => {
if (pos === "up") {
currentData.className = "collectionUp";
} else if (pos === "down") {
currentData.className = "normal";
}
});
} else {
if (pos === "up") {
Array.from(ow).forEach((currentData: any) => {
// TODO: erase after iOS testing:
// if (currentData.className.includes("normal") || !currentData.className) {
if (this.globalService.isDesktop && this.cabriService.coinsModeInCM) {
currentData.className = "numpadCoinsDesktop";
} else if (this.cabriService.mirrorMode) {
currentData.className = "numpadMirror";
} else {
currentData.className = "numpad";
}
// }
});
} else if (pos === "down") {
Array.from(ow).forEach((currentData: any) => {
// TODO: erase after iOS testing:
// if (currentData.className.includes("numpad") || currentData.className.includes("numpadMirror") || !currentData.className) {
if (this.cabriService.coinsModeInCM) {
currentData.className = "downCoinsMode";
} else {
currentData.className = "normal";
}
// }
});
}
}
}
}
} catch (error) {
throw error;
}
}
setOperation(mode: string = "result", value: string = "?"): Promise<void> {
return new Promise(async (resolve, reject) => {
if (this.page.isActivePage()) {
let operation = this.getCurrentOperation();
this.mode = mode;
let result;
try {
operation = operation.replace(/×/g, "*");
operation = operation.replace(/−/g, "-");
operation = operation.replace(/,/g, ".");
operation = operation.replace(/\:/g, "/");
eval("result = " + operation);
operation = operation.replace(/\*/g, "×");
operation = operation.replace(/-/g, "−");
operation = operation.replace(/\./g, ",");
operation = operation.replace(/\//g, ":");
} catch {
result = null;
}
const tmp = operation.split(" ");
// Compter le nombre de symboles pour savoir si c'est une opération simple
if ((operation.match(/[+\-*:]/g) || []).length == 1) {
this.splitNumber(tmp[0], tmp[2]);
} else { // custom operation
this.cabriService.nb1 = this.cabriService.currentActivity.currentVariables.nb1;
this.cabriService.nb2 = this.cabriService.currentActivity.currentVariables.nb2;
this.cabriService.nb3 = this.cabriService.currentActivity.currentVariables?.nb3;
this.cabriService.nb4 = this.cabriService.currentActivity.currentVariables?.nb4;
}
if (this.cabriService.currentActivity.id === "10") {
let str = "<p class='resopro'>" + this.cabriService.currentExercice.probleme.consigne + "</p>";
if (this.cabriService.participantAnswer) {
if (this.cabriService.participantAnswer instanceof Fraction) {
const latex = this.cabriService.participantAnswer.toLatex();
const element = await MathJax.tex2svgPromise(latex);
element.querySelector("svg").setAttribute("style", "height: 0.8em; width: auto");
str += `<span>${element.outerHTML}</span>`;
} else {
str += "<h2> Ton résultat : " + (typeof this.cabriService.participantAnswer === "string"? this.cabriService.participantAnswer.replace(".",",") : this.cabriService.participantAnswer) + "</h2>";
}
}
if (window.document.querySelector(this.operationWrapperID + "[data-original] div")) {
window.document.querySelector(this.operationWrapperID + "[data-original] div").innerHTML = str;
} else if (window.document.querySelector(this.operationWrapperID + " div")) {
window.document.querySelector(this.operationWrapperID + " div").innerHTML = str;
}
this.setMaxFontSize();
} else {
if (this.paramDisplayMode) {
if (
this.paramDisplayMode.value === "fingers" ||
this.paramDisplayMode.value === "dice" ||
this.paramDisplayMode.value === "coins"
) {
this.displayOperationWrapperImgMode(mode, value, result, tmp);
} else if (this.paramDisplayMode.value === "collection") {
this.displayOperationWrapperCollectionMode(mode, value, tmp);
} else if (this.paramDisplayMode.value === "letters") {
this.displayOperationWrapperDefaultMode(mode, value, result, tmp);
}
} else {
this.displayOperationWrapperDefaultMode(mode, value, result, tmp);
}
}
resolve();
} else {
reject("killed by leave");
}
});
}
setMaxFontSize(fontSize = null) {
if (!fontSize) {
// default fontSize value
fontSize = Math.round((window.innerHeight * 2) / 100 + (window.innerWidth * 1) / 100);
}
let mainWrapper;
if (window.document.querySelector(this.operationWrapperID + "[data-original] div")) {
mainWrapper = window.document.querySelector(this.operationWrapperID + "[data-original] div");
} else if (window.document.querySelector(this.operationWrapperID)) {
window.document.querySelector(this.operationWrapperID + " div");
}
if (mainWrapper) {
const paragraph = mainWrapper.querySelector("p");
if (mainWrapper && paragraph) {
let maxHeight = mainWrapper.offsetHeight;
let responseHeight;
if (this.globalService.isMobile) {
responseHeight = (window.innerHeight * 2.5) / 100;
} else {
responseHeight = (window.innerHeight * 5) / 100;
}
if(!isNaN(Number(fontSize))){
paragraph.style.fontSize = fontSize + "px";
const lineHeightValue = fontSize + 4;
paragraph.style.lineHeight = lineHeightValue + "px";
const numberLines = AppUtils.getParagraphLines(lineHeightValue,paragraph?.clientHeight);
if(numberLines >= 4){
// resoPro -> avoid the paragraph exceeding the operation wrapper and overlapping its border
maxHeight = mainWrapper.clientHeight;
}
if (maxHeight < responseHeight + paragraph.offsetHeight && fontSize > 1) {
this.setMaxFontSize(fontSize - 1);
}
}
}
}
}
hideOperation() {
if (this.page.isActivePage()) {
this.operationWrapperID = this.globalService.isCordova ? "#operationWrapperCordova" : "#operationWrapper";
window.document.querySelector("#page-div section").style.opacity = "0";
if (window.document.querySelector(this.operationWrapperID + " p")) {
window.document.querySelector(this.operationWrapperID + " p").style.opacity = "0";
}
}
}
showOperation() {
if (this.page.isActivePage()) {
this.operationWrapperID = this.globalService.isCordova ? "#operationWrapperCordova" : "#operationWrapper";
window.document.querySelector("#page-div section").style.opacity = "1";
if (window.document.querySelector(this.operationWrapperID + " p")) {
window.document.querySelector(this.operationWrapperID + " p").style.opacity = "1";
}
}
}
hideOperationAndWrapper() {
try {
if (this.page.isActivePage()) {
this.operationWrapperID = this.globalService.isCordova ? "#operationWrapperCordova" : "#operationWrapper";
if (window.document.querySelector("#page-div section")) {
window.document.querySelector("#page-div section").style.opacity = "0";
}
if (this.paramDisplayMode) {
if (this.paramDisplayMode.value === "collection") {
this.operationWrapperID = "#operationWrapper";
}
}
if (window.document.querySelectorAll(this.operationWrapperID)?.length > 0) {
window.document.querySelectorAll(this.operationWrapperID).forEach(currentClass => {
if (currentClass?.style) {
currentClass.style.opacity = "0";
}
});
}
this.page.cabriService.operationWrapperdisplayed = false;
this.page.detectChanges();
}
} catch (error) {
throw error;
}
}
showOperationAndWrapper() {
if (this.page.isActivePage()) {
this.operationWrapperID = this.globalService.isCordova ? "#operationWrapperCordova" : "#operationWrapper";
console.log("show up wrapper : " + this.operationWrapperID);
if (this.paramDisplayMode) {
if (this.paramDisplayMode.value === "collection") {
this.operationWrapperID = "#operationWrapper";
}
}
window.document.querySelector("#page-div section").style.opacity = "1";
if (window.document.querySelectorAll(this.operationWrapperID)?.length > 0) {
window.document.querySelectorAll(this.operationWrapperID).forEach(currentClass => {
if (currentClass) {
currentClass.style.opacity = "1";
}
});
} else {
console.log("operation wrapper not found");
}
this.page.cabriService.operationWrapperdisplayed = true;
this.page.detectChanges();
}
}
clearResponse(mode: string = null, setOperationParam2: string = null): Promise<void> {
return new Promise((resolve, reject) => {
if (this.page.isActivePage()) {
if (window.document.querySelector(".ZDR .svg-container")) {
window.document.querySelector(".ZDR .svg-container").innerHTML = "";
}
if (window.document.querySelector(".theZDR p")) {
window.document.querySelector(".theZDR p").innerHTML = "";
window.document.querySelector(".theZDR").style.opacity = "0";
}
console.log("clearresponse mode = " + mode + " setopparam2 = " + setOperationParam2);
// fix bug undefined ow on switchInputMethod:
this.startRender();
setTimeout(() => {
this.setOperation(mode, setOperationParam2);
resolve();
}, 50);
} else {
reject("killed by leave");
}
});
}
setResponse(mode: string, value: any) {
// display response
this.setOperation(mode, value);
if (window.document.querySelector(".theZDR")) {
window.document.querySelector(".theZDR p").innerHTML = value;
window.document.querySelector(".theZDR").style.opacity = "1";
}
}
getCurrentOperation(): string {
if (this.page.isActivePage()) {
if (this.cabriService?.currentActivity?.currentVariables?.operation) {
// get operation
let operator;
switch (this.cabriService.currentActivity.currentVariables.operation) {
case "1":
operator = " + ";
break;
case "2":
operator = " × ";
break;
case "3":
operator = " - ";
break;
case "4":
operator = " : ";
break;
case "5":
operator = this.cabriService.currentActivity.currentVariables._customOperation;
for (let i = 1; i <= 4; i++) {
const key = `nb${i}`;
const value = this.cabriService.currentActivity.currentVariables[key];
if (value) {
if (value instanceof Fraction) {
operator = operator.replace(
new RegExp(`\\$${key}\\$`, "g"),
`${value.numerateur}/${value.denominateur}`
);
} else {
operator = operator.replace(
new RegExp(`\\$${key}\\$`, "g"),
value.toFixed(8).replace(/\.?0+$/, "").replace(".",",")
);
}
}
}
return operator;
}
this.currentOperator = operator;
return (
[
this.cabriService.currentActivity.currentVariables.nb1,
this.cabriService.currentActivity.currentVariables.nb2,
this.cabriService.currentActivity.currentVariables.nb3,
this.cabriService.currentActivity.currentVariables.nb4,
].filter(v => v !== undefined && v !== null).join(operator)
);
} else {
return "";
}
}
}
checkDisplayMode(mode): boolean {
if (this.paramDisplayMode) {
if (this.paramDisplayMode.value === mode) {
return true;
}
}
return false;
}
getUserOperation(mode?: string) {
// get operation
let userOperation = "";
if (this.checkDisplayMode("letters")) {
const operation = this.getCurrentOperation();
const temp = operation.split(" ");
if (mode === "nb1") {
window.document.querySelectorAll(".first-number").forEach(element => {
userOperation += element.innerHTML.match(/\d+/g);
});
userOperation += window.document.querySelector(".signe-operation").innerHTML;
userOperation += temp[2];
} else {
userOperation += temp[0];
userOperation += window.document.querySelector(".signe-operation").innerHTML;
window.document.querySelectorAll(".second-number").forEach(element => {
userOperation += element.innerHTML.match(/\d+/g);
});
}
} else {
window.document.querySelectorAll(".first-number").forEach(element => {
userOperation += element.innerHTML.match(/\d+/g);
});
userOperation += window.document.querySelector(".signe-operation").innerHTML;
window.document.querySelectorAll(".second-number").forEach(element => {
userOperation += element.innerHTML.match(/\d+/g);
});
}
return userOperation;
}
setFingers() {
let str = ""; // '<p>';
const currentOperation = this.getCurrentOperation();
const tmp = currentOperation.split(" ");
tmp.forEach((element: any) => {
// tslint:disable-next-line: triple-equals
if (element == Number(element)) {
str += '<img src="assets/finger/' + element + '.png" height="120px">';
} else {
str += "<span>" + element + "</span>";
}
});
str += "";
if (this.cabriService.currentActivity.slug === "calculmental") {
window.document.querySelector("#operationWrapper p").innerHTML = str;
} else if (this.cabriService.currentActivity.slug === "in-out") {
window.document.querySelector(".VueTextbox .ProseMirror span span").innerHTML = str;
}
}
getSpanNumber(n: string, position: string) {
const j = String(n).length;
// console.log(j);
let result = "";
for (let i = 0; i < j; i++) {
let classCSS = "";
switch (j - (i + 1)) {
case 0:
classCSS = "unite";
break;
case 1:
classCSS = "dizaine";
break;
case 2:
classCSS = "centaine";
break;
case 3:
classCSS = "millier";
break;
}
if (this.cabriService.currentActivity.getParam("v-display-mode")) {
if (this.cabriService.currentActivity.getParam("v-display-mode").value === "letters") {
classCSS = "";
}
}
result += '<span class="' + classCSS + " " + position + ' number">' + (n + "")[i].replace(".", ",") + "</span>";
}
return result;
}
splitNumber(nb1: string, nb2: string) {
const res = (Number(nb1) + Number(nb2)).toString();
// split numbers :
this.cabriService.nb1 = nb1;
this.cabriService.nb2 = nb2;
this.cabriService.result = res;
this.cabriService.nb1U = Number(nb1) % 10;
this.cabriService.nb1D = ((Number(nb1) % 100) - this.cabriService.nb1U) / 10;
this.cabriService.nb1C = ((Number(nb1) % 1000) - (this.cabriService.nb1 % 100)) / 100;
this.cabriService.nb1M = (Number(nb1) - this.cabriService.nb1U - 10 * this.cabriService.nb1D - 100 * this.cabriService.nb1C) / 1000;
this.cabriService.nb2U = Number(nb2) % 10;
this.cabriService.nb2D = ((Number(nb2) % 100) - this.cabriService.nb2U) / 10;
this.cabriService.nb2C = ((Number(nb2) % 1000) - (this.cabriService.nb2 % 100)) / 100;
this.cabriService.nb2M = (Number(nb2) - this.cabriService.nb2U - 10 * this.cabriService.nb2D - 100 * this.cabriService.nb2C) / 1000;
this.cabriService.resU = Number(res) % 10;
this.cabriService.resD = ((Number(res) % 100) - this.cabriService.resU) / 10;
this.cabriService.resC = ((Number(res) % 1000) - (this.cabriService.result % 100)) / 100;
this.cabriService.resM = (Number(res) - this.cabriService.resU - 10 * this.cabriService.resD - 100 * this.cabriService.resC) / 1000;
// console.log('split nb1U : ' + this.cabriService.nb1U);
// console.log('split nb1D : ' + this.cabriService.nb1D);
// console.log('split nb1C : ' + this.cabriService.nb1C);
// console.log('split nb1M : ' + this.cabriService.nb1M);
// console.log('split nb2U : ' + this.cabriService.nb2U);
// console.log('split nb2D : ' + this.cabriService.nb2D);
// console.log('split nb2C : ' + this.cabriService.nb2C);
// console.log('split nb2M : ' + this.cabriService.nb2M);
// console.log('split resU : ' + this.cabriService.resU);
// console.log('split resD : ' + this.cabriService.resD);
// console.log('split resC : ' + this.cabriService.resC);
// console.log('split resM : ' + this.cabriService.resM);
// set units strings for text:
this.cabriService.nb1Units = this.cabriService.nb1U < 2 ? $localize`unité` : $localize`unités`;
this.cabriService.nb1Tens = this.cabriService.nb1D < 2 ? $localize`dizaine` : $localize`dizaines`;
this.cabriService.nb1Hundreds = this.cabriService.nb1C < 2 ? $localize`centaine` : $localize`centaines`;
this.cabriService.nb1Thousands = this.cabriService.nb1M < 2 ? $localize`millier` : $localize`milliers`;
this.cabriService.nb2Units = this.cabriService.nb2U < 2 ? $localize`unité` : $localize`unités`;
this.cabriService.nb2Tens = this.cabriService.nb2D < 2 ? $localize`dizaine` : $localize`dizaines`;
this.cabriService.nb2Hundreds = this.cabriService.nb2C < 2 ? $localize`centaine` : $localize`centaines`;
this.cabriService.nb2Thousands = this.cabriService.nb2M < 2 ? $localize`millier` : $localize`milliers`;
this.cabriService.resUnits = this.cabriService.resU < 2 ? $localize`unité` : $localize`unités`;
this.cabriService.resTens = this.cabriService.resD < 2 ? $localize`dizaine` : $localize`dizaines`;
this.cabriService.resHundreds = this.cabriService.resC < 2 ? $localize`centaine` : $localize`centaines`;
this.cabriService.resThousands = this.cabriService.resM < 2 ? $localize`millier` : $localize`milliers`;
// set TTS strings:
this.cabriService.nb1U === 1
? (this.cabriService.nb1U_TTS = $localize`:tts:une`)
: (this.cabriService.nb1U_TTS = this.cabriService.nb1U);
this.cabriService.nb1D === 1
? (this.cabriService.nb1D_TTS = $localize`:tts:une`)
: (this.cabriService.nb1D_TTS = this.cabriService.nb1D);
this.cabriService.nb1C === 1
? (this.cabriService.nb1C_TTS = $localize`:tts:une`)
: (this.cabriService.nb1C_TTS = this.cabriService.nb1C);
this.cabriService.nb1M === 1
? (this.cabriService.nb1M_TTS = $localize`:tts:une`)
: (this.cabriService.nb1M_TTS = this.cabriService.nb1M);
this.cabriService.nb2U === 1
? (this.cabriService.nb2U_TTS = $localize`:tts:une`)
: (this.cabriService.nb2U_TTS = this.cabriService.nb2U);
this.cabriService.nb2D === 1
? (this.cabriService.nb2D_TTS = $localize`:tts:une`)
: (this.cabriService.nb2D_TTS = this.cabriService.nb2D);
this.cabriService.nb2C === 1
? (this.cabriService.nb2C_TTS = $localize`:tts:une`)
: (this.cabriService.nb2C_TTS = this.cabriService.nb2C);
this.cabriService.nb2M === 1
? (this.cabriService.nb2M_TTS = $localize`:tts:une`)
: (this.cabriService.nb2M_TTS = this.cabriService.nb2M);
this.cabriService.resU === 1
? (this.cabriService.resU_TTS = $localize`:tts:une`)
: (this.cabriService.resU_TTS = this.cabriService.resU);
this.cabriService.resD === 1
? (this.cabriService.resD_TTS = $localize`:tts:une`)
: (this.cabriService.resD_TTS = this.cabriService.resD);
this.cabriService.resC === 1
? (this.cabriService.resC_TTS = $localize`:tts:une`)
: (this.cabriService.resC_TTS = this.cabriService.resC);
this.cabriService.resM === 1
? (this.cabriService.resM_TTS = $localize`:tts:une`)
: (this.cabriService.resM_TTS = this.cabriService.resM);
return;
}
saveDom() {
super.saveDom();
this.cabriService.currentSavedDom = "calculmental";
}
restoreDom() {
super.restoreDom();
// if (canvasOnly) {
// clean all custom elements in #page-div
// window.document.querySelector("#page-div").removeChild(window.document.querySelector("#page-div #operationWrapper"));
// }
this.startRender();
}
checkActivityChange(): boolean {
return true;
const activityChange =
this.cabriService.currentSavedDom !== "calculmental" ||
this.cabriService.savedDomHoloMode !== this.cabriService.holoMode ||
this.cabriService.savedDomMirrorMode !== this.cabriService.mirrorMode;
// console.log("checkActivityChange = " + activityChange);
return activityChange;
}
private displayOperationWrapperImgMode(mode, value, result, tmp) {
if (tmp.length > 0) {
// first-number
// split operation into units (variables set in cabri-data.service):
if (this.exerciseOptionNumbers && this.exerciseOptionNumbers.length > 0) {
let nb1Value;
if (this.cabriService.currentExercice && Number(this.cabriService.currentExercice.operation) === 2) {
nb1Value = tmp[0];
} else {
nb1Value = this.exerciseOptionNumbers[0].img;
}
let str = "";
if (mode === "result" || !result) {
// '<span class="first-number first-number-letter">' + tmp[0] + "</span> ";
str += '<span class="first-number first-number-img">' + nb1Value + "</span> ";
str += "<span class='signe-operation signe-operation-wrapper'> " + tmp[1] + " </span> ";
str += this.exerciseOptionNumbers[1].img + " ";
str += '<span class="signe-egale signe-egale-wrapper">=</span> ';
str += '<span id="reponse-inline" class="number reponse response-wrapper">' + value + "</span>";
} else if (mode === "nb1") {
// texte a trous _nb1
str += '<span id="reponse-inline" class="number second-number reponse">' + value + "</span> ";
str += '<span class="signe-operation signe-operation-wrapper">' + tmp[1] + "</span> ";
str += nb1Value + " ";
str += '<span class="signe-egale signe-egale-wrapper">=</span> ';
str += this.getSpanNumber(result, "result");
} else if (mode === "nb2") {
// texte a trous _nb2
str += '<span class="first-number first-number-img">' + nb1Value + "</span> ";
str += '<span class="signe-operation signe-operation-wrapper">' + tmp[1] + "</span> ";
str += '<span id="reponse-inline" class="number second-number reponse response-wrapper">' + value + "</span> ";
str += '<span class="signe-egale signe-egale-wrapper">=</span> ';
str += this.getSpanNumber(result, "result");
} else if (mode === "full") {
str += '<span class="first-number first-number-img">' + nb1Value + "</span> ";
str += '<span class="signe-operation signe-operation-wrapper" >' + tmp[1] + "</span> ";
str += this.exerciseOptionNumbers[1].img + " ";
str += '<span class="signe-egale signe-egale-wrapper">=</span> ';
str += '<span id="reponse-inline" class="response-wrapper">' + value + "</span>";
} else if (mode === "+zero") {
str += '<span class="first-number first-number-img">' + nb1Value + "</span> ";
str += '<span class="signe-operation signe-operation-wrapper">' + tmp[1] + "</span>";
str += this.exerciseOptionNumbers[1].img;
str += '<span class="signe-egale signe-egale-wrapper">=</span>';
str += '<span id="reponse-inline" class="response-wrapper">' + value + "</span>";
}
str += "";
const element = window.document.querySelector(this.operationWrapperID + " div")
if(element){
element.innerHTML = str;
}
}
if (
this.cabriService.smallOperationHelp === true &&
String(this.cabriService.currentActivity.variables["v-cursor-op"]) === "1" &&
mode === "result"
) {
this.hilightCDU();
} else if (
this.cabriService.smallOperationHelp === false &&
String(this.cabriService.currentActivity.variables["v-cursor-op"]) === "1" &&
mode === "result"
) {
this.unhilightCDU();
}
}
}
hilightCDU(){
this.cduHilighted = true;
this.page.cd.detectChanges();
}
unhilightCDU(){
this.cduHilighted = false;
this.page.cd.detectChanges();
}
private async displayOperationWrapperDefaultMode(mode, value, result, tmp) {
// security to hide Constellations and Img operation wrapper if exists
const operationWrapperImgAndConstellations2 = document.querySelectorAll("[data-cloned]");
operationWrapperImgAndConstellations2.forEach(element => {
element.setAttribute("hidden", "true");
});
// console.error(mode, value, result, tmp);
if (tmp.length > 0) {
// split operation into units (variables set in cabri-data.service):
let operationResult = "";
let cssParagraph = "";
if (this.paramDisplayMode) {
cssParagraph = "letters";
}
cssParagraph += " mode-" + mode;
let str = "<p class='" + cssParagraph + "'>";
// console.error(mode, result);
let valueDecimale = String(value);
if (valueDecimale !== "...") {
valueDecimale = valueDecimale.replace(".",",");
value = valueDecimale;
}
if (mode === "result" || !result) {
if (this.paramDisplayMode) {
if (this.paramDisplayMode.value === "letters") {
tmp[0] = AppUtils.numberToLetter(tmp[0], this.globalService.locale);
tmp[2] = AppUtils.numberToLetter(tmp[2], this.globalService.locale);
str += '<span class="first-number first-number-letter">' + tmp[0] + "</span> ";
str += '<span class="signe-operation">' + tmp[1] + "</span> ";
str += '<span class="second-number second-number-letter">' + tmp[2] + "</span> ";
str += '<span class="signe-egale">=</span> ';
str += '<span id="reponse-inline" class="number reponse">' + value + "</span>";
}
} else {
str += this.getSpanNumber(tmp[0], "first-number") + " ";
str += '<span class="signe-operation">' + tmp[1] + "</span> ";
str += this.getSpanNumber(tmp[2], "second-number") + " ";
str += '<span class="signe-egale">=</span> ';
str += '<span id="reponse-inline" class="number reponse">' + value + "</span>";
}
} else if (mode === "nb1") {
if (this.paramDisplayMode) {
if (this.paramDisplayMode.value === "letters") {
tmp[2] = AppUtils.numberToLetter(tmp[2], this.globalService.locale);
operationResult = '<span class="result number">' + AppUtils.numberToLetter(result, this.globalService.locale);
+"</span>";
} else {
operationResult = this.getSpanNumber(result, "result");
}
} else {
operationResult = this.getSpanNumber(result, "result");
}
// texte a trous _nb1
str += '<span id="reponse-inline" class="number second-number reponse">' + value + "</span> ";
str += '<span class="signe-operation">' + tmp[1] + "</span> ";
str += this.getSpanNumber(tmp[2], "first-number") + " ";
str += '<span class="signe-egale">=</span> ';
str += operationResult;
} else if (mode === "nb2") {
if (this.paramDisplayMode) {
if (this.paramDisplayMode.value === "letters") {
tmp[0] = AppUtils.numberToLetter(tmp[0], this.globalService.locale);
operationResult = '<span class="first-number number">' + AppUtils.numberToLetter(result, this.globalService.locale);
+"</span> ";
} else {
operationResult = this.getSpanNumber(result, "result");
}
} else {
operationResult = this.getSpanNumber(result, "result");
}
// texte a trous _nb2
str += this.getSpanNumber(tmp[0], "first-number") + " ";
str += '<span class="signe-operation">' + tmp[1] + "</span> ";
str += '<span id="reponse-inline" class="number second-number reponse">' + value + "</span> ";
str += '<span class="signe-egale">=</span> ';
str += operationResult;
} else if (mode === "full") {
str += this.getSpanNumber(tmp[0], "first-number") + " ";
str += '<span class="signe-operation">' + tmp[1] + "</span> ";
str += this.getSpanNumber(tmp[2], "second-number") + " ";
str += '<span class="signe-egale">=</span> ';
str += value;
} else if (mode === "+zero") {
if (this.paramDisplayMode) {
if (this.paramDisplayMode.value === "letters") {
tmp[0] = AppUtils.numberToLetter(tmp[0], this.globalService.locale);
tmp[2] = AppUtils.numberToLetter(tmp[2], this.globalService.locale);
str += '<span class="first-number">' + tmp[0] + "</span>";
str += '<span class="signe-operation">' + tmp[1] + "</span>";
str += '<span class="second-number">' + tmp[2] + "</span>";
str += '<span class="signe-egale">=</span>';
str += '<span id="reponse-inline" class="number reponse">' + value + "</span>";
if (this.cabriService.participantAnswer) {
str += '<h2 class="participantAnswer">'+$localize `Ta réponse`+' : ' + this.cabriService.participantAnswer + "</h2>";
}
}
} else {
str += this.getSpanNumber(tmp[0], "first-number");
str += '<span class="signe-operation">' + tmp[1] + "</span>";
str += this.getSpanNumber(tmp[2], "second-number");
str += '<span class="signe-egale">=</span>';
str += '<span id="reponse-inline" class="number reponse">' + value + "</span>";
}
}
str += "</p>";
if (window.document.querySelector(this.operationWrapperID + "[data-original] div")) {
window.document.querySelector(this.operationWrapperID + "[data-original] div").innerHTML = str;
} else if (window.document.querySelector(this.operationWrapperID + " div")) {
window.document.querySelector(this.operationWrapperID + " div").innerHTML = str;
}
if (this.paramDisplayMode?.value === "letters") {
if (this.mode === "+zero" || this.mode === "result" || !result) {
let fontSize;
if (this.mode === "+zero") {
this.page.getMaxFontSize(result);
if (this.page.maxFontSize.includes("px")) {
fontSize = this.page.maxFontSize.replace("px", "");
} else {
fontSize = this.page.maxFontSize;
}
} else if (this.mode === "result" || !result) {
fontSize = Math.round((window.innerHeight * 4) / 100 + (window.innerWidth * 1) / 100);
}
this.setMaxFontSize(fontSize);
}
}
if (
this.cabriService.smallOperationHelp === true &&
String(this.cabriService.currentActivity.variables["v-cursor-op"]) === "1" &&
mode === "result"
) {
this.hilightCDU();
} else if (
this.cabriService.smallOperationHelp === false &&
String(this.cabriService.currentActivity.variables["v-cursor-op"]) === "1" &&
mode === "result"
) {
this.unhilightCDU();
}
}
}
private displayOperationWrapperCollectionMode(mode, value, tmp) {
if (tmp.length > 0) {
if (value === "?") {
value = "...";
}
let str = "";
str += `<span id="reponse-inline" class="number reponse constellation-reponse">${value}</span>`;
const leftPosition = document.querySelector(".leftPosition") as HTMLElement;
const rightPosition = document.querySelector(".rightPosition") as HTMLElement;
const responseContainer = document.querySelector(".response-wrapper") as HTMLElement;
let nb1ValueHTML;
if (this.cabriService.currentExercice && Number(this.cabriService.currentExercice.operation) === 2) {
nb1ValueHTML = "<span class='first-number first-number-constellation'>" + tmp[0] + "</span> ";
} else {
nb1ValueHTML = this.collectionsImgs.firstNumber[this.collectionsImgs.firstNumber.length - 1];
}
if (leftPosition) {
leftPosition.innerHTML = nb1ValueHTML;
}
if (rightPosition) {
rightPosition.innerHTML = this.collectionsImgs.secondNumber[this.collectionsImgs.secondNumber.length - 1];
}
if (responseContainer) {
if (str !== "undefined") {
responseContainer.innerHTML = str;
}
}
if (
this.cabriService.smallOperationHelp === true &&
String(this.cabriService.currentActivity.variables["v-cursor-op"]) === "1" &&
mode === "result"
) {
this.hilightCDU();
} else if (
this.cabriService.smallOperationHelp === false &&
String(this.cabriService.currentActivity.variables["v-cursor-op"]) === "1" &&
mode === "result"
) {
this.unhilightCDU();
}
}
}
hackHelpImageRendering(security = 0) {
if (window.store.getters.cabri.SceneUpdate.CabriObjects) {
// tslint:disable-next-line:forin
for (const m in window.store.getters.cabri.SceneUpdate.CabriObjects) {
if (
window.store.getters.cabri.SceneUpdate.CabriObjects.hasOwnProperty(m) &&
window.store.getters.cabri.SceneUpdate.CabriObjects[m] &&
window.store.getters.cabri.SceneUpdate.CabriObjects[m].type === "media" &&
window.store.getters.cabri.SceneUpdate.CabriObjects[m].media
) {
if (
window.store.getters.cabri.SceneUpdate.CabriObjects[m].id !== 51735 &&
window.store.getters.cabri.SceneUpdate.CabriObjects[m].id !== 51732
) {
// console.error(window.store.getters.cabri.Scene.meshes[m]);
window.store.getters.cabri.SceneUpdate.CabriObjects[m].media.renderingGroupId = 2;
} else if (
window.store.getters.cabri.SceneUpdate.CabriObjects[m].id === 51735 ||
window.store.getters.cabri.SceneUpdate.CabriObjects[m].id === 51732
) {
window.store.getters.cabri.SceneUpdate.CabriObjects[m].media.renderingGroupId = 1;
}
}
}
if (security < 20) {
// rerun after 2 seconds just to be sure
setTimeout(() => {
this.hackHelpImageRendering(security++);
}, 500);
}
}
}
/**
* Cabri help elements rescale attempt
*/
rescaleMeshes(): Promise<void> {
return new Promise((resolve, reject) => {
window.store.getters.cabri.Scene.meshes.forEach(m => {
// m.doNotSyncBoundingInfo = true;
// m.freezeWorldMatrix();
// m.convertToUnIndexedMesh();
// if (m.id === "background") {
// // background width proportion = 4096/3072 = 1.333333:
// m.scaling.x = 1.33;
// m.scaling.z = 1.33;
// // m.scaling.z = 1;
// console.log("cabri background resized");
// }
if (m.name.includes("media")) {
// background width proportion = 4096/3072 = 1.333333:
// m.scaling.x = 2;
console.log("m.scaling.z = " + m.scaling.z);
m.scaling.z = m.scaling.z + 0.1;
m.position.x = m.position.x + 0.2;
m.computeWorldMatrix();
// m.scaling.z = 1;
console.log("r rescaled = " + m.name);
}
});
this.page.cd.detectChanges();
// window.store.getters.cabri.Scene.render();
// this.startRender();
resolve();
});
}
/**
* Calculates OW position depending on context / device
*/
calculateOperationWrapperPosition(repeatQuestionWithKeyboard = false) {
if (this.page.didRestore || this.page.firstTime || this.page.activityRestarted) {
if (this.cabriService.inputMethod === "drawing") {
if (this.paramDisplayMode) {
if (this.paramDisplayMode && this.paramDisplayMode.value && this.paramDisplayMode.value === "collection") {
this.toggleOperationWrapperPosition("up");
} else {
this.toggleOperationWrapperPosition("down");
}
} else {
if (this.cabriService.mirrorMode) {
this.toggleOperationWrapperPosition("up");
} else {
this.toggleOperationWrapperPosition("down");
}
}
} else if (this.cabriService.inputMethod === "numpad") {
if (this.cabriService.mirrorMode) {
this.toggleOperationWrapperPosition("up");
} else {
this.toggleOperationWrapperPosition("down");
}
} else if (this.cabriService.inputMethod === "stt") {
if (this.cabriService.mirrorMode) {
this.toggleOperationWrapperPosition("up");
} else {
this.toggleOperationWrapperPosition("down");
}
}
} else {
if (this.cabriService.cabriInputSttStatus && !this.page.writeOperationOutEnabled) {
// STT
if (this.cabriService.mirrorMode) {
this.toggleOperationWrapperPosition("up");
} else {
if (repeatQuestionWithKeyboard && this.cabriService.currentExercice.resultMode !== "+zero") {
this.toggleOperationWrapperPosition("up");
} else {
this.toggleOperationWrapperPosition("down");
}
}
if (this.cabriService.collectionModeInCM && !this.cabriService.mirrorMode) {
this.toggleOperationWrapperPosition("down");
}
} else if (this.cabriService.cabriInputNumpadStatus ||
(this.page.writeOperationOutEnabled && !this.cabriService.cabriInputDrawStatus)) {
// NUMPAD
this.toggleOperationWrapperPosition("up");
} else if (this.cabriService.cabriInputDrawStatus) {
// DRAW
if (this.cabriService.mirrorMode) {
this.toggleOperationWrapperPosition("up");
} else {
if (this.paramDisplayMode && this.paramDisplayMode.value && this.paramDisplayMode.value === "collection") {
if (this.globalService.isTablet) {
this.toggleOperationWrapperPosition("down");
} else {
this.toggleOperationWrapperPosition("up");
}
} else {
this.toggleOperationWrapperPosition("down");
}
}
}
}
}
// Toggle Small Help In Cabri
// CABRI COMMANDS:
// this.store.getters.cabri.api.activateButton('btn-big-help');
// this.store.getters.cabri.api.setObjectValue('v-big-help-size', 3);
// this.store.getters.cabri.api.activateButton('btn-small-help');
// this.store.getters.cabri.api.setObjectValue('v-small-help-size', 0.5);
async toggleOperationSmallHelp(status: boolean = null, bypassCD = null): Promise<void> {
return new Promise(async (resolve, reject) => {
if (status === null) {
this.cabriService.smallOperationHelp = !this.cabriService.smallOperationHelp;
} else if (!bypassCD) {
this.cabriService.smallOperationHelp = status;
}
const spanUnite = window.document.querySelector(this.page.operationWrapperId + " > div > p > span.unite")
? this.page.operationWrapperId + " > div > p > span.unite"
: null;
const spanDizaine = window.document.querySelector(this.page.operationWrapperId + " > div > p > span.dizaine")
? this.page.operationWrapperId + " > div > p > span.dizaine"
: null;
if (this.cabriService.smallOperationHelp === true) {
// SHOW
this.page.activateButton("btn-small-help");
this.page.activateButton("btn-small-help");
console.log("this.smallHelpHeight final = " + this.smallHelpHeight);
this.page.setObjectValue("v-help-height", this.smallHelpHeight);
this.cabriService.smallOperationHelp = true;
await this.timeOut(10);
if (spanUnite) {
if (
window.document.querySelector(spanUnite + ".first-number") &&
window.document.querySelector(spanUnite + ".first-number.number")
) {
window.document.querySelector(spanUnite + ".first-number.number").style.color = "#14FF00";
}
if (
window.document.querySelector(spanUnite + ".second-number") &&
window.document.querySelector(spanUnite + ".second-number.number")
) {
window.document.querySelector(spanUnite + ".second-number.number").style.color = "#14FF00";
}
}
if (spanDizaine) {
if (
window.document.querySelector(spanDizaine + ".first-number") &&
window.document.querySelector(spanDizaine + ".first-number.number")
) {
window.document.querySelector(spanDizaine + ".first-number.number").style.color = "#00AFEC";
}
if (
window.document.querySelector(spanDizaine + ".second-number") &&
window.document.querySelector(spanDizaine + ".second-number.number")
) {
window.document.querySelector(spanDizaine + ".second-number.number").style.color = "#00AFEC";
}
}
if (this.cabriService.currentActivity.getParam("v-display-mode")) {
if (this.cabriService.currentActivity.getParam("v-display-mode").value !== "collection") {
this.page.activateButton("btn-show-help");
}
} else {
this.page.activateButton("btn-show-help");
}
this.startRender();
this.hackHelpImageRendering();
} else if (this.cabriService.smallOperationHelp === false) {
// HIDE
this.startRender();
this.cabriService.smallOperationHelp = false;
if (spanUnite) {
if (
window.document.querySelector(spanUnite + ".first-number") &&
window.document.querySelector(spanUnite + ".first-number.number")
) {
window.document.querySelector(spanUnite + ".first-number.number").style.color = "#00AFEC";
}
if (
window.document.querySelector(spanUnite + ".second-number") &&
window.document.querySelector(spanUnite + ".second-number.number")
) {
window.document.querySelector(spanUnite + ".second-number.number").style.color = "#00AFEC";
}
}
if (spanDizaine) {
if (
window.document.querySelector(spanDizaine + ".first-number") &&
window.document.querySelector(spanDizaine + ".first-number.number")
) {
window.document.querySelector(spanDizaine + ".first-number.number").style.color = "#00AFEC";
}
if (
window.document.querySelector(spanDizaine + ".second-number") &&
window.document.querySelector(spanDizaine + ".second-number.number")
) {
window.document.querySelector(spanDizaine + ".second-number.number").style.color = "#00AFEC";
}
}
this.page.activateButton("btn-hide-help");
}
if (!bypassCD) {
this.page.detectChanges();
}
await this.timeOut(10);
resolve();
});
}
}