problem with dabbing files for each language and not to be seen in other languages

My site owns this feature,but not everything goes out.
I tried to change the parameters of the server part but does not help, there is someone who understands,
I am a novice developer

Language change:

The user can select a language from the drop-down list.

When you select a language, you query the server to retrieve the contents of the fairy tale file in the selected language.

Folk Tales:

The user can upload folktales for the selected language.

Downloaded files are displayed in the appropriate subcategory.

The contents of each file are displayed in text format.

Web counter:

The visitors counter is increased each time you visit the page or press the "Increase Counter" button.

The current value of the counter is displayed on the page.

Overall structure:

The page is divided into categories, represented by blocks with headers.

Each category can have subcategories with additional content.

You can upload files and display them on the page depending on the language you choose.

Server part (approximately):

Server on Node.js using Express, multer and other necessary modules.

Storage of uploaded files in the server memory.

Transfer of data between client and server via AJAX (Fetch API).

Important remarks:

This code provides the basis for further development. Additional security checks, error handling and other features should be added depending on specific requirements.

files should be dubbed on the site itself, each language should have its own files, the user will see only those files that have been added to the language he chose

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FAIRY-TALIA</title>
    <style>
        /* Add your styles here */
        body {
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f8f8f8;
        }

        header {
            background-color: #4CAF50;
            padding: 20px;
            text-align: center;
            color: white;
            font-size: 24px;
        }

        main {
            margin: 20px;
        }

        h1 {
            text-align: center;
            font-family: 'cursive', sans-serif;
            color: #333;
        }

        .category {
            margin-top: 20px;
        }

        .language-select {
            margin-bottom: 10px;
        }

        .tales-list,
        .authors-list,
        .blog-list {
            list-style: none;
            padding: 0;
        }

        .footer {
            background-color: #333;
            color: white;
            text-align: center;
            padding: 10px;
            position: fixed;
            bottom: 0;
            width: 100%;
        }
    </style>
</head>

