{
  "information": {
    "Title": "Arrange_Pupill_Math_Simulation",
    "Author": [
      "kangrui",
      "lookang",
      "storyboard by meiyoke"
    ],
    "AuthorLogo": [
      "",
      "",
      ""
    ],
    "Password": "unused",
    "Keywords": "",
    "Abstract": "",
    "Copyright": "",
    "Level": "",
    "Language": "",
    "Logo": [
      "./logo.png"
    ],
    "RunAlways": "true",
    "ModelTab": "",
    "ModelTabTitle": "",
    "ModelName": "",
    "FixedNavigationBar": "false",
    "CSSFile": "",
    "DetectedFiles": [
      "./logo.png"
    ],
    "AuxiliaryFiles": [
      "",
      "./lib/xapiwrapper.min.js"
    ],
    "HTMLHead": "<script src=\"./lib/xapiwrapper.min.js\"></script>\n\n<style>\n@keyframes blink {\n  50% {\n    opacity: 0;\n  }\n}\n\n.blinking {\n  animation: 1s step-start 0s infinite normal none running blink; \n}\n</style>\n",
    "SaveInXMLFormat": "false",
    "IncludeSource": "true",
    "IncludeLibrary": "true",
    "UglifyJS": "false",
    "PreviewFullModel": "false",
    "UseInterpreter": "true",
    "UseDeltaForODE": "false"
  },
  "description": {
    "pages": []
  },
  "model": {
    "variables": {
      "pages": [
        {
          "Name": "Var Table 1",
          "Active": "true",
          "Internal": "false",
          "Type": "undefined",
          "PageComment": "",
          "Variables": [
            {
              "Name": "scenarios",
              "Value": "{}",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pupils",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "selectedScenario",
              "Value": "\"Scenario A\"",
              "Type": "String",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "roomX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "roomY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pupilX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pupilY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "roomImage",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pupilImage",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "roomText",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "textX",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "textY",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "selectedPupil",
              "Value": "-1",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pastAttemptsByScenario",
              "Value": "{}",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "totalScore",
              "Value": "0",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            }
          ]
        },
        {
          "Name": "lookang",
          "Active": "true",
          "Internal": "false",
          "Type": "VARIABLE_EDITOR",
          "PageComment": "",
          "Variables": [
            {
              "Name": "t",
              "Value": "0",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "dt",
              "Value": "0.05",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "currentPupilX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "currentPupilY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "targetPupilX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "targetPupilY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "speed",
              "Value": "1",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pupilText",
              "Value": "[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pupilsReachedTarget",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            }
          ]
        }
      ]
    },
    "initialization": {
      "pages": [
        {
          "Name": "scenarios",
          "Active": "true",
          "Internal": "false",
          "Type": "undefined",
          "Comment": "",
          "Code": "scenarios  = {\n    \"Scenario A\": {\n        scenario: \"There are 18 pupils and there are 5 rooms. Each room cannot take more than 4 pupils. How should I arrange them?\",\n        pupils: 18,\n        rooms: [\n          {\n            room: \"Music Room\",\n            image: \"Music-Room.png\",\n            max: 4,\n            min: 1,\n          },\n          {\n            room: \"Classroom\",\n            image: \"Class-Room.png\",\n            max: 4,\n            min: 1,\n          },\n          {\n            room: \"Computer Room\",\n            image: \"Computer-Room.png\",\n            max: 4,\n            min: 1,\n          },\n          {\n            room: \"Art Room\",\n            image: \"Art-Room.png\",\n            max: 4,\n            min: 1,\n          },\n          {\n            room: \"Math Room\",\n            image: \"Math-Room.png\",\n            max: 4,\n            min: 1,\n          },\n        ],\n    },\n     \"Scenario B\": {\n        scenario: \"There are 16 pupils and there are 4 rooms. Each room cannot take more than 4 pupils. How should I arrange them?\",\n        pupils: 16,\n        rooms: [\n          {\n            room: \"Music Room\",\n            image: \"Music-Room.png\",\n            max: 4,\n            min: 1,\n          },\n          {\n            room: \"Classroom\",\n            image: \"Class-Room.png\",\n            max: 4,\n            min: 1,\n          },\n          {\n            room: \"Computer Room\",\n            image: \"Computer-Room.png\",\n            max: 4,\n            min: 1,\n          },\n          {\n            room: \"Art Room\",\n            image: \"Math-Room.png\",\n            max: 4,\n            min: 1,\n          },\n        ],\n    }\n}"
        },
        {
          "Name": "pupils",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "for (let i = 0; i < scenarios[selectedScenario].pupils; i++) {\npupilText[i]= i+1;\n// [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]\n   \n    \n}\n\n\n\npupils = [\n    {\n        image: \"Chinese-Female.png\",\n    },\n    {\n        image: \"Chinese-Male.png\",\n    },\n    {\n        image: \"Eurasian-Female.png\",\n    },\n    {\n        image: \"Eurasian-Male.png\",\n    },\n    {\n        image: \"Indian-Female.png\",\n    },\n    {\n        image: \"Indian-Male.png\",\n    },\n    {\n        image: \"Malay-Female.png\",\n    },\n    {\n        image: \"Malay-Male.png\",\n    },\n    {\n        image: \"Chinese-Female.png\",\n    },\n    {\n        image: \"Chinese-Male.png\",\n    },\n    {\n        image: \"Eurasian-Female.png\",\n    },\n    {\n        image: \"Eurasian-Male.png\",\n    },\n    {\n        image: \"Indian-Female.png\",\n    },\n    {\n        image: \"Indian-Male.png\",\n    },\n    {\n        image: \"Malay-Female.png\",\n    },\n    {\n        image: \"Malay-Male.png\",\n    },\n        {\n        image: \"Chinese-Female.png\",\n    },\n    {\n        image: \"Chinese-Male.png\",\n    },\n]"
        },
        {
          "Name": "fontGlow",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "// fontGlow\n//enableGlow(\"pupiltextSet2D\")\nwindow.setTimeout(() => {\n  enableBlinking(\"pupiltextSet2D\");\n}, 100);\n\n\nwindow.setTimeout(() => {\n  disableBlinking(\"pupiltextSet2D\");\n}, 3000);\n"
        },
        {
          "Name": "init",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "initRooms();\ninitPupils();\ninitpupilsReachedTarget();"
        }
      ]
    },
    "evolution": {
      "information": {
        "FPS": "20",
        "SPD": "1",
        "RealTimeVariable": "",
        "Autoplay": "false"
      },
      "pages": [
        {
          "Name": "Evol Page 1",
          "Active": "true",
          "Internal": "false",
          "Type": "ODE_EDITOR",
          "Comment": "",
          "IndependentVariable": "t",
          "Increment": "dt",
          "Equations": [
            {
              "state": "pupilX[i]",
              "rate": "pupilsReachedTarget[i]?0:(targetPupilX[i] -currentPupilX[i])*speed"
            },
            {
              "state": "pupilY[i]",
              "rate": "pupilsReachedTarget[i]?0:(targetPupilY[i] -currentPupilY[i])*speed"
            },
            {
              "state": "",
              "rate": ""
            }
          ],
          "Method": "RungeKutta",
          "AbsoluteTolerance": "",
          "PreliminaryCode": {
            "Code": "// Preliminary code for ODE : Evol Page 1",
            "Comment": ""
          },
          "EventMaximumStep": "",
          "Events": {
            "pages": []
          },
          "ZenoEffect": {
            "Code": "",
            "Comment": "",
            "StopAfterEffect": "true"
          },
          "AccelerationIndependentOfVelocity": "false",
          "ForceSynchronization": "false",
          "UseBestInterpolation": "false",
          "EstimateFirstStep": "false",
          "MemoryLength": "",
          "InternalStep": "",
          "MaximumStep": "",
          "MaximumNumberOfSteps": "10000",
          "RelativeTolerance": "",
          "Tolerance": "",
          "DelayList": "",
          "DelayMaximum": "",
          "DelayAddDiscont": "",
          "DelayInitialCondition": {
            "Comment": "",
            "Code": ""
          },
          "DirectIncidenceMatrix": "",
          "Discontinuities": {
            "pages": []
          },
          "ErrorHandling": {
            "pages": []
          }
        }
      ]
    },
    "fixed_relations": {
      "pages": [
        {
          "Name": "FixRel Page 1",
          "Active": "true",
          "Internal": "false",
          "Type": "undefined",
          "Comment": "",
          "Code": "// Initialize pupilsReachedTarget if it doesn't exist\nif (typeof pupilsReachedTarget === \"undefined\" || pupilsReachedTarget.length !== currentPupilX.length) {\n    pupilsReachedTarget = Array(currentPupilX.length).fill(false); // Initialize tracking array\n}\n\n// Variable to check if all pupils are at their targets\nlet allAtTarget = true;\n\n// Threshold for determining if a pupil has reached its target\nconst threshold = 0.001;\n\n// Check each pupil\nfor (let i = 0; i < currentPupilX.length; i++) {\n    if (!pupilsReachedTarget[i]) { // Only check pupils still in motion\n        // Calculate the distance to the target\n        let distance = Math.sqrt(\n            Math.pow(pupilX[i] - targetPupilX[i], 2) + \n            Math.pow(pupilY[i] - targetPupilY[i], 2)\n        );\n\n        if (distance <= threshold) {\n            pupilsReachedTarget[i] = true; // Mark this pupil as having reached its target\n        } else {\n            allAtTarget = false; // At least one pupil is not at the target\n        }\n    }\n}\n\n// Automatically pause the ODE if all pupils are at their targets\nif (allAtTarget) {\n    _pause(); // Pause the ODE solver\n}\n\nconsole.log(\"Pupils reached targets:\", pupilsReachedTarget);\nconsole.log(\"All at target:\", allAtTarget);\n"
        }
      ]
    },
    "custom": {
      "pages": [
        {
          "Name": "initFunctions",
          "Active": "true",
          "Internal": "false",
          "Type": "undefined",
          "Comment": "",
          "Code": "function initRooms() {\n    scenarios[selectedScenario].rooms.forEach(room => room.count = 0);\n    roomX = [];\n    roomY = [];\n    roomImage = [];\n    textX = [];\n    textY = [];\n    roomText = [];\n\n    let numOfRooms = scenarios[selectedScenario].rooms.length;\n    let currentY = 0.85;  \n    let roomIndex = 0;\n\n    while (roomIndex < numOfRooms) {\n        let roomsInRow = Math.min(3, numOfRooms - roomIndex);\n        let xCoords;\n\n        if (roomsInRow === 1) {\n            xCoords = [0.5];  \n        } else if (roomsInRow === 2) {\n            xCoords = [0.3, 0.7]; \n        } else {\n            xCoords = [0.15, 0.5, 0.85]; \n        }\n\n        for (let i = 0; i < roomsInRow; i++) {\n            roomX.push(xCoords[i]);\n            roomY.push(currentY);\n            scenarios[selectedScenario].rooms[roomIndex].x = xCoords[i];\n            scenarios[selectedScenario].rooms[roomIndex].y = currentY;\n            roomImage.push(\"./rooms/\" + scenarios[selectedScenario].rooms[roomIndex].image);  \n            textX.push(xCoords[i]);\n            textY.push(currentY - 0.15);\n            roomText.push(scenarios[selectedScenario].rooms[roomIndex].room);\n            roomIndex++;\n        }\n\n        currentY -= 0.3;\n    }\n}\n\nfunction initPupils() {\n    pupils.forEach(pupil => pupil.room = '');\n    pupilX = [];\n    pupilY = [];\n    pupilImage = [];\n\n    let numOfPupils = scenarios[selectedScenario].pupils;\n    //console.log(numOfPupils)\n    let currentY = 0.25;\n    let pupilIndex = 0;\n\n\n   while (pupilIndex < numOfPupils) {\n        let pupilsInRow = Math.min(9, numOfPupils - pupilIndex);  \n        let xCoords = [];\n    \n        for (let i = 0; i < pupilsInRow; i++) {\n            xCoords.push((i + 1) / 10);  \n        }\n    \n        for (let i = 0; i < pupilsInRow; i++) {\n            pupilX.push(xCoords[i]);\n            pupilY.push(currentY);\n            pupils[pupilIndex].x = xCoords[i];\n            pupils[pupilIndex].y = currentY;\n            pupilImage.push(\"./pupils/\" + pupils[pupilIndex].image);  \n            pupilIndex++;\n        }\n    \n        currentY -= 0.15; \n    }\n}\n\nfunction initpupilsReachedTarget (){\n    for (let i = 0; i <scenarios[selectedScenario].pupils; i++) {\n    pupilsReachedTarget[i] = false\n    }\n    \n}"
        },
        {
          "Name": "onRelease",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function onRelease(x, y, index) {\n    let rooms = scenarios[selectedScenario].rooms;\n    let currentRoomName = pupils[index].room;\n\n    if (currentRoomName) {\n        for (let i = 0; i < rooms.length; i++) {\n            let room = rooms[i];\n            let roomX = room.x;\n            let roomY = room.y;\n            let halfSize = 0.15;\n\n            if (room.room === currentRoomName && x >= roomX - halfSize && x <= roomX + halfSize && y >= roomY - halfSize && y <= roomY + halfSize) {\n                return;\n            }\n        }\n\n        for (let i = 0; i < rooms.length; i++) {\n            if (rooms[i].room === currentRoomName && rooms[i].hasOwnProperty('count')) {\n                rooms[i].count -= 1;\n                pupils[index].room = '';\n                break;\n            }\n        }\n    }\n\n    for (let i = 0; i < rooms.length; i++) {\n        let room = rooms[i];\n        let roomX = room.x;\n        let roomY = room.y;\n        let halfSize = 0.15;\n\n        if (x >= roomX - halfSize && x <= roomX + halfSize && y >= roomY - halfSize && y <= roomY + halfSize) {\n            if (!room.hasOwnProperty('count')) {\n                room.count = 0;\n            }\n\n            pupils[index].room = room.room;\n            room.count += 1;\n        }\n    }\n}\n"
        },
        {
          "Name": "check",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function check() {\n    let checkCount = 0;\n    let currentAttempt = [];\n\n    scenarios[selectedScenario].rooms.forEach(room => {\n        checkCount += room.count;\n        currentAttempt.push(`${room.room}: ${room.count} pupils`);\n    });\n\n    if (checkCount != scenarios[selectedScenario].pupils) {\n        alert(\"Incorrect. Try Again!\");\n        return;\n    }\n\n    for (let room of scenarios[selectedScenario].rooms) {\n        if (room.count < room.min || room.count > room.max) {\n            alert(\"Incorrect. Try Again!\");\n            return;\n        }\n    }\n\n    if (!pastAttemptsByScenario[selectedScenario]) {\n        pastAttemptsByScenario[selectedScenario] = [];\n    }\n\n    alert(\"Congrats! You did it, now try a different approach or a different scenario!\")\n    pastAttemptsByScenario[selectedScenario].push(currentAttempt);\n    displayPastAnswers();\n    reset();\n    sendState(1); //xAPI\n}\n\nfunction displayPastAnswers() {\n    const pastAnswersDiv = document.getElementById(\"pastAttempts\");\n    pastAnswersDiv.innerHTML = \"\";\n\n    for (let scenario in pastAttemptsByScenario) {\n        let scenarioDiv = document.createElement(\"div\");\n        scenarioDiv.innerHTML = `<h3 style=\"margin: 0; font-size: 18px; font-weight: bold;\">${scenario}:</h3>`;\n\n        let attemptsContainer = document.createElement(\"div\");\n        attemptsContainer.style.display = \"flex\";\n        attemptsContainer.style.flexWrap = \"wrap\";\n\n        pastAttemptsByScenario[scenario].forEach((attempt, index) => {\n            let attemptDiv = document.createElement(\"div\");\n            attemptDiv.innerHTML = `<strong style=\"font-size: 16px;\">Attempt ${index + 1}:</strong><br>${attempt.join('<br>')}`;\n            attemptDiv.style.padding = \"10px\";\n            attemptDiv.style.width = \"200px\";\n            attemptDiv.style.textAlign = \"left\";\n            attemptsContainer.appendChild(attemptDiv);\n        });\n\n        scenarioDiv.appendChild(attemptsContainer);\n        pastAnswersDiv.appendChild(scenarioDiv);\n    }\n}\n"
        },
        {
          "Name": "reset",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function reset() {\n    initRooms();\n    initPupils();\n}"
        },
        {
          "Name": "xApi",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function getParameters() {\n  var urlParams = new URLSearchParams(window.location.search);\n  var endpoint = urlParams.get('endpoint') + \"/\";\n  var auth = urlParams.get('auth');\n\n  var actorObject = JSON.parse(urlParams.get('actor')); // this needs to be JSON decoded\n  var actor = actorObject ? actorObject.id : null;\n  var activity_id = urlParams.get('activityId'); // for example, http://adlnet.gov/expapi/activities/question/{question-id}\n\n  // document.querySelector(\"#cookieId\").innerText = \"Cookie: \" + auth;\n //  document.querySelector(\"#questionId\").innerText = \"QuestionId: \" + activity_id;\n // document.querySelector(\"#userId\").innerText = \"UserId: \" + actor ;\n\n  var conf = {\n    \"endpoint\" : endpoint,\n    \"auth\": `Basic ${auth}`\n    ,\"withCredentials\": true\n  };\n\n  ADL.XAPIWrapper.changeConfig(conf);\n\n  return {\n    actor,\n    activity_id\n  }\n}\n\nfunction sendState(answer){\n  if (totalScore === 'randomText'){\n    totalScore = 0;\n  }\n  if(answer === 'randomText'){\n    totalScore = 'randomText';\n  } else {\n    totalScore = totalScore + answer;\n  }\n\n  try {\n    var parameters = getParameters();\n    var stateval = {\n      score: totalScore\n    };\n    ADL.XAPIWrapper.sendState(\"http://adlnet.gov/expapi/activities/question/\" + parameters.activity_id,\n        {\"mbox\":\"mailto:tom@example.com\"},\n        parameters.actor, null, stateval);\n  //   document.querySelector(\"#result\").innerText = \"Score Submitted: \" + totalScore;\n  } catch (err) {\n    console.error(\"An error has occurred!\", err);\n  //   document.querySelector(\"#result\").innerText = \"Error has occurred: \" + err;\n  }\n}\n"
        },
        {
          "Name": "lookangSolutionFinder",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function findSolution() {\n    let rooms = scenarios[selectedScenario].rooms;\n    let totalPupils = scenarios[selectedScenario].pupils;\n    let solution = Array(rooms.length).fill(0); // Array to hold the number of pupils in each room\n\n    let remainingPupils = totalPupils;\n\n    // First, satisfy the minimum requirement for each room\n    for (let i = 0; i < rooms.length; i++) {\n        solution[i] = rooms[i].min;\n        remainingPupils -= rooms[i].min;\n    }\n\n    // Distribute remaining pupils across rooms without exceeding the max\n    for (let i = 0; i < rooms.length && remainingPupils > 0; i++) {\n        let availableSpace = rooms[i].max - solution[i];\n        let toAdd = Math.min(remainingPupils, availableSpace);\n        solution[i] += toAdd;\n        remainingPupils -= toAdd;\n    }\n\n    // If we couldn't distribute all pupils, return no solution\n    if (remainingPupils > 0) {\n        alert(\"No valid solution found with the given constraints.\");\n        return;\n    }\n\n    // Apply the solution to the rooms\n    for (let i = 0; i < rooms.length; i++) {\n        rooms[i].count = solution[i];\n    }\n\n    // Assign pupils to rooms and move the shapes\n    assignPupilsToRooms(solution);\n    alert(\"Solution found and applied!\");\n}\n\nfunction assignPupilsToRooms(solution) {\n    for (let i = 0; i < scenarios[selectedScenario].pupils;i++){\n        currentPupilX[i] = pupilX[i];\n        currentPupilY[i] = pupilY[i];\n    }\n    \n    \n    \n    let pupilIndex = 0;\n\n    for (let i = 0; i < solution.length; i++) {\n        let count = solution[i];\n        let room = scenarios[selectedScenario].rooms[i];\n        console.log(solution)\n        for (let j = 0; j < count; j++) {\n            // Update pupil's assigned room\n            pupils[pupilIndex].room = room.room;\n            \n            // Update pupil position to match the room's coordinates\n            //pupilX[pupilIndex] = room.x + (j % 2) * 0.1 - 0.05; // Offset for neat alignment\n            //pupilY[pupilIndex] = room.y - Math.floor(j / 2) * 0.1; // Stack vertically\n            targetPupilX[pupilIndex] = room.x + (j % 2) * 0.1 - 0.05; // Set X target\n            targetPupilY[pupilIndex] = room.y - Math.floor(j / 2) * 0.1; // Set Y target\n            \n\n            // Increment pupilIndex\n            pupilIndex++;\n        }\n    }\n\n    // Trigger visual updates for pupilSets\n    //_view.pupilSets.setNumberOfElements(pupilIndex);\n   // _view.pupilSets.setPosition(pupilX, pupilY);\n}\n"
        },
        {
          "Name": "solutionFinder",
          "Active": "false",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function findSolution() {\n    let rooms = scenarios[selectedScenario].rooms;\n    let totalPupils = scenarios[selectedScenario].pupils;\n    let solution = Array(rooms.length).fill(0);\n\n    let remainingPupils = totalPupils;\n\n    // Ensure minimum requirement\n    for (let i = 0; i < rooms.length; i++) {\n        solution[i] = rooms[i].min;\n        remainingPupils -= rooms[i].min;\n    }\n\n    // Distribute remaining pupils\n    for (let i = 0; i < rooms.length && remainingPupils > 0; i++) {\n        let availableSpace = rooms[i].max - solution[i];\n        let toAdd = Math.min(remainingPupils, availableSpace);\n        solution[i] += toAdd;\n        remainingPupils -= toAdd;\n    }\n\n    if (remainingPupils > 0) {\n        alert(\"No valid solution found with the given constraints.\");\n        return;\n    }\n\n    // Set target positions\n    let pupilIndex = 0;\n    for (let i = 0; i < solution.length; i++) {\n        let room = rooms[i];\n        for (let j = 0; j < solution[i]; j++) {\n            targetPupilX[pupilIndex] = room.x + (j % 2) * 0.1 - 0.05; // Set X target\n            targetPupilY[pupilIndex] = room.y - Math.floor(j / 2) * 0.1; // Set Y target\n            pupilIndex++;\n        }\n    }\n\n    // Initialize current positions\n    for (let i = 0; i < totalPupils; i++) {\n        currentPupilX[i] = pupilX[i];\n        currentPupilY[i] = pupilY[i];\n    }\n\n    // Start the ODE solver\n    _play(); // Starts ODE to animate motion\n}\n"
        },
        {
          "Name": "fontGlow",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "\nfunction enableBlinking (elementId) {\n  var element = document.getElementById(elementId);\n  element.setAttribute(\"class\", \"blinking\");\n}\nfunction disableBlinking (elementId) {\n  var element = document.getElementById(elementId);\n  element.removeAttribute(\"class\");\n}\n\n"
        }
      ]
    },
    "elements": {
      "list": []
    }
  },
  "view": {
    "Tree": [
      {
        "Name": "wrapper",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [],
        "Children": [
          {
            "Name": "firstRow",
            "Type": "Panel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "CSS",
                "value": "\"{\nmargin-bottom: 10px\n}\""
              }
            ],
            "Children": [
              {
                "Name": "currentScenario",
                "Type": "Label",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "scenarios[selectedScenario].scenario"
                  }
                ]
              }
            ]
          },
          {
            "Name": "secondRow",
            "Type": "Panel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "CSS",
                "value": "\"{ margin-bottom: 10px }\""
              }
            ],
            "Children": [
              {
                "Name": "selectScenario",
                "Type": "ComboBox",
                "Properties": [
                  {
                    "name": "Options",
                    "value": "[\"Scenario A\", \"Scenario B\"]"
                  },
                  {
                    "name": "OnChange",
                    "value": "var opts = _view.selectScenario.getProperty(\"SelectedOptions\");  \nselectedScenario = (opts.length > 0)? opts[0]:\"\";\ninitRooms();\ninitPupils();\ninitpupilsReachedTarget ();"
                  },
                  {
                    "name": "CSS",
                    "value": "\"{ margin-right: 10px }\""
                  }
                ]
              },
              {
                "Name": "check",
                "Type": "Button",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"Check\""
                  },
                  {
                    "name": "OnPress",
                    "value": "check()"
                  },
                  {
                    "name": "Width",
                    "value": "\"20%\""
                  }
                ]
              },
              {
                "Name": "solve_2",
                "Type": "Button",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"Need Help?\""
                  },
                  {
                    "name": "OnPress",
                    "value": "findSolution()\n_play()"
                  },
                  {
                    "name": "Width",
                    "value": "\"20%\""
                  }
                ]
              }
            ]
          },
          {
            "Name": "plottingPanel",
            "Type": "PlottingPanel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "Width",
                "value": "\"100%\""
              },
              {
                "name": "Height",
                "value": "\"90vh\""
              },
              {
                "name": "Enabled",
                "value": "true"
              },
              {
                "name": "Gutters",
                "value": "[0,0,0,0]"
              },
              {
                "name": "AutoScaleY",
                "value": "false"
              },
              {
                "name": "AutoScaleX",
                "value": "false"
              },
              {
                "name": "MaximumX",
                "value": "1"
              },
              {
                "name": "MinimumX",
                "value": "0"
              },
              {
                "name": "MinimumY",
                "value": "0"
              },
              {
                "name": "MaximumY",
                "value": "1"
              },
              {
                "name": "TLMessage",
                "value": "\"t = \"+t.toFixed(2)"
              }
            ],
            "Children": [
              {
                "Name": "roomSets",
                "Type": "ImageSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].rooms.length"
                  },
                  {
                    "name": "Sensitivity",
                    "value": "0"
                  },
                  {
                    "name": "SizeX",
                    "value": "0.3"
                  },
                  {
                    "name": "SizeY",
                    "value": "0.3"
                  },
                  {
                    "name": "X",
                    "value": "roomX"
                  },
                  {
                    "name": "Y",
                    "value": "roomY"
                  },
                  {
                    "name": "ImageUrl",
                    "value": "roomImage"
                  }
                ]
              },
              {
                "Name": "roomSetsCentre",
                "Type": "ShapeSet2D",
                "Properties": [
                  {
                    "name": "X",
                    "value": "roomX"
                  },
                  {
                    "name": "Y",
                    "value": "roomY"
                  },
                  {
                    "name": "SizeX",
                    "value": "0.3"
                  },
                  {
                    "name": "SizeY",
                    "value": "0.3"
                  },
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].rooms.length"
                  },
                  {
                    "name": "ShapeType",
                    "value": "\"RECTANGLE\""
                  },
                  {
                    "name": "FillColor",
                    "value": "\"rgba(200,200,200,0.1)\""
                  },
                  {
                    "name": "DrawLines",
                    "value": "false"
                  }
                ]
              },
              {
                "Name": "roomNameSets",
                "Type": "TextSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].rooms.length"
                  },
                  {
                    "name": "X",
                    "value": "textX"
                  },
                  {
                    "name": "Y",
                    "value": "textY"
                  },
                  {
                    "name": "Text",
                    "value": "roomText"
                  }
                ]
              },
              {
                "Name": "pupilSets",
                "Type": "ImageSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].pupils"
                  },
                  {
                    "name": "X",
                    "value": "pupilX"
                  },
                  {
                    "name": "Y",
                    "value": "pupilY"
                  },
                  {
                    "name": "SizeX",
                    "value": "0.1"
                  },
                  {
                    "name": "SizeY",
                    "value": "0.15"
                  },
                  {
                    "name": "EnabledPosition",
                    "value": "\"ENABLED_ANY\""
                  },
                  {
                    "name": "ImageUrl",
                    "value": "pupilImage"
                  },
                  {
                    "name": "ElementInteracted",
                    "value": "selectedPupil"
                  },
                  {
                    "name": "OnRelease",
                    "value": "onRelease(pupilX[selectedPupil], pupilY[selectedPupil],selectedPupil)"
                  }
                ]
              },
              {
                "Name": "pupilSetsCentre",
                "Type": "ShapeSet2D",
                "Properties": [
                  {
                    "name": "X",
                    "value": "pupilX"
                  },
                  {
                    "name": "Y",
                    "value": "pupilY"
                  },
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].pupils"
                  },
                  {
                    "name": "SizeX",
                    "value": "0.1"
                  },
                  {
                    "name": "SizeY",
                    "value": "0.15"
                  },
                  {
                    "name": "ShapeType",
                    "value": "\"RECTANGLE\""
                  },
                  {
                    "name": "FillColor",
                    "value": "\"rgba(0,0,0,0.01)\""
                  },
                  {
                    "name": "DrawLines",
                    "value": "false"
                  }
                ]
              },
              {
                "Name": "pupiltextSet2D",
                "Type": "TextSet2D",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "%pupilText%"
                  },
                  {
                    "name": "X",
                    "value": "pupilX"
                  },
                  {
                    "name": "Y",
                    "value": "pupilY"
                  },
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].pupils"
                  }
                ]
              },
              {
                "Name": "text1",
                "Type": "Text2D",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"text1\""
                  },
                  {
                    "name": "X",
                    "value": ".5"
                  },
                  {
                    "name": "Y",
                    "value": ".5"
                  },
                  {
                    "name": "Visibility",
                    "value": "false"
                  }
                ]
              }
            ]
          },
          {
            "Name": "pastAttempts",
            "Type": "Panel",
            "Properties": [
              {
                "name": "ClassName",
                "value": "\"pastAttempts\""
              },
              {
                "name": "CSS",
                "value": "\"{text-align: left}\""
              }
            ]
          }
        ]
      }
    ],
    "RootProperties": []
  },
  "metadata": {
    "APP": "WebEJS",
    "CreatedWith": "WebEJS : The web version of Easy JavaScript Simulations",
    "MoreInfo": "WebEJS 1.1",
    "version": "https://www.um.es/fem/wikis/webejs/"
  }
}