boolean evaluator in Javascript?

I’m trying to avoid writing this from scratch and would love if anyone has an idea

const testCases = [
    { text: "keyword1 is present but keyword4 is not here", boolExpr: "(keyword1 OR keyword2) AND (keyword3 OR keyword4)", expected: false },
    { text: "keyword1 and keyword3 are both present", boolExpr: "(keyword1 OR keyword2) AND (keyword3 OR keyword4)", expected: true },
    { text: "keyword1 and keyword3 are present, but keyword5 is also here", boolExpr: "(keyword1 OR keyword2) AND (keyword3 OR keyword4) AND NOT (keyword5 OR keyword6)", expected: false },
    { text: "keyword1 and keyword3 are present, without keyword5", boolExpr: "(keyword1 OR keyword2) AND (keyword3 OR keyword4) AND NOT (keyword5 OR keyword6)", expected: true },
    { text: 'The "phrase 1" and "phrase 2" are present', boolExpr: '("phrase 1" OR keyword1) AND ("phrase 2" OR keyword2) AND NOT ("phrase 3" OR keyword3)', expected: true },
    { text: 'The "phrase 1" is here but not "phrase 2"', boolExpr: '("phrase 1" OR keyword1) AND ("phrase 2" OR keyword2) AND NOT ("phrase 3" OR keyword3)', expected: false },
    { text: 'The "phrase 1" and "phrase 2" are here, but also "phrase 3"', boolExpr: '("phrase 1" OR keyword1) AND ("phrase 2" OR keyword2) AND NOT ("phrase 3" OR keyword3)', expected: false },
    { text: 'keyword1, keyword3 and keyword6 are all here', boolExpr: "(keyword1 OR keyword2) AND (keyword3 OR keyword4) AND NOT (keyword5 OR keyword6)", expected: false },
];

Unfortunately I can’t use eval() 🙁

any thoughts?

OnClick EventListener not working in my code

I am trying to execute code when a button is pressed. I currently have the “catch all” alert set up.

My code

$(document).ready(function() {
  //bulk submit handler This section works when this form is shown.  In this instance, I have the form
  //I currently have the form hidden
  $("#bulkSubmit").submit(function(e) {
    e.preventDefault();

    var form = $(this);
    var frmUrl = form.attr('action')

    $.ajax({
      type: "POST",
      url: frmUrl,
      data: form.serialize()
    });
  });
});