<body>

    <header>
        <h1>FAIRY-TALIA</h1>
    </header>

    <main>
        <div class="category" id="languageCategory">
            <h2>Language Category</h2>
            <select class="language-select" onchange="changeLanguage()">
                <option value="en">English</option>
                <option value="ru">Russian</option>
                <option value="de">German</option>
                <option value="pt">Portuguese</option>
                <option value="es">Spanish</option>
                <option value="fr">French</option>
                <option value="ro">Romanian</option>
            </select>
        </div>

        <div class="category" id="folkTalesCategory">
            <h2>Folk Tales</h2>
            <input type="file" id="fileInputFolk" onchange="displayFile('folk')"/>
            <pre id="fileContentFolk"></pre>
            <ul class="tales-list" id="folkTalesList">
                <!-- Populate with folk tales -->
            </ul>
        </div>

        <div class="category" id="authorsTalesCategory">
            <h2>Author's Tales</h2>
            <input type="file" id="fileInputAuthors" onchange="displayFile('authors')"/>
            <pre id="fileContentAuthors"></pre>
            <ul class="authors-list" id="authorsTalesList">
                <!-- Populate with author's tales -->
            </ul>
        </div>

        <div class="category" id="blogCategory">
            <h2>Blog</h2>
            <input type="file" id="fileInputBlog" onchange="displayFile('blog')"/>
            <pre id="fileContentBlog"></pre>
            <ul class="blog-list" id="blogContentList">
                <!-- Populate with blog content -->
            </ul>
        </div>
    </main>

    <footer class="footer">
        <p>Visitors Count: <span id="visitorsCount">0</span></p>
        <p>Contact: [email protected]</p>
    </footer>

    <script>
        function displayFile(category) {
            const fileInput = document.getElementById(`fileInput${category}`);
            const fileContent = document.getElementById(`fileContent${category}`);

            const file = fileInput.files[0];
            if (file) {
                const reader = new FileReader();

                reader.onload = function (e) {
                    fileContent.textContent = e.target.result;
                    switch (category) {
                        case 'folk':
                            loadFolkTales(e.target.result);
                            break;
                        case 'authors':
                            loadAuthorsTales(e.target.result);
                            break;
                        case 'blog':
                            loadBlog(e.target.result);
                            break;
                        default:
                            break;
                    }
                };

                reader.readAsText(file);
            } else {
                fileContent.textContent = 'No file selected';
            }
        }

        function changeLanguage() {
            const selectedLanguage = document.getElementById('languageCategory').querySelector('select').value;
            loadFolkTalesContent(selectedLanguage);
            loadAuthorsTalesContent(selectedLanguage);
            loadBlogContent(selectedLanguage);
        }

        function loadFolkTales(content) {
            const folkTalesList = document.getElementById('folkTalesList');
            folkTalesList.innerHTML = '';

            const tales = content.split('n');
            tales.forEach(tale => {
                const listItem = document.createElement('li');
                listItem.textContent = tale;
                folkTalesList.appendChild(listItem);
            });
        }

        function loadAuthorsTales(content) {
            const authorsTalesList = document.getElementById('authorsTalesList');
            authorsTalesList.innerHTML = '';

            const tales = content.split('n');
            const sortedTales = tales.sort((a, b) => {
                const [aName] = a.split('-');
                const [bName] = b.split('-');
                return aName.localeCompare(bName);
            });

            sortedTales.forEach(tale => {
                const listItem = document.createElement('li');
                listItem.textContent = tale;
                authorsTalesList.appendChild(listItem);
            });
        }

        function loadBlog(content) {
            const blogContentList = document.getElementById('blogContentList');
            blogContentList.innerHTML = '';

            const posts = content.split('n');
            posts.forEach(post => {
                const listItem = document.createElement('li');
                listItem.textContent = post;
                blogContentList.appendChild(listItem);
            });
        }

        function loadFolkTalesContent(language) {
            const content = {
                en: 'English Folk Tale 1nEnglish Folk Tale 2nEnglish Folk Tale 3',
                ru: 'Russian Folk Tale 1nRussian Folk Tale 2nRussian Folk Tale 3',
                de: 'German Folk Tale 1nGerman Folk Tale 2nGerman Folk Tale 3',
                pt: 'Portuguese Folk Tale 1nPortuguese Folk Tale 2nPortuguese Folk Tale 3',
                es: 'Spanish Folk Tale 1nSpanish Folk Tale 2nSpanish Folk Tale 3',
                fr: 'French Folk Tale 1nFrench Folk Tale 2nFrench Folk Tale 3',
                ro: 'Romanian Folk Tale 1nRomanian Folk Tale 2nRomanian Folk Tale 3',
            };
            loadFolkTales(content[language]);
        }

        function loadAuthorsTalesContent(language) {
            const content = {
                en: 'John Doe - English Author's Tale 1nJane Smith - English Author's Tale 2nAlice Johnson - English Author's Tale 3',
                ru: 'Иван Иванов - Russian Author's Tale 1nМария Петрова - Russian Author's Tale 2nАлексей Сидоров - Russian Author's Tale 3',
                de: 'Hans Müller - German Author's Tale 1nAnna Schmidt - German Author's Tale 2nKlaus Wagner - German Author's Tale 3',
                pt: 'João Silva - Portuguese Author's Tale 1nAna Santos - Portuguese Author's Tale 2nCarlos Pereira - Portuguese Author's Tale 3',
                es: 'Juan López - Spanish Author's Tale 1nMaria González - Spanish Author's Tale 2nCarlos García - Spanish Author's Tale 3',
                fr: 'Jean Dupont - French Author's Tale 1nMarie Martin - French Author's Tale 2nPierre Lambert - French Author's Tale 3',
                ro: 'Ion Popescu - Romanian Author's Tale 1nAna Vasilescu - Romanian Author's Tale 2nMihai Radu - Romanian Author's Tale 3',
            };
            loadAuthorsTales(content[language]);
        }

        function loadBlogContent(language) {
            const content = {
                en: 'English Blog Post 1nEnglish Blog Post 2nEnglish Blog Post 3',
                ru: 'Russian Blog Post 1nRussian Blog Post 2nRussian Blog Post 3',
                de: 'German Blog Post 1nGerman Blog Post 2nGerman Blog Post 3',
                pt: 'Portuguese Blog Post 1nPortuguese Blog Post 2nPortuguese Blog Post 3',
                es: 'Spanish Blog Post 1nSpanish Blog Post 2nSpanish Blog Post 3',
                fr: 'French Blog Post 1nFrench Blog Post 2nFrench Blog Post 3',
                ro: 'Romanian Blog Post 1nRomanian Blog Post 2nRomanian Blog Post 3',
            };
            loadBlog(content[language]);
        }

        // Initialize the page with the default language
        loadFolkTalesContent('en');
        loadAuthorsTalesContent('en');
        loadBlogContent('en');
    </script>
