{"id":17,"date":"2026-09-07T22:17:38","date_gmt":"2026-09-07T22:17:38","guid":{"rendered":"https:\/\/www.gizmo421.info\/?page_id=17"},"modified":"2026-09-07T22:27:53","modified_gmt":"2026-09-07T22:27:53","slug":"17-2","status":"publish","type":"page","link":"https:\/\/www.gizmo421.info\/index.php\/17-2\/","title":{"rendered":""},"content":{"rendered":"<p><!DOCTYPE html><br \/>\n<html lang=\"en\"><br \/>\n<head><br \/>\n  <meta charset=\"UTF-8\"><br \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><br \/>\n  <title>Monkeytype Clone Preview<\/title><\/p>\n<style>\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=Roboto+Mono:wght@400;500;700&display=swap');<\/p>\n<p>    body {\n      background-color: #1e1e1e;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      min-height: 100vh;\n      margin: 0;\n    }<\/p>\n<p>    .mt-wrapper {\n      --mt-bg: #323437;\n      --mt-main: #e2b714;\n      --mt-caret: #e2b714;\n      --mt-sub: #646669;\n      --mt-text: #d1d0c5;\n      --mt-error: #ca4754;\n      --mt-error-sub: #7e2a33;<\/p>\n<p>      background-color: var(--mt-bg);\n      color: var(--mt-text);\n      font-family: 'Roboto Mono', monospace;\n      padding: 40px;\n      border-radius: 12px;\n      width: 100%;\n      max-width: 950px;\n      position: relative;\n      min-height: 400px;\n      display: flex;\n      flex-direction: column;\n      justify-content: space-between;\n      box-shadow: 0 10px 30px rgba(0,0,0,0.5);\n    }<\/p>\n<p>    .mt-header {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin-bottom: 2rem;\n    }<\/p>\n<p>    .mt-logo {\n      font-size: 1.5rem;\n      font-weight: 700;\n      color: var(--mt-text);\n      letter-spacing: -1px;\n    }<\/p>\n<p>    .mt-logo span { color: var(--mt-main); }<\/p>\n<p>    .mt-modes {\n      display: flex;\n      align-items: center;\n      background-color: #2c2e31;\n      padding: 6px 14px;\n      border-radius: 8px;\n      gap: 12px;\n    }<\/p>\n<p>    .mt-mode-group { display: flex; gap: 8px; }\n    .mt-divider { width: 2px; height: 16px; background-color: var(--mt-sub); opacity: 0.3; }<\/p>\n<p>    .mt-btn {\n      background: none;\n      border: none;\n      color: var(--mt-sub);\n      font-family: inherit;\n      font-size: 0.85rem;\n      font-weight: 700;\n      cursor: pointer;\n      transition: color 0.15s ease;\n    }<\/p>\n<p>    .mt-btn:hover, .mt-btn.active { color: var(--mt-main); }<\/p>\n<p>    .mt-live-stats { font-size: 1.8rem; color: var(--mt-main); height: 40px; margin-bottom: 10px; }<\/p>\n<p>    .mt-typing-area {\n      position: relative;\n      font-size: 1.5rem;\n      line-height: 2.3rem;\n      height: 110px;\n      overflow: hidden;\n      cursor: default;\n    }<\/p>\n<p>    #mt-hidden-input { position: absolute; opacity: 0; left: -9999px; }\n    #mt-words { display: flex; flex-wrap: wrap; gap: 0.6em; transition: transform 0.15s ease; }\n    .mt-word { display: flex; color: var(--mt-sub); }\n    .mt-char { position: relative; }\n    .mt-char.correct { color: var(--mt-text); }\n    .mt-char.incorrect { color: var(--mt-error); }\n    .mt-char.extra { color: var(--mt-error-sub); }<\/p>\n<p>    #mt-caret {\n      position: absolute;\n      width: 2px;\n      height: 1.8rem;\n      background-color: var(--mt-caret);\n      border-radius: 1px;\n      transition: all 0.08s ease;\n      animation: mt-blink 1s infinite;\n    }<\/p>\n<p>    @keyframes mt-blink {\n      0%, 100% { opacity: 1; }\n      50% { opacity: 0; }\n    }<\/p>\n<p>    .mt-focus-notice {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      gap: 8px;\n      position: absolute;\n      top: 0; left: 0; right: 0; bottom: 0;\n      background-color: rgba(50, 52, 55, 0.85);\n      backdrop-filter: blur(2px);\n      color: var(--mt-text);\n      font-size: 1rem;\n      border-radius: 12px;\n      opacity: 0;\n      pointer-events: none;\n      transition: opacity 0.2s ease;\n    }<\/p>\n<p>    .mt-wrapper.blur .mt-focus-notice { opacity: 1; pointer-events: auto; }<\/p>\n<p>    .mt-results { display: none; gap: 40px; align-items: center; margin-top: 20px; }\n    .mt-results.active { display: flex; }\n    .mt-typing-area.hidden { display: none; }<\/p>\n<p>    .mt-stat-label { font-size: 0.9rem; color: var(--mt-sub); }\n    .mt-stat-value { font-size: 3.5rem; color: var(--mt-main); font-weight: 700; line-height: 1; }<\/p>\n<p>    .mt-icon-btn {\n      background: none;\n      border: none;\n      color: var(--mt-sub);\n      cursor: pointer;\n      margin-left: auto;\n      transition: color 0.2s ease;\n    }\n    .mt-icon-btn:hover { color: var(--mt-text); }\n  <\/style>\n<p><\/head><br \/>\n<body><\/p>\n<div class=\"mt-wrapper\">\n<header class=\"mt-header\">\n<div class=\"mt-logo\">monkey<span>type<\/span><\/div>\n<div class=\"mt-modes\">\n<div class=\"mt-mode-group\">\n        <button class=\"mt-btn active\" data-mode=\"time\">time<\/button><br \/>\n        <button class=\"mt-btn\" data-mode=\"words\">words<\/button>\n      <\/div>\n<div class=\"mt-divider\"><\/div>\n<div class=\"mt-mode-group\" id=\"time-options\">\n        <button class=\"mt-btn active\" data-val=\"15\">15<\/button><br \/>\n        <button class=\"mt-btn\" data-val=\"30\">30<\/button><br \/>\n        <button class=\"mt-btn\" data-val=\"60\">60<\/button>\n      <\/div>\n<div class=\"mt-mode-group\" id=\"word-options\" style=\"display: none;\">\n        <button class=\"mt-btn\" data-val=\"10\">10<\/button><br \/>\n        <button class=\"mt-btn active\" data-val=\"25\">25<\/button><br \/>\n        <button class=\"mt-btn\" data-val=\"50\">50<\/button>\n      <\/div>\n<\/p><\/div>\n<\/header>\n<div class=\"mt-live-stats\"><span id=\"mt-counter\">15<\/span><\/div>\n<div class=\"mt-typing-area\" id=\"mt-typing-area\">\n    <input type=\"text\" id=\"mt-hidden-input\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" autofocus \/><\/p>\n<div id=\"mt-caret\"><\/div>\n<div id=\"mt-words\"><\/div>\n<\/p><\/div>\n<div id=\"mt-focus-notice\" class=\"mt-focus-notice\">\n    <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"><\/line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"><\/line><\/svg><br \/>\n    Click or press any key to focus\n  <\/div>\n<div class=\"mt-results\" id=\"mt-results\">\n<div class=\"mt-stat-block\">\n<div class=\"mt-stat-label\">wpm<\/div>\n<div class=\"mt-stat-value\" id=\"mt-res-wpm\">0<\/div>\n<\/p><\/div>\n<div class=\"mt-stat-block\">\n<div class=\"mt-stat-label\">acc<\/div>\n<div class=\"mt-stat-value\" id=\"mt-res-acc\">0%<\/div>\n<\/p><\/div>\n<div class=\"mt-stat-block\">\n<div class=\"mt-stat-label\">raw<\/div>\n<div class=\"mt-stat-value\" id=\"mt-res-raw\">0<\/div>\n<\/p><\/div>\n<p>    <button id=\"mt-restart-btn\" class=\"mt-icon-btn\" title=\"Restart Test\"><br \/>\n      <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M21.5 2v6h-6M21.34 15.57a10 10 0 1 1-.57-8.38l5.67-5.67\"><\/path><\/svg><br \/>\n    <\/button>\n  <\/div>\n<\/div>\n<p><script>\ndocument.addEventListener('DOMContentLoaded', () => {\n  const dictionary = [\"the\",\"be\",\"of\",\"and\",\"a\",\"to\",\"in\",\"he\",\"have\",\"it\",\"that\",\"for\",\"they\",\"with\",\"as\",\"not\",\"on\",\"she\",\"at\",\"by\",\"this\",\"we\",\"you\",\"do\",\"but\",\"from\",\"or\",\"which\",\"one\",\"would\",\"all\",\"will\",\"there\",\"say\",\"who\",\"make\",\"when\",\"can\",\"more\",\"if\",\"no\",\"man\",\"out\",\"other\",\"so\",\"what\",\"time\",\"up\",\"go\",\"about\",\"than\",\"into\",\"could\",\"state\",\"only\",\"new\",\"year\",\"some\",\"take\",\"them\",\"see\",\"know\",\"take\",\"people\",\"into\",\"year\",\"your\",\"good\",\"some\",\"could\"];<\/p>\n<p>  let mode = 'time', targetVal = 15, timer = null, timeLeft = 15, isRunning = false;\n  let wordList = [], wordIdx = 0, charIdx = 0, correctChars = 0, totalTyped = 0;<\/p>\n<p>  const wrapper = document.querySelector('.mt-wrapper'), input = document.getElementById('mt-hidden-input');\n  const wordsEl = document.getElementById('mt-words'), caret = document.getElementById('mt-caret');\n  const counterEl = document.getElementById('mt-counter'), resultsEl = document.getElementById('mt-results');\n  const typingArea = document.getElementById('mt-typing-area');<\/p>\n<p>  function init() {\n    clearInterval(timer); isRunning = false; wordIdx = 0; charIdx = 0; correctChars = 0; totalTyped = 0; input.value = '';\n    resultsEl.classList.remove('active'); typingArea.classList.remove('hidden');<\/p>\n<p>    if (mode === 'time') { timeLeft = targetVal; counterEl.textContent = timeLeft; buildWords(100); } \n    else { counterEl.textContent = `0\/${targetVal}`; buildWords(targetVal); }<\/p>\n<p>    positionCaret(); input.focus();\n  }<\/p>\n<p>  function buildWords(count) {\n    wordList = []; wordsEl.innerHTML = '';\n    for (let i = 0; i < count; i++) {\n      const word = dictionary[Math.floor(Math.random() * dictionary.length)];\n      wordList.push(word);\n      const wDiv = document.createElement('div'); wDiv.className = 'mt-word';\n      word.split('').forEach(ch => {\n        const cSpan = document.createElement('span'); cSpan.className = 'mt-char'; cSpan.textContent = ch; wDiv.appendChild(cSpan);\n      });\n      wordsEl.appendChild(wDiv);\n    }\n  }<\/p>\n<p>  function positionCaret() {\n    const currentWord = wordsEl.children[wordIdx]; if (!currentWord) return;\n    const chars = currentWord.children; let targetEl = chars[charIdx];<\/p>\n<p>    if (targetEl) { caret.style.left = targetEl.offsetLeft + 'px'; caret.style.top = targetEl.offsetTop + 'px'; } \n    else if (chars.length > 0) {\n      const lastChar = chars[chars.length - 1];\n      caret.style.left = (lastChar.offsetLeft + lastChar.offsetWidth) + 'px'; caret.style.top = lastChar.offsetTop + 'px';\n    }<\/p>\n<p>    if (targetEl && targetEl.offsetTop > 40) wordsEl.style.transform = `translateY(-${targetEl.offsetTop}px)`;\n    else if (wordIdx === 0) wordsEl.style.transform = 'translateY(0px)';\n  }<\/p>\n<p>  function startEngine() {\n    isRunning = true;\n    if (mode === 'time') {\n      timer = setInterval(() => { timeLeft--; counterEl.textContent = timeLeft; if (timeLeft <= 0) finish(); }, 1000);\n    }\n  }\n\n  input.addEventListener('input', (e) => {\n    if (!isRunning) startEngine();\n    const currentWord = wordList[wordIdx], wordEl = wordsEl.children[wordIdx], val = input.value;\n    totalTyped++;<\/p>\n<p>    if (e.inputType === 'deleteContentBackward') {\n      if (charIdx > 0) {\n        charIdx--; const charEl = wordEl.children[charIdx];\n        if (charEl.classList.contains('extra')) charEl.remove(); else charEl.className = 'mt-char';\n      }\n    } else if (val.endsWith(' ')) {\n      if (charIdx > 0) {\n        wordIdx++; charIdx = 0; input.value = '';\n        if (mode === 'words') { counterEl.textContent = `${wordIdx}\/${targetVal}`; if (wordIdx >= targetVal) finish(); }\n      }\n    } else {\n      const typedChar = val[val.length - 1], chars = wordEl.children;\n      if (charIdx < currentWord.length) {\n        if (typedChar === currentWord[charIdx]) { chars[charIdx].classList.add('correct'); correctChars++; } \n        else chars[charIdx].classList.add('incorrect');\n        charIdx++;\n      } else if (chars.length < currentWord.length + 10) {\n        const extraSpan = document.createElement('span'); extraSpan.className = 'mt-char extra'; extraSpan.textContent = typedChar;\n        wordEl.appendChild(extraSpan); charIdx++;\n      }\n    }\n    positionCaret();\n  });\n\n  function finish() {\n    clearInterval(timer); isRunning = false; typingArea.classList.add('hidden');\n    let elapsedMin = mode === 'time' ? (targetVal \/ 60) : 0.5;\n    let wpm = Math.round((correctChars \/ 5) \/ elapsedMin), acc = totalTyped > 0 ? Math.round((correctChars \/ totalTyped) * 100) : 0;<\/p>\n<p>    document.getElementById('mt-res-wpm').textContent = isNaN(wpm) ? 0 : wpm;\n    document.getElementById('mt-res-acc').textContent = `${acc}%`;\n    document.getElementById('mt-res-raw').textContent = Math.round((totalTyped \/ 5) \/ elapsedMin) || 0;\n    resultsEl.classList.add('active');\n  }<\/p>\n<p>  wrapper.addEventListener('click', () => input.focus());\n  input.addEventListener('focus', () => wrapper.classList.remove('blur'));\n  input.addEventListener('blur', () => wrapper.classList.add('blur'));<\/p>\n<p>  document.querySelectorAll('.mt-btn').forEach(btn => {\n    btn.addEventListener('click', (e) => {\n      e.target.closest('.mt-mode-group').querySelectorAll('.mt-btn').forEach(b => b.classList.remove('active'));\n      e.target.classList.add('active');\n      if (e.target.dataset.mode) {\n        mode = e.target.dataset.mode;\n        document.getElementById('time-options').style.display = mode === 'time' ? 'flex' : 'none';\n        document.getElementById('word-options').style.display = mode === 'words' ? 'flex' : 'none';\n        targetVal = mode === 'time' ? 15 : 25;\n      } else if (e.target.dataset.val) targetVal = parseInt(e.target.dataset.val);\n      init();\n    });\n  });<\/p>\n<p>  document.getElementById('mt-restart-btn').addEventListener('click', init);\n  init();\n});\n<\/script><br \/>\n<\/body><br \/>\n<\/html><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Monkeytype Clone Preview monkeytype time words 15 30 60 10 25 50 15 Click or press any key to focus wpm 0 acc 0% raw 0<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-17","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/pages\/17","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/comments?post=17"}],"version-history":[{"count":6,"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/pages\/17\/revisions"}],"predecessor-version":[{"id":23,"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/pages\/17\/revisions\/23"}],"wp:attachment":[{"href":"https:\/\/www.gizmo421.info\/index.php\/wp-json\/wp\/v2\/media?parent=17"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}