1const memoryGridConfig = { 2 small: { cols: 6, max: 6 }, 3 medium: { cols: 4, max: 8 }, 4 big: { cols: 6, max: 12 }, 5}; 6 7let memoryFiles = []; 8 9function getMemoryMode() { 10 return $('#input-question-memory').val() || 'small'; 11} 12 13function getMemoryConfig() { 14 return memoryGridConfig[getMemoryMode()] || memoryGridConfig.small; 15} 16 17function syncMemoryFilesToForm() { 18 const dt = new DataTransfer(); 19 memoryFiles.forEach(file => dt.items.add(file)); 20 const syncInput = document.getElementById('memory-image-sync'); 21 if (syncInput) syncInput.files = dt.files; 22} 23 24function addMemoryFile() { 25 const { max } = getMemoryConfig(); 26 if (memoryFiles.length >= max) { 27 show.error({ text: `Grid preenchido (${max}/${max}).`, close: true }); 28 return; 29 } 30 $('#memory-image-input').trigger('click'); 31} 32 33function renderMemoryGrid() { 34 const grid = $('#memory-images'); 35 const { cols, max } = getMemoryConfig(); 36 37 if (memoryFiles.length > max) { 38 memoryFiles = memoryFiles.slice(0, max); 39 } 40 41 grid.css('grid-template-columns', `repeat(${cols}, minmax(0, 1fr))`); 42 grid.empty(); 43 44 for (let i = 0; i < max; i++) { 45 if (memoryFiles[i]) { 46 const url = URL.createObjectURL(memoryFiles[i]); 47 grid.append(` 48 <div class="memory-slot"> 49 <img src="${url}" alt="Imagem ${i + 1}"> 50 <button type="button" class="memory-remove" data-index="${i}">Ã</button> 51 </div> 52 `); 53 } else { 54 grid.append(`<div class="memory-slot empty"></div>`); 55 } 56 } 57 58 syncMemoryFilesToForm(); 59} 60 61function loadMemoryGrid(files) { 62 if (!files) return; 63 64 const grid = $('#memory-images'); 65 const { cols, max } = getMemoryConfig(); 66 67 const limitedFiles = files.slice(0, max); 68 69 grid.css('grid-template-columns', `repeat(${cols}, minmax(0, 1fr))`); 70 grid.empty(); 71 72 for (let i = 0; i < max; i++) { 73 const url = limitedFiles[i]; 74 75 if (url) { 76 const safeUrl = encodeURI(url); 77 78 const slot = $(` 79 <div class="memory-slot"> 80 <img loading="lazy" src="${safeUrl}" alt="Imagem ${i + 1}"> 81 <button type="button" class="memory-remove" data-index="${i}">Ã</button> 82 </div> 83 `); 84 85 grid.append(slot); 86 } else { 87 grid.append(`<div class="memory-slot empty"></div>`); 88 } 89 } 90} 91 92let jogadas = 0; 93let acertos = 0; 94let erros = 0; 95let acertosTotal = 0; 96 97let tempo = 0; 98let timer = null; 99 100let clickCard = null; 101let slot1 = null; 102let slot2 = null; 103let lock = false; 104 105function atualizarHUD() { 106 $("#hud-tempo").text(tempo); 107 $("#hud-jogadas").text(jogadas); 108 $("#hud-acertos").text(acertos); 109 $("#hud-erros").text(erros); 110 111 $("#points-memory").val(acertos); 112 $("#erros-memory").val(erros); 113 $("#time-memory").val(tempo); 114 $("#plays-memory").val(jogadas); 115} 116 117function iniciarTimer() { 118 if (timer) clearInterval(timer); 119 120 tempo = 0; 121 timer = setInterval(() => { 122 tempo++; 123 atualizarHUD(); 124 }, 1000); 125} 126 127function animacaoVitoria() { 128 show.success({ text:"ð Parabéns! Você completou o jogo!"}); 129 $(".memory-slot").addClass("vitoria"); 130 131 setTimeout(() => { 132 $(".memory-slot").removeClass("vitoria"); 133 }, 1500); 134} 135 136function verificarVitoria(totalPares) { 137 if (acertos === totalPares) { 138 clearInterval(timer); 139 animacaoVitoria(); 140 } 141} 142 143function resetSelection() { 144 card1 = card2 = null; 145 slot1 = slot2 = null; 146 lock = false; 147} 148 149 150// 4. Clique 151$(document).on('click', '.memory-slot', function (e) { 152 const slot = $(this); 153 154 lock = true; 155 156 // impede clicar na mesma carta ou em carta já resolvida 157 if (slot.hasClass('flipped') || slot.hasClass('matched')) return; 158 159 slot.addClass('flipped'); 160 clickMemorySlot(slot); 161 162 e.stopPropagation(); 163}); 164 165function clickMemorySlot(slot) { 166 jogadas++; 167 if ($('.flipped').length === 2) { 168 $('.flipped').each(function() { 169 if (!$(this).hasClass('matched')) { 170 if ( $(this).data('id') === slot.data('id') && $(this).data('slot') !== slot.data('slot') ) { 171 acertos++; 172 slot.addClass('matched').removeClass('flipped'); 173 $(this).addClass('matched').removeClass('flipped'); 174 setTimeout(() => { resetSelection(); lock = false; verificarVitoria(acertosTotal); }, 300); 175 } else { 176 erros++; 177 178 setTimeout(() => { 179 slot.removeClass('flipped'); 180 $(this).removeClass('flipped'); 181 182 resetSelection(); 183 lock = false;
184 }, 700); 185 } 186 } 187 }) 188 } 189 190 lock = false; 191 atualizarHUD(); 192} 193 194function generateQuizMemory(id, files) { 195 if (!files) return; 196 197 $('#quiz-option').append(` 198 <div id="hud" class="hud-memory"> 199 <span>â± Tempo: <span id="hud-tempo">0</span>s</span> 200 <span>ð¯ Jogadas: <span id="hud-jogadas">0</span></span> 201 <span>â Acertos: <span id="hud-acertos">0</span></span> 202 <span>â Erros: <span id="hud-erros">0</span></span> 203 204 <input type="text" name="points" id="points-memory" hidden/> 205 <input type="text" name="erros" id="erros-memory" hidden/> 206 <input type="text" name="time" id="time-memory" hidden/> 207 <input type="text" name="plays" id="plays-memory" hidden/> 208 <input hidden name="answer" value="${id}" /> 209 </div> 210 211 212 <div class="d-flex justify-content-center start-memory-game"> 213 <div id="memory-images" class="memory-grid mt-3"></div> 214 </div> 215 `); 216 217 const grid = $('#memory-images'); 218 const { cols, max } = getMemoryConfig(); 219 220 // 1. Cria pares com ID fixo 221 const base = files.slice(0, max).map((url, i) => ({ 222 id: i, 223 url: decodeURIComponent(url) 224 })); 225 226 const pairs = [...base, ...base]; 227 228 // 2. Embaralha 229 for (let i = pairs.length - 1; i > 0; i--) { 230 const j = Math.floor(Math.random() * (i + 1)); 231 [pairs[i], pairs[j]] = [pairs[j], pairs[i]]; 232 } 233 234 grid.css('grid-template-columns', `repeat(${cols}, minmax(0, 1fr))`); 235 grid.empty(); 236 237 // 3. Monta o grid 238 pairs.forEach((card, i) => { 239 grid.append(` 240 <div class="memory-slot" data-id="${card.id}" data-slot="${i}"> 241 <div class="card-inner"> 242 <div class="card-front"></div> 243 <div class="card-back"> 244 <img loading="lazy" src="${card.url}"> 245 </div> 246 </div> 247 </div> 248 `); 249 }); 250 251 acertos = 0; 252 erros = 0; 253 jogadas = 0; 254 acertosTotal = max; // quantidade de pares 255 atualizarHUD(); 256 iniciarTimer(); 257 258} 259 260 261
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.