</body>

</html>

server.js

const express = require('express');
const multer = require('multer');
const app = express();
const port = 5000;

app.use(express.json());

const folkTalesByLanguage = {};

const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

app.post('/api/uploadFolkTales', upload.single('folkTalesFile'), (req, res) => {
    const { content, language } = req.body;

    if (!folkTalesByLanguage[language]) {
        folkTalesByLanguage[language] = [];
    }
    folkTalesByLanguage[language].push(content);

    res.send('Folk tales uploaded successfully');
});

app.get('/api/getContent', (req, res) => {
    const language = req.query.language || 'en';

    if (folkTalesByLanguage[language] && folkTalesByLanguage[language].length > 0) {
        const content = folkTalesByLanguage[language].join('n');
        res.send(content);
    } else {
        res.send('No content available for the selected language');
    }
});

app.listen(port, () => {
    console.log(`Server is running at http://localhost:${port}`);
});

script.js

  fetch(`/api/getContent?language=${language}`)
      .then(response => response.text())
      .then(content => {
          loadFolkTales(content);
      })
      .catch(error => {
          console.error('Error fetching content:', error);
      });
}

function uploadFolkTales() {
  const fileInput = document.getElementById('fileInputFolk');
  const fileContent = document.getElementById('fileContentFolk');

  const file = fileInput.files[0];
  if (file) {
      const reader = new FileReader();

      reader.onload = function (e) {
          fileContent.textContent = e.target.result;
          const selectedLanguage = document.getElementById('languageCategory').querySelector('select').value;
          sendFolkTalesToServer(e.target.result, selectedLanguage);
      };

      reader.readAsText(file);
  } else {
      fileContent.textContent = 'No file selected';
  }
}

function sendFolkTalesToServer(content, language) {
  fetch('/api/uploadFolkTales', {
      method: 'POST',
      headers: {
          'Content-Type': 'application/json',
      },
      body: JSON.stringify({
          content: content,
          language: language,
      }),
  })
  .then(response => response.text())
  .then(message => {
      console.log(message);
      loadFolkTalesFromServer(language);
  })
  .catch(error => {
      console.error('Error uploading folk tales:', error);
  });
}

let visitorsCount = 0;

function increaseCounter() {
  visitorsCount++;
  document.getElementById('visitorsCount').textContent = visitorsCount;
}

document.addEventListener('DOMContentLoaded', () => {
  increaseCounter();
  const selectedLanguage = document.getElementById('languageCategory').querySelector('select').value;
  loadFolkTalesFromServer(selectedLanguage);
});

// Additional functions and existing code remain unchanged
// ...
</script>

I thought the problem was in the server part and the function, but before that everything was right, maybe I accidentally deleted or missed something, and also for some reason when I changed something in the script.js file I had broken categories.Also I tried me port on 8080 and 5000 but did not help me

Is there a standard way in JS to download a large file from the backend using a passcode/password?

I am creating an application where users can download a huge file/s (around 8GB, depending on the user). The file must be password protected, so a GET request with a param isn’t ideal.

Using .blob() on the response leads to RAM issues if the file is too big.

I also checked https://github.com/jimmywarting/StreamSaver.js but I would prefer something more “official” if possible.

