{
  "information": {
    "Title": "ejss_model_guards_riddle Guard's Riddle, game to position numbers apart by the number they are in",
    "Author": [
      "Shaun Quek",
      "Loo Kang Wee",
      "Francisco Esquembre",
      "F\u00e9lix Jes\u00fas Garc\u00eda Clemente.",
      "based on idea by Theresa Heng"
    ],
    "AuthorLogo": [
      "",
      "",
      "",
      "",
      ""
    ],
    "Password": "",
    "Keywords": "",
    "Abstract": "picture of guard is from powerpoint defult images.\npermission to use given by microsoft",
    "Copyright": "",
    "Level": "",
    "Language": "",
    "Logo": [
      "./guards_riddle/Screenshot 2021-06-05 at 12.30.53 PM.png"
    ],
    "RunAlways": "true",
    "ModelTab": "",
    "ModelTabTitle": "",
    "ModelName": "",
    "FixedNavigationBar": "false",
    "CSSFile": "",
    "DetectedFiles": [
      "./guards_riddle/Screenshot 2021-06-05 at 12.30.53 PM.png"
    ],
    "AuxiliaryFiles": [
      "./guards_riddle/"
    ],
    "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<script data-ad-client=\"ca-pub-0121577198857509\" async=\"true\" src=\"https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js\"></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": "n",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "guardX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "guardY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "[]",
              "Domain": "public"
            },
            {
              "Name": "initGuardX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "guardVal",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "guardPos",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "guardWidth",
              "Value": "1",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "guardHeight",
              "Value": "1.5",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "pairList",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "boxX",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "boxY",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "boxPos",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "boxOccupied",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "textStr",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "interact",
              "Value": "0",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "thresholdDist",
              "Value": "0.3",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "font",
              "Value": "\"normal normal 3vmax\"",
              "Type": "String",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "score",
              "Value": "0",
              "Type": "double",
              "Dimension": "",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "imageurl",
              "Value": "[\"./guards_riddle/01.png\",\"./guards_riddle/01.png\",\"./guards_riddle/02.png\",\"./guards_riddle/02.png\",\"./guards_riddle/03.png\",\"./guards_riddle/03.png\",\"./guards_riddle/04.png\",\"./guards_riddle/04.png\",\"./guards_riddle/05.png\",\"./guards_riddle/05.png\",\"./guards_riddle/06.png\",\"./guards_riddle/06.png\",\"./guards_riddle/07.png\",\"./guards_riddle/07.png\",\"./guards_riddle/08.png\",\"./guards_riddle/08.png\"]",
              "Type": "String",
              "Dimension": "[8]",
              "Comment": "null",
              "Domain": "public"
            },
            {
              "Name": "boxFillColor",
              "Value": "[]",
              "Type": "Object",
              "Dimension": "",
              "Comment": "per-box color for solver",
              "Domain": "public"
            },
            {
              "Name": "solverMessage",
              "Value": "\"\"",
              "Type": "String",
              "Dimension": "",
              "Comment": "canvas TLMessage during solve",
              "Domain": "public"
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": "public"
            }
          ]
        },
        {
          "Name": "Var Table 2",
          "Active": "true",
          "Internal": "false",
          "Type": "VARIABLE_EDITOR",
          "PageComment": "",
          "Variables": [
            {
              "Name": "showHint",
              "Value": "false",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            },
            {
              "Name": "",
              "Value": "",
              "Type": "double",
              "Dimension": "",
              "Comment": "",
              "Domain": ""
            }
          ]
        }
      ]
    },
    "initialization": {
      "pages": [
        {
          "Name": "Init Page",
          "Active": "true",
          "Internal": "false",
          "Type": "CODE_EDITOR",
          "Comment": "",
          "Code": "if(n == undefined)\n  n = 3;\n_view.comboBox.setProperty('SelectedOptions', [n]);\n\nfor(var i = 0; i < n * 2; i++){\n  guardX.push(i * guardWidth), guardY.push(guardHeight);\n  initGuardX.push(i * guardWidth);\n  guardVal.push(parseInt(i / 2) + 1);\n  guardPos.push(-1);\n  boxX.push(i * guardWidth), boxY.push(-guardHeight);\n  boxPos.push(i);\n  boxOccupied.push(false);\n  boxFillColor.push('#FFD700');\n  textStr.push(parseInt(i / 2) + 1);\n}\n\n// Reset solver state on every reset\nif (typeof _solverTimer !== 'undefined' && _solverTimer) { clearTimeout(_solverTimer); _solverTimer = null; }\nif (typeof _solverRunning !== 'undefined') { _solverRunning = false; _solverPaused = false; _solverIdx = 0; _solverSteps = []; }\nif (typeof _updateSolverUI === 'function') _updateSolverUI(null);\n\n// Expose solver API to HTML buttons (guard against double-init on reset)\nif (!window._solver || !window._solver._initialized) {\n  window._solver = {\n    _delay: 400, _initialized: true,\n    start:       function() { _startSolve(); },\n    togglePause: function() { _togglePause(); },\n    step:        function() { _stepOnce(); },\n    reset:       function() { _resetSolverMode(); },\n    setSpeed: function(val) {\n      var d=[2000,1200,700,400,200,120,70,30,10];\n      var l=['Slowest','Very Slow','Slow','Medium','Normal','Fast','Very Fast','Super Fast','Instant'];\n      var idx=Math.max(0,Math.min(8,parseInt(val)-1));\n      window._solver._delay=d[idx];\n      var lbl=document.getElementById('speedLabel'); if(lbl) lbl.textContent=l[idx];\n    }\n  };\n}"
        }
      ]
    },
    "evolution": {
      "information": {
        "FPS": "20",
        "SPD": "1",
        "RealTimeVariable": "",
        "Autoplay": "true"
      },
      "pages": []
    },
    "fixed_relations": {
      "pages": []
    },
    "custom": {
      "pages": [
        {
          "Name": "Lib Page",
          "Active": "true",
          "Internal": "false",
          "Type": "LIBRARY_EDITOR",
          "Comment": "",
          "Code": "//https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode\nfunction toggleFullScreen() {\n  if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {\n    if (document.documentElement.requestFullscreen) { document.documentElement.requestFullscreen(); }\n    else if (document.documentElement.msRequestFullscreen) { document.documentElement.msRequestFullscreen(); }\n    else if (document.documentElement.mozRequestFullScreen) { document.documentElement.mozRequestFullScreen(); }\n    else if (document.documentElement.webkitRequestFullscreen) { document.documentElement.webkitRequestFullscreen(); }\n  } else {\n    if (document.exitFullscreen) { document.exitFullscreen(); }\n    else if (document.msExitFullscreen) { document.msExitFullscreen(); }\n    else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); }\n    else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); }\n  }\n}\n\n// === SOLVER ENGINE (Backtracking) ===\nvar _solverSteps, _solverIdx, _solverRunning, _solverPaused, _solverTimer;\n\n// Pre-compute every TRY / BACK / SOLVED / NONE step for the backtracking search\nfunction _buildSteps(numN) {\n  var steps = [], board = new Array(2*numN).fill(0), tries = 0, backtracks = 0;\n  function bt(rank) {\n    if (rank > numN) {\n      steps.push({type:'SOLVED',board:board.slice(),tries:tries,backtracks:backtracks,p1:-1,p2:-1,rank:rank});\n      return true;\n    }\n    for (var p1 = 0; p1 <= 2*numN - rank - 1; p1++) {\n      var p2 = p1 + rank;\n      if (board[p1]===0 && board[p2]===0) {\n        board[p1] = board[p2] = rank; tries++;\n        steps.push({type:'TRY',rank:rank,p1:p1,p2:p2,board:board.slice(),tries:tries,backtracks:backtracks});\n        if (bt(rank+1)) return true;\n        board[p1] = board[p2] = 0; backtracks++;\n        steps.push({type:'BACK',rank:rank,p1:p1,p2:p2,board:board.slice(),tries:tries,backtracks:backtracks});\n      }\n    }\n    return false;\n  }\n  if (!bt(1)) steps.push({type:'NONE',board:board.slice(),tries:tries,backtracks:backtracks,p1:-1,p2:-1,rank:-1});\n  return steps;\n}\n\n// Apply a board-state snapshot to the visual simulation\nfunction _applyBoard(board, step) {\n  for (var i = 0; i < n*2; i++) {\n    guardX[i]=initGuardX[i]; guardY[i]=guardHeight; guardPos[i]=-1;\n    boxOccupied[i]=false; boxFillColor[i]='#FFD700';\n  }\n  score = 0;\n  var rc = {};\n  for (var pos = 0; pos < n*2; pos++) {\n    var rk = board[pos];\n    if (rk > 0) {\n      if (!rc[rk]) rc[rk]=0;\n      var gIdx = 2*(rk-1)+rc[rk]; rc[rk]++;\n      guardX[gIdx]=boxX[pos]; guardY[gIdx]=boxY[pos]; guardPos[gIdx]=pos;\n      boxOccupied[pos]=true; boxFillColor[pos]='#87CEEB'; score++;\n    }\n  }\n  if (step && step.p1>=0 && step.p2>=0) {\n    var hl = step.type==='TRY' ? '#90EE90' : '#FFB6C1';\n    boxFillColor[step.p1]=hl; boxFillColor[step.p2]=hl;\n  }\n  if (step && step.type==='SOLVED') {\n    for (var j=0; j<n*2; j++) { if (boxOccupied[j]) boxFillColor[j]='#FFD700'; }\n    score = n*2;\n  }\n  _model.update();\n}\n\nfunction _doStep() {\n  if (_solverIdx >= _solverSteps.length) { _solverRunning=false; _updateSolverUI(null); return; }\n  var step = _solverSteps[_solverIdx++];\n  _applyBoard(step.board, step);\n  solverMessage = _stepLabel(step);\n  _updateSolverUI(step);\n  if (step.type==='SOLVED' || step.type==='NONE') {\n    _solverRunning=false;\n    if (step.type==='SOLVED') {\n      setTimeout(function() {\n        _tools.showOkDialog(\"Solution found in \"+step.tries+\" tries and \"+step.backtracks+\" backtracks!\\nBoard: [\"+step.board.join(\", \")+\"]\");\n      }, 100);\n    }\n  }\n}\n\nfunction _runLoop() {\n  if (!_solverRunning || _solverPaused) return;\n  _doStep();\n  if (_solverRunning) {\n    var d = (window._solver && window._solver._delay) ? window._solver._delay : 400;\n    _solverTimer = setTimeout(_runLoop, d);\n  }\n}\n\nfunction _startSolve() {\n  if (_solverTimer) clearTimeout(_solverTimer);\n  _reset();\n  _solverSteps=_buildSteps(n); _solverIdx=0; _solverRunning=true; _solverPaused=false;\n  _updateSolverUI(null);\n  var d = (window._solver && window._solver._delay) ? window._solver._delay : 400;\n  _solverTimer = setTimeout(_runLoop, d);\n}\n\nfunction _togglePause() {\n  if (!_solverSteps || _solverSteps.length===0) { _startSolve(); return; }\n  _solverPaused = !_solverPaused;\n  if (!_solverPaused) { _solverRunning=true; _runLoop(); }\n  _updateSolverUI(null);\n}\n\nfunction _stepOnce() {\n  if (_solverTimer) { clearTimeout(_solverTimer); _solverTimer=null; }\n  _solverRunning = false;\n  if (!_solverSteps || _solverSteps.length===0) { _reset(); _solverSteps=_buildSteps(n); _solverIdx=0; }\n  _solverPaused = true; _doStep();\n}\n\nfunction _resetSolverMode() {\n  if (_solverTimer) clearTimeout(_solverTimer);\n  _solverTimer=null; _solverRunning=false; _solverPaused=false; _solverIdx=0; _solverSteps=[];\n  _reset();\n}\n\nfunction _stepLabel(step) {\n  if (!step) return '';\n  if (step.type==='TRY')    return 'Trying rank '+step.rank+' at boxes '+(step.p1+1)+' and '+(step.p2+1);\n  if (step.type==='BACK')   return 'Backtracking rank '+step.rank+' from boxes '+(step.p1+1)+' and '+(step.p2+1);\n  if (step.type==='SOLVED') return 'SOLVED in '+step.tries+' tries, '+step.backtracks+' backtracks';\n  if (step.type==='NONE')   return 'No solution for n='+n+' ('+step.tries+' tries, '+step.backtracks+' backtracks)';\n  return '';\n}\n\nfunction _updateSolverUI(step) {\n  try {\n    var sE=document.getElementById('solverStatus'),\n        stE=document.getElementById('stepCounter'),\n        tE=document.getElementById('tryCount'), bE=document.getElementById('backtrackCount'),\n        lE=document.getElementById('solverLog'), bdE=document.getElementById('boardDisplay'),\n        bsE=document.getElementById('btnAutoSolve'),\n        bpE=document.getElementById('btnPause'), btE=document.getElementById('btnStep');\n    if (!sE) return;\n    var total = _solverSteps ? _solverSteps.length : 0;\n    if (stE) stE.textContent = _solverIdx+' / '+total;\n    if (!step) {\n      if (_solverIdx===0) {\n        sE.textContent='Press Auto-Solve or One Step to start.';\n        sE.style.borderLeftColor='#3498db'; sE.style.background='#eaf2ff'; sE.style.color='#2c3e50';\n        if (bdE) bdE.textContent='';\n      }\n      if (bsE) bsE.disabled=_solverRunning;\n      if (bpE) { bpE.disabled=(_solverIdx===0); bpE.textContent=(_solverRunning&&!_solverPaused)?'Pause':'Resume'; }\n      if (btE) btE.disabled=false;\n      return;\n    }\n    if (tE) tE.textContent=step.tries||0;\n    if (bE) bE.textContent=step.backtracks||0;\n    var brd=step.board||[];\n    var brdHtml=brd.map(function(v){\n      return '<span style=\"display:inline-block;min-width:1.8em;text-align:center;'+(v>0?'background:#87CEEB;border-radius:3px;font-weight:bold;':'')+'\">'+(v===0?'_':v)+'</span>';\n    }).join(' ');\n    if (bdE) bdE.innerHTML='Board: ['+brdHtml+']';\n    var msg='', col='#3498db', bg='#eaf2ff', tc='#2c3e50';\n    if (step.type==='TRY')    { msg='Trying rank '+step.rank+' at positions '+(step.p1+1)+' and '+(step.p2+1)+' \u00e2\u20ac\u201d must be exactly '+step.rank+' apart'; col='#27ae60'; bg='#eafaf1'; tc='#1a5733'; }\n    else if (step.type==='BACK')   { msg='Backtracking rank '+step.rank+' \u00e2\u20ac\u201d no valid completion from here, trying next option'; col='#e74c3c'; bg='#fdedec'; tc='#7b241c'; }\n    else if (step.type==='SOLVED') { msg='Solution found! '+step.tries+' placements tried, '+step.backtracks+' backtracks needed'; col='#f39c12'; bg='#fef9e7'; tc='#7d6608'; }\n    else if (step.type==='NONE')   { msg='No solution exists for n='+n+' \u00e2\u20ac\u201d tried '+step.tries+' placements and '+step.backtracks+' backtracks exhaustively'; col='#e74c3c'; bg='#fdedec'; tc='#7b241c'; }\n    sE.innerHTML=msg; sE.style.borderLeftColor=col; sE.style.background=bg; sE.style.color=tc;\n    if (lE && step.type!=='SOLVED') {\n      var lc=step.type==='TRY'?'#90EE90':step.type==='BACK'?'#FFB6C1':step.type==='NONE'?'#FF6B6B':'#FFD700';\n      var bs2=(step.board||[]).map(function(v){return v===0?'_':v;}).join(',');\n      var ln=document.createElement('div');\n      ln.style.cssText='color:'+lc+';padding:1px 2px;';\n      ln.textContent='['+_solverIdx+'] '+_stepLabel(step)+'  ['+bs2+']';\n      lE.appendChild(ln); lE.scrollTop=lE.scrollHeight;\n    }\n    if (bsE) bsE.disabled=_solverRunning;\n    if (bpE) {\n      var cp=_solverRunning||(_solverIdx>0&&_solverIdx<total&&step.type!=='SOLVED'&&step.type!=='NONE');\n      bpE.disabled=!cp; bpE.textContent=(_solverRunning&&!_solverPaused)?'Pause':'Resume';\n    }\n    if (btE) btE.disabled=(_solverIdx>=total);\n  } catch(e) { console.log('SolverUI:',e); }\n}"
        }
      ]
    },
    "elements": {
      "list": []
    }
  },
  "view": {
    "Tree": [
      {
        "Name": "topPanel",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [
          {
            "name": "Width",
            "value": "\"100%\""
          },
          {
            "name": "Font",
            "value": "font"
          },
          {
            "name": "Display",
            "value": "\"inline-flex\""
          }
        ],
        "Children": [
          {
            "Name": "buttonsAutoSolver",
            "Type": "Panel",
            "Properties": [
              {
                "name": "Html",
                "value": "<style>\n  .solver-controls {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 4px; /* small gap */\n    align-items: center;\n    margin-bottom: 0px;\n  }\n\n  .solver-btn {\n    min-height: 20px;\n    padding: 4px 6px; /* reduced width */\n    border-radius: 6px;\n    border: none;\n    font-size: 0.6em;\n    font-weight: bold;\n    cursor: pointer;\n    touch-action: manipulation;\n    box-shadow: 0 1px 2px rgba(0,0,0,0.15);\n    white-space: nowrap; /* prevent stretching */\n  }\n\n  .solver-btn:active {\n    transform: scale(0.95);\n  }\n\n  .btn-start { background:#27ae60; color:#fff; }\n  .btn-pause { background:#e67e22; color:#fff; }\n  .btn-step  { background:#3498db; color:#fff; }\n</style>\n\n<div class=\"solver-controls\">\n\n  <button id=\"btnAutoSolve\"\n    class=\"solver-btn btn-start\"\n    onclick=\"window._solver && window._solver.start()\">\n    \ud83e\udd16AutoSolve\n  </button>\n\n  <button id=\"btnPause\"\n    class=\"solver-btn btn-pause\"\n    onclick=\"window._solver && window._solver.togglePause()\"\n    disabled>\n    \u23f8\n  </button>\n\n  <button id=\"btnStep\"\n    class=\"solver-btn btn-step\"\n    onclick=\"window._solver && window._solver.step()\">\n    \u23ed\n  </button>\n\n</div>"
              },
              {
                "name": "Width",
                "value": "\"30%\""
              },
              {
                "name": "Display",
                "value": "showHint?\"inline\":\"none\""
              }
            ]
          },
          {
            "Name": "label",
            "Type": "Label",
            "Properties": [
              {
                "name": "Text",
                "value": "\"Rank: 1 to\""
              },
              {
                "name": "Width",
                "value": "\"30%\""
              },
              {
                "name": "Font",
                "value": "font"
              }
            ]
          },
          {
            "Name": "comboBox",
            "Type": "ComboBox",
            "Properties": [
              {
                "name": "Options",
                "value": "[3, 4, 5, 6, 7, 8]"
              },
              {
                "name": "OnChange",
                "value": "var selected = _view.comboBox.getProperty(\"SelectedOptions\")[0];\nn = parseInt(selected);\n_reset();\n"
              },
              {
                "name": "Width",
                "value": "\"30%\""
              },
              {
                "name": "Font",
                "value": "font"
              }
            ]
          },
          {
            "Name": "reset",
            "Type": "Button",
            "Properties": [
              {
                "name": "Text",
                "value": "\"\u21bbReset\""
              },
              {
                "name": "OnClick",
                "value": "_reset();"
              },
              {
                "name": "Width",
                "value": "\"30%\""
              },
              {
                "name": "Font",
                "value": "font"
              }
            ]
          }
        ]
      },
      {
        "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": "2"
              },
              {
                "name": "XFixedTick",
                "value": "0.5"
              },
              {
                "name": "Enabled",
                "value": "true"
              },
              {
                "name": "OnDoubleClick",
                "value": "toggleFullScreen()"
              },
              {
                "name": "SquareAspect",
                "value": "true"
              },
              {
                "name": "MaximumY",
                "value": "guardHeight * 3 / 2"
              },
              {
                "name": "MaximumX",
                "value": "guardWidth * n * 2"
              },
              {
                "name": "YFixedTick",
                "value": "guardY[0]+guardHeight/2"
              },
              {
                "name": "YAutoTicks",
                "value": "false"
              },
              {
                "name": "MinimumX",
                "value": "-guardWidth"
              },
              {
                "name": "MinimumY",
                "value": "-guardHeight * 3 / 2"
              },
              {
                "name": "XTickStep",
                "value": "1"
              },
              {
                "name": "YTickStep",
                "value": "guardY[0]+guardHeight/2"
              },
              {
                "name": "XAutoTicks",
                "value": "false"
              },
              {
                "name": "Height",
                "value": "\"80vh\""
              },
              {
                "name": "XScalePrecision",
                "value": "1"
              },
              {
                "name": "Width",
                "value": "\"100%\""
              },
              {
                "name": "TLMessage",
                "value": "solverMessage"
              }
            ],
            "Children": [
              {
                "Name": "boxSet",
                "Type": "ShapeSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "n * 2"
                  },
                  {
                    "name": "FillColor",
                    "value": "boxFillColor"
                  },
                  {
                    "name": "SizeX",
                    "value": "guardWidth"
                  },
                  {
                    "name": "ShapeType",
                    "value": "\"RECTANGLE\""
                  },
                  {
                    "name": "X",
                    "value": "boxX"
                  },
                  {
                    "name": "Y",
                    "value": "boxY"
                  },
                  {
                    "name": "SizeY",
                    "value": "guardHeight"
                  }
                ]
              },
              {
                "Name": "guardSet",
                "Type": "ShapeSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "n * 2"
                  },
                  {
                    "name": "OnRelease",
                    "value": "var x = guardX[interact], y = guardY[interact];\nvar choosenBox = -1, minDist = thresholdDist * 2;\nfor(var i = 0; i < n * 2; i++){\n  if(boxOccupied[i]) continue;\n  var curX = boxX[i], curY = boxY[i];\n  var dist = (curX - x) ** 2 + (curY - y) ** 2;\n  if(dist <= minDist){ choosenBox = i; minDist = dist; }\n}\nif(guardPos[interact] != -1){\n  boxOccupied[guardPos[interact]] = false;\n  boxFillColor[guardPos[interact]] = '#FFD700';\n  score--;\n}\nvar pairCard = interact % 2 == 0 ? interact + 1 : interact - 1;\nif(choosenBox != -1 && (guardPos[pairCard] == -1 || Math.abs(guardPos[pairCard] - boxPos[choosenBox]) == guardVal[interact])){\n  guardX[interact] = boxX[choosenBox];\n  guardY[interact] = boxY[choosenBox];\n  boxOccupied[choosenBox] = true;\n  boxFillColor[choosenBox] = '#87CEEB';\n  guardPos[interact] = boxPos[choosenBox];\n  score++;\n  if(score == n * 2){\n    _tools.showOkDialog(\"Congratulations, you managed to arrange all the guards correctly!\");\n  }\n} else {\n  guardX[interact] = initGuardX[interact];\n  guardY[interact] = guardHeight;\n  guardPos[interact] = -1;\n}"
                  },
                  {
                    "name": "FillColor",
                    "value": "\"rgba(200,220,208,1)\""
                  },
                  {
                    "name": "Sensitivity",
                    "value": "0"
                  },
                  {
                    "name": "SizeX",
                    "value": "guardWidth"
                  },
                  {
                    "name": "ShapeType",
                    "value": "\"RECTANGLE\""
                  },
                  {
                    "name": "X",
                    "value": "guardX"
                  },
                  {
                    "name": "Y",
                    "value": "guardY"
                  },
                  {
                    "name": "SizeY",
                    "value": "guardHeight"
                  },
                  {
                    "name": "EnabledPosition",
                    "value": "\"ENABLED_ANY\""
                  },
                  {
                    "name": "ElementInteracted",
                    "value": "interact"
                  }
                ]
              },
              {
                "Name": "textSet",
                "Type": "TextSet2D",
                "Properties": [
                  {
                    "name": "NumberOfElements",
                    "value": "n * 2"
                  },
                  {
                    "name": "X",
                    "value": "guardX"
                  },
                  {
                    "name": "Y",
                    "value": "guardY"
                  },
                  {
                    "name": "Text",
                    "value": "textStr"
                  },
                  {
                    "name": "Font",
                    "value": "font"
                  }
                ]
              },
              {
                "Name": "offset",
                "Type": "Group2D",
                "Expanded": "false",
                "Properties": [],
                "Children": [
                  {
                    "Name": "imageSet",
                    "Type": "ImageSet2D",
                    "Properties": [
                      {
                        "name": "NumberOfElements",
                        "value": "n * 2"
                      },
                      {
                        "name": "SizeX",
                        "value": "guardWidth"
                      },
                      {
                        "name": "X",
                        "value": "guardX"
                      },
                      {
                        "name": "Y",
                        "value": "guardY"
                      },
                      {
                        "name": "ImageUrl",
                        "value": "imageurl"
                      },
                      {
                        "name": "SizeY",
                        "value": "guardHeight"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "Name": "html",
        "Type": "Panel",
        "Properties": [
          {
            "name": "Html",
            "value": "<p><b>Instructions:</b> Choose the number of guard ranks and drag each guard into the yellow boxes. </p><iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/HgTgImPw0t0?si=LzHacDoxeiPTPHHF\" 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>\n<p><b>Rule:</b> Two guards of rank <em>k</em> must be placed exactly <em>k</em> boxes apart (|pos2 - pos1| = k). Example: two Rank-3 guards must be 3 positions apart.</p><div style=\"font-family:Arial,sans-serif;padding:8px 12px;line-height:1.6;\">\n\n  <p style=\"margin:4px 0 8px;\">\n    <b>\ud83c\udfaf Goal:</b> Place all <b>2n guards</b> into the numbered boxes below\n    so that every pair follows the spacing rule.\n  </p>\n\n  <div style=\"background:#fff3cd;border-left:4px solid #f0c040;border-radius:6px;padding:8px 12px;margin-bottom:10px;\">\n    <b>\ud83d\udccf The Rule:</b> The two guards of rank <em>k</em> must be placed\n    exactly <em>k</em> boxes apart.<br>\n    Formally: &nbsp;<code style=\"background:#ffeaa7;padding:2px 6px;border-radius:3px;\">|position\u2082 \u2212 position\u2081| = k</code>\n  </div>\n\n  <b>\ud83d\udcd6 Example</b> (n = 4, boxes numbered 1\u20138):\n  <table style=\"border-collapse:collapse;margin:6px 0 10px;font-size:0.88em;\">\n    <tr>\n      <td style=\"padding:2px 6px;color:#888;\">Box&nbsp;#</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">1</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">2</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">3</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">4</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">5</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">6</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">7</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fffde7;min-width:28px;\">8</td>\n    </tr>\n    <tr>\n      <td style=\"padding:2px 6px;color:#888;\">Guard</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#c8e6c9;font-weight:bold;\">4</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#bbdefb;font-weight:bold;\">1</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#bbdefb;font-weight:bold;\">1</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fff9c4;font-weight:bold;\">3</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#c8e6c9;font-weight:bold;\">4</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fce4ec;font-weight:bold;\">2</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fff9c4;font-weight:bold;\">3</td>\n      <td style=\"padding:2px 8px;text-align:center;border:1px solid #ccc;background:#fce4ec;font-weight:bold;\">2</td>\n    </tr>\n  </table>\n\n  <ul style=\"margin:0 0 6px;padding-left:20px;font-size:0.9em;\">\n    <li>Rank&nbsp;<b>1</b> at boxes 2 &amp; 3 \u2192 apart by <b>1</b> \u2713</li>\n    <li>Rank&nbsp;<b>2</b> at boxes 6 &amp; 8 \u2192 apart by <b>2</b> \u2713</li>\n    <li>Rank&nbsp;<b>3</b> at boxes 4 &amp; 7 \u2192 apart by <b>3</b> \u2713</li>\n    <li>Rank&nbsp;<b>4</b> at boxes 1 &amp; 5 \u2192 apart by <b>4</b> \u2713</li>\n  </ul>\n\n  <p style=\"margin:4px 0;font-size:0.88em;color:#555;\">\n    \ud83d\udca1 <em>Drag a guard from the top row into a yellow box below.\n    Invalid placements snap back automatically.\n    Use <b>Auto-Solve</b> below to watch the computer find the solution step by step!</em>\n  </p>\n\n</div>"
          }
        ]
      },
      {
        "Name": "solverPanel",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [
          {
            "name": "Html",
            "value": "<div id=\"solverSection\" style=\"font-family:Arial,sans-serif;padding:12px 16px;box-sizing:border-box;\">\n\n  <h3 style=\"color:#2c3e50;margin:0 0 8px;font-size:1.1em;\">\n    \ud83e\udd16 Computer Solver \u2014 Watch the Thinking Process\n  </h3>\n\n  <div style=\"background:#f0f4f8;border-left:4px solid #3498db;border-radius:6px;padding:10px 14px;margin-bottom:10px;font-size:0.85em;line-height:1.5;\">\n    <strong>About:</strong> The computer uses <strong>backtracking search</strong> \u2014 it tries each placement in order. If stuck, it undoes the last move and tries the next option (like navigating a maze by always going back when you hit a dead-end).\n    <br><strong>Colour code:</strong>\n    <span style=\"background:#90EE90;padding:1px 5px;border-radius:3px;\">green = trying now</span>\n    &nbsp;\n    <span style=\"background:#FFB6C1;padding:1px 5px;border-radius:3px;\">pink = backtracked</span>\n    &nbsp;\n    <span style=\"background:#87CEEB;padding:1px 5px;border-radius:3px;\">blue = placed on path</span>\n  </div>\n\n  <!-- Stats -->\n  <div style=\"display:flex;gap:16px;font-size:0.82em;color:#555;margin-bottom:8px;\">\n    <span>Step: <strong id=\"stepCounter\">0 / 0</strong></span>\n    <span>Tries: <strong id=\"tryCount\" style=\"color:#27ae60;\">0</strong></span>\n    <span>Backtracks: <strong id=\"backtrackCount\" style=\"color:#e74c3c;\">0</strong></span>\n  </div>\n\n  <!-- Status -->\n  <div id=\"solverStatus\"\n    style=\"background:#eaf2ff;border-left:4px solid #3498db;padding:8px 12px;border-radius:4px;margin-bottom:8px;min-height:28px;font-size:0.88em;line-height:1.4;color:#2c3e50;\">\n    Press Auto-Solve or One Step to start.\n  </div>\n\n  <!-- Board -->\n  <div id=\"boardDisplay\"\n    style=\"font-family:monospace;font-size:0.88em;padding:6px 10px;background:#f8f9fa;border-radius:4px;margin-bottom:8px;min-height:24px;\">\n  </div>\n\n  <!-- Log -->\n  <details>\n    <summary style=\"cursor:pointer;font-weight:bold;font-size:0.88em;color:#2c3e50;padding:4px 0;\">\n      \ud83d\udccb Step Log (click to expand)\n    </summary>\n\n    <div style=\"display:flex;justify-content:flex-end;margin:4px 0;\">\n      <button onclick=\"var l=document.getElementById('solverLog');if(l)l.innerHTML='';\"\n        style=\"background:none;border:1px solid #ccc;padding:2px 8px;border-radius:4px;cursor:pointer;font-size:0.8em;color:#666;\">\n        Clear\n      </button>\n    </div>\n\n    <div id=\"solverLog\"\n      style=\"background:#1e1e1e;color:#d4d4d4;font-family:monospace;font-size:0.78em;padding:8px;border-radius:4px;max-height:200px;overflow-y:auto;\">\n    </div>\n  </details>\n\n  <!-- Pattern Info -->\n  <div style=\"background:#fff9e6;border:1px solid #f0c040;border-radius:8px;padding:10px 14px;margin-top:12px;font-size:0.84em;line-height:1.5;\">\n    <strong>\ud83e\udde0 When does a solution exist?</strong><br>\n    n=3 \u274c &nbsp; n=4 \u2705 (4 1 1 3 4 2 3 2) &nbsp; n=5 \u2705 (2 3 2 5 3 4 1 1 5 4) &nbsp; n=6 \u274c &nbsp; n=7 \u274c &nbsp; n=8 \u2705\n\n    <details>\n      <summary style=\"cursor:pointer;color:#2980b9;\">Reveal the pattern</summary>\n      Solutions exist when <strong>n mod 4 = 0 or 3</strong> (standard Langford problem). Backtracking <em>proves</em> no solution by exhaustively testing every possibility.\n    </details>\n  </div>\n\n</div>"
          },
          {
            "name": "Display",
            "value": "showHint?\"inline\":\"none\""
          }
        ],
        "Children": []
      },
      {
        "Name": "hint",
        "Type": "Panel",
        "Expanded": "true",
        "Properties": [],
        "Children": [
          {
            "Name": "button",
            "Type": "Button",
            "Properties": [
              {
                "name": "Text",
                "value": "\"Hint?\""
              },
              {
                "name": "OnClick",
                "value": "if (showHint==true)\n{showHint=false}\nelse if (showHint==false)\n{showHint=true}"
              }
            ]
          }
        ]
      }
    ],
    "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/"
  }
}