{
  "information": {
    "Title": "Math_Estimation_of_Area",
    "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>",
    "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": "selectedScenario",
              "Value": "\"Scenario A\"",
              "Type": "String",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "shapeX",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "shapeY",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "imagePiece",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "shapeIndex",
              "Value": "-1",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "pieces",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "selected",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "enabled",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "number",
              "Value": "[]",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "numberOfPieces",
              "Value": "0",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            }
          ]
        },
        {
          "Name": "xApi",
          "Active": "true",
          "Internal": "false",
          "Type": "VARIABLE_EDITOR",
          "PageComment": "",
          "Variables": [
            {
              "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": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            }
          ]
        }
      ]
    },
    "initialization": {
      "pages": [
        {
          "Name": "scenarios",
          "Active": "true",
          "Internal": "false",
          "Type": "undefined",
          "Comment": "",
          "Code": "/*\nIn Scenario A, the shape is described with the following properties:\n\nShape Type: Blue (indicating the color of the shape to visually differentiate it from other scenarios).\n\nScenario Description: The task for the user is to \"Estimate the area of this irregular shape.\"\n\nGrid Dimensions:\n\nThe grid spans an area defined by x = 3 and y = 2. This suggests the shape is placed on a grid system that might be divided into smaller units for visual estimation purposes.\nShape Construction (Pieces):\n\nThe pieces array provides a structural description of the connections between parts of the shape:\n{connected: [2]} indicates that the first piece is connected to the piece indexed at 2.\n{connected: -1} indicates isolated pieces with no connections.\n{connected: [0]} shows that this piece is connected to the piece indexed at 0.\n{connected: -1} repeats for other isolated segments.\nThis network of connections essentially forms the framework of the irregular shape.\nArea:\n\nThe estimated area of the shape is defined as 5. This is likely a measure in terms of the number of squares covered by the shape on the grid.\nHow the Description Translates to the Shape\nThe connections between pieces in the array define how different parts of the shape are related and potentially placed on the grid. These connections, when visualized, outline the full irregular shape.\nThe defined color, grid size, and connectivity ensure the representation is consistent with the intended scenario for estimation.\nThe visual output you shared aligns with this description, providing the user a way to estimate the area based on its appearance on a structured grid.\n*/\n\nscenarios = {\n    \"Scenario A\": {\n        shape: \"blue\",\n        scenario: \"Estimate the area of this irregular shape\",\n        x: 3,\n        y: 2,\n        pieces: [\n            {connected: [2]},\n            {connected: -1},\n            {connected: [0]},\n            {connected: -1},\n            {connected: -1},\n            {connected: -1}\n           \n        ],\n        area: 5,\n         offsetX: 0,\n            offsetY: 1\n    },\n    \"Scenario B\": {\n        shape: \"orange\",\n        scenario: \"Estimate the area of this irregular shape\",\n        x: 3,\n        y: 2,\n        pieces: [\n            {connected: [2, 3, 5]},\n            {connected: -1},\n            {connected: [0, 3, 5]},\n            {connected: [0, 2, 5]},\n            {connected: -1},\n            {connected: [0, 2, 3]},\n         \n        ],\n        area: 4,\n           offsetX: 0,\n            offsetY: 1\n    },\n    \"Scenario C\": {\n        shape: \"heart\",\n        scenario: \"Estimate the area of this heart\",\n        x: 4,\n        y: 3,\n        pieces: [\n            {connected: [8]},\n            {connected: -1},\n            {connected: -1},\n            {connected: [11]},\n            {connected: [9]},\n            {connected: -1},\n            {connected: -1},\n            {connected: [10]},\n            {connected: [0]},\n            {connected: [4]},\n            {connected: [7]},\n            {connected: [3]}\n          \n        ],\n        area: 8,\n          offsetX: 0,\n            offsetY: 0\n    },\n    \"Scenario D\": {\n    shape: \"star\",\n    scenario: \"Estimate the area of this star\",\n    x: 3,\n    y: 3,\n    pieces: [\n        {connected: [4]},\n        {connected: [3, 5]},\n        {connected: [4, 6]},\n        {connected: [1]},\n        {connected: [0, 2]},\n        {connected: [1]},\n        {connected: [2]}\n    ],\n    area: 6, // The area can be the number of squares the shape occupies\n    offsetX: 0, // Center alignment on x-axis\n    offsetY: 0  // Center alignment on y-axis\n}\n\n}"
        },
        {
          "Name": "init",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "initShape();"
        },
        {
          "Name": "lookang",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "// lookang\nif (_isMobile){\n  //do nothing\n  }\n  \n  else{\n    // copy this into the initialization\n// make the font bigger\n\n_view.plottingPanel.getMessageDecoration(\"TL\").getFont().setFontSize(\"2vw\");\n_view.plottingPanel.getMessageDecoration(\"TR\").getFont().setFontSize(\"1vw\");\n_view.plottingPanel.getMessageDecoration(\"BL\").getFont().setFontSize(\"1vw\");\n_view.plottingPanel.getMessageDecoration(\"BR\").getFont().setFontSize(\"1vw\");\n\n//_view.plottingPanel.getMessageDecoration(\"TL\").getStyle().setFillColor(\"red\");\n    }"
        }
      ]
    },
    "evolution": {
      "information": {
        "FPS": "20",
        "SPD": "1",
        "RealTimeVariable": "",
        "Autoplay": "true"
      },
      "pages": []
    },
    "fixed_relations": {
      "pages": []
    },
    "custom": {
      "pages": [
        {
          "Name": "initShape",
          "Active": "true",
          "Internal": "false",
          "Type": "undefined",
          "Comment": "",
          "Code": "function initShape() {\n    shapeX = [];\n    shapeY = [];\n    imagePiece = [];\n    pieces = [];\n    selected = [];\n    enabled = [];\n    number = [];\n    numberOfPieces = 0;\n    shapeIndex = -1;\n\n    let rows = scenarios[selectedScenario].y;\n    let columns = scenarios[selectedScenario].x;\n    let index = 1;\n\n    let graphWidth = 20;\n    let graphHeight = 20;\n\n    let availableX = [];\n    let availableY = [];\n    for (let i = 1; i < graphWidth; i += 2) {\n        availableX.push(i);\n    }\n    for (let i = graphHeight - 1; i > 1; i -= 2) {\n        availableY.push(i);\n    }\n\n   // let startXIndex = Math.floor((availableX.length - columns) / 2);\n   // let startYIndex = Math.floor((availableY.length - rows) / 2);\n   let startXIndex = Math.floor((availableX.length - columns + scenarios[selectedScenario].offsetX) / 2) ;\n    let startYIndex = Math.floor((availableY.length - rows) / 2) + scenarios[selectedScenario].offsetY;\n\n    /*\n    // Custom positioning for each scenario\n    if (selectedScenario === \"Scenario A\") {\n        startXIndex = Math.floor((availableX.length - columns) / 2)  ;\n        startYIndex = Math.floor((availableY.length - rows) / 2) +1; // Keep vertical position down with +\n    } else if (selectedScenario === \"Scenario B\") {\n        startXIndex = Math.floor((availableX.length - columns) / 2) ; \n        startYIndex = Math.floor((availableY.length - rows) / 2)+1;        // Keep vertical position down +\n    } else if (selectedScenario === \"Scenario C\") {\n        startXIndex = Math.floor((availableX.length - columns) / 2);\n        startYIndex = Math.floor((availableY.length - rows) / 2) ;   // Shift down for Scenario C\n    }\n    */\n\n    for (let row = 0; row < rows; row++) {\n        for (let col = 0; col < columns; col++) {\n            let x = availableX[startXIndex + col];\n            let y = availableY[startYIndex + row];\n\n            shapeX.push(x);\n            shapeY.push(y);\n            pieces.push(\"rgba(0,0,0,0)\");\n            selected.push(0);\n            enabled.push(\"ENABLED_NO_MOVE\");\n            number.push(\"\");\n            imagePiece.push(`./${scenarios[selectedScenario].shape}/${scenarios[selectedScenario].shape}-${index}.png`);\n            \n            index += 1;\n        }\n    }\n}\n"
        },
        {
          "Name": "onClick",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function onClick(shapeIndex) {\n    const selectedIndex = selected.findIndex(value => value === 1);\n    const isSelected = selected.includes(1);\n    const shapePiece = scenarios[selectedScenario].pieces[shapeIndex];\n\n    if (selectedIndex === shapeIndex) {\n        selected[shapeIndex] = 0;\n        console.log('1');\n        return;\n    }\n\n    if (!isSelected && shapePiece.connected === -1) {\n        numberOfPieces += 1;\n        pieces[shapeIndex] = \"rgba(40, 255, 0, 0.6)\";\n        enabled[shapeIndex] = \"ENABLED_NONE\";\n        number[shapeIndex] = numberOfPieces;\n        console.log('2');\n        return;\n    }\n\n    if (isSelected) {\n        selected.fill(0);\n\n        if (shapePiece.connected === -1) {\n            alert(\"Try matching a closer estimation to one block\");\n            return;\n        }\n\n        if (shapePiece.connected.includes(selectedIndex)) {\n            numberOfPieces += 1;\n            pieces[shapeIndex] = \"rgba(40, 255, 0, 0.6)\";\n            enabled[shapeIndex] = \"ENABLED_NONE\";\n            number[shapeIndex] = numberOfPieces;\n            pieces[selectedIndex] = \"rgba(40, 255, 0, 0.6)\";\n            enabled[selectedIndex] = \"ENABLED_NONE\";\n            number[selectedIndex] = numberOfPieces;\n        } else {\n            alert(\"Try matching a closer estimation to one block\");\n        }\n        return;\n    }\n\n    selected[shapeIndex] = 1;\n}\n"
        },
        {
          "Name": "check",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function check () {\n    if (scenarios[selectedScenario].area === numberOfPieces) {\n        alert(\"You did it!, the number of pieces is approximately \" + numberOfPieces );\n        sendState(1); //xAPI \n        reset();\n    } else {\n        alert(\"Incorrect! Try again!\");\n        reset();\n    }\n}"
        },
        {
          "Name": "reset",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "function reset() {\n    initShape();\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"
        }
      ]
    },
    "elements": {
      "list": []
    }
  },
  "view": {
    "Tree": [
      {
        "Name": "wrapper",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [],
        "Children": [
          {
            "Name": "firstRow",
            "Type": "Panel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "CSS",
                "value": "\"{ margin-bottom: 10px }\""
              }
            ],
            "Children": []
          },
          {
            "Name": "secondRow",
            "Type": "Panel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "CSS",
                "value": "\"{ margin-bottom: 10px }\""
              }
            ],
            "Children": [
              {
                "Name": "currentScenario",
                "Type": "Label",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "scenarios[selectedScenario].scenario"
                  }
                ]
              },
              {
                "Name": "selectScenario",
                "Type": "ComboBox",
                "Properties": [
                  {
                    "name": "CSS",
                    "value": "\"{ margin-right: 10px }\""
                  },
                  {
                    "name": "Options",
                    "value": "[\"Scenario A\", \"Scenario B\", \"Scenario C\"]"
                  },
                  {
                    "name": "OnChange",
                    "value": "var opts = _view.selectScenario.getProperty(\"SelectedOptions\");  \nselectedScenario = (opts.length > 0)? opts[0]:\"\";\ninitShape();"
                  }
                ]
              },
              {
                "Name": "check",
                "Type": "Button",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"check\""
                  },
                  {
                    "name": "CSS",
                    "value": "\"{ margin-right: 10px }\""
                  },
                  {
                    "name": "OnPress",
                    "value": "check()"
                  },
                  {
                    "name": "Width",
                    "value": "\"20%\""
                  }
                ]
              },
              {
                "Name": "reset",
                "Type": "Button",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"reset\""
                  },
                  {
                    "name": "OnPress",
                    "value": "reset()"
                  },
                  {
                    "name": "Width",
                    "value": "\"20%\""
                  }
                ]
              }
            ]
          },
          {
            "Name": "plottingPanel",
            "Type": "PlottingPanel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "AutoScaleX",
                "value": "false"
              },
              {
                "name": "AutoScaleY",
                "value": "false"
              },
              {
                "name": "MinimumX",
                "value": "6"
              },
              {
                "name": "MinimumY",
                "value": "8"
              },
              {
                "name": "MaximumX",
                "value": "14"
              },
              {
                "name": "MaximumY",
                "value": "14"
              },
              {
                "name": "Enabled",
                "value": "true"
              },
              {
                "name": "Width",
                "value": "\"100%\""
              },
              {
                "name": "Height",
                "value": "\"90vh\""
              },
              {
                "name": "Gutters",
                "value": "[50,0,0,50]"
              },
              {
                "name": "OnPress",
                "value": "selected = selected.map(() => 0)"
              },
              {
                "name": "TLMessage",
                "value": "`Number of squares estimated: ${numberOfPieces}`"
              },
              {
                "name": "XFixedTick",
                "value": "10"
              },
              {
                "name": "YFixedTick",
                "value": "10"
              },
              {
                "name": "XTickStep",
                "value": "2"
              },
              {
                "name": "YTickStep",
                "value": "2"
              },
              {
                "name": "XAutoTicks",
                "value": "false"
              },
              {
                "name": "YAutoTicks",
                "value": "false"
              },
              {
                "name": "SquareAspect",
                "value": "true"
              },
              {
                "name": "MarginX",
                "value": "5"
              },
              {
                "name": "MarginY",
                "value": "5"
              }
            ],
            "Children": [
              {
                "Name": "shapeSet",
                "Type": "ImageSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].pieces.length"
                  },
                  {
                    "name": "X",
                    "value": "shapeX"
                  },
                  {
                    "name": "Y",
                    "value": "shapeY"
                  },
                  {
                    "name": "SizeX",
                    "value": "2"
                  },
                  {
                    "name": "SizeY",
                    "value": "2"
                  },
                  {
                    "name": "ImageUrl",
                    "value": "imagePiece"
                  }
                ]
              },
              {
                "Name": "shapeCoverSet",
                "Type": "ShapeSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].pieces.length"
                  },
                  {
                    "name": "X",
                    "value": "shapeX"
                  },
                  {
                    "name": "Y",
                    "value": "shapeY"
                  },
                  {
                    "name": "SizeX",
                    "value": "2"
                  },
                  {
                    "name": "SizeY",
                    "value": "2"
                  },
                  {
                    "name": "ShapeType",
                    "value": "\"RECTANGLE\""
                  },
                  {
                    "name": "EnabledPosition",
                    "value": "enabled"
                  },
                  {
                    "name": "Sensitivity",
                    "value": "0"
                  },
                  {
                    "name": "ElementInteracted",
                    "value": "shapeIndex"
                  },
                  {
                    "name": "OnPress",
                    "value": "onClick(shapeIndex)"
                  },
                  {
                    "name": "FillColor",
                    "value": "pieces"
                  },
                  {
                    "name": "LineWidth",
                    "value": "selected"
                  }
                ]
              },
              {
                "Name": "numberSet",
                "Type": "TextSet2D",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "number"
                  },
                  {
                    "name": "NumberOfElements",
                    "value": "scenarios[selectedScenario].pieces.length"
                  },
                  {
                    "name": "X",
                    "value": "shapeX"
                  },
                  {
                    "name": "Y",
                    "value": "shapeY"
                  }
                ]
              }
            ]
          }
        ]
      }
    ],
    "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/"
  }
}