How do websites like TransferXL or WeTransfer achieve this ?

How can I access a specific OnGet function of a RazorPage from javascript?

I’ve got a razor page with 3 OnGet functions but no matter how I try to call it, it always goes to the original OnGet function.

public class MyRazorPageModel : PageModel
{
    private readonly ISessionProvider ISP = null;

    public MyRazorPageModel(ISessionProvider iSessionProvider)
    {
        ISP = iSessionProvider;
    }

    public void OnGet(int employeeId)
    {
        //All requests come here for some reason

        //Load logic
    }

    public void OnGetNextEmployee(int employeeId)
    {
        int index = ISP.EmployeeIds.FindIndex(id => id == employeeId);

        if(index == -1) //Not found
        {
            OnGet(employeeId);
        }
        else if(index == ISP.EmployeeIds.Count - 1) //End of list
        {
            OnGet(employeeId);
        }
        else
        {
            int nextEmployeeId = ISP.EmployeeIds[index + 1];
            OnGet(nextEmployeeId);
        }
    }

    public void OnGetPreviousEmployee(int employeeId)
    {
        int index = ISP.EmployeeIds.FindIndex(id => id == employeeId);

        if (index == -1) //Not found
        {
            OnGet(employeeId);
        }
        else if (index == 0) //Start of list
        {
            OnGet(employeeId);
        }
        else
        {
            int previousEmployeeId = ISP.EmployeeIds[index - 1];
            OnGet(previousEmployeeId);
        }
    }
}

In javascript I have:

var wnd = window.parent.$("#DetailWnd").data("kendoWindow");
var _url = "/MyRazorPage?handler=NextEmployee?employeeId=" + $('#EmployeeId').val();
wnd.refresh({
    url: _url
});

But it only ever goes to OnGet, never OnGetNextEmployee or OnGetPreviousEmployee.

How do i solve this complex non-linear method with js?

Net =  ( basic + housing + transport ) - (PAYE + INSS )

Tables(Gross)

basic : x

housing : 30 % of basic

Transport Allowance:

Net Salary Range    Transport Allowance

0 to 500    50

501 to 750  100

751 to 1000 150

1001 to 1500    200

Above 1500  250

(Deductions)

INSS : 0.05(x)

PAYE (calculated using progression):

amounts converted from usd to franc using exchange rate of 1: 2477

Taxable Income Range    Tax Rate

0 to 162,000    3%

162,001 to 1,800,000    15%

1,800,001 to 3,600,000  30%

Above 3,600,000 40%

the challenge was: given the net value (for example 700) calculate the value of the basic salary.

function calculateBasicSalary(netSalary) {
  // Define the transport allowance ranges
  const ranges = [
      { min: 0, max: 500, allowance: 50 },
      { min: 501, max: 750, allowance: 100 },
      { min: 751, max: 1000, allowance: 150 },
      { min: 1001, max: 1500, allowance: 200 },
      { min: 1501, max: Infinity, allowance: 250 },
  ];

  // Find the appropriate transport allowance for the given net salary
  const transportAllowance = ranges.find(range => netSalary >= range.min && netSalary <= range.max).allowance;

  // Calculate housing allowance (30% of basic)
  const housingAllowance = 0.3 * (netSalary - transportAllowance);

  // Calculate basic salary before deductions
  const basicSalaryBeforeDeductions = netSalary - housingAllowance - transportAllowance;

  // Reconvert basic allowance for PAYE calculation
  const payeBasic = basicSalaryBeforeDeductions / 2477;

  // Calculate INSS deduction (5% of basic)
  const inssDeduction = 0.05 * payeBasic * 2477;

  // Calculate taxable income for PAYE
  const taxableIncome = netSalary - inssDeduction;

  // Calculate PAYE deduction using progressive rates
  let payeDeduction;
  if (taxableIncome <= 162000) {
      payeDeduction = 0.03 * payeBasic * 2477;
  } else if (taxableIncome <= 1800000) {
      payeDeduction = 0.15 * payeBasic * 2477;
  } else if (taxableIncome <= 3600000) {
      payeDeduction = 0.3 * payeBasic * 2477;
  } else {
      payeDeduction = 0.4 * payeBasic * 2477;
  }

  // Add INSS and PAYE deductions to basic salary
  const basicSalary = basicSalaryBeforeDeductions + inssDeduction + payeDeduction;

  return {
      basic: basicSalary,
      housing: housingAllowance,
      transport: transportAllowance,
      inss: inssDeduction,
      paye: payeDeduction,
      net: netSalary,
  };
}

