{
  "information": {
    "Title": "ejss_model_astoundingly_average Astoundingly Average Number Game to promote Creative Thinking",
    "Author": [
      "Francisco Esquembre",
      "Shaun Quek",
      "Loo Kang Wee",
      "F\u00e9lix Jes\u00fas Garc\u00eda Clemente",
      "based on idea by Theresa Heng",
      "Ryan Tan"
    ],
    "AuthorLogo": [
      "./01authorPacoEsquembre2011.png",
      "./01authorlooakng50x50.png",
      "./01authorFelix_J_Garcia_Clemente.png",
      "",
      "",
      ""
    ],
    "Password": "",
    "Keywords": "",
    "Abstract": "",
    "Copyright": "",
    "Level": "",
    "Language": "",
    "Logo": [
      "./astoundingly_average/Screenshot 2021-06-10 at 4.33.44 PM (2).png"
    ],
    "RunAlways": "true",
    "ModelTab": "",
    "ModelTabTitle": "",
    "ModelName": "",
    "FixedNavigationBar": "false",
    "CSSFile": "",
    "DetectedFiles": [
      "./01authorFelix_J_Garcia_Clemente.png",
      "./01authorPacoEsquembre2011.png",
      "./01authorlooakng50x50.png",
      "./astoundingly_average/Screenshot 2021-06-10 at 4.33.44 PM (2).png"
    ],
    "AuxiliaryFiles": [
      "./assessment.json",
      "./MakeAssessmentJson20230825.py"
    ],
    "HTMLHead": "<script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=UA-3326007-19\"></script>\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n  gtag('config', 'UA-3326007-19');\n</script>\n",
    "SaveInXMLFormat": "false",
    "IncludeSource": "true",
    "IncludeLibrary": "true",
    "UglifyJS": "false",
    "PreviewFullModel": "false",
    "UseInterpreter": "true",
    "UseDeltaForODE": "false"
  },
  "description": {
    "pages": [
      {
        "Name": "Intro Page",
        "Active": "true",
        "Internal": "false",
        "Type": "DESCRIPTION_EDITOR",
        "Locale": "_default_",
        "Title": "Intro Page",
        "External": "false",
        "Code": "<html>\n<head></head>\n<body>\n<p> </p>\n</body>\n</html>"
      }
    ]
  },
  "model": {
    "variables": {
      "pages": [
        {
          "Name": "Var Table",
          "Active": "true",
          "Internal": "false",
          "Type": "VARIABLE_EDITOR",
          "PageComment": "",
          "Variables": [
            {
              "Name": "numOfCards",
              "Value": "20",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "cardX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "cardY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "initX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "initY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "cardVal",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "cardWidth",
              "Value": "1",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "cardHeight",
              "Value": "1.3",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "cardColor",
              "Value": "\"white\"",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "highlightColor",
              "Value": "\"#fff176\"",
              "Type": "String",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "font",
              "Value": "\"normal normal 2vw\"",
              "Type": "String",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "taskFont",
              "Value": "\"normal normal 1.3vw\"",
              "Type": "String",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "dragThreshold",
              "Value": "0.7",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "whichGroup",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "whichCircle",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "numOfCards",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "interact",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "curTask",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "task",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "instructionStr",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "ruleStr",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            }
          ]
        },
        {
          "Name": "Shape Var",
          "Active": "true",
          "Internal": "false",
          "Type": "VARIABLE_EDITOR",
          "PageComment": "",
          "Variables": [
            {
              "Name": "shapeLength",
              "Value": "3",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "shapePoints",
              "Value": "{}",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "shapeColor",
              "Value": "{}",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "circleCoord",
              "Value": "{}",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "circleLength",
              "Value": "1.3",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "groupSpacing",
              "Value": "shapeLength * 2",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "groupArr",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            }
          ]
        },
        {
          "Name": "lookang",
          "Active": "true",
          "Internal": "false",
          "Type": "VARIABLE_EDITOR",
          "PageComment": "",
          "Variables": [
            {
              "Name": "enabledposition",
              "Value": "\"ENABLED_NONE\"",
              "Type": "String",
              "Dimension": "[numOfCards]",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "visiblity",
              "Value": "false",
              "Type": "boolean",
              "Dimension": "[numOfCards]",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "escKeyPressed",
              "Value": "false",
              "Type": "boolean",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            }
          ]
        },
        {
          "Name": "answerHistory",
          "Active": "true",
          "Internal": "false",
          "Type": "VARIABLE_EDITOR",
          "PageComment": "",
          "Variables": [
            {
              "Name": "isFirstTry",
              "Value": "true",
              "Type": "boolean",
              "Dimension": "[7]",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            }
          ]
        }
      ]
    },
    "initialization": {
      "pages": [
        {
          "Name": "Init Page",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "// Initialising the cards\nvar curX = -cardWidth * 9 / 2;\n\nfor(var i = 1; i <= 20; i++){\n  let idx = i - 1;\n  cardVal[idx] = i;\n  cardX[idx] = curX;\n  if(i <= 10)\n    cardY[idx] = cardHeight * 2;\n  else\n    cardY[idx] = cardHeight;\n    \n  initX[idx] = cardX[idx], initY[idx] = cardY[idx];\n  \n  curX += cardWidth;\n  if(i == 10)\n    curX = -cardWidth * 9 / 2;\n    \n  // whichGroup identifies which group the card is in currently. If the card is not in a group, whichGroup will be null\n  whichGroup[idx] = null;\n  // whichCricle identifies which circle the card is in currently. If the card is not in a cricle, whichCricle will be -1.\n  whichCircle[idx] = -1;\n}\n\n  \n  \n\n"
        },
        {
          "Name": "init Shape",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "// shapePoints is to define the points that we are going to use for the 2d polygons\nvar penRadius = triRadius = shapeLength / 2;\nshapePoints = {\n  \"triangle\": [\n    [0, triRadius * Math.sin(Math.PI / 3), -triRadius * Math.sin(Math.PI / 3), 0],\n    [triRadius, -triRadius * Math.cos(Math.PI / 3), -triRadius * Math.cos(Math.PI / 3), triRadius]\n  ],\n  \"square\": [\n    [-shapeLength / 2, shapeLength / 2, shapeLength / 2, -shapeLength / 2, -shapeLength / 2],\n    [shapeLength / 2, shapeLength / 2, -shapeLength / 2, -shapeLength / 2, shapeLength / 2]\n  ],\n  \"pentagon\": [\n    [0, penRadius * Math.cos(Math.PI / 10), penRadius * Math.sin(Math.PI / 5), -penRadius * Math.sin(Math.PI / 5), -penRadius * Math.cos(Math.PI / 10), 0],\n    [penRadius, penRadius * Math.sin(Math.PI / 10), -penRadius * Math.cos(Math.PI / 5), -penRadius * Math.cos(Math.PI / 5), penRadius * Math.sin(Math.PI / 10), penRadius]\n  ]\n};\n// circleCoord defines the coordinates of the circles relative to the center\npenRadius = shapeLength * 2/3;\ntriRadius = shapeLength * 1/2;\ncircleCoord = {\n  \"triangle\": [\n    [-triRadius * Math.sin(Math.PI / 3), triRadius * Math.sin(Math.PI / 3), 0],\n    [triRadius * Math.cos(Math.PI / 3), triRadius * Math.cos(Math.PI / 3), -triRadius]\n  ],\n  \"square\": [\n    [-shapeLength * 3/4, 0, shapeLength * 3/4, 0],\n    [0, shapeLength * 3/4, 0, -shapeLength * 3/4]\n  ],\n  \"pentagon\": [\n    [-penRadius * Math.sin(Math.PI / 5), penRadius * Math.sin(Math.PI / 5), penRadius * Math.sin(Math.PI * 2/5), 0, -penRadius * Math.sin(Math.PI * 2/5)],\n    [penRadius * Math.cos(Math.PI / 5), penRadius * Math.cos(Math.PI / 5), -penRadius * Math.cos(Math.PI * 2/5), -penRadius, -penRadius * Math.cos(Math.PI * 2/5)]\n  ]\n};\n// the color of the shapes  \nshapeColor = {\n  \"triangle\": \"yellow\",\n  \"square\": \"lightblue\",\n  \"pentagon\": \"red\"\n};\n"
        },
        {
          "Name": "Init Task",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "if(curTask == undefined)\n  curTask = 1;\n// defining the different tasks\ntask = [\n\n  [\n    \"Choose any 4 cards and place them in the triangle and circles.\",\n    \"The number in the triangle must be the average of the three numbers in the circles surrounding the triangle.\",\n    [\"triangle\"]\n  ],\n  [\n    \"Choose any 9 cards and place them in the triangle, square and circles.\",\n    \"(i) The number in the triangle must be the average of the three numbers in the circles surrounding the triangle.<br/>(ii) The number in the square must be the average of the four numbers in the circles surrounding the square.\",\n    [\"triangle\", \"square\"]\n  ],\n  [\n    \"Choose the given 3 cards (highlighted in yellow) and decide the 4th card number and place all of them in the triangle and circles.\",\n    \"The number in the triangle must be the average of the three numbers in the circles surrounding the triangle.\",\n    [\"triangle\"]\n  ],\n  [\n    \"Select four consecutive numbers from the deck of cards to place them in the pattern with the same condition.\",\n    \"The number in the triangle must be the average of the three numbers in the circles surrounding the triangle.\",\n    [\"triangle\"]\n  ],\n  [\n    \"Place the numbers, 1, 2, 3, 4, 5, 6, 7 and 8 into the two patterns.\",\n    \"The number in the triangle must be the average of the three numbers in the circles surrounding the triangle.\",\n    [\"triangle\", \"triangle\"]\n  ],\n  \n  [\n    \"Place the number cards 1 to 12 into the two patterns below.\",\n    \"The number in the pentagon must be the average of the five numbers in the circles surrounding the pentagon.\",\n    [\"pentagon\", \"pentagon\"]\n  ],\n  [\n    \"Place the number cards 1 to 12 into the three patterns below.\",\n    \"The number in the triangle must be the average of the three numbers in the circles surrounding the triangle.\",\n    [\"triangle\", \"triangle\", \"triangle\"]\n  ],\n];\n\n// hightlight cards specific to the task\n//lookang to enable task1 n 2\nif(curTask == 1|| curTask == 2|| curTask == 4){\n  for (var i=0; i<numOfCards ; i++) {\n  enabledposition[i] = \"ENABLED_ANY\"\n  cardColor[i] =highlightColor\n  visiblity[i] = true\n}\n\n  }\n  //lookang\n\n\nif(curTask == 3){\n  cardColor[12] = cardColor[16] = cardColor[17] = highlightColor;\n  enabledposition[12] = enabledposition[16] =enabledposition[17] = \"ENABLED_ANY\"\nvisiblity[12] = true\nvisiblity[16] = true\nvisiblity[17] = true\n//assume (13+17+18)/3 = 16\n enabledposition[15] = \"ENABLED_ANY\"\n // just enable all\n for (var i=0; i<numOfCards ; i++) {\n  enabledposition[i] = \"ENABLED_ANY\"\n  visiblity[i] = true\n  //cardColor[i] =highlightColor\n}\n\n\n \n \n\n}\nelse if(curTask == 5){\n  for(var i = 0; i < 8; i++){\n    cardColor[i] = highlightColor;\n    enabledposition[i] = \"ENABLED_ANY\"\n     visiblity[i] = true\n  }\n}\nelse if(curTask == 6 || curTask == 7){\n  for(var i = 0; i < 12; i++){\n    cardColor[i] = highlightColor;\n    enabledposition[i] = \"ENABLED_ANY\"\n    visiblity[i] = true\n  }\n}\n\n// set the text\ninstructionStr = task[curTask - 1][0];\nruleStr = task[curTask - 1][1];\n// create the groups\nfor(var i = 0; i < task[curTask - 1][2].length; i++) {\n  addGroup(task[curTask - 1][2][i]);\n}\n\n_view.comboBox.setProperty(\"SelectedOptions\", [curTask]);"
        }
      ]
    },
    "evolution": {
      "information": {
        "FPS": "20",
        "SPD": "1",
        "RealTimeVariable": "",
        "Autoplay": "true"
      },
      "pages": []
    },
    "fixed_relations": {
      "pages": [
        {
          "Name": "FixRel Page",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": ""
        }
      ]
    },
    "custom": {
      "pages": [
        {
          "Name": "Group Class",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EDITOR",
          "Comment": "",
          "Code": "// creating a 'Group' class.\n/*\nA \"Group\" comprises of the shape, and the circles around it.\nCurrently, 3 different types of shapes are implemented: \"triangle\", \"square\", \"pentagon\"\n\nIMPORTANT: if you want to add any of these 'groups' into the plottingPanel, do so via the addGroup() function. Also currently there is no support for\ndeleting existing groups (other than through reseting) due to the limitations of EJSS.\n\nThe attributes of this class are:\nshapeType: the shape type of the this group (\"triangle\", \"square\", \"pentagon\")\nid: the unique integer id assigned to this group\nname: the name of the group\nxPos and yPos: arrays containing the x and y positions of the shapes in the group. xPos[0] and yPos[0] refers to position of the center of the group.\nval: array containing the numbers currently contained in the shapes. If there is no number, default to -1. val[0] refers to the number in the center.\n\n\nThe current methods for this class are:\nisValid(): determines if the average of the values in the circles equals to the value in the center\ngetter and setter functions for x and y: refers to the x and y coordinates of the center of the group. Should be accessed if the group has to be repositioned.\n*/\nclass Group {\n  constructor(shapeType, id, x, y) {\n    // checking if the shapeType exists\n    if(!shapePoints.hasOwnProperty(shapeType)) {\n      shapeType = \"triangle\"\n    }\n    this.shapeType = shapeType;\n    this.id = id, this.name = \"group\" + this.id;\n\n    this.xPos = [x], this.yPos = [y];\n    this.val = [-1];\n\n    // creating the group\n    this.groupElement = _view._addElement(EJSS_DRAWING2D.group, this.name, _view.groupSet);\n    // setting the coordinates of the group\n    this.groupElement.setProperties( {\n      \"X\": x,\n      \"Y\": y\n    } );\n    // creating the shape\n    var mainShape = _view._addElement(EJSS_DRAWING2D.polygon, this.name + \"_main\", _view[this.name]);\n    // setting the points of the shape\n    mainShape.setProperties( {\n      \"X\": 0,\n      \"Y\": 0,\n      \"PointsX\": shapePoints[shapeType][0],\n      \"PointsY\": shapePoints[shapeType][1],\n      \"FillColor\": shapeColor[shapeType]\n    } );\n\n    // adding the circles\n    for(var i = 0; i < circleCoord[shapeType][0].length; i++) {\n      // the current X and Y position of the circle\n      let curX = circleCoord[shapeType][0][i], curY = circleCoord[shapeType][1][i];\n      // adding the circle coordinates to the circleX and circleY array\n      this.xPos.push(curX + x), this.yPos.push(curY + y);\n      this.val.push(-1);\n      // creating the circle in the plottingPanel\n      let circleShape = _view._addElement(EJSS_DRAWING2D.shape, this.name + \"_\" + i, _view[this.name]);\n      // setting the size, position and color of the circle\n      circleShape.setProperties( {\n        \"X\": curX,\n        \"Y\": curY,\n        \"SizeX\": circleLength,\n        \"SizeY\": circleLength,\n        \"FillColor\": \"White\"\n      } );\n    }\n\n    // creating the label at the bottom right hand corner of the group\n    var labelFontSize = \"24pt\";\n    if ([1, 3, 4].includes(curTask)) {\n      labelFontSize = \"0\";\n    }\n    var label = _view._addElement(EJSS_DRAWING2D.text, this.name + \"label\", _view[this.name]);\n    label.setProperties( {\n      Text: this.id,\n      X: -shapeLength *2/3,\n      Y: -shapeLength * (0.6),\n      FontSize: labelFontSize\n\n    } );\n  }\n\n  // determines if the average of the values in the circles equals to the value in the center\n  // returns -1 if not all positions have been filled in; 1 if valid; 0 if invalid\n  isValid() {\n    var sum = 0;\n    for(var i = 0; i < this.val.length; i++) {\n      if(this.val[i] == -1) {\n        return -1;\n      }\n      if(i != 0) {\n        sum += this.val[i];\n      }\n    }\n    return ((sum /(this.val.length - 1) == this.val[0]) ? 1 : 0);\n  }\n\n  // getter and setter functions for x and y\n  get x() {\n    return this.xPos[0];\n  }\n  get y() {\n    return this.yPos[0];\n  }\n  set x(val) {\n    this.xPos[0] = val;\n    for(var i = 1; i <= circleCoord[this.shapeType][0].length; i++) {\n      this.xPos[i] = val + circleCoord[this.shapeType][0][i - 1];\n    }\n    // when we change the x position of the group, the change must also be reflected in EJSS\n    this.groupElement.setProperty(\"X\", val);\n  }\n  set y(val) {\n    this.yPos[0] = val;\n    for(var i = 1; i <= circleCoord[this.shapeType][1].length; i++) {\n      this.yPos[i] = val + circleCoord[this.shapeType][1][i - 1];\n    }\n    this.groupElement.setProperty(\"Y\", val);\n  }\n}"
        },
        {
          "Name": "addGroup",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EDITOR",
          "Comment": "",
          "Code": "/*\nThe addGroup function is used to add new 'groups' into the plottingPanel. \nIt also repositions the groups such that they will always be aligned with the center.\n*/\nfunction addGroup (shapeType) {\n  \n  var groupObj = new Group(shapeType, String.fromCharCode(65 + groupArr.length), 0, -shapeLength * 4/5);\n  groupArr.push(groupObj);\n  \n  // setting the X values such that the groups are center aligned\n  var n = groupArr.length, curX;\n  if(n % 2 == 0){\n    curX = -groupSpacing * (n / 2 - 1/2);\n  }\n  else{\n    curX = -groupSpacing * parseInt(n / 2);\n  }\n  for(var i = 0; i < n; i++){\n    groupArr[i].x = curX;\n    curX += groupSpacing;\n  }\n}"
        },
        {
          "Name": "checkTask",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EDITOR",
          "Comment": "",
          "Code": "// the checkTask function is to check whether the numbers are positioned correctly according to the tasks\nfunction checkTask() {\n  var isValid = 1;\n  // running through each group and checking if the numbers are valid\n  var correctGroups = [];\n  for (groupObj of groupArr) {\n    let res = groupObj.isValid();\n    // compiling a list of all the correct groups for display later\n    if (res == 1)\n      correctGroups.push(groupObj.id);\n    isValid = Math.min(isValid, res);\n  }\n  // UNFILLED SHAPES\n  if (isValid == -1) {\n    _tools.showOkDialog(\"Not all the patterns have been filled in!\");\n    onAnswerInvalid();\n    return;\n  }\n\n  // TASK-SPECIFIC CASES\n  // must use 13, 17 and 18\n  if (curTask == 3) {\n    let checkVal = [13, 17, 18];\n    for (var i = 0; i < checkVal.length; i++) {\n      if (whichGroup[checkVal[i] - 1] == null) {\n        _tools.showOkDialog(\"You didn't use all the required numbers!\");\n        onAnswerIncorrect();\n        return;\n      }\n    }\n  }\n  // numbers must be consecutive\n  else if (curTask == 4) {\n    let checkCounter = 0;\n    for (var i = 0; i < whichGroup.length; i++) {\n      if (whichGroup[i] == null && checkCounter == 1) {\n        checkCounter = 2;\n      }\n      else if (whichGroup[i] != null) {\n        if (checkCounter == 0) {\n          checkCounter = 1;\n        }\n        if (checkCounter == 2) {\n          _tools.showOkDialog(\"The numbers you chose are not consecutive!\");\n          onAnswerIncorrect();\n          return;\n        }\n      }\n    }\n  }\n  // can only use numbers from 1 - 8\n  else if (curTask == 5) {\n    for (var i = 8; i < whichGroup.length; i++) {\n      if (whichGroup[i] != null) {\n        _tools.showOkDialog(\"You can only use numbers from 1 to 8!\");\n        onAnswerIncorrect();\n        return;\n      }\n    }\n  }\n  // can only use numbers from 1 - 12\n  else if (curTask == 6 || curTask == 7) {\n    for (var i = 12; i < whichGroup.length; i++) {\n      if (whichGroup[i] != null) {\n        _tools.showOkDialog(\"You can only use numbers from 1 to 12!\");\n        onAnswerIncorrect();\n        return;\n      }\n    }\n  }\n  // INCORRECT PATTERNS i.e. the average of numbers in the circles does not equal to the number in the center\n  if (isValid == 0) {\n    if (correctGroups.length == 0) {\n      _tools.showOkDialog(\"None of the patterns are correct!\");\n    }\n    else {\n      let outputStr = \"Only pattern\" + (correctGroups.length == 1 ? \" \" : \"s \");\n      for (var i = 0; i < correctGroups.length; i++) {\n        outputStr += correctGroups[i];\n        if (i != correctGroups.length - 1) {\n          outputStr += \", \";\n        }\n      }\n      outputStr += (correctGroups.length == 1 ? \" is \" : \" are \") + \"correct!\";\n      _tools.showOkDialog(outputStr);\n    }\n    onAnswerIncorrect();\n  } else {\n    // SUCCESS MESSAGE :)\n    _tools.showOkDialog(\"The values are all correctly placed. Well done!\");\n    onAnswerCorrect();\n  }\n}"
        },
        {
          "Name": "Pedagogy Solver",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EDITOR",
          "Comment": "",
          "Code": "var thinkingTimeouts = [];\nvar thinkingRunning = false;\nvar thinkingEnabledSnapshot = [];\n\nfunction getThinkingDefaultHtml() {\n  return \"<b>Thinking guide</b>: Try the task yourself first. Then click <b>Show Thinking</b> to watch one possible solution, or to see why a task has no solution.\";\n}\n\nvar thinkingScripts = {\n  1: {\n    title: \"Task 1: One possible solution\",\n    lead: \"Strategy: choose three outer cards whose total is divisible by 3, because the center must be their average.\",\n    finish: \"This is one valid solution. Many other solutions are possible.\",\n    steps: [\n      { text: \"Place 1 in a circle.\", move: { value: 1, group: 0, slot: 1 } },\n      { text: \"Place 2 in another circle.\", move: { value: 2, group: 0, slot: 2 } },\n      { text: \"Place 9 in the last circle. The outer total is now 1 + 2 + 9 = 12.\", move: { value: 9, group: 0, slot: 3 } },\n      { text: \"Now divide by 3. Since 12 / 3 = 4, place 4 in the triangle.\", move: { value: 4, group: 0, slot: 0 } }\n    ]\n  },\n  2: {\n    title: \"Task 2: Solve one shape at a time\",\n    lead: \"A good strategy is to complete one pattern first, then use a second average relationship for the other pattern.\",\n    finish: \"This is one valid arrangement of 9 different cards. Students can look for other working sets too.\",\n    steps: [\n      { text: \"Start with the triangle. Place 1 in a circle.\", move: { value: 1, group: 0, slot: 1 } },\n      { text: \"Place 2 in the next triangle circle.\", move: { value: 2, group: 0, slot: 2 } },\n      { text: \"Place 6 in the last triangle circle. The outer total is 1 + 2 + 6 = 9.\", move: { value: 6, group: 0, slot: 3 } },\n      { text: \"The average is 9 / 3 = 3, so place 3 in the triangle.\", move: { value: 3, group: 0, slot: 0 } },\n      { text: \"Now solve the square. Place 4 on the square.\", move: { value: 4, group: 1, slot: 1 } },\n      { text: \"Add 5 to the square.\", move: { value: 5, group: 1, slot: 2 } },\n      { text: \"Add 8 to the square.\", move: { value: 8, group: 1, slot: 3 } },\n      { text: \"Place 11 in the last square circle. The outer total is 4 + 5 + 8 + 11 = 28.\", move: { value: 11, group: 1, slot: 4 } },\n      { text: \"The square center must be 28 / 4 = 7, so place 7 in the square.\", move: { value: 7, group: 1, slot: 0 } }\n    ]\n  },\n  3: {\n    title: \"Task 3: Work backward from the given cards\",\n    lead: \"Here the three given cards fix the outer total, so the missing card is determined by the average rule.\",\n    finish: \"The missing card is 16 because it is the average of 13, 17 and 18.\",\n    steps: [\n      { text: \"Place the given card 13 in a circle.\", move: { value: 13, group: 0, slot: 1 } },\n      { text: \"Place the given card 17 in another circle.\", move: { value: 17, group: 0, slot: 2 } },\n      { text: \"Place the given card 18 in the last circle. Their total is 13 + 17 + 18 = 48.\", move: { value: 18, group: 0, slot: 3 } },\n      { text: \"Divide by 3. Since 48 / 3 = 16, the missing card must be 16.\", move: { value: 16, group: 0, slot: 0 } }\n    ]\n  },\n  4: {\n    title: \"Task 4: Why there is no solution\",\n    lead: \"The fastest route is to reason algebraically instead of guessing and checking.\",\n    finish: \"So no set of four consecutive cards can satisfy the triangle-average rule.\",\n    steps: [\n      { text: \"Call the four consecutive cards n, n + 1, n + 2 and n + 3.\" },\n      { text: \"Their total is 4n + 6.\" },\n      { text: \"If one card were the average of the other three, then all four cards together would total 4 times the center card.\" },\n      { text: \"That means the total would have to be a multiple of 4.\" },\n      { text: \"But 4n + 6 always leaves remainder 2 when divided by 4, so it can never be a multiple of 4.\" }\n    ]\n  },\n  5: {\n    title: \"Task 5: Use all 8 cards across two triangles\",\n    lead: \"Solve one triangle cleanly, then use the remaining cards to complete the second triangle.\",\n    finish: \"This uses each number from 1 to 8 exactly once. A second solution also exists.\",\n    steps: [\n      { text: \"For the first triangle, place 1 in a circle.\", move: { value: 1, group: 0, slot: 1 } },\n      { text: \"Place 3 in another circle.\", move: { value: 3, group: 0, slot: 2 } },\n      { text: \"Place 8 in the last circle. The outer total is 1 + 3 + 8 = 12.\", move: { value: 8, group: 0, slot: 3 } },\n      { text: \"So the first center is 12 / 3 = 4. Place 4 in the triangle.\", move: { value: 4, group: 0, slot: 0 } },\n      { text: \"Now use the remaining cards on the second triangle. Place 2 in a circle.\", move: { value: 2, group: 1, slot: 1 } },\n      { text: \"Place 6 in another circle.\", move: { value: 6, group: 1, slot: 2 } },\n      { text: \"Place 7 in the last circle. The outer total is 2 + 6 + 7 = 15.\", move: { value: 7, group: 1, slot: 3 } },\n      { text: \"So the second center is 15 / 3 = 5. Place 5 in the triangle.\", move: { value: 5, group: 1, slot: 0 } }\n    ]\n  },\n  6: {\n    title: \"Task 6: Build each pentagon from an average of 5 cards\",\n    lead: \"For each pentagon, add the five outer cards first. The center must be one fifth of that total.\",\n    finish: \"This is one valid arrangement. There are many more because several outer totals can work.\",\n    steps: [\n      { text: \"For the first pentagon, place 1 on the outside.\", move: { value: 1, group: 0, slot: 1 } },\n      { text: \"Add 2 to the outside.\", move: { value: 2, group: 0, slot: 2 } },\n      { text: \"Add 3 to the outside.\", move: { value: 3, group: 0, slot: 3 } },\n      { text: \"Add 6 to the outside.\", move: { value: 6, group: 0, slot: 4 } },\n      { text: \"Add 8 to the last outside spot. The outer total is 1 + 2 + 3 + 6 + 8 = 20.\", move: { value: 8, group: 0, slot: 5 } },\n      { text: \"So the first center is 20 / 5 = 4. Place 4 in the pentagon.\", move: { value: 4, group: 0, slot: 0 } },\n      { text: \"Now solve the second pentagon. Place 5 on the outside.\", move: { value: 5, group: 1, slot: 1 } },\n      { text: \"Add 7 to the outside.\", move: { value: 7, group: 1, slot: 2 } },\n      { text: \"Add 10 to the outside.\", move: { value: 10, group: 1, slot: 3 } },\n      { text: \"Add 11 to the outside.\", move: { value: 11, group: 1, slot: 4 } },\n      { text: \"Add 12 to the last outside spot. The outer total is 5 + 7 + 10 + 11 + 12 = 45.\", move: { value: 12, group: 1, slot: 5 } },\n      { text: \"So the second center is 45 / 5 = 9. Place 9 in the pentagon.\", move: { value: 9, group: 1, slot: 0 } }\n    ]\n  },\n  7: {\n    title: \"Task 7: Why there is no solution\",\n    lead: \"Use a total-sum argument. It is faster and more convincing than random trial and error.\",\n    finish: \"So the cards 1 to 12 cannot be split into three valid triangle-average groups.\",\n    steps: [\n      { text: \"In any triangle group, the center equals the average of the three outer cards.\" },\n      { text: \"So the outer total equals 3 times the center.\" },\n      { text: \"That means the total of all four cards in one triangle group is 4 times the center, so it must be a multiple of 4.\" },\n      { text: \"If all three triangle groups were valid, the grand total of all 12 cards would also have to be a multiple of 4.\" },\n      { text: \"But 1 + 2 + 3 + ... + 12 = 78, and 78 is not a multiple of 4.\" }\n    ]\n  }\n};\n\nfunction renderThinkingPanel(title, lead, items, conclusion) {\n  var html = \"<b>\" + title + \"</b><br/>\" + lead;\n  if (items.length > 0) {\n    html += \"<ol>\";\n    for (var i = 0; i < items.length; i++) {\n      html += \"<li>\" + items[i] + \"</li>\";\n    }\n    html += \"</ol>\";\n  }\n  if (conclusion) {\n    html += \"<p><b>Conclusion:</b> \" + conclusion + \"</p>\";\n  }\n  return html;\n}\n\nfunction setThinkingHtml(html) {\n  if (_view && _view.solverText) {\n    _view.solverText.setProperty(\"Text\", html);\n  }\n}\n\nfunction clearThinkingTimeouts() {\n  for (var i = 0; i < thinkingTimeouts.length; i++) {\n    window.clearTimeout(thinkingTimeouts[i]);\n  }\n  thinkingTimeouts = [];\n}\n\nfunction stopThinkingPlayback(resetPanel) {\n  if (resetPanel === undefined) {\n    resetPanel = true;\n  }\n  clearThinkingTimeouts();\n  thinkingRunning = false;\n  if (thinkingEnabledSnapshot.length === enabledposition.length) {\n    enabledposition = thinkingEnabledSnapshot.slice();\n  }\n  thinkingEnabledSnapshot = [];\n  if (resetPanel) {\n    setThinkingHtml(getThinkingDefaultHtml());\n  }\n  _update();\n}\n\nfunction getCardIndexForValue(value) {\n  for (var i = 0; i < cardVal.length; i++) {\n    if (cardVal[i] === value) {\n      return i;\n    }\n  }\n  return -1;\n}\n\nfunction placeCardValueInGroup(value, groupIndex, slotIndex) {\n  var cardIndex = getCardIndexForValue(value);\n  if (cardIndex < 0 || !groupArr[groupIndex]) {\n    return false;\n  }\n  if (whichGroup[cardIndex] != null) {\n    whichGroup[cardIndex].val[whichCircle[cardIndex]] = -1;\n  }\n  var targetGroup = groupArr[groupIndex];\n  cardX[cardIndex] = targetGroup.xPos[slotIndex];\n  cardY[cardIndex] = targetGroup.yPos[slotIndex];\n  targetGroup.val[slotIndex] = cardVal[cardIndex];\n  whichGroup[cardIndex] = targetGroup;\n  whichCircle[cardIndex] = slotIndex;\n  cardColor[cardIndex] = \"#c5e1a5\";\n  return true;\n}\n\nfunction startThinkingPlayback() {\n  var script = thinkingScripts[curTask];\n  if (!script) {\n    setThinkingHtml(getThinkingDefaultHtml());\n    return;\n  }\n  clearThinkingTimeouts();\n  thinkingRunning = true;\n  thinkingEnabledSnapshot = enabledposition.slice();\n  for (var i = 0; i < enabledposition.length; i++) {\n    enabledposition[i] = \"ENABLED_NONE\";\n  }\n  var items = [];\n  var delay = 0;\n  setThinkingHtml(renderThinkingPanel(script.title, script.lead, items, \"\"));\n  _update();\n  for (var stepIndex = 0; stepIndex < script.steps.length; stepIndex++) {\n    (function(step, currentDelay) {\n      thinkingTimeouts.push(window.setTimeout(function() {\n        if (step.move) {\n          placeCardValueInGroup(step.move.value, step.move.group, step.move.slot);\n        }\n        items.push(step.text);\n        setThinkingHtml(renderThinkingPanel(script.title, script.lead, items, \"\"));\n        _update();\n      }, currentDelay));\n    }(script.steps[stepIndex], delay + (script.steps[stepIndex].delay || 1400)));\n    delay += (script.steps[stepIndex].delay || 1400);\n  }\n  thinkingTimeouts.push(window.setTimeout(function() {\n    thinkingRunning = false;\n    if (thinkingEnabledSnapshot.length === enabledposition.length) {\n      enabledposition = thinkingEnabledSnapshot.slice();\n    }\n    setThinkingHtml(renderThinkingPanel(script.title, script.lead, items, script.finish));\n    _update();\n  }, delay + 300));\n}\n\nfunction showThinkingProcess() {\n  stopThinkingPlayback(false);\n  _reset();\n  isFirstTry[curTask - 1] = false;\n  if (typeof questionAppendHistory === \"function\") {\n    questionAppendHistory(\"Q\" + curTask, \"Guided thinking viewed.\");\n  }\n  startThinkingPlayback();\n}"
        },
        {
          "Name": "question",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EDITOR",
          "Comment": "",
          "Code": "function onAnswerCorrect() {\n  const qn = `Q${curTask}`;\n  const groupInfo = groupArr.map(formatGroup);\n\n  startQuestion(qn);\n  addQuestionHistory(`Valid answer${isFirstTry[curTask - 1] ? \" (First try)\" : \"\"}:\\n${groupInfo.join(\"\\n\")}\\n`);\n  awardQuestionMarks(isFirstTry[curTask - 1] ? 2 : 1)\n  endQuestion();\n}\nfunction onAnswerInvalid() {\n  const qn = `Q${curTask}`;\n  const groupInfo = groupArr.map(formatGroup);\n  \n  questionAppendHistory(qn, `Invalid answer:\\n${groupInfo.join(\"\\n\")}\\n`);\n}\nfunction onAnswerIncorrect() {\n  const qn = `Q${curTask}`;\n  isFirstTry[curTask - 1] = false;\n  const groupInfo = groupArr.map(formatGroup);\n  \n  questionAppendHistory(qn, `Incorrect answer:\\n${groupInfo.join(\"\\n\")}\\n`);\n}\n\n/** @param {number} value */\nfunction formatSlot(value) {\n  return value === -1 ? \"X\" : value.toString();\n}\n\nfunction formatGroup(group) {\n  const results = [\"(\"];\n  for (let i = 1; i < group.val.length; i++) {\n    if (i > 1) results.push(\" \");\n    results.push(formatSlot(group.val[i]));\n  }\n  results.push(`) Center: ${formatSlot(group.val[0])} `);\n  switch (group.isValid()) {\n    case -1:\n      // do something if group.isValid() === -1\n      results.push('\ud83e\udd14');\n      break;\n    case 0: \n      // do something if group.isValid() === 0\n      results.push('\u274c');\n      break;\n    case 1:\n      // do something if group.isValid() === 1\n      results.push('\u2705');\n  }\n  return results.join(\"\");\n}"
        },
        {
          "Name": "questionLib",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EXTERNAL_EDITOR",
          "Comment": "",
          "Code": ""
        },
        {
          "Name": "Lib Page",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EDITOR",
          "Comment": "",
          "Code": "// copy into custom function\ndocument.onkeydown = function(evt) {\n  evt = evt || window.event;\n  var isEscape = false;\n  if (\"key\" in evt) {\n    isEscape = (evt.key === \"Escape\" || evt.key === \"Esc\");\n  } \n  else {\n    isEscape = (evt.keyCode === 27);\n  }\n  if (isEscape) {\n    //alert(\"Escape\");\n    //escKeyPressed = true\n  escKeyPressed = !escKeyPressed; // Toggle escKeyPressed\n  }\n  \n} "
        }
      ]
    },
    "elements": {
      "list": []
    }
  },
  "view": {
    "Tree": [
      {
        "Name": "topPanel",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [],
        "Children": [
          {
            "Name": "btnContainer",
            "Type": "Panel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "CSS",
                "value": "{\n  \"justify-content\": \"center\",\n  \"align-items\": \"flex-start\",\n  \"flex-wrap\": \"wrap\",\n  \"gap\": \"8px\"\n}\n"
              },
              {
                "name": "Display",
                "value": "\"flex\""
              }
            ],
            "Children": [
              {
                "Name": "taskText2",
                "Type": "Label",
                "Properties": [
                  {
                    "name": "TextAlign",
                    "value": "\"left\""
                  },
                  {
                    "name": "Text",
                    "value": "\"Instructions: \" +instructionStr"
                  },
                  {
                    "name": "Font",
                    "value": "taskFont"
                  },
                  {
                    "name": "Display",
                    "value": "\"none\""
                  }
                ]
              },
              {
                "Name": "label",
                "Type": "Label",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"Select Task: \""
                  },
                  {
                    "name": "Font",
                    "value": "font"
                  }
                ]
              },
              {
                "Name": "comboBox",
                "Type": "ComboBox",
                "Properties": [
                  {
                    "name": "Options",
                    "value": "[1, 2, 3, 4, 5, 6, 7]"
                  },
                  {
                    "name": "OnChange",
                    "value": "stopThinkingPlayback(false);\nvar selected = _view.comboBox.getProperty(\"SelectedOptions\")[0];\ncurTask = parseInt(selected);\n_reset();\n"
                  },
                  {
                    "name": "Width",
                    "value": "\"10%\""
                  },
                  {
                    "name": "Font",
                    "value": "font"
                  }
                ]
              },
              {
                "Name": "checkTask",
                "Type": "Button",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"\ud83e\udd14Check\""
                  },
                  {
                    "name": "OnClick",
                    "value": "checkTask();"
                  },
                  {
                    "name": "Width",
                    "value": "\"10%\""
                  },
                  {
                    "name": "Font",
                    "value": "font"
                  }
                ]
              },
              {
                "Name": "reset",
                "Type": "Button",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"\u21bbReset\""
                  },
                  {
                    "name": "OnClick",
                    "value": "stopThinkingPlayback(false);\n_reset();\n"
                  },
                  {
                    "name": "Width",
                    "value": "\"10%\""
                  },
                  {
                    "name": "Font",
                    "value": "font"
                  }
                ]
              },
              {
                "Name": "thinkingButton",
                "Type": "Button",
                "Properties": [
                  {
                    "name": "Text",
                    "value": "\"Show Thinking\""
                  },
                  {
                    "name": "OnClick",
                    "value": "showThinkingProcess();"
                  },
                  {
                    "name": "Font",
                    "value": "font"
                  },
                  {
                    "name": "Display",
                    "value": "escKeyPressed?\"inline-block\":\"none\""
                  }
                ]
              },
              {
                "Name": "taskText",
                "Type": "Label",
                "Properties": [
                  {
                    "name": "CSS",
                    "value": "{\n   \"border\": \"2px solid black\"\n}\n"
                  },
                  {
                    "name": "TextAlign",
                    "value": "\"left\""
                  },
                  {
                    "name": "Text",
                    "value": "\"<b>Instructions</b>:<br/>\" + instructionStr + \"<br/><b>Rules</b>:<br/>\" + ruleStr"
                  },
                  {
                    "name": "Width",
                    "value": "\"100%\""
                  },
                  {
                    "name": "Font",
                    "value": "taskFont"
                  },
                  {
                    "name": "Display",
                    "value": "\"inline-block\""
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "Name": "mainPanel",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [],
        "Children": [
          {
            "Name": "plottingPanel",
            "Type": "PlottingPanel",
            "Expanded": "true",
            "Properties": [
              {
                "name": "Gutters",
                "value": "[0,0,0,0]"
              },
              {
                "name": "YScalePrecision",
                "value": "0"
              },
              {
                "name": "XFixedTick",
                "value": "-6"
              },
              {
                "name": "Enabled",
                "value": "true"
              },
              {
                "name": "SquareAspect",
                "value": "true"
              },
              {
                "name": "YFixedTick",
                "value": "-5"
              },
              {
                "name": "YAutoTicks",
                "value": "false"
              },
              {
                "name": "XTickStep",
                "value": "12"
              },
              {
                "name": "YTickStep",
                "value": "10"
              },
              {
                "name": "AutoScaleY",
                "value": "true"
              },
              {
                "name": "AutoScaleX",
                "value": "true"
              },
              {
                "name": "XAutoTicks",
                "value": "false"
              },
              {
                "name": "Height",
                "value": "\"80vh\""
              },
              {
                "name": "XScalePrecision",
                "value": "0"
              },
              {
                "name": "Width",
                "value": "\"100%\""
              }
            ],
            "Children": [
              {
                "Name": "groupSet",
                "Type": "Group2D",
                "Properties": []
              },
              {
                "Name": "shapeSet",
                "Type": "ShapeSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "numOfCards"
                  },
                  {
                    "name": "OnRelease",
                    "value": "var minDist = dragThreshold ** 2;\nvar curX = cardX[interact], curY = cardY[interact];\nvar choosenGroup = null, choosenCircle = -1;\n\nfor (groupObj of groupArr) {\n  for (var i = 0; i < groupObj.xPos.length; i++) {\n    if (groupObj.val[i] != -1)\n      continue;\n    var cX = groupObj.xPos[i];\n    var cY = groupObj.yPos[i];\n    var curDist = (curX - cX) ** 2 + (curY - cY) ** 2;\n\n    if (curDist < minDist) {\n      choosenGroup = groupObj;\n      choosenCircle = i;\n      minDist = curDist;\n    }\n  }\n}\n\nif (whichGroup[interact] != null) {\n  whichGroup[interact].val[whichCircle[interact]] = -1;\n  whichGroup[interact] = null;\n}\n\nif (choosenGroup == null) {\n  cardX[interact] = initX[interact];\n  cardY[interact] = initY[interact];\n} else {\n  cardX[interact] = choosenGroup.xPos[choosenCircle];\n  cardY[interact] = choosenGroup.yPos[choosenCircle];\n  choosenGroup.val[choosenCircle] = cardVal[interact];\n\n  whichGroup[interact] = choosenGroup;\n  whichCircle[interact] = choosenCircle;\n}\n\n// console.log(groupArr);\n"
                  },
                  {
                    "name": "FillColor",
                    "value": "cardColor"
                  },
                  {
                    "name": "Sensitivity",
                    "value": "0"
                  },
                  {
                    "name": "SizeX",
                    "value": "cardWidth"
                  },
                  {
                    "name": "ShapeType",
                    "value": "\"RECTANGLE\""
                  },
                  {
                    "name": "X",
                    "value": "cardX"
                  },
                  {
                    "name": "Y",
                    "value": "cardY"
                  },
                  {
                    "name": "SizeY",
                    "value": "cardHeight"
                  },
                  {
                    "name": "EnabledPosition",
                    "value": "enabledposition"
                  },
                  {
                    "name": "ElementInteracted",
                    "value": "interact"
                  }
                ]
              },
              {
                "Name": "textSet",
                "Type": "TextSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "numOfCards"
                  },
                  {
                    "name": "X",
                    "value": "cardX"
                  },
                  {
                    "name": "Y",
                    "value": "cardY"
                  },
                  {
                    "name": "Text",
                    "value": "cardVal"
                  },
                  {
                    "name": "Visibility",
                    "value": "visiblity"
                  },
                  {
                    "name": "Font",
                    "value": "font"
                  }
                ]
              }
            ]
          },
          {
            "Name": "solverText",
            "Type": "Label",
            "Properties": [
              {
                "name": "CSS",
                "value": "{\n   \"border\": \"2px solid #4f6f52\",\n   \"background\": \"#f7fbf5\",\n   \"padding\": \"10px\",\n   \"border-radius\": \"8px\"\n}\n"
              },
              {
                "name": "TextAlign",
                "value": "\"left\""
              },
              {
                "name": "Text",
                "value": "\"<b>Thinking guide</b>: Try the task yourself first. Then click <b>Show Thinking</b> to watch one possible solution, or to see why a task has no solution.\""
              },
              {
                "name": "Width",
                "value": "\"100%\""
              },
              {
                "name": "Font",
                "value": "taskFont"
              },
              {
                "name": "Display",
                "value": "\"inline-block\""
              }
            ]
          },
          {
            "Name": "taskText3",
            "Type": "Label",
            "Properties": [
              {
                "name": "CSS",
                "value": "{\n   \"border\": \"2px solid black\"\n}\n"
              },
              {
                "name": "TextAlign",
                "value": "\"left\""
              },
              {
                "name": "Text",
                "value": "\"<br/><b>Rules</b>:<br/>\" + ruleStr"
              },
              {
                "name": "Width",
                "value": "\"100%\""
              },
              {
                "name": "Font",
                "value": "taskFont"
              },
              {
                "name": "Display",
                "value": "\"none\""
              }
            ]
          }
        ]
      },
      {
        "Name": "html",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [
          {
            "name": "Html",
            "value": "<h2>Hints:</h2>\n<p>Task 4 has no solution. Suggest a reason why?</p>\n<p>Task 5 has solutions that the final averages are 4 and 5 respectively, there are two possible solutions. Do you know both of them?</p>\n<p>Task 6 can take to use final averages in the middle of the range of numbers, like 5 and 8 for example. There should be quite a few solutions here.</p> \n<p>Task 7 has no solution.Suggest a reason why?</p>"
          },
          {
            "name": "Display",
            "value": "escKeyPressed?\"inline-block\":\"none\""
          }
        ],
        "Children": []
      },
      {
        "Name": "html2",
        "Type": "Panel",
        "Properties": [
          {
            "name": "Html",
            "value": "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/sBy0P4RaaMM?si=Z3s0dSgkL4W0tOWw\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen></iframe><h2>Description</h2>\n\n<p><strong>Can you solve this average number game before the guided method appears?</strong></p>\n\n<p>\nThis 5-minute walkthrough shows students how to solve the\n<strong>Astoundingly Average Number Game</strong> slowly and clearly using\nsums, averages, and logical reasoning.\n</p>\n\n<p><strong>In this lesson, students will learn how to:</strong></p>\n\n<ul>\n  <li>solve Task 1, Task 2, Task 3, Task 5, and Task 6 step by step</li>\n  <li>understand why Task 4 and Task 7 are no-solution challenges</li>\n  <li>use the applet\u2019s <strong>Check</strong>, <strong>Reset</strong>, and <strong>Show Thinking</strong> features</li>\n  <li>divide by 3, 4, or 5 depending on the shape</li>\n  <li>reason logically using totals and averages</li>\n</ul>\n\n<p><strong>Best for:</strong></p>\n\n<ul>\n  <li>Primary and lower secondary mathematics</li>\n  <li>Enrichment and creative thinking lessons</li>\n  <li>Self-checking after students try the puzzle independently</li>\n</ul>\n\n<p>\nTry the simulation here:<br>\n<a href=\"https://iwant2study.org/lookangejss/math/ejss_model_astoundingly_average/\" target=\"_blank\" rel=\"noopener\">\nhttps://iwant2study.org/lookangejss/math/ejss_model_astoundingly_average/\n</a>\n</p>\n\n<p>\nExplore more Mathematics interactive resources from\nOpen Source Physics @ Singapore:<br>\n<a href=\"https://sg.iwant2study.org/ospsg/index.php/interactive-resources/mathematics\" target=\"_blank\" rel=\"noopener\">\nhttps://sg.iwant2study.org/ospsg/index.php/interactive-resources/mathematics\n</a>\n</p>"
          }
        ]
      }
    ],
    "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/"
  }
}