addButton = document.getElementById('btnCheckInSubmit');
addButton.addEventListener("click", function() {
  alert("clicked");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="addCustomerMain main">
  <h1>Add Customer</h1>
  <hr>
  <form method="post" id="addCustomer">
    <div class="formContent">
      <div class="formElement">
        <label for="custName">Name</label>
        <input class="txtLarge" type="text" name="custName" id="custName">
      </div>
    </div>
    <div class="formContent">
      <div class="formElement">
        <label for="custAddress">Address</label>
        <input class="txtLarge" type="text" name="custAddress" id="custAddress">
      </div>
    </div>
    <div class="formContent">
      <div class="formElement">
        <label for="custCity">City</label>
        <input class="txtSmall" type="text" name="custCity" id="custCity">
      </div>
      <div class="formElement">
        <label for="custState">State</label>
        <input class="txtXSmall" type="text" name="custState" id="custState">
      </div>
      <div class="formElement">
        <label for="custZip">Zip</label>
        <input class="txtXSmall" type="text" name="custZip" id="custZip">
      </div>
    </div>
    <div class="formContent">
      <div class="formElement">
        <label for="custPhone">Phone</label>
        <input type="text" name="custPhone" id="custPhone" class="txtLarge">
      </div>
    </div>
  </form>
  <div class="formContent" id="divCheckInSubmit">
    <div class="formElement">
      <button id="btnCheckInSubmit" class="btnSubmit">Add Customer</button>
    </div>
  </div>
</div>
<!-- the script is included here -->
<!-- <script src="../js/addCustomer.js" defer></script> -->

The code I want to work, works if I comment out the JQuery for the bulksubmit, but if it is still in there, the checkinsubmit button’s eventlister for “click” does not fire.

Cannot import JS library opus-recorder in TypeScript project

In my Vite TypeScript React application I’m trying to import the Opus Recorder library (https://www.npmjs.com/package/opus-recorder).

I have set this flag in tsconfig.json:

  "compilerOptions": {

    "allowJs": true,

and imported this library in my index.tsx in this way:

import * as opus from '../../../node_modules/opus-recorder/dist/recorder.min.js';

but when I try to invoke the constructor:

const recorder = new opus.Recorder({ encoderSampleRate: 44100 });

I get TypeError: opus.Recorder is not a constructor.

I also created a type declaration file in types/index.d.ts:

declare module 'opus-recorder' {
  // Recorder Configuration Interface
  interface RecorderConfig {
    bufferLength?: number;
    encoderApplication?: number;
    encoderFrameSize?: number;
    encoderPath?: string;
    encoderSampleRate?: number;
    maxFramesPerPage?: number;
    mediaTrackConstraints?: boolean | MediaTrackConstraints; // Allow flexible input
    monitorGain?: number;
    numberOfChannels?: number;
    recordingGain?: number;
    resampleQuality?: number;
    streamPages?: boolean;
    wavBitDepth?: number;
    sourceNode?: { context: AudioContext | null } | MediaStreamAudioSourceNode;
  }

  // Recorder Class
  class Recorder {
    // Static Methods
    static isRecordingSupported(): boolean;

    // Constructor
    constructor(config?: RecorderConfig);

    // Instance Properties
    state: "inactive" | "loading" | "recording" | "paused";  // Possible states
    config: RecorderConfig;
    encodedSamplePosition: number;

    // Instance Methods (simplified for brevity)
    initAudioContext(): void;
    initWorklet(): Promise<void>;
    initEncoder(): Promise<void>;
    initialize: Promise<void>; // Combined promise for initWorklet & initEncoder
  }

  export default Recorder;
}

but I get the same error.
Can someone please help me?

Allowing once to use the microphone on Google Chrome multiple times

I have the following piece of code that has two textareas and two buttons. Each button controls its own text area. Once started, the script listen to the audio and when finished fills the textarea with the transcription of the audio listened. The problem is: every time the button is clicked, Google Chrome asks for permission to use the microphone. Is there a way to make this request happen only once?

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Transcrição de Áudio</title>
    <style>
        textarea {
            width: 100%;
            height: 150px;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <textarea id="transcription1" placeholder="A transcrição aparecerá aqui"></textarea>
    <button id="startStopBtn1">Iniciar/Parar Transcrição 1</button>
    <textarea id="transcription2" placeholder="A transcrição aparecerá aqui"></textarea>
    <button id="startStopBtn2">Iniciar/Parar Transcrição 2</button>

    <script>
        let isRecording1 = false;
        let isRecording2 = false;
        let recognition1;
        let recognition2;
        let silenceTimer1;
        let silenceTimer2;
        let hasPermission1 = false;
        let hasPermission2 = false;

        const startStopBtn1 = document.getElementById('startStopBtn1');
        const transcriptionInput1 = document.getElementById('transcription1');
        const startStopBtn2 = document.getElementById('startStopBtn2');
        const transcriptionInput2 = document.getElementById('transcription2');

        // Função para inicializar o reconhecimento de fala
        function initRecognition(recognition, transcriptionInput, silenceTimer) {
            recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
            recognition.continuous = true;
            recognition.interimResults = true;
            recognition.lang = 'pt-BR';

            recognition.onresult = (event) => {
                clearTimeout(silenceTimer);
                let interimTranscript = '';
                for (let i = event.resultIndex; i < event.results.length; ++i) {
                    if (event.results[i].isFinal) {
                        transcriptionInput.value += event.results[i][0].transcript + 'n';
                    } else {
                        interimTranscript += event.results[i][0].transcript;
                    }
                }
            };

            recognition.onspeechend = () => {
                resetSilenceTimer(recognition, silenceTimer);
            };

            recognition.onerror = (event) => {
                console.error('Erro no reconhecimento de fala:', event.error);
                stopRecording(recognition, silenceTimer);
            };

            return recognition;
        }

        // Inicializar reconhecimento de fala ao clicar no botão pela primeira vez
        startStopBtn1.addEventListener('click', () => {
            if (!hasPermission1) {
                hasPermission1 = true;
                recognition1 = initRecognition(recognition1, transcriptionInput1, silenceTimer1);
            }
            toggleRecording(recognition1, startStopBtn1, transcriptionInput1, silenceTimer1, isRecording1);
        });

        startStopBtn2.addEventListener('click', () => {
            if (!hasPermission2) {
                hasPermission2 = true;
                recognition2 = initRecognition(recognition2, transcriptionInput2, silenceTimer2);
            }
            toggleRecording(recognition2, startStopBtn2, transcriptionInput2, silenceTimer2, isRecording2);
        });

        function toggleRecording(recognition, button, transcriptionInput, silenceTimer, isRecording) {
            if (isRecording) {
                stopRecording(recognition, silenceTimer);
                button.textContent = "Iniciar Transcrição";
            } else {
                startRecording(recognition, button, transcriptionInput, silenceTimer);
                button.textContent = "Parar Transcrição";
            }
            isRecording = !isRecording;
        }

        function startRecording(recognition, button, transcriptionInput, silenceTimer) {
            recognition.start();
            resetSilenceTimer(recognition, silenceTimer);
        }

        function stopRecording(recognition, silenceTimer) {
            recognition.stop();
            clearTimeout(silenceTimer);
        }

        function resetSilenceTimer(recognition, silenceTimer) {
            clearTimeout(silenceTimer);
            silenceTimer = setTimeout(() => {
                stopRecording(recognition, silenceTimer);
            }, 5000);
        }
    </script>
</body>
</html>

I have no idea on how to deal with that problem. I’d like to allow only once and somehow keep the permission valid

React UI not updating when React a property of React object state changes

I have a component that uses an object as the state. The object is passed in as a prop. The problem is, I have an input field where there is a cancel button. When the user clicks on the cancel button, I discard all the handleChange events which is saved on the local component state, then just reuse the original prop that was passed in. The text in the input field however, does not reset to the original value and keeps the value that was with the change event.

// Prop structure myObjProp
{id: '', inputText: 'Original String Val'}

const MyComponent = ({myObjProp}) => {
  const [objState, setObjState] = useState({...myObjProp})
  const {id, inputText} = objState

  const handleChange = (e) => setObjState({...objState, inputText: e.target.value})
   
  const handleCancel = () => setObjState(myObjProp) // Should reset `inputText` back to `Original String Val`
  

  return (
    <div>
      <input onChange={handleChange} />
      <button onClick={handleCancel} defaultValue={inputText} >Cancel</button>
    </div>
  )
}

As an example, when the component first loads, the text in the input will be Original String Val. When I then start typing and the input value is something like Original String Val Changed, after I click the Cancel button, the text in the input should be Original String Val which is the original value from the prop and I set in the cancel handler, but text does not revert back and stays as the new text I just typed Original String Val Changed

Batch converting 1000’s of .fla files to .png in Adobe Animate

I need to convert thousands of assets from .fla to .png the bulk of which are not animated (id like to do the animated ones as png spritesheets if possible). Is there any way to automate this process in Adobe Animate so I don’t have to do this manually?

I have searched a ton but the closest I’ve found is a code snippet on the adobe help website from 2017 for doing a similar thing with SVGs but I’m not sure how to implement it or modify this as I don’t know javascript.

Puppetter – Read the value of CDPJSHandle {}

I am just trying to scrap something from a website.

I am running into a problem when trying to access the value of a property that is on an element. The value returns CDPJSHandle {} instead of the object that I expect.

    const element = await page.$('canvas');
    const properties = await element.getProperties();
    const [firstKey]  = await properties.keys();
    const propertyValue = await element.getProperty(firstKey);

    console.log({
      element,        // CDPElementHandle { handle: CDPJSHandle {} },
      properties,     // Map(1) { 'jQuery3700346878389459100542' => CDPJSHandle {} },
      firstKey,       // 'jQuery3700346878389459100542',
      propertyValue,  // CDPJSHandle {}
    });

This jQuery3700346878389459100542 is a custom property attached to this html element. I can access the property via the browser with document.querySelector('canvas').jQuery370058052487285485872; which returns the object that I expect.

I know that a similar question has been asked here, which will work if I’m referencing a native HTML element property. However my scenario differs as I’m looking for a custom property.

const evaluatedValue = await element?.evaluate((el, firstKey) => el[firstKey], firstKey);
const evaluatedTextValue = await element.evaluate(el => el.id);

console.log({
  evaluatedValue, // undefined
  evaluatedTextValue, // 'n                        '
});

How can I access this property correctly?

How to use a inject button inside of a chrome extension to inject code into the current tab?

I’ve tried a lot of resources to fix my issue, but everything I’ve found is about instantly injecting the code once the user has entered the site; not when a button is pressed to inject the code.

I tried videos, posts and research – nothing worked. I was expecting for my inject button to run the code entered into a textbox e.g. ‘console.log(‘demo’);’.

Why do Bootstrap Table extensions use class inheritance instead of modifying the prototype?

I’m currently studying the jQuery bootstrap-table plugin and I’ve noticed something that I don’t fully understand. In the main bootstrap-table.js file, they instantiate a BootstrapTable class and assign it to $.BootstrapTable, which makes sense to me.

However, for extensions, they do the following:

$.BootstrapTable = class extends $.BootstrapTable {
  // extension code
}

This creates a new JavaScript file with the entire BootstrapTable class and the additional extension code. This approach seems to create two large JavaScript files with duplicate definitions of the class.

Wouldn’t it be more efficient to modify the prototype of the class directly to avoid code duplication? For example:

BootstrapTable.prototype.newFunction = function() {
  // new function code
}

Additionally, by storing the old method in a variable and calling it within the new function, we can preserve the extensions that precede us. For example:

const oldExistFunction = $.BootstrapTable.prototype.existFunction;
$.BootstrapTable.prototype.existFunction = function() {
  oldExistFunction.call(this);
  console.log('This is the new existFunction.');
}

By doing this, we wouldn’t have duplicated class definitions. Are there specific reasons for choosing class inheritance over prototype modification in this context? What are the advantages and disadvantages of each approach?

I appreciate any insights or explanations you can provide. Thank you!

What I tried:
I tried modifying the prototype directly and storing the old method in a variable before redefining it. I expected this to avoid code duplication and maintain the previous extensions’ functionality.

What I expected:
I expected that modifying the prototype directly would be a more efficient way to add new functionality without duplicating the entire class definition.

What actually happened:
While modifying the prototype worked as expected in my tests, I’m wondering if there are specific reasons why the bootstrap-table plugin developers chose to use class inheritance instead. Are there particular advantages or use cases that make inheritance a better choice in this context?

SVG element calculated position is wrong when svg is not its viewBox size

I have an svg map displaying countries. I want to create an svg element that gets the same position of the selected country as overlay an element. Thing is that it only gets the accurate position when the size matches with the viewBox size and this even works resizing, but the problem arises when it calculates in smaller screens or when the svg is streched above its viewbox size. Then it’s inaccurate.

Added a pen https://codepen.io/rKaiser/pen/xxoqEMj?editors=1111

// Parent <g>
var parentGroup = document.getElementById('map');
// Country ID
var childGroup = document.getElementById('de');

// Get the bounding box of the child <g>
var bbox = childGroup.getBBox();
console.log('Child BBox:', bbox);

// Get the transformation matrix of the parent <g>
var parentCTM = parentGroup.getCTM();
console.log('Parent CTM:', parentCTM);

// Get the position of the child <g> relative to the parent <g>
var childCTM = childGroup.getCTM();
console.log('Child CTM:', childCTM);

// Calculate the position of the child <g> relative to the parent <g>
var topLeftX = childCTM.e - parentCTM.e;
var topLeftY = childCTM.f - parentCTM.f;
console.log('Top Left X:', topLeftX, 'Top Left Y:', topLeftY);

// Create an SVG red square 
var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');

rect.setAttribute('x', topLeftX);
rect.setAttribute('y', topLeftY);
rect.setAttribute('width', bbox.width);
rect.setAttribute('height', bbox.height);
rect.setAttribute('fill', 'red');
rect.setAttribute('opacity', '0.35');

// Append the square to the parent <g>
parentGroup.appendChild(rect);

Just to be sure, if there’s a better way to do it, my reasoning wanting to do this is that there will several icons on the map and doing this will make the icons stay on top of the countries and not hidden, when placing the icon in the smaller countries would get the icon partly hidden because of the stacking order and theres no z-index unfortunately.

Thanks!

Wobble animation in text-path issue

I am trying to create an alert to broadcast via stream elements.

I want the user’s text, which is dynamic, to fit a path that draws a curve. Said text, I want it to have the wobble animation. If the text is drawn normally, the animation works perfectly. On the other hand, when going through a path, it does not play or does so as if it were an entire block of text and not the letters independently.

HTML

<div class="text-container">
    <div class="awsome-text-container">
        <svg width="100%" height="100%" viewBox="0 0 200 400" preserveAspectRatio="xMidYMid meet">
            <path id="curve" d="M -35,50 L-35,325 Q-35,375 65,375 L175,375" fill="transparent" stroke="black" stroke-width="2"/>
            <text font-size="85px">
                <textPath id="username-container" href="#curve"></textPath>
            </text>
        </svg>
    </div>
    <p>{{message}}</p>
</div>

CSS

@import url('https://fonts.googleapis.com/css?family=Caprasimo');

* {
    font-family: 'Caprasimo', sans-serif;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.awsome-text-container {
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 999;
    width: 100%;
    height: 400px;
    text-align: center;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: visible;
}

.animated-letter {
    animation-duration: 1.5s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    opacity: 1;
    display: inline-block;
}

.text-container {
    font-size: 16px;
    color: black;
    text-align: center;
    margin: auto;
}

@keyframes wobble {
    0% {
        transform: translateX(0) rotate(0deg);
    }
    15% {
        transform: translateX(-2px) rotate(-2deg);
    }
    30% {
        transform: translateX(2px) rotate(2deg);
    }
    45% {
        transform: translateX(-1.5px) rotate(-1.5deg);
    }
    60% {
        transform: translateX(1.5px) rotate(1.5deg);
    }
    75% {
        transform: translateX(-1px) rotate(-1deg);
    }
    90% {
        transform: translateX(1px) rotate(1deg);
    }
    100% {
        transform: translateX(0) rotate(0deg);
    }
}

JS

function stringToAnimatedHTML(s, anim) {
    const stringAsArray = s.split('');
    const animationDuration = '1.5s';

    const animatedLetters = stringAsArray.map((letter, index) => {
        const randomDelay = Math.random() * 1;
        const transformValues = `translateX(${Math.random() * 2 - 1}px)`;
        return `<tspan class="animated-letter ${anim}" style="animation-duration: ${animationDuration}; animation-delay: ${randomDelay}s; transform: ${transformValues};">${letter}</tspan>`;
    });

    return animatedLetters.join('');
}

const name = '{{name}}';
const animation = 'wobble';
const userNameContainer = document.querySelector('#username-container');
userNameContainer.innerHTML = stringToAnimatedHTML(name, animation);

is it possible to set the initial coordinates of the node in the ngx-graph library

Hello everyone I wrote code to visualize the graph using ngx-graph, but I ran into a problem, I need to center the main nodes (in my data they are marked with a specific tag). Are there any options to implement this?

For example in d3.js I can set the coordinates before rendering, which allowed me to get rid of this problem. But unfortunately I need to solve this problem using the ngx-graph library.
what i have now
In the screenshot, the nodes with a yellow background should be located in the center (under each other) Like this:
what i need(

Securing Javascript to Native Calls using WebKit

When a Javascript posts a message to Native Code using

window.webkit.messageHandlers.<messageHandlerName>.postMessage(<messageBody>)

If I have a JS calling the Native code like this.

window.webkit.messageHandlers.countryListHandler.postMessage("<country List payload>")

How can this invocation be limited to a specific script ? Can WKContentWorld help here ? if yes then how?
Can creating a custom world name help?

First Firefox extension test not going well

I am writing a first test of a firefox extension. I am using the following websites as assistance:

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items

https://github.com/mdn/webextensions-examples/blob/main/menu-demo/background.js

Here is my code:

mainfest.json

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
  "content_scripts":[
    {
     "matches":["<all_urls>"],
     "js":["main.js"]
    }
  ],
  "permissions":["contextMenus"]
}

main.js

alert("test");

function onError(error) {
  alert(error);
}

browser.contextMenus.create(
  {
    id: "AlertTest",
    title: "Test2",
    contexts: ["all"],
  },
  onCreated,
);

alert("Test 2");

browser.contextMenus.onClicked.addListener((info, tab) => {
  switch (info.menuItemId) {
    case "AlertTest":
      console.log(info.selectionText);
      alert("The test extension is up and running");
      break;
  }
});

The extension does load, but i never get to alert(“Test 2”);. In addition the console says “TypeError: browser.contextMenus is undefined”. Please let me know what I’m doing wrong.

Counter not Resetting – Javascript

I currently have a program with some teams that are in pairs. Clicking on a team increases the Wins of the team being clicked, and increases the Losses of the pair it is linked to. A team with two losses is disabled and changes their text to “Eliminated”.

I have a reset button that is supposed to clear all of the counters and, in theory, by clearing the counters the disabled buttons should be reenabled again. However, this is not the case. Looking at the console you can see the buttons don’t restart their count until you press them, meaning the disabled buttons stay disabled, but what puzzles me is that their text switches back to the team name. How do I get the counter to reset completely after I press the reset button?

Any input would be greatly appreciated 🙂

let groups = [{
    name: "Chaos Coordinators",
    wins: 0,
    losses: 0
  },
  {
    name: "Sofa King Awesome",
    wins: 0,
    losses: 0
  },
  {
    name: "The Nerd Herd",
    wins: 0,
    losses: 0
  },
  {
    name: "The Laughing Stock",
    wins: 0,
    losses: 0
  },
  {
    name: "Brainy Bunch Gone Wild",
    wins: 0,
    losses: 0
  },
  {
    name: "Cereal Killers",
    wins: 0,
    losses: 0
  },
  {
    name: "The Mismatched Socks",
    wins: 0,
    losses: 0
  },
  {
    name: "The Awkward Turtles",
    wins: 0,
    losses: 0
  }
];


// Create pairs from the groups
function makeMatches(array) {
  return array.map((_, i) => (i % 2 === 0) ? [array[i], array[i + 1]] : []).filter(v => v.length === 2);
}

let matches = makeMatches(groups);

// Create a map of team names to their index
const groupIndexMap = {};
groups.forEach((group, index) => {
  groupIndexMap[group.name] = index;
});

// Function to handle button clicks
function handleButtonClick(groupName) {
  const matchIndex = groupIndexMap[groupName];
  const match = matches.find(match => match.some(group => group.name === groupName));


  if (!match) return;

  match.forEach((group, button) => {
    if (group.name === groupName) {
      group.wins += 1;
    } else if (group.losses < 2) {
      group.losses += 1;
    }
  });

  updateButtonTexts();
  console.log(groups);
}

// Function to update button texts
function updateButtonTexts() {
  groups.forEach((group, index) => {
    const button = document.getElementById(`button${index + 1}`);
    if (button) {
      button.textContent = `${group.name} - Wins: ${group.wins} - Losses: ${group.losses}`;
    }
    if (group.losses == 2) {
      button.textContent = 'Eliminated';
      button.disabled = true;
    }
  });
}

// Function to reset all counters
function resetCounters() {
  groups.forEach(group => {
    group.wins = 0;
    group.losses = 0;
  });
  updateButtonTexts();
}


// Initialize button click handlers
function initializeButtons() {
  groups.forEach((group) => {
    const button = document.querySelector(`[data-team-name='${group.name}']`);
    if (button) {
      button.onclick = () => handleButtonClick(group.name);
    }
  });

  // Initialize reset button handler
  document.getElementById('resetButton').onclick = resetCounters;

  // Initial update of button texts
  updateButtonTexts();
}

// Initial render and setup
initializeButtons();
#group-buttons {
  position: relative;
  /* Container should be relative for positioning buttons absolutely */
  width: 100%;
  height: 500px;
  /* Adjust height as needed */
  border: 1px solid #ccc;
}

.group-button {
  position: absolute;
  /* Allows for free positioning */
  cursor: pointer;
  /* Indicates the element is clickable */
  padding: 10px;
  background: #f0f0f0;
  border: 1px solid #ddd;
  border-radius: 5px;
}


/* Example styles for individual buttons */

#button1 {
  top: 50px;
  left: 50px;
}

#button2 {
  top: 50px;
  left: 200px;
}

#button3 {
  top: 150px;
  left: 50px;
}

#button4 {
  top: 150px;
  left: 200px;
}

#button5 {
  top: 250px;
  left: 50px;
}