// Example usage:
const netSalary = 1200; // Replace with your desired net salary
const result = calculateBasicSalary(netSalary);
console.log(result);

I tried the above function which returned the below values… my function was obviously wrong because even in the results the housing is not 30% of basic and the inss is not 5% of basic which leads me to believe every other value in the result is most likely wrong as well:

{
  basic: 756,
  housing: 300,
  transport: 200,
  inss: 35,
  paye: 21,
  net: 1200
}

Why does an arrow disappear at some angles in HTML Canvas?

I am facing a weird bug in HTML Canvas. I want to draw an arrow but for some reason it disappears for some coordinates. Here is the MCVE:

    const canvas = document.getElementById('scene') as HTMLCanvasElement

    // canvas sizing
    const ctx = canvas.getContext('2d')
    if (ctx === null) { console.error(`ctx is ${ctx}`); return }

    canvas.width = 512
    canvas.height = 512

    let from = {x:317, y:166}
    let to = {x:439, y:56}
    let arrowHeadSize = 20
    let arrowFinsAngle = Math.PI/6
    let path = new Path2D()
    
    // arrow body
    path.moveTo(from.x, from.y)
    path.lineTo(to.x, to.y)

    // arrow head
    let radians_to = Math.atan2(to.y - from.y, to.x - from.x)
    
    path.moveTo(to.x, to.y);
    path.lineTo(to.x - arrowHeadSize * Math.cos(radians_to - arrowFinsAngle), to.y - arrowHeadSize * Math.sin(radians_to - arrowFinsAngle));
    path.moveTo(to.x, to.y);
    path.lineTo(to.x - arrowHeadSize * Math.cos(radians_to + arrowFinsAngle), to.y - arrowHeadSize * Math.sin(radians_to + arrowFinsAngle));

    path.closePath()

    ctx.lineWidth = 4
    ctx.strokeStyle = "white"
    ctx.lineCap = "round"
    ctx.lineJoin = "round"
    ctx.stroke(path)

This bug occurs in the Chrome browser but not in Firefox.

arrow bug in Chrome

Set 3 values to default values if only one of them returns ‘undefined’

I am unable to set all three values (state, city, zip) to default (Sitka, Alaska, 99801) if only one of them returns ‘undefined’.

We are using this code in Unbounce page builder with MaxMind geo location finder.

$(window).on('load', function() {
  $.getScript('//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js', function() {
    geoip2.city(function(geoipResponse) {
      let city = geoipResponse.city.names.en || 'Sitka'; // Default city to 'Sitka' if undefined
      let state = geoipResponse.subdivisions[0].names.en || 'Alaska'; // Default state to 'Alaska' if undefined
      let zip = geoipResponse.postal.code || '99801'; // Default zip to '99801' if undefined
      $('#lp-pom-form-520 #State').val(state);
      $('#lp-pom-form-520 #City').val(city);
      $('#lp-pom-form-520 #Zip').val(zip);
    }, function(error) {
      console.error('Error fetching geoip data:', error);
    });
  });
});

I also tried this, but it doesnt worked:

<script>
$(window).on('load', function() {
 $.getScript('//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js', function() {
  geoip2.city(function(geoipResponse) {
   let city = geoipResponse.city.names.en || 'Sitka';
   let state = geoipResponse.subdivisions[0].names.en || 'Alaska';
   let zip = geoipResponse.postal.code || '99801';
   // Set default values if any of the fields is undefined
   if (!city || !state || !zip) {
     city = 'Sitka';
     state = 'Alaska';
     zip = '99801';
   }
   $('#lp-pom-form-520 #State').val(state);
   $('#lp-pom-form-520 #City').val(city);
   $('#lp-pom-form-520 #Zip').val(zip);
  }, function(error) {
   console.error('Error fetching geoip data:', error);
  });
 });
});
</script>

