React stop function with useState

i have a button with which i start a test function:

<button type="button" onClick={startTestFrequencyList}>{
  frequenciesTestRunning ? 'Stop Test Frequency' : 'Start Test Frequency'
}</button>

The startTestFrequencyList either starts the testFrequencyList or stops it.

const [stopTest, setStopTest] = useState(false);
const [frequenciesTestRunning, setFrequenciesTestRunning] = useState(false);
const startTestFrequencyList = () => {
  if (frequenciesTestRunning) {
    window.alert("Already testing")
    setStopTest(true);
  } else {
    setFrequenciesTestRunning(true);
    testFrequencyList();
  }
}

Inside the startTestFrequencyList function i execute a lot of fetch calls in a loop. Which i want to stop if the user clicks the button again.

const testFrequencyList = async () => { 
  for (const item of frequencyList) {
    try {
      // Stop the fetching
      if (stopTest) {
        // STOP TEST
        stopTest(false);
        setFrequenciesTestRunning(false);
        return;
      }
      const response = await fetch('http://127.0.0.1:8000/frequency/testWithRe/', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(item),
      });
      const testResult = await response.json();
      // do something
    } catch (error) {
      console.error('Error:', error);
    }
  }
}

The problem is, whenever stopTest is set to true, nothing happens. It seems like the function does not get the newest state of stopTest.

How can I make it work path.resolve in my function? [duplicate]

I can’t understand why path.resolve in variable basePath doesn’t work in such primitive code. I get the value undefined. I tried using an array and join (‘/’ ) instead of path resolve, but it had no effect on the result

import http from 'http'
import fs from 'fs'
import path from 'path'

const PORT = 3000

const server = http.createServer((req, res) => {
  console.log('Server request:', req.headers.host)
  console.log(`url: '${req.url}' method:${req.method}`)

  res.setHeader('Content-Type', 'text/html')

  const createPath = (page) => {
    path.resolve(process.cwd(), 'views', `${page}.html`)
  }

  console.log('After createPath:', createPath('index'))

  let basePath = ''

  console.log(req.url)

  switch (req.url) {
    case '/':
      basePath = createPath('index')
      console.log('1st case:', basePath)
      break
    case '/contacts':
      basePath = createPath('contacts')
      break
    default:
      basePath = createPath('error')
      res.statusCode = 404
      break
  }

  console.log(basePath)

  fs.readFile(basePath, (err, data) => {
    if (err) {
      console.log('We have an error:', err.message)
      res.end('We have an error:', err.message)
    } else {
      res.write(data)
      // console.log(`Status Code: ${res.statusCode} Status Message: ${res.statusMessage}`)
      res.end(`Status Code: ${res.statusCode} Status Message: ${res.statusMessage}`)
    }
  })
})

server.listen(PORT, 'localhost', (err) => {
  err ? console.error(err.message) : console.log(`Server started http://localhost:${PORT}`)
})

How to syntax highlight in textarea in react

I need to apply syntax highlighting to a code written in a custom language in textarea in react.
So that as user type it highlights the code within the textarea and not to create a separate div or something.

I tried using react-simple-code-editor with prism and react-syntax-highlighter but those doesn’t work well…. either i can’t style to my preference or they are creating a separate div which is of no use as why would i need a separate highlighted code with my original code.
Prism did work though but can figure it out to embed it in the textarea.
please help.

This is the editor component.

import '../styles/Editor.css'
import PropTypes from 'prop-types'
import React, { useState, useEffect } from 'react';

export default function Editor({ disabled = false, code }) {
    // const [liveCode, setLiveCode] = useState('');
    const [lineNumbers, setLineNumbers] = useState([]);
    const codeAreaRef = React.createRef();

    const updateLineNumbers = (text) => {
        const lines = text.split('n');
        setLineNumbers(new Array(lines.length).fill().map((_, i) => i + 1));
    };

    useEffect(() => {
        if (disabled && code) {
            updateLineNumbers(code);
        }
    }, [])

    useEffect(() => {
        if (codeAreaRef.current) {
            codeAreaRef.current.addEventListener('scroll', () => {
                const codeArea = codeAreaRef.current;
                const lineNumbersContainer = codeAreaRef.current.previousSibling;
                lineNumbersContainer.scrollTop = codeArea.scrollTop;
            });
        }
    }, [codeAreaRef]);

    const handleCodeChange = (event) => {
        const newText = event.target.value;
        // setLiveCode(newText);
        updateLineNumbers(newText);
    };

    return (
        <div className="editor-container">
            <div className="line-numbers">
                {lineNumbers.map((line, index) => (
                    <div key={index} className="line-number">
                        {line}
                    </div>
                ))}
            </div>
            <textarea id="codeArea" disabled={disabled} value={code} onChange={handleCodeChange} ref={codeAreaRef}></textarea>
        </div>
    )
}

