- // ==UserScript==
- // @name Wirelyre Select Saves (with next pc save)
- // @namespace http://tampermonkey.net/
- // @version 0.1
- // @description save selection
- // @author 13pake, TamTheBoss111
- // @match https://wirelyre.github.io/tetra-tools/pc-solver.html*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=github.io
- // @grant GM_addStyle
- // @license MIT
- // ==/UserScript==
-
- (function() {
- 'use strict';
-
- GM_addStyle("#solutions > a { border-radius: 4px; }");
- GM_addStyle("#solutions { row-gap: 20px; }");
- GM_addStyle("#select-save { background-color: rgba(0,0,0,0.2); color: #fff; border: 1px solid rgba(0,0,0,0.3); margin-left: 5px; }");
- GM_addStyle("#label-save { margin-top: 10px; }");
-
- // Constants
- var pieces = ['T', 'I', 'L', 'J', 'S', 'Z', 'O'];
- var colors = [
- 'rgb(180, 81, 172)', // purple
- 'rgb(65, 175, 222)', // cyan
- 'rgb(239, 149, 54)', // orange
- 'rgb(24, 131, 191)', // blue
- 'rgb(102, 198, 92)', // green
- 'rgb(239, 98, 77)', // red
- 'rgb(247, 211, 62)', // yellow
- ];
- var remainingPieces = [4, 1, 5, 2, 6, 3, 7];
- var piecesUsed = [3, 6, 2, 5, 1, 4, 0];
- var pcNumSelectOptions = ["1st", "2nd", "3rd", "4th", "5th", "6th", "7th"]
-
-
- window.onload = function() {
-
- // Add save selection
- var label = document.createElement('label');
- label.id = 'label-save';
- label.innerHTML = 'Save';
- document.querySelectorAll('#query > div:nth-child(6)')[0].appendChild(label);
-
- var select = document.createElement('select');
- label.appendChild(select);
- select.id = 'select-save';
-
- var selectOptions = ['All', ...pieces];
-
- for (var i = 0; i < selectOptions.length; i++) {
- var option = document.createElement('option');
- option.value = selectOptions[i];
- option.text = selectOptions[i];
- select.appendChild(option);
- }
-
- // Add pc num selection
- var pcNumLabel = document.createElement('label');
- pcNumLabel.id = 'label-pc-num';
- pcNumLabel.innerHTML = 'PC # ';
- document.querySelectorAll('#query > div:nth-child(6)')[0].appendChild(pcNumLabel);
-
- // Create the slider
- var pcNumSlider = document.createElement('input');
- pcNumSlider.type = 'range';
- pcNumSlider.id = 'slider-pc-num';
- pcNumSlider.min = '1';
- pcNumSlider.max = '7';
- pcNumSlider.step = '1';
- pcNumSlider.value = '1';
- pcNumLabel.appendChild(pcNumSlider);
-
- // Display the selected value
- var pcNumDisplay = document.createElement('span');
- pcNumDisplay.id = 'slider-value';
- pcNumDisplay.innerHTML = '1'; // Default value
- pcNumLabel.appendChild(pcNumDisplay);
-
- // Update the displayed value when the slider changes
- pcNumSlider.addEventListener('input', function () {
- pcNumDisplay.innerHTML = pcNumSlider.value;
-
- var queue = document.getElementById('queue').value;
-
- // check if queue is just pieces
- var piecesOnlyMatch = queue.match(/^[TILJSZO]*$/);
- if (piecesOnlyMatch) {
- //console.log('good queue');
- } else {
- return;
- }
-
- var queuePieces = pieces.map(function(piece) {
- return (queue.split(piece).length - 1);
- });
-
- // We're just gonna assume the queue length is correct !!!
-
- //console.log('queue pieces', queuePieces);
- var solutionsContainer = document.getElementById('solutions');
-
- // Loop over all 'a' tags inside the solutions container
- var aTags = solutionsContainer.getElementsByTagName('a');
- for (let aNode of aTags) {
- // console.log('A child node has been added or removed.', mutation.addedNodes[0]);
- try {
- var dataField = aNode.firstChild.getAttribute('data-field');
- var solutionPieces = pieces.map(function(piece) {
- return (dataField.split(piece).length - 1) / 4;
- });
- //console.log('pieces used', solutionPieces);
-
- // get difference between arrays
- var differentIndex = -1;
- for (let i = 0; i < queuePieces.length; i++) {
- if (queuePieces[i] !== solutionPieces[i]) {
- differentIndex = i;
- }
- }
- // console.log('saved piece', pieces[differentIndex]);
- aNode.style.borderTop = "10px solid " + colors[differentIndex];
- aNode.classList.add(pieces[differentIndex]);
-
- // Calculate what PC comes from this save
- let bag = new Set(["T", "I", "J", "L", "O", "S", "Z"]);
- // console.log("queuevalue", queue)
-
- let currentPCNum = pcNumSlider.value - 1; // -1 so that its an index starting from 0
-
- // If there is a saved piece (4p setup with see7/3p setup with see8)
- if (differentIndex != -1) {
- // console.log(piecesUsed[currentPCNum], currentPCNum);
- for (let j = 1; j < piecesUsed[currentPCNum] + 2; j++) {
- // console.log("inloop")
- // console.log("piece to remove", queue[queue.length - j])
- bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag
- // console.log("bag currently: ", Array.from(bag).join(""))
- }
- var save = Array.from(bag).join("");
- //console.log("final save", save);
- // Add the saved piece
-
- // If there is a saved piece (4p setup with see7/3p setup with see8)
- save += pieces[differentIndex];
- // console.log("final save", save);
-
- // Reorder the string
- const chars = save.split("");
-
- const correctOrder = "TIJLOSZ";
-
- // Sort the characters based on their position in the custom order
- chars.sort((a, b) => correctOrder.indexOf(a) - correctOrder.indexOf(b));
-
- save = chars.join("");
- } else if (differentIndex == -1) {
- // console.log(piecesUsed[currentPCNum], currentPCNum);
- for (let j = 1; j < piecesUsed[currentPCNum] + 1; j++) {
- // console.log("inloop")
- // console.log("piece to remove", queue[queue.length - j])
- bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag
- // console.log("bag currently: ", Array.from(bag).join(""))
- }
- var save = Array.from(bag).join("");
- }
-
- // hard coded stuff:
- //console.log(pcNumSelect.value)
- if (pcNumSlider.value == 2) { // for dealing with some 3+1setups on 2nd for 3rd pc saves
- save = pieces[differentIndex];
- }
- if (pcNumSlider.value == 3) { // for renaming 4th pc
- const reference = "TIJLOSZ";
-
- const missing = reference.split("").filter(letter => !save.includes(letter));
- let dupe = "";
- if (save.includes("TT")) {
- dupe = "T"
- } else if (save.includes("II")) {
- dupe = "I"
- } else if (save.includes("JJ")) {
- dupe = "J"
- } else if (save.includes("LL")) {
- dupe = "L"
- } else if (save.includes("OO")) {
- dupe = "O"
- } else if (save.includes("SS")) {
- dupe = "S"
- } else if (save.includes("ZZ")) {
- dupe = "Z"
- }
- // console.log(missing, dupe)
-
- if (missing.length > 0 && dupe == "") {
- save = `no ${missing.join("")}`;
- } else {
- // console.log("dupe")
- save = `${dupe}>${missing.join("")}`;
- // console.log("save", save)
- }
- }
- if (pcNumSlider.value == 5) { // for renaming 6th pc
- const reference = "TIJLOSZ";
-
- const missing = reference.split("").filter(letter => !save.includes(letter));
- let dupe = "";
- if (save.includes("TT")) {
- dupe = "T"
- } else if (save.includes("II")) {
- dupe = "I"
- } else if (save.includes("JJ")) {
- dupe = "J"
- } else if (save.includes("LL")) {
- dupe = "L"
- } else if (save.includes("OO")) {
- dupe = "O"
- } else if (save.includes("SS")) {
- dupe = "S"
- } else if (save.includes("ZZ")) {
- dupe = "Z"
- }
- // console.log(missing, dupe)
-
- if (missing.length > 0 && dupe == "") {
- save = `no ${missing.join("")}`;
- } else {
- // console.log("dupe")
- save = `${dupe}>${missing.join("")}`;
- // console.log("save", save)
- }
- }
- if (pcNumSlider.value == 7) { // for renaming 1st/8th pc
- const reference = "TIJLOSZ";
-
- const missing = reference.split("").filter(letter => !save.includes(letter));
- let dupe = "";
- if (save.includes("TT")) {
- dupe = "T"
- } else if (save.includes("II")) {
- dupe = "I"
- } else if (save.includes("JJ")) {
- dupe = "J"
- } else if (save.includes("LL")) {
- dupe = "L"
- } else if (save.includes("OO")) {
- dupe = "O"
- } else if (save.includes("SS")) {
- dupe = "S"
- } else if (save.includes("ZZ")) {
- dupe = "Z"
- }
- // console.log(missing, dupe)
-
- if (missing.length == 0) {
- save = "1st PC";
- } else {
- // console.log("dupe")
- save = `${dupe}>${missing.join("")} 8th PC`;
- // console.log("save", save)
- }
- }
-
- // checks if the datafield is full and hence there is a pc
- if (!dataField.includes("_") && save != undefined) {
- if (currentPCNum != 6) {
- save += " " + pcNumSelectOptions[currentPCNum + 1]
- }
- // Check if there is an old text node there and delete it
- let existingTextNode = aNode.firstChild.firstChild.querySelector('text');
- // console.log(existingTextNode);
-
- if (existingTextNode) {
- // If an existing text node is found, remove it
- aNode.firstChild.firstChild.removeChild(existingTextNode);
- }
- // Create the new text elem and add it
- const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
- text.setAttribute("x", "100"); // Set x to the center
- text.setAttribute("y", "15"); // Adjust y as needed
- text.setAttribute("fill", "black");
- text.setAttribute("text-anchor", "middle"); // Center the text horizontally
- text.setAttribute("font-size", "15"); // Font size
- text.textContent = save;
- aNode.firstChild.firstChild.appendChild(text);
- }
-
-
-
-
-
- } catch (e) {
- // do nothing lol
- }
-
-
- }
-
- });
-
- // On select change
- select.onchange = function(event) {
- selectSave(event.target.value);
- }
-
- function selectSave(value) {
- if (value !== 'All') {
- document.querySelectorAll('#solutions > a').forEach(function(a) {
- a.style.display = 'none';
- // a.style.borderTopWidth = '0'; commented out by tam
- });
- document.querySelectorAll('#solutions > a.' + value).forEach(function(a) {
- a.style.display = 'block';
- });
- } else if (value == 'All') {
- document.querySelectorAll('#solutions > a').forEach(function(a) {
- a.style.display = 'block';
- a.style.borderTopWidth = '10px';
- });
- }
- }
-
- // Add listener for solutions and also the whole body for the slider
- var targetNode = document.getElementById('solutions');
- var config = {
- // attributes: true,
- childList: true,
- subtree: true,
- characterData: true
- };
-
- var observer = new MutationObserver(function(mutationsList) {
-
- var queue = document.getElementById('queue').value;
-
- // check if queue is just pieces
- var piecesOnlyMatch = queue.match(/^[TILJSZO]*$/);
- if (piecesOnlyMatch) {
- //console.log('good queue');
- } else {
- return;
- }
-
- var queuePieces = pieces.map(function(piece) {
- return (queue.split(piece).length - 1);
- });
-
- // We're just gonna assume the queue length is correct !!!
-
- //console.log('queue pieces', queuePieces);
-
- for (var mutation of mutationsList) {
- if (mutation.type == 'childList') {
- // console.log('A child node has been added or removed.', mutation.addedNodes[0]);
- try {
- var aNode = mutation.addedNodes[0];
- var dataField = aNode.firstChild.getAttribute('data-field');
- var solutionPieces = pieces.map(function(piece) {
- return (dataField.split(piece).length - 1) / 4;
- });
- //console.log('pieces used', solutionPieces);
-
- // get difference between arrays
- var differentIndex = -1;
- for (let i = 0; i < queuePieces.length; i++) {
- if (queuePieces[i] !== solutionPieces[i]) {
- differentIndex = i;
- }
- }
- // console.log('saved piece', pieces[differentIndex]);
- aNode.style.borderTop = "10px solid " + colors[differentIndex];
- aNode.classList.add(pieces[differentIndex]);
-
- // Calculate what PC comes from this save
- let bag = new Set(["T", "I", "J", "L", "O", "S", "Z"]);
- // console.log("queuevalue", queue)
-
- let currentPCNum = pcNumSlider.value - 1; // -1 so that its an index starting from 0
-
- // If there is a saved piece (4p setup with see7/3p setup with see8)
- if (differentIndex != -1) {
- // console.log(piecesUsed[currentPCNum], currentPCNum);
- for (let j = 1; j < piecesUsed[currentPCNum] + 2; j++) {
- // console.log("inloop")
- // console.log("piece to remove", queue[queue.length - j])
- bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag
- // console.log("bag currently: ", Array.from(bag).join(""))
- }
- var save = Array.from(bag).join("");
- //console.log("final save", save);
- // Add the saved piece
-
- // If there is a saved piece (4p setup with see7/3p setup with see8)
- save += pieces[differentIndex];
- // console.log("final save", save);
-
- // Reorder the string
- const chars = save.split("");
-
- const correctOrder = "TIJLOSZ";
-
- // Sort the characters based on their position in the custom order
- chars.sort((a, b) => correctOrder.indexOf(a) - correctOrder.indexOf(b));
-
- save = chars.join("");
- } else if (differentIndex == -1) {
- // console.log(piecesUsed[currentPCNum], currentPCNum);
- for (let j = 1; j < piecesUsed[currentPCNum] + 1; j++) {
- // console.log("inloop")
- // console.log("piece to remove", queue[queue.length - j])
- bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag
- // console.log("bag currently: ", Array.from(bag).join(""))
- }
- var save = Array.from(bag).join("");
- }
-
- // hard coded stuff:
- //console.log(pcNumSelect.value)
- if (pcNumSlider.value == 2) { // for dealing with some 3+1setups on 2nd for 3rd pc saves
- save = pieces[differentIndex];
- }
- if (pcNumSlider.value == 3) { // for renaming 4th pc
- const reference = "TIJLOSZ";
-
- const missing = reference.split("").filter(letter => !save.includes(letter));
- let dupe = "";
- if (save.includes("TT")) {
- dupe = "T"
- } else if (save.includes("II")) {
- dupe = "I"
- } else if (save.includes("JJ")) {
- dupe = "J"
- } else if (save.includes("LL")) {
- dupe = "L"
- } else if (save.includes("OO")) {
- dupe = "O"
- } else if (save.includes("SS")) {
- dupe = "S"
- } else if (save.includes("ZZ")) {
- dupe = "Z"
- }
- // console.log(missing, dupe)
-
- if (missing.length > 0 && dupe == "") {
- save = `no ${missing.join("")}`;
- } else {
- // console.log("dupe")
- save = `${dupe}>${missing.join("")}`;
- // console.log("save", save)
- }
- }
- if (pcNumSlider.value == 5) { // for renaming 6th pc
- const reference = "TIJLOSZ";
-
- const missing = reference.split("").filter(letter => !save.includes(letter));
- let dupe = "";
- if (save.includes("TT")) {
- dupe = "T"
- } else if (save.includes("II")) {
- dupe = "I"
- } else if (save.includes("JJ")) {
- dupe = "J"
- } else if (save.includes("LL")) {
- dupe = "L"
- } else if (save.includes("OO")) {
- dupe = "O"
- } else if (save.includes("SS")) {
- dupe = "S"
- } else if (save.includes("ZZ")) {
- dupe = "Z"
- }
- // console.log(missing, dupe)
-
- if (missing.length > 0 && dupe == "") {
- save = `no ${missing.join("")}`;
- } else {
- // console.log("dupe")
- save = `${dupe}>${missing.join("")}`;
- // console.log("save", save)
- }
- }
- if (pcNumSlider.value == 7) { // for renaming 1st/8th pc
- const reference = "TIJLOSZ";
-
- const missing = reference.split("").filter(letter => !save.includes(letter));
- let dupe = "";
- if (save.includes("TT")) {
- dupe = "T"
- } else if (save.includes("II")) {
- dupe = "I"
- } else if (save.includes("JJ")) {
- dupe = "J"
- } else if (save.includes("LL")) {
- dupe = "L"
- } else if (save.includes("OO")) {
- dupe = "O"
- } else if (save.includes("SS")) {
- dupe = "S"
- } else if (save.includes("ZZ")) {
- dupe = "Z"
- }
- // console.log(missing, dupe)
-
- if (missing.length == 0) {
- save = "1st PC";
- } else {
- // console.log("dupe")
- save = `${dupe}>${missing.join("")} 8th PC`;
- // console.log("save", save)
- }
- }
-
- // checks if the datafield is full and hence there is a pc
- if (!dataField.includes("_") && save != undefined) {
- if (currentPCNum != 6) {
- save += " " + pcNumSelectOptions[currentPCNum + 1]
- }
-
- // Create the new text elem and add it
- const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
- text.setAttribute("x", "100"); // Set x to the center
- text.setAttribute("y", "15"); // Adjust y as needed
- text.setAttribute("fill", "black");
- text.setAttribute("text-anchor", "middle"); // Center the text horizontally
- text.setAttribute("font-size", "15"); // Font size
- text.textContent = save;
- aNode.firstChild.firstChild.appendChild(text);
- }
-
-
-
-
-
- } catch (e) {
- // do nothing lol
- }
-
- }
- }
- });
-
- observer.observe(targetNode, config);
- }
- })();