Regex: match a whole word that starts with a prefix? [duplicate]

How can I match a whole word that starts with a prefix? For example:

const str = 'ease-in-out filter blur-[200px] opacity-0'
const res = str.replace(/(^|s)(blur-+.*)/g, '')

result (it removes everything after the match):

ease-in-out filter

expected result:

ease-in-out filter opacity-0

The words that I want to match sometimes can be as follows:

blur-3xl
blur-large

and so on but always starts with blur-

Any ideas?

Trouble displaying additional images on button click in React Gallery component

I have a React Gallery component that initially displays a set number of images. When a button is clicked, I want the component to show additional images. However, my current implementation is not working as expected. The code is provided below:

import React, { useState } from 'react';
import GridElem1 from '../assets/img/App/gallery/grid-row-1.jpg'
import GridElem2 from '../assets/img/App/gallery/grid-col-1.jpg'
import GridElem3 from '../assets/img/App/gallery/grid-row-2.jpg'
import GridElem4 from '../assets/img/App/gallery/grid-col-2.jpg'
import GridElem5 from '../assets/img/App/gallery/grid-col-3.jpg'
import GridElem6 from '../assets/img/App/gallery/grid-row-3.jpg'
import GridElem7 from '../assets/img/App/gallery/grid-row-4.jpg'
import GridElem8 from '../assets/img/App/gallery/grid-col-4.jpg'
import GridElem9 from '../assets/img/App/gallery/grid-col-5.jpg'
import GridElem10 from '../assets/img/App/gallery/grid-row-5.jpg'
import GridElem11 from '../assets/img/App/gallery/grid-row-6.jpg'
import GridElem12 from '../assets/img/App/gallery/grid-col-6.jpg'
import {
    MDBCol,
    MDBRow,
} from 'mdb-react-ui-kit';