Editor.propTypes = {
    disabled: PropTypes.bool,
    code: PropTypes.string
}

Axios returning parsed JSON data in ReactJS with an undefined value for file key

I am having an odd issue where my Laravel API is returning JSON data to my react front-end via Axios and then Axios is parsing the data and returning an undefined value for a specific key “file”.

Ive added a transformResponse function to the Axios get method that logs the response before and after doing my own parsing and I still get the same result. Im also using the reviver parameter to log the value when the key is file.

api.get(`xxxxx`, {
            transformResponse: (res) => {
                console.log(res);

                const  data = JSON.parse(res, (key,value) => {
                    if (key === 'file' && value !== null) console.log(value);
        
                    return value;
                });

                console.log(data);

                return data;
            },
        }).then(res => {

The output of the first log:

{"data":{"value":{"value": 20,"users": [],"file":{"id":20,"fileable_id":2,"folder_id":21,"group_id":null,"name":"IMG_6274.jpg","size":4263000,"downloads":1,"created_at":"2023-11-01T17:24:17.000000Z","updated_at":"2023-11-01T17:24:29.000000Z","deleted_at":null,"extension":"jpg","size_formatted":"4.07 MB","full_url":"https://ca-dev-stor.s3.us-east-2.amazonaws.com/club/2/fields/38/2b837cdd-ee95-49a9-992d-74211b4400da.jpg"}}}}

The output of the second log:

{
    "id": 20,
    "fileable_id": 2,
    "folder_id": 21,
    "group_id": null,
    "name": "IMG_6274.jpg",
    "size": 4263000,
    "downloads": 1,
    "created_at": "2023-11-01T17:24:17.000000Z",
    "updated_at": "2023-11-01T17:24:29.000000Z",
    "deleted_at": null,
    "extension": "jpg",
    "size_formatted": "4.07 MB",
    "full_url": "https://ca-dev-stor.s3.us-east-2.amazonaws.com/club/2/fields/38/2b837cdd-ee95-49a9-992d-74211b4400da.jpg"
}

And the output of the third log:

{
    "data": {
        "value": {
            "value": 20,
            "users": [],
            "file": undefined
        }
    }
}

However if i take the original line and parse it as a string instead of from the response object i get no issue. Not sure how to fully reproduce this – mostly hoping someone has run into this issue before. Thanks!

React Native, expo notififaction. Not getting the notitifaction, what can be the problem?

I am trying to use react native, expo notifications. I want to get notifaction pushed localy to me from the app if it is closed or open.

The starting time is when you are awake,
The endtime is when you go to sleep.
notificationCount is how many counts you want to get.

Well it works in away that is not saying there is a problem, but I do not get any notification from this peace of code that I will show you

import React, { useEffect, useState } from 'react';
import { View, Text } from 'react-native';
import * as Notifications from 'expo-notifications';

const NotificationScheduler = () => {
  const startTime = new Date();
  // Start time: 02:00 adjust, (hour, min, 0, 0)
  startTime.setHours(2, 0, 0, 0); 
  const endTime = new Date();
  // End time: 03:30 adjust, (hour, min, 0, 0)
  endTime.setHours(3, 30, 0, 0); 
  // Number of notifications, How many times you want to get notification.. 
  // ATTH; Higher number is just to get them more frequently while testing.
  const notificationCount = 240; 
  // This is just to get the message displayed on the screen if any, if it does, and no notification
  // is displayed, then something is working but not as it should.
  const [notificationMessage, setNotificationMessage] = useState('No notifications yet.');
  // Getting the difference on time, to calculate the frequent interval on the time. 
  const timeDifference = endTime.getTime() - startTime.getTime();
  // Making the interval.
  const interval = Math.max(1, Math.round(timeDifference / notificationCount));

  useEffect(() => {
    // Ensure I have permission to send notifiactions
    const requestPermissions = async () => {
      const { status } = await Notifications.requestPermissionsAsync();
      if (status !== 'granted') {
        // if not please go to settings and allow them
        alert('Please go to settings and allow notifications!');
        return;
      }
    };

    requestPermissions();

    // The scheduler for notification.
[2:21 AM]
const scheduleNotifications = async () => {
  const currentDate = new Date();
  console.log('------ Starts  ------')
  for (let i = 1; i < notificationCount; i++) {
    // making the trigger for sending notifications on spesific time and sqedule them.
    const trigger = new Date(startTime.getTime() + i * interval);
    console.log('trigger : ' + trigger);
    // Setting up the notififactions
    await Notifications.scheduleNotificationAsync({
      content: {
        title: "Time to check!",
        body:`This is notification number ${i + 1}.`,
        data: { data: 'data goes here'},
      },
      trigger: {
        ...trigger,
        repeats: true,
      },
    });
  }
};

const notificationListener = Notifications.addNotificationReceivedListener(notification => {
  setNotificationMessage(notification.request.content.body);
});

const foregroundNotificationListener = Notifications.addNotificationResponseReceivedListener(response => {
  setNotificationMessage(response.notification.request.content.body);
});

scheduleNotifications();

return () => {
  Notifications.removeNotificationSubscription(notificationListener);
  Notifications.removeNotificationSubscription(foregroundNotificationListener);
};
}, []);

return (
<View>
  <Text>Notifications scheduled!</Text>
  <Text>Latest Notification: {notificationMessage}</Text>
</View>
);
};

export default NotificationScheduler;

Get left & top of absolute child after parent rotates

how can I calculate the new left & top px of an absolute child if the relative parent rotates so the child stays in the same spot?

I want the blue bar to get on the spot of the red bar, after the blackbox rotates.

<div id="box">
  <div id="mover"></div>
</div>
<div id="fixed"></div>


*{margin:0px;padding:0px;}

#box{width:300px;height:300px;background-color:#000;position:relative;transform:rotate(10deg);}

#mover{width:10px;height:50px;background-color:blue;position:absolute;left:100px;top:250px;transform:rotate(-10deg);}

#fixed{position:fixed;left:100px;top:250px;background-color:red;width:10px;height:50px;opacity:0.5;}

https://codepen.io/kornel-berne/pen/GRzqamK

Thanks a lot!

enter image description here

Div outline being covered even with z-index set

I’m trying to create a sudoku grid, consisting of 9 boxes in a 3×3 grid, each containing 9 cells in a 3×3 grid. However the outline of the boxes are being covered by the outline of the cells of other boxes, even though I’ve set the z-index of the box class to be higher than the cell class.

I’m still fairly new at webdev, and I’m really stuck on how to fix this!

Thank you!!

I tried setting the position attribute of each class to something other than static, but that didn’t seem to do anything.

for (let i = 0; i < 9; i++) {
    const grid = document.getElementById("puzzle-grid");

    const box = document.createElement("div");

    //generate a box to hold 9 cells
    box.classList.add("box");

    //generate cells inside each box
    for (let j = 0; j < 9; j++) {
        const cell = document.createElement("div");
        cell.classList.add("cell");

        box.appendChild(cell);
    }
    grid.appendChild(box);
}
.grid-container {
    width: 300px;
    height: 300px;
    margin: 0 auto;
    border: 6px solid black;

    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    z-index: 1000;
    background: rgb(200, 200, 200, 50);
}

.box {
    outline: 2px solid black;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    z-index: 100;
    overflow: hidden;
    position: relative;
}

.cell {
    outline: solid 1px #999;
    z-index: 1;
    position: relative;
}
<div class="grid-container" id="puzzle-grid"></div>

Why I can’t see rendered error messages in jQuery validate plugin?

I’ve completed the form inputs with a name attribute, filled the validation plugin method, but still can’t see the rendered error messages. Even though the initial console.log for ($.validator) is writing that the validator is connected. And it seem that the cdn scripts are formulated in a propriate way.

$(function() {
  if ($.validator) {
    console.log('$.validator is defined'); // consoles ok
  }
  $('#form').validate({
    rules: {
      name: "required",
      phone1: {
        required: true,
        minlength: 2,
      },
      phone2: {
        required: true,
        minlength: 2,
      },
    },
    messages: {
      name: "Please enter your name",
      phone1: {
        required: "We need your email address to contact you",
        minlength: "Your phone number must be at least 5 characters long",
        message: "Please enter a valid phone number",
      },
      phone2: {
        required: "We need your email address to contact you",
        minlength: "Your phone number must be at least 5 characters long",
        message: "Please enter a valid phone number",
      },
    }
  });
})
<form action="submit" class="form" id="form">
  <label for="name">Name (text)</label>
  <input type="text" id="name" name="name" value="" />
  <label for="phone1">Phone1</label>
  <input type="tel" id="phone1" name="phone1" value="" />
  <label for="phone2">Phone2</label>
  <input type="tel" id="phone2" name="phone2" value="" />
  <button type="submit" class="submit">Submit</button>
</form>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="./jquery.move-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.20.0/jquery.validate.min.js" integrity="sha512-WMEKGZ7L5LWgaPeJtw9MBM4i5w5OSBlSjTjCtSnvFJGSVD26gE5+Td12qN5pvWXhuWaWcVwF++F7aqu9cvqP0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="./index.js"></script>
</body>

Tebex Create A Payment

I’m attempting to create a payment via Tebex’s Plugin API. However, I cannot seem to create the payment via the POST request.

Here is my code:

                        let tebexRequest = await axios({
                            method: 'POST',
                            url: `https://plugin.tebex.io/payments`,
                            headers: {
                                'X-Tebex-Secret' : config.tebexSecret
                            },
                            data: {
                                note: `Account ${requestUserId}`,
                                package: Number(row[0].tebexpackageid),
                                price: Number(row[0].price),
                                ign: fivemUsername
                            }
                        }).catch(e => { console.log('tebex errorn'); console.log(e) });

I believe my issue is in the format of my data key. I’m using AXIOS and here is the documentation for the POST request for reference according to Tebex in the image provided. If I’m doing the body of my request wrong, how am I supposed to format it?

I’ve also provided the error I am receiving in the images attached as-well.

tebex docs
error

I was hoping it would create the payment on Tebex but it did not. This is supposed to create a manual payment via the API.

random word replacement using react from js code

I am trying to lean react by solving a js problem in react. Providing the js code challenge below. I am seeing the below error in editor and I am not seeing any error in browser console. I googled but still no luck, not sure how to solve it. Providing my code below and stackblitz. Can you guys help me.

Error: Property ‘dataset’ does not exist on type ‘EventTarget’.(2339)

https://stackblitz.com/edit/stackblitz-starters-d3neo5?description=React%20%20%20TypeScript%20starter%20project&file=src%2FApp.tsx,src%2Fstyle.css,src%2Findex.tsx&title=React%20Starter

https://www.youtube.com/watch?v=xd08ZrFCiJ4&list=PL4cUxeGkcC9hhNl8shRf6TIL-dNkpSRV0&index=10

import { FC } from 'react';

import './style.css';

export const App: FC<{ name: string }> = ({ name }) => {
  const buttons = document.querySelectorAll('button');
  const textarea = document.querySelector('textarea');
  const output = document.querySelector('.output');

  // flavours
  const flavours = {
    ninja: ['dojo', 'shogun', 'shinobi', 'samuri', 'shuriken'],
    pokemon: ['pika', 'pokeball', 'pokedex', 'evolve', 'ash', 'gym'],
    space: ['universe', 'galaxy', 'telescope', 'comet', 'stars'],
  };

  // functions
  const flavourize = (inputText, flavour) => {
    const textArray = inputText.split(' ');

    for (let i = 0; i < textArray.length; i++) {
      if (i % 3 === 0) {
        const random = Math.floor(Math.random() * flavour.length);
        textArray[i] = flavour[random];
      }
    }

    return textArray.join(' ');
  };

  const updateOutput = (text) => {
    output.textContent = text;
  };

  // event listener
  buttons.forEach((b) => {
    b.addEventListener('click', (e) => {
      e.preventDefault();
      if (textarea.value) {
        const f = e.target.dataset.flavour;
        const text = flavourize(textarea.value, flavours[f]);
        updateOutput(text);
      }
    });
  });

  return (
    <div>
      <h1>Hello {name}!</h1>
      <p>Start editing to see some magic happen :)</p>

      <form>
        <textarea></textarea>
        <div className="buttons">
          <p>Choose your theme:</p>
          <button data-flavour="ninja">Ninja</button>
          <button data-flavour="pokemon">Pokemon</button>
          <button data-flavour="space">Space</button>
        </div>
      </form>
    </div>
  );
};

MediaStream is ended after setRemoteDescription on negotiation

Inside my video conference application, I want to implement screen share feature. I am using PeerJs library and since they don’t have the support to such feature, I have to build it from WebRTC API. I am currently facing the following issue: when I start the negotiation between connected peers, to add the share screen track to the peerConnection, and I setRemetoDescription with the offer, the stream from the Peer that wants to share the screen, is ended, losing the current video stream.

Is there a way to prevent that? Is this something related to the PeerJs library? Am I doing anything wrong?

This is my function when a user wants to share the screen:

const shareScreen = async () => {
    if (myPeer) {
      navigator.mediaDevices
        .getDisplayMedia({ video: { cursor: "always" }, audio: true })
        .then(async (stream) => {
          myStream.addTrack(stream.getVideoTracks()[0]);
          setMyScreenStream(stream);
          if (Object.keys(peerConnection).length !== 0) {
            peerConnection.addTrack(stream.getVideoTracks()[0], myStream);
            peerConnection.onnegotiationneeded = async () => {
              try {
                console.log("negotiating");
                const offer = await peerConnection.createOffer();
                await peerConnection.setLocalDescription(offer);
                socket.emit("negotiation", {
                  desc: peerConnection.localDescription,
                });
              } catch (err) {
                console.error(err);
              }
            };
          }
        });
    }
  };

And then, on my socket:

 socket.on("negotiating", async ({ desc }) => {
        try {
          if (desc) {
            if (desc.type === "offer") {
              console.log("desc type", desc.type);
              await peerConnection.setRemoteDescription(desc); // Here the Stream is ended.
            } else {
              console.log("Unsupported SDP type.");
            }
          }
        } catch (error) {
          console.log(error);
        }
      });

Infinite scrolling catches on vigorous scrolling/swiping

I have an infinite scroll box. There is a list of items and as the list scrolls up, items are appended from the bottom, and vice versa for scrolling down. When the user scrolls down or up normally, it works as expected. When they scroll with a laptop trackpad or on a screen with enough force, then the scroll bar reaches the top and the user needs to scroll down again for it work. Is there a way to get around this?

Here’s a codepen link to what I’m trying to do. Seems like it won’t scroll down on load in codepen (this is not the problem so please ignore), please scroll down a bit for it to work. I can produce the described behavior when I use a laptop trackpad or touch screen, I swipe down so the list moves upwards. Hope this wasn’t confusing – basically I want the scroll bar to never reach the top no matter how hard a user scrolls/swipes.

let container = document.querySelector('.calendar-container')
let calendar = document.querySelector('.calendar')

container.addEventListener('scroll', function (event) {

  const factor = container.scrollTop / (container.scrollHeight - container.offsetHeight);
  if(factor < 0.4) {
      let move = calendar.querySelector(':last-child')
      move.remove();
      calendar.prepend(move);
  } else if(factor > 0.6) {
      let move = calendar.querySelector(':first-child')
      move.remove();
      calendar.append(move);
  }

});

calendar.scroll(0,100);

Write rust app that allows sandboxed plugins written in .. rust?

I want to write an app in rust that is extensible with plugins written by (untrusted) users. Those plugins are downloadable via a web platform and can be installed by any user of the core software, but of course I want to protect the naive from the malicious users and have the plugins run in a sandboxed environment. Still the plugins should execute as fast as possible.

My take is to use wasm and a javascript sandbox as an interface.

  • Write main app in rust.
  • Users write plugins in rust and compile to wasm using the wasm32-unknown-unknown target.
  • Users create javascript bindings using wasm-bindgen
  • The core app emloys a javascript engine like V8 to execute the javascript frontend of the plugins.

I see a few downsides with this approach, mainly going through javascript and it’s engines which seems unnecessary. Isn’t there a faster approach to execute sandboxed web assembly directly from rust?

StompJs publish not sending to springBoot Server

Ive created a stompclient with js that can send messages to a spring boot server written in kotlin.
the problem is, the publish method of the stompClient supposedly sends the payload but the server doesn’t receive anything or return anything and the stompclient doesn’t return any error.

Here is my stompCode :

$(document).ready(function () {
    "use strict";
    let stompClient = null;
    let username = null;

    const stompConfig = {
      connectHeaders: {
        login: "user",
        passcode: "b7b0b48f-70a7-41ec-9be1-fde416564aef"
      },
      brokerURL: "ws://localhost:8080/chat",
      debug: function (str) {
        console.log('STOMP: ' + str);
      },
      reconnectDelay: 500,
      // Subscriptions should be done inside onConnect as those need to reinstated when the broker reconnects
      onConnect: function (frame) {
        const subscription = stompClient.subscribe('/topic/greetings', (greeting) => {
            showGreeting(JSON.parse(greeting.body).content);
        });
      }
    };

    stompClient = new StompJs.Client(stompConfig);

    function connect(){
        //will call the onConnect event on stompClient config
        stompClient.activate();
        username = $("#insertedName").val().trim() + " " + Math.round(Math.random() * 1000);
    }

    function send(){
        if (!stompClient.connected) {
            alert("Broker disconnected, can't send message.");
            return;
        }
        if ($("#insertedMessage").val().trim().length > 0) {
            const msg = $("#insertedMessage").val().trim()
            const payLoad = {from: username, message: msg, type: 'TEXT'};
            stompClient.publish({destination: '/app/hello', body: JSON.stringify({'name': $("#name").val()})
        });
      }
    }

    function disconnect(){
        stompClient.deactivate();
    }
});

stomp client response when i send :

STOMP: >>> SEND
destination:/app/hello
content-length:2

Tried changing the URL, tried changing waypoints, responses enabling a CORS extension, and nothing worked.

here is my spring boot config and controller :

override fun configureMessageBroker(config: MessageBrokerRegistry) {
        config.setApplicationDestinationPrefixes("/app")
        config.enableSimpleBroker("/topic/")
    }

    override fun registerStompEndpoints(registry: StompEndpointRegistry) {
        registry.addEndpoint("/chat")
    }
@MessageMapping("/chat")
    @SendTo("/topic/greetings")
    fun sendMessage(@Payload message: Message): Message {
        return Message(message.from,message.message,message.type)
    }

How to dynamically create a url that contains a date in the format yyyymmdd from the current url

I have the following code for auto scrolling page content to reveal more text.

I want the code to proceed to the next url automatically by opening it in a new tab. The problem is I have tried to parse the url to auto increment on the current date but I can’t get it to work.
The format of the current url is, for example:

https://www.example.com/data/20230102 so the next url should be https://www.example.com/data/20230103

The date format is YYYYMMDD. Only the date changes, the rest of the url stays the same.

At the moment, our example currentUrl is https://www.example.com/data/20230102 but instead of proceeding to https://www.example.com/data/20230103, the code proceeds to https://www.example.com/data/19700102 with the wrong nextUrl.

I need to use the currentUrl and calculate the next url so it needs to transition into a new date, month or year properly.

What I have so far:

// Function to get the next URL
function getNextUrl() {
    const currentUrl = new URL(window.location.href);
    const currentDate = new Date(Number(currentUrl.pathname.split('/')[2]));
    currentDate.setDate(currentDate.getDate() + 1);

    const year = currentDate.getFullYear();
    const month = (currentDate.getMonth() + 1).toString().padStart(2, '0');
    const day = currentDate.getDate().toString().padStart(2, '0');

    const nextUrl = `https://www.example.com/data/${year}${month}${day}`;

    return nextUrl;
}

// Function to auto-scroll if the last child does not have the class "current"
function autoScrollIfNeeded() {
    const pagination = document.querySelector('.pagination'); // Get the pagination element
    const listItems = pagination.querySelectorAll('li'); // Get all list items within pagination

    // Get the last list item
    const lastListItem = listItems[listItems.length - 1];

    // Get the page height
    const pageHeight = document.body.scrollHeight;

    // Check if we're not at the bottom and the last list item doesn't have the "current" class
    if (window.scrollY < pageHeight - window.innerHeight && !lastListItem.classList.contains('current')) {
        // Scroll down the page
        window.scrollBy(0, window.innerHeight); // You can adjust the scroll distance if needed
    } else {
        // If the last list item has the "current" class, scroll one more time and then stop
        window.scrollBy(0, window.innerHeight);
        clearInterval(scrollInterval); // Stop scrolling after the last scroll

        // Open the next link
        const nextUrl = getNextUrl();
        window.open(nextUrl, '_blank'); // Open the next URL in a new tab
    }
}

// Check and scroll every 100 milliseconds
const scrollInterval = setInterval(autoScrollIfNeeded, 100);

// Call the function when the page loads
window.addEventListener('load', autoScrollIfNeeded);