#button6 {
  top: 250px;
  left: 200px;
}

#button7 {
  top: 350px;
  left: 50px;
}

#button8 {
  top: 350px;
  left: 200px;
}
<button id="resetButton">Reset All Counters</button>
<div id="group-buttons">
  <button id="button1" class="group-button" data-team-name="Chaos Coordinators">Chaos Coordinators - Wins: 0 - Losses: 0</button>
  <button id="button2" class="group-button" data-team-name="Sofa King Awesome">Sofa King Awesome - Wins: 0 - Losses: 0</button>
  <button id="button3" class="group-button" data-team-name="The Nerd Herd">The Nerd Herd - Wins: 0 - Losses: 0</button>
  <button id="button4" class="group-button" data-team-name="The Laughing Stock">The Laughing Stock - Wins: 0 - Losses: 0</button>
  <button id="button5" class="group-button" data-team-name="Brainy Bunch Gone Wild">Brainy Bunch Gone Wild - Wins: 0 - Losses: 0</button>
  <button id="button6" class="group-button" data-team-name="Cereal Killers">Cereal Killers - Wins: 0 - Losses: 0</button>
  <button id="button7" class="group-button" data-team-name="The Mismatched Socks">The Mismatched Socks - Wins: 0 - Losses: 0</button>
  <button id="button8" class="group-button" data-team-name="The Awkward Turtles">The Awkward Turtles - Wins: 0 - Losses: 0</button>
</div>