const Gallery = () => {
    const allImages = [GridElem1, GridElem2, GridElem3, GridElem4, GridElem5, GridElem6, GridElem7, GridElem8, GridElem9, GridElem10, GridElem11, GridElem12]
    const imagesPerPage = 1;
    const [visibleImages, setVisibleImages] = useState(allImages.slice(0, imagesPerPage));
    const showMoreImages = () => {
        const currentVisibleCount = visibleImages.length;
        const newVisibleImages = allImages.slice(currentVisibleCount, currentVisibleCount + imagesPerPage);
        const uniqueNewVisibleImages = newVisibleImages.filter(img => !visibleImages.includes(img));
        setVisibleImages((prevVisibleImages) => [...prevVisibleImages, ...uniqueNewVisibleImages]);
    }
    // console.log(visibleImages);
    // visibleImages.map((img, index) => {
    //     console.log(allImages[index]);
    // })

    return (
        <>
            {visibleImages.map((image, index) => (
                <MDBRow key={index}>
                    <MDBCol lg={4} md={12} className='mb-4 mb-lg-0'>
                        <img
                            src={image}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 1}`} />

                        <img
                            src={allImages[index * 2 + 1]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 2}`} />
                    </MDBCol>

                    <MDBCol lg={4} className='mb-4 mb-lg-0'>
                        <img
                            src={allImages[index * 2 + 2]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 3}`} />

                        <img
                            src={allImages[index * 2 + 3]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 4}`} />
                    </MDBCol>

                    <MDBCol lg={4} className='mb-4 mb-lg-0'>
                        <img
                            src={allImages[index * 2 + 4]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 5}`} />

                        <img
                            src={allImages[index * 2 + 5]}
                            className='w-100 shadow-1-strong rounded mb-4'
                            alt={`Image ${index * 2 + 6}`} />
                    </MDBCol>
                </MDBRow>

            ))}
            {visibleImages.length < allImages.length && (
                <button onClick={showMoreImages}>Показать еще</button>
            )}
        </>
    );
}

export default Gallery;

I attempted to implement a “show more” functionality in the Gallery component. However, the additional images are not being displayed correctly. I expected that clicking the “Show More” button would append more images to the existing ones.

How I can prevent object modification after saving record to db by Sequelize?

I have an imaginative object:

{
   '0_1': 'value',
   '1_1': 'value',
   '5_5': 'value'
}

The order of these properties is important. But after that I save this record in table by Sequelize – order changes.

  createGameState(state: TGameStateCreationAttributes): Promise<IGameState> {
    return this.gameStateModel.create(state);
  }

{
   '1_1': 'value',
   '5_5': 'value',
   '0_1': 'value'
}

How I can change this behavior?

Filtering content with buttons, but when all are active and one is clicked again, it only shows that result

everyone. As the title suggests, I’m trying to use buttons to filter my pricing tables, which is working, but when all buttons are clicked/active (minus the clear button, which shows all the content again) and you click another one, it will only show the filter result of the last button clicked. What should happen is that when all buttons are active (minus the clear button) and another is clicked, the result will stay the same

<script>

$(document).ready(function() {
  $('.btn').click(function() {
    var pars = $('#contents div');
    

    if ($(this).data('target') == 'all') {          
      pars.show(); 
      $('.btn').removeClass('active');
      
      
    } else {
      if ($('#contents div:visible').length == pars.length) {                
        pars.hide();
        
      }

      $('#contents div.' + $(this).data('target')).show();
      $(this).addClass('active');
      
    }
  })
})

</script>


<button id="B1" class="btn" data-target="columns-one">B1</button>
<button id="B2" class="btn" data-target="columns-two">B2</button>
<button id="B3" class="btn" data-target="columns-three">B3</button>
<button id="clear" class="btn" data-target="all">Clear</button>

What I’ve gathered is that its a logical error in the else statement, that will hide the results because all the content is showing. I’ve tried disabling the buttons to prevent users from being able to the click active buttons again, button it doesn’t work as intended.

<script>

$(document).ready(function() {
  $('.btn').click(function() {
    var pars = $('#contents div');
    var buttonId = $(this).attr('id');

    if ($(this).data('target') == 'all') {          
      pars.show(); 
      $('.btn').removeClass('active');
      $('.btn').prop('disabled', false);
      
    } else {
      if ($('#contents div:visible').length == pars.length) {                
        pars.hide();
        buttonId.prop('disabled', true);
      }

      $('#contents div.' + $(this).data('target')).show();
      $(this).addClass('active');
      
    }
  })
})

</script>

I’d appreciate any advice/help given. Thanks

How to draw offcanvas of offscreen canvas to onscreen canvas?

What

I’m making a 2D game on pure JS and I use CanvasRenderingContext2D.translate() to emulate camera movements. I mean that my drawable level is much bigger than the canvas itself (when the canvas size for example is about 1920×1080, player can stand at (72000, 72000) coordinate).

Everything works well, but now I’m trying to implement shadows and lights using offscreen canvas that I fill with black and make arc areas with calculated alpha where the lights sources are positioned on the level.

Problem

When I try to copy offscreen canvas to onscreen one, it’s always rendered at (0, 0) of onscreen canvas with the canvas size (1920×1080 from example).

Some code if you need it

That’s how I setup the canvas created on html page

const canvas = document.getElementById("canvas1");
const ctx = canvas.getContext("2d");

canvas.width = document.body.offsetWidth;
canvas.height = document.body.offsetHeight - 50;

That’s how I create offscreen canvas in code

// canvasSize is a real size of onscreen canvas, nothing changes if I set it to 72000x72000
var offScreenCanvas = document.createElement('canvas');
offScreenCanvas.width = this.canvasSize.x;
offScreenCanvas.height = this.canvasSize.y;
var context = offScreenCanvas.getContext("2d");

That’s some ways I tried to draw it

// where c is onscreen canvas context
c.putImageData(context.getImageData(this.camera.pos.x, this.camera.pos.y, this.canvasSize.x, this.canvasSize.y), this.camera.pos.x, this.camera.pos.y);
c.drawImage(offScreenCanvas, 0, 0);
c.drawImage(offScreenCanvas, 0, 0, 72000, 72000);
// also tried other overloads

All of these ways are ended up with the same result

How do I display a username, with javascript and html, on another page without getting a “null” error?

I am new at Javascript and I wanted to make a simple login page that has a username field that you input. The data is then displayed on the next page, a welcome (username) page. I tried using the local storage option. Didn’t work. Using the simplest methods I could find on the internet, the research deemed fruitless. Here is my simplified code:

Index.html:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Login</title>
</head>

<body>
<form action=“welcome.html”>
    <input type=“text” id=“username”>
    <input type=“submit”>
</form>
<script src=“script.js”></script>
</body>

Script.js:

function username(){
  var usernameId = document.getElementById("username").value;
  localStorage.setItem("id", usernameId);
  return false;
}

Welcome.html:

Blah blah blah blah

<body>
    <h1>Welcome</h1>
    <h2 id=“fetchUsername”></h2>
</body>

I pretty much got this far and everything else just goes down hill from there. Can someone please fix, change, do anything that makes it work in a simple, beginner friendly way. Thanks again!

Error regarding useLegacyLights when using A-frame

I’m currently building a website and I want to use a moving 360 degree image as a background. After a bit of research I stumbled upon this post and I decided to use the A-Frame framework. I did most of the work on a school computer that most likely was using an older version of chrome to test the code. The program worked fine. I saved the code on my USB and opened the same page on my home computer, using the newest version of chrome (I was using the newest A-frame version 1.5.0 and the newest threejs version r158.).

The page was completely broken, but I narrowed the problem down to the A-Line framework. The following html code returned the error message

Uncaught TypeError: Cannot set properties of undefined (setting useLegacyLights)

<a-scene>
    <a-sky src="public/space.png"></a-sky> 
</a-scene>

There was a warning message as well:

The property .useLegacyLights has been deprecated. Migrate your lighting according to the following guide.

So I looked into that, but was confused since I wasn’t directly using the threejs module. It turned out that there is a single line of code in the a-frame renderer.js script that causes the issue:

renderer.useLegacyLights = !data.physicallyCorrectLights;

But I don’t know what to do with any of this information. I’m unsure if there is something wrong with my code, if the browser is not compatible or if the framework is simply outdated? Should I use older threejs versions to sidestep the issue instead? Thanks!

I tried to follow the guide the warning message provided.

<a-light type="ambient" useLegacyLight="false"></a-light>

But I don’t have any clue if this did anything. It just left me confused. I’m just starting out with web development, so I have no actual clue what is happening here.

Splitting a string into multiple parts

I’m coding a Discord bot and want to add a fun “flirt” command. You could basically ping a user to flirt with them, and the bot would just send a little line of text from an API, and ping the user. Thing is, I’m still quite new and don’t really know how to remove parts from an API while converting into a string.

Here is my code:

const { SlashCommandBuilder } = require("discord.js");
const fetch = require("node-fetch");

module.exports = {
  cooldown: 5,
  data: new SlashCommandBuilder()
    .setName("flirt")
    .setDescription("Select a member to flirt with.")
    .addUserOption((option) =>
      option
        .setName("target")
        .setDescription("The member to flirt with.")
        .setRequired(true)
    ),
  async execute(interaction) {
    const member = interaction.options.getUser("target");
    const userTag = `${member.username}`;

    const url = `https://vinuxd.vercel.app/api/pickup`;
    const data = await (await fetch(url)).text();
    var new_string = data.replace(`{"pickup":"`, "");
    console.log(new_string);
    return interaction.reply(`Hey ${member}, my babygirl. ${new_string} `);
  },
};

Keep in mind I just want to remove the last “} part, I removed the first part already. Am I just being dumb or?