Why does Import a systemjs module failing in Javascript

I have a React application that I try to import a module Registered as a systemjs module using the following code snippet.

import System from 'systemjs';
const imported_module;

System.import("https://example.js")
    .then((module) => {
      // Use the module
      imported_module = module;
    })
    .catch((error) => {
      console.error('Error loading the module:', error);
    });

However, when I try to import it I get the following error even though I have installed systemjs npm module.

ERROR in ./node_modules/systemjs/dist/system-node.cjs
Module not found: Error: Can't resolve 'fs' in '/node_modules/systemjs/dist'
 @ ./node_modules/systemjs/dist/system-node.cjs 7785:17-30
 @ ./src/index.js

Can anybody figure out what am I doing wrong here?

Memory Leak issue when running dev environment on local machine [Vue/Nuxtjs]

So I have a Nuxt dev environment opened locally on my PC, which has 16gb of RAM, but something that keeps happening and has happened ever since I updated the framework on this specific site is that Volar (whatever that is) keeps hitting memory capacity and rebooting the server, even though nothing on my screen is rebooting–things just progressively lag more and more until it runs out of memory and flushes itself. This process repeats itself about 5-6 times before VSCode decides to terminate the process altogether. I have no idea what is causing this problem; my tsconfig.json seems to be excluding node-modules, and my other projects don’t have this issue. It’s a bit of an annoying problem, considering my site will be a catalog. For the time being though to the extent of my knowledge, nothing is connected serverside. I’ve only been using Nuxt for about a month now, so I’m still new to this whole thing.

Here is the output of the memory leak (simulated via simply running dev mode):

enter image description here

Also attached here is my package.json:

{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "overrides": {
    "lodash.pick": "3.0.0",
    "postcss": "^8.4.32",
    "vite": "^5.0.12"
  },
  "devDependencies": {
    "@formkit/auto-animate": "^0.8.1",
    "@nuxtjs/color-mode": "^3.3.2",
    "@nuxtjs/device": "^3.1.1",
    "@nuxtjs/stylelint-module": "^5.1.0",
    "autoprefixer": "^10.4.16",
    "nuxt": "^3.9.3",
    "nuxt-vite": "^0.3.5",
    "postcss": "^8.4.32",
    "tailwindcss": "^3.4.0",
    "vue": "^3.4.3",
    "vue-router": "^4.2.5"
  },
  "dependencies": {
    "sass": "^1.69.7"
  }
}

and my tsconfig.json:

// Generated by nuxi
{
  "compilerOptions": {
    "forceConsistentCasingInFileNames": true,
    "jsx": "preserve",
    "jsxImportSource": "vue",
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "skipLibCheck": true,
    "isolatedModules": true,
    "useDefineForClassFields": true,
    "strict": true,
    "noImplicitThis": true,
    "esModuleInterop": true,
    "types": [],
    "verbatimModuleSyntax": true,
    "allowJs": true,
    "noEmit": true,
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    "paths": {
      "~": [
        ".."
      ],
      "~/*": [
        "../*"
      ],
      "@": [
        "../../../../../../.."
      ],
      "@/*": [
        "../../../../../../../*"
      ],
      "~~": [
        ".."
      ],
      "~~/*": [
        "../*"
      ],
      "@@": [
        ".."
      ],
      "@@/*": [
        "../*"
      ],
      "assets": [
        "../assets"
      ],
      "assets/*": [
        "../assets/*"
      ],
      "public": [
        "../public"
      ],
      "public/*": [
        "../public/*"
      ],
      "#app": [
        "../node_modules/nuxt/dist/app"
      ],
      "#app/*": [
        "../node_modules/nuxt/dist/app/*"
      ],
      "vue-demi": [
        "../node_modules/nuxt/dist/app/compat/vue-demi"
      ],
      "#color-mode-options": [
        "./color-mode-options.mjs"
      ],
      "#vue-router": [
        "./vue-router-stub"
      ],
      "#imports": [
        "./imports"
      ],
      "#build": [
        "."
      ],
      "#build/*": [
        "./*"
      ],
      "#components": [
        "./components"
      ]
    }
  },
  "include": [
    "./nuxt.d.ts",
    "../**/*",
    "../node_modules/@nuxtjs/color-mode/runtime",
    "../node_modules/@nuxt/devtools/runtime",
    "../node_modules/@nuxt/telemetry/runtime",
    "..",
    "../../../../../../.."
  ],
  "exclude": [
    "../node_modules",
    "../../node_modules",
    "../node_modules/nuxt/node_modules",
    "../node_modules/@nuxtjs/color-mode/runtime/server",
    "../node_modules/@nuxt/devtools/runtime/server",
    "../node_modules/@nuxt/telemetry/runtime/server",
    "../dist",
    "../.output"
  ]
}

How can we manage global state in react native?

I am a new to react native i am using redux persist and i am able to get the data in the first screen view from the use selector but when i click button present in first view it navigate to second view but in that second view i am not able to get the use selector data.

here is my app.js
<QueryClientProvider client={queryClient}>
      <ToastProvider>
        <NavigationContainer>
          <Provider store={store}>
            <PersistGate loading={null} persistor={persistor}>
              <Stack.Navigator initialRouteName={`Login`}>
                <Stack.Screen name="Registration" component={Registration} />
                <Stack.Screen name="Login" component={Login} />
                <Stack.Screen name="Home" component={HomeScreen} />
                <Stack.Screen name="second" component={SecondScreen} />
              </Stack.Navigator>
            </PersistGate>
          </Provider>
        </NavigationContainer>
      </ToastProvider>
    </QueryClientProvider>

here is my store
import { combineReducers, configureStore } from “@reduxjs/toolkit”;
import userReducer from “./userSlice”;

import storage from “@react-native-async-storage/async-storage”;
import { persistStore, persistReducer } from “redux-persist”;

const persistConfig = {
key: “root”,
storage,
version: 1,
};

const persistedReducer = persistReducer(persistConfig, userReducer);

export const store = configureStore({
reducer: {
users: persistedReducer,
},
});

export const persistor = persistStore(store);

here is my login code
onSubmit={(values, { resetForm }) => {
        console.log(values);
        login(values).then((res) => {
          console.log(res);
          if (res?.success === true) {
            toast.show("Hello user", {
              type: "success",
              placement: "bottom",
            });
            dispatch(
              setLogin({
                userid: res?.user?._id,
                token: res?.token,
                name: res?.user?.username,
              })
            );
            resetForm();
            navigation.navigate("Home");
          } else {
            console.log("no data");
          }
        });
      }}

I have tried using redux persist but it is not working as expected, when i click login button it navigate to home view where it view the name from use selector but when i click the button from the home view it navigate to second view but in second view it is not showing the data
[enter image description here](https://i.stack.imgur.com/FOq0G.jpg)

Can I use Node.JS PassThrough stream as a simple input buffer?

I am running a subprocess from Node.js, let’s call it generator. I need to read its output and process it. At some times, the generator spits out a big chunk of data, around 50MB/s. But most of the time, it produces data at much slower rate.

The code that reads the data also sometimes slows down and doesn’t read as fast. Overall, my Node.js program reads faster than the generator produces, but these changes in both read speed on my side and output speed of the generator result in occasional back pressure which slows the generator.

I want to have up to about 50MB of generators output buffered in Node.js. I tried this, but I am not seeing much improvement and I do not know how to accurately benchmark this:

/**
 * 
 * @param nodeInputStream
 * @returns {Promise<null>} returns when end of stream is reached
 */
async function readAndProcessStream(nodeInputStream)  {
    // implementation redundant
    return;
}

async function createProcessAndRead() {
    const childArgs = ["arg1", "arg2"];
    const programName = "my_program";
    console.log("Spawn with args: ", programName, childArgs.join(" "));
    const childProc = child_process.spawn(
        programName,
        childArgs,
        {
            stdio:["ignore", "pipe", "ignore"],
            detached: true
        }
    );

    const exitCodePromise = new Promise((resolve, reject) => {
        childProc.once('close', resolve);
    });

    // Try to make a 50MB buffer
    const bufferStream = new PassThrough({emitClose: true, highWaterMark: 50*1024*1024});
    childProc.stdout.pipe(bufferStream);
    await readAndProcessStream(bufferStream);
    // make sure to wait till the process really exists
    await exitCodePromise;
}

Is the above code correct to make a 50MB worth of buffer space between the generator and the function that handles the stream? If not, what is the correct approach?

Handling multiple parameters in app.param()

I’m working on an API in Express.js and trying to implement an app.param() function that handles the id parameter in a GET request:

app.param('id', (req, res, next, id) => {
    const envelopeIndex = Number(id);
    const envelopeId = envelopes.findIndex(envelope => envelope.id === envelopeIndex);
    if (envelopeId === -1) {
        res.status(400).send("Error: No envelope found with this ID");
    }
    req.id = envelopeId;
    next();
});

For another POST request handler that transfers some amount from one envelope to another (through their IDs), I also want to validate two route parameters that are both IDs (/envelopes/:from/:to/).

My questions:

  1. Can I refactor the middleware above so that it handles multiple parameters and I don’t have to repeat myself?
  2. If so, is there a way I can dynamically assign to the request object the validated ID (e.g. if I am validating ID of ‘from’, it assigns req.senderId the validated ID, etc.)

I tried:

  • Repeating the middleware three times (once per route parameter)

Acknowledge whether user has a program bound to a certain protocol

I need to know if on their browser or OS, user has a navigation program associated with the protocol geo:

My link are like this: <a href="geo:51.5125509,-0.2190250">Address</a>

Previously, I was just checking if user was on mobile, and in this case, open the link. If on desktop, the link was changed to

https://www.openstreetmap.org/directions?to=51.5125509,-0.2190250.

However, user can have registered a default website or program on desktop for a given protocol, so I want to change my function.

I’v tried to test

navigator.registerProtocolHandler('geo', 'https://www.example.com/%s', 'Test Geo Handler');

but it necessarily triggers a permission modale and actually does not tell anything about what I need.

EDIT: I already checked these questions but in my case it’s not a custom protocol so I thought I might have a chance.

Check if a browser supports a custom protocol using JavaScript?

How to check if a custom protocol supported

tabulator.js: list with valuelookup and custom ajax-get

I am trying to use a list inside a column at tabulator.js.
The source of this list should be a custom ajax request.
As far as I understood, I must return a promise.
But it doesn’t work. The http-request is done, but I see in the dropdown only nonsense.
Can someone give me a hint, please?

{title:"Name", field:"name", editor:"list", editorParams:{
    valuesLookup:function(cell, filterTerm){
          res =  $.ajax({
              url: "/api/v1/networks",
              type: "GET",
              contentType: "application/json; charset=utf-8",
              dataType: "json",
          });
          return res.promise();
    }
}},

If I use the implemented “valuesURL” it is working fine, but I can not use this later on.

Make custom tag

I want to make custom tag of my name.so what do I do for making custom tag.
eg. if I am entered that tag then some default behavior has to add with that.
eg.h1 tag make text bold and big while we didn’t give any type of css to that.

I don’t understand why an anonymous function, which I am passing to onClick() event on a button, is not passing the argument

This code is working absolutely fine, when button is clicked, anonymous function is triggered which calls myFunction(), and then myFunction() updates the content, which results the 'updated state' text in button.

image_1

But when I try to achieve the same results using this approach, I don’t know why this code fails, myFunction() is working fine but the problem is that it is not updating the content which I am passing through argument in anonymous function.

image_2

International Input in Angular 17

I have recently updated my angular project from 13.3 to 17. And hence had to replace the library intl-input-phone with someting that supports angular 17. Another option that i came accross was ngx-intl-tel-input but again it does not support angular 17.

I am trying to use https://www.npmjs.com/package/intl-tel-input thats a javascript library.
I tried to create a custom component and use it but not getting a clue. I appreciate if someone came accross this and found a hack.

Maintainers please dont mark the question by asking me to provide reproducable code or not following guidelines.

Combining relevant data in two different arrays

Can you help on how to combine data in two different arrays with different structures?

I take data via API, the first request:

[
  {
    "category_id": "12345",
    "category_name": "itemgroup 1",
    "category_is_hidden": "0",
    "product_id": "9999999",
    "product_name": "item 1",
    "product_sku": "0002344",
    "product_brand": null,
    "product_vendor_code": "art 123",
    "is_productset": "0",
    "productset_items": null,
    "is_service": "0",
    "is_serial": "0",
    "variations": {
      "id": "1122334455",
      "name": "red",
      "measurement_unit": "unit_piece",
      "quantity_minimal_piece": "1.000",
      "sku": null,
      "vendor_code": "",
      "retail_price": "2550.00",
      "wholesale_price": "2550.00",
      "discount_type": "percent",
      "discount": "0.00",
      "barcodes": ["2000471000002", "2000481000009"]
    }
  }
]

second request:

[
  {
    "9999999": {
      "company_id": 63,
      "branch_id": 69,
      "variation_id": 954629,
      "supplier_id": 0,
      "quantity": 1
    }
  }
]

I need to match the data by product_id and get the output in the format:
Product Name, Quantity

At the moment I only came up with:

async function getstockandproductinfo() {
  try {
    const stockinforesponse = await axios.get(`${BASE_URL}/stock?branch_id=0`, {
      headers: {'API-KEY': API_KEY}
    });
    const productinforesponse = await axios.get (`${BASE_URL}/products`, {
      headers: {'API-KEY': API_KEY}
    });
    const productdata = productinforesponse.data;
    const stocksdata = stockinforesponse.data;
    const meld = [].concat(productdata, stocksdata);

    meld.forEach(item => {
      if (typeof item === 'object' && item !== null) {
        for (const product_id in item) {
          if (item[product_id] && item[product_id].hasOwnProperty('quantity')) {
            const quantity = item[product_id].quantity;
            console.log(`Product ID: ${product_id}, Quantity: ${quantity}`);
          }
        }
      }
    });

  } catch (error) {
    console.error('Error', error);
  }
}

getstockandproductinfo();

when I try to get the product name I get undefined

I will be glad for any help, as I am a complete noob)

Popup remains at top of page

Web surfing I found a hotspot/popup that I incorporated into my page, but lost the link to the site where I found it. Now, I changed something and the popup displays at the top of the image. The left and right seem to work fine, but the popups do not align with the top of the pins on the image. enter image description here looking at the image, the popup should be displayed near the red pin for Wk6. I am not sure what I changed that now makes it display improperly. The website is https://2af.team/afa/booth.php

Any help would be appreciated.

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Second Air Force</title>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/styles.css?v=<?php echo time(); ?>">
  </head>
  <body>
    <?PHP include "disclaimer.php";?>
    <header class="imgbox">
      <img src="./images/2AF_banner-min.png" alt="Second Air Force" class="banner-center-fit">
    </header>
    <section>
      <div class="container">
        <img class="img-center" src="./images/boothall-min.png" alt="Booth Poster">
        <div class="all-tooltip">
          <div class="tooltip tooltip-1">
            <div class="pin">
              <ion-icon name="add-circle"></ion-icon>
            </div>
            <div class="tooltip-content">
              <div class="arrow"></div>
                <div class="content">
                  <h1>It's Time: Second Air Force invests in the next generation</h1>
                  <p>KEESLER AIR FORCE BASE, MIssissippi<br>
                  <a style="color: blue" href="https://www.2af.aetc.af.mil/News/Article-Display/Article/3288234/its-time-second-air-force-invests-in-the-next-generation/" target="_blank">https://www.2af.aetc.af.mil/News/Article-Display/Article/3288234/its-time-second-air-force-invests-in-the-next-generation/</a></p>
              </div>
            </div>
          </div>
          <div class="tooltip tooltip-2">
            <div class="pin">
              <ion-icon name="add-circle"></ion-icon>
            </div>
            <div class="tooltip-content">
              <div class="arrow"></div>
                <div class="content">
                  <h1>CSAF 23 Message to Airmen: Follow Through</h1>
                  <p>OFFICE OF THE CHEIF OF STAFF, Washington DC<br>
                  <a style="color: blue" href="https://www.af.mil/Portals/1/documents/2023SAF/CSAF_23_Message_to_Airmen_Follow_Through.pdf" target="_blank">https://www.af.mil/Portals/1/documents/2023SAF/CSAF-23-Message-to-Airmen-Follow-Through.pdf</a></p>
              </div>
            </div>
          </div>
          <div class="tooltip tooltip-3">
            <div class="pin">
              <ion-icon name="add-circle"></ion-icon>
            </div>
            <div class="tooltip-content">
              <div class="arrow"></div>
                <div class="content">
                  <h1>Air Force Revamps 'Zero Week' at BMT to Better Prepare Recruits for Stress</h1>
                  <p>JOINT BASE SAN ANTONIO-LACKLAND, Texas<br>
                  <a style="color: blue" href="https://www.airandspaceforces.com/air-force-zero-week-bmt/" target="_blank">https://www.airandspaceforces.com/air-force-zero-week-bmt/</a></p>
              </div>
            </div>
          </div>
          <div class="tooltip tooltip-4">
            <div class="pin">
              <ion-icon name="add-circle"></ion-icon>
            </div>
            <div class="tooltip-content">
              <div class="arrow"></div>
                <div class="content">
                  <h1>Where Trainees Transform into the World's Greatest Airmen</h1>
                  <p>JOINT BASE SAN ANTONIO-LACKLAND, Texas<br>
                  <a style="color: blue" href="https://www.airforce.com/training/military-training/bmt/overview/" target="_blank">https://www.airforce.com/training/military-training/bmt/overview/</a></p>
              </div>
            </div>
          </div>
          <div class="tooltip tooltip-5">
            <div class="pin">
              <ion-icon name="add-circle"></ion-icon>
            </div>
            <div class="tooltip-content">
              <div class="arrow"></div>
                <div class="content">
                  <h1>DoD Fire Academy: Fired up for training</h1>
                  <p>GOODFELLOW AIR FORCE BASE, Texas<br>
                  <a style="color: blue" href="https://www.aetc.af.mil/News/Article-Display/Article/2970829/dod-fire-academy-fired-up-for-training/" target="_blank">https://www.aetc.af.mil/News/Article-Display/Article/2970829/dod-fire-academy-fired-up-for-training/</a></p>
              </div>
            </div>
          </div>
          <div class="tooltip tooltip-6">
            <div class="pin">
              <ion-icon name="add-circle"></ion-icon>
            </div>
            <div class="tooltip-content">
              <div class="arrow"></div>
                <div class="content">
                  <h1>Keesler AFB unveils innovative classroom environment for ‘Mach 21 Airmen’</h1>
                  <p>KEESLER AIR FORCE BASE, Mississippi<br>
                  <a style="color: blue" href="https://www.af.mil/News/Article-Display/Article/1732995/keesler-afb-unveils-innovative-classroom-environment-for-mach-21-airmen/" target="_blank">https://www.af.mil/News/Article-Display/Article/1732995/keesler-afb-unveils-innovative-classroom-environment-for-mach-21-airmen/</a></p>
              </div>
            </div>
          </div>
          <div class="tooltip tooltip-7">
            <div class="pin">
              <ion-icon name="add-circle"></ion-icon>
            </div>
            <div class="tooltip-content">
              <div class="arrow"></div>
                <div class="content">
                  <h1>US Air Force Leadership Insights Maj. Gen. Michele C. Edmondson, Commander, Second Air Force on Technical Training Transformation</h1>
                  <p>KEESLER AIR FORCE BASE, Mississippi<br>
                  <a style="color: blue" href="https://www.halldale.com/articles/21667-mst-us-air-force-leadership-insights-maj-gen-michele-c-edmondson-commander-second-air-force-on-technical-training-transformation-and-more" target="_blank">https://www.halldale.com/articles/21667-mst-us-air-force-leadership-insights-maj-gen-michele-c-edmondson-commander-second-air-force-on-technical-training-transformation-and-more</a></p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  <footer class="foot">
    <?PHP include "navbar.php";?>
  </footer>
  <script>
    const tooltips = document.querySelectorAll(".all-tooltip .tooltip");
    const fullDiv = document.querySelector("section");
    const container = document.querySelector(".container");
    let timeoutId;
    window.addEventListener("resize", contentPosition);
    window.addEventListener("DOMContentLoaded", contentPosition);

    function contentPosition() {
    tooltips.forEach((tooltip) => {
        const pin = tooltip.querySelector(".pin");
        const content = tooltip.querySelector(".tooltip-content");
        const arrow = tooltip.querySelector(".arrow");
        const pinLeft = pin.offsetLeft;
        if (pinLeft + content.offsetWidth / 2 > fullDiv.offsetWidth) {
          const extraLeft = fullDiv.offsetWidth - (pinLeft + content.offsetWidth / 2);
          // console.log('right-conflict', tooltip)
          content.style.left = pinLeft - content.offsetWidth / 2 + extraLeft - 30 + "px";
          content.style.top = pin.offsetTop + 30 + "px";
        } else if (
          pin.offsetLeft + container.offsetLeft < content.offsetWidth / 2
        ) 
        
        {
          // console.log('left conflict', pin.offsetLeft)
          content.style.left = pinLeft - container.offsetLeft + "px";
          content.style.top = pin.offsetTop + 30 + "px";
        } else {
          content.style.left = pinLeft - content.offsetWidth / 2 + "px";
          content.style.top = pin.offsetTop + 30 + "px";
        }
          arrow.style.left =
          pinLeft - content.offsetLeft + pin.offsetWidth / 2 + "px";
      });
    }
    tooltips.forEach((tooltip) => {
    const pin = tooltip.querySelector(".pin");
    const content = tooltip.querySelector(".tooltip-content");
    pin.addEventListener("mouseover", () => {
        tooltip.classList.add("active");
    });
    pin.addEventListener("mouseleave", () => {
        timeoutId = setTimeout(() => {
        if (!tooltip.classList.contains("content-hover")) {
            tooltip.classList.remove("active");
        }
        }, 2000);
    });
    content.addEventListener("mouseover", () => {
        clearTimeout(timeoutId);
        tooltip.classList.add("active");
        tooltip.classList.add("content-hover");
    });
    content.addEventListener("mouseleave", () => {
        timeoutId = setTimeout(() => {
        tooltip.classList.remove("active");
        tooltip.classList.remove("content-hover");
        }, 2000);
    });
    });
    
</script>
</body>
</html>

CSS

* {
margin: 0;
padding: 0;
}
body {
background-color: #112349;
}

h1{
  font-size: 6rem;
}

h2{
  font-size: 4rem;
  color: rgb(44, 44, 135);
  font-size: 2.4rem;
  font-weight: 800;
}

ul{
  margin-top: 1rem;
  margin-left: auto;
  margin-right: auto;
  width: 100%;
}

ul li{
  margin: 10px 0 10px 0;
}

hr{
  opacity: 50%;
}
  
li{
  color: white;
  display: inline-block;
  overflow-x: auto;
  text-align: center;
  font-size: 1.5rem;
  padding: 10 5 10 5;
  text-align: left;
}

.li1size{
  width: 20%;
}

.li2size{
  width: 40%;
}

.li3size{
  text-align: center;
  width: 25%;
}

.li4size{
  text-align: center;
  width: 15%;
}

video{
  max-width: 1400px;
}

#drag_drop{
  background-color : #f9f9f9;
  border : #ccc 4px dashed;
  line-height : 250px;
  padding : 12px;
  font-size : 24px;
  text-align : center;
}

a{
  color: whitesmoke;
}

.banner{
max-width: 100%;
margin: auto;
}

.disclaimer{
  position: sticky;
  margin-bottom: .5rem;
  left:0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #eeecec;
  color: rgb(255, 0, 0);
}

.disclaimer p{
  font-size: .75rem;
  text-align: center;
}

.imgbox{
display: grid;
height: 100%;
}

.banner-center-fit{
max-width: 100%;
max-height: 100hv;
margin: auto;
display: inline-block;
}

.center-fit{
max-width: 33%;
max-height: 100hv;
margin: auto;
display: inline-block;
}

.fblogo {
  display: inline-block;
  margin-left: auto;
  margin-right: auto;
  width: 30%;
  border-radius: 10px;
  color: whitesmoke;
  font-size: 3vw;
}

#images{
  text-align: center;
}

.img{
  width: 50%;
}

nav{
  display: flex;
  font-size: 2rem;
  justify-content: space-between;
  padding: 1.5rem;
  font-weight: 700;
  color: rgb(73, 73, 73);
}

.links{
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.links a{
  color: black;
}

.links a svg{
  height: 3rem;
  width: 3rem;
}

.links img{
  height: 3rem;
  border: 1px solid black;
}

.center{
  display:flex;
  justify-content:center;
}

.div-center{
  display:flex;
  justify-content:center;
  margin-top: 10px;
}

.div-size{
  width: 100%;
  margin: 0;
  padding: 0;
}

section{
  margin-bottom: 60px;
}

.div-size-2{
  width: 100%;
  margin: 0;
  padding: 0;
}

.img-center{
  width: 100%;
}

footer{
  position: fixed;
  bottom: 0;
  left:0;
  background: white;
  width: 100%;
  height: 4rem;
}

table{
  border-collapse: collapse;
  margin-left: auto;
  margin-right: auto;
  margin-top: 10px;
  width: 30%;
  height: 100%;
  float: left;
  text-align: center;
}

th{
  padding-top: 1rem;
  padding-bottom: 1rem;
  padding-left: 1rem;
  padding-right: 1rem;
  font-size: 2rem;
  color: whitesmoke;
}

td{
  padding-top: 1rem;
  padding-bottom: 1rem;
  padding-left: 1rem;
  padding-right: 1rem;
  font-size: 1.5rem;
  color: whitesmoke;
  text-align: center;
  max-width: 33%;
}








@media screen and (max-width: 700px) {
  
  h1{
      font-size: 3rem;
  }
  
  h2{
      font-size: 2.5rem;
  }
  
  h3{
      font-size: 2rem;
  }
  
  p{
      font-size: 1.6rem;
  }

video{
  max-width: 650px;
}

  table{
      width: 100%;
      border-collapse: separate; 
      border-spacing: 1em;
      border: 0;
  }

  th{
      font-size: 2rem;
      padding-top: .8rem;
      padding-bottom: .8rem;
      padding-left: .8rem;
      padding-right: .8rem;
  }

  td{
      font-size: 1.5rem;
      padding-top: .8rem;
      padding-bottom: .8rem;
      padding-left: .8rem;
      padding-right: .8rem;
  }

  .disclaimer p{
      font-size: 1rem;
  }
}

  
@media screen and (max-width: 480px) {

  h1{
      font-size: 2.5rem;
  }
  
  h2{
      font-size: 2rem;
  }
  
  h3{
      font-size: 1.8rem;
  }
  
  p{
      font-size: 1.4rem;
  }

  video{
    max-width: 100%;
  }
  
  table{
      width: 100%;
      border-collapse: separate; 
      border-spacing: 1em;
      border: 0;
  }

  th{
      font-size: 1.2rem;
      padding-top: .5rem;
      padding-bottom: .5rem;
      padding-left: .5rem;
      padding-right: .5rem;
  }

  td{
      font-size: 1rem;
      padding-top: .5rem;
      padding-bottom: .5rem;
      padding-left: .5rem;
      padding-right: .5rem;
  }

  li{
      display: block;
      width: 100%;
    }

    .li1size{
      width: 100%;
    }
    
    .li2size{
      width: 100%;
    }
    
    .li3size{
      text-align: left;
      width: 100%;
    }
    
    .li4size{
      text-align: left;
      width: 100%;
    }
    
  .disclaimer p{
      font-size: .5rem;
  }

  .vertical{
      display:flex;
    }

}


/* Hotspot styling below */
*  
.container {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  position: relative;
}

.container img {
  height: 100%;
  width: 100%;
}

.all-tooltip {
  position: absolute;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
}

.tooltip-content {
  position: absolute;
  background-color: rgb(255, 255, 255);
  box-shadow: 0px 0px 20px #00000020;
  padding: 30px;
  border-radius: 8px;
  width: 90vw;
  max-width: max-content;
  opacity: 0;
  pointer-events: none;
  /* left: -50%; */
  z-index: 2;
}

.tooltip-content .arrow {
  position: absolute;
  width: 10px;
  height: 10px;
  border: 10px solid transparent;
  border-bottom-color: rgb(255, 255, 255);
  top: 0px;
  left: 50%;
  transform: translate(-50%, -100%) rotate(0deg);
}

.popup {
  position:absolute;
  z-index:20000;
  top: 0px;
  left: 0px;
  display: none;
  background-color:#dd8;
  border: 1px solid;
}

.pin {
  position: absolute;
  content: "";
  top: 50%;
  left: 80%;
  height: 25px;
  width: 25px;
  background-color: rgb(255, 255, 255);
  border-radius: 50%;
  cursor: pointer;
}

.pin:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background-color: rgb(255, 255, 255);
  border-radius: 50%;
  animation: puls-effect 1s ease infinite;
}

.tooltip.active .tooltip-content {
  opacity: 1;
  pointer-events: all;
  display: block;
}

/* Custom Style for tooltip-1 */

.tooltip-1 .pin {
  top: 7.5%;
  left: 28%;
  height: 15px;
  width: 15px;
  background-color: rgb(250, 0, 0);
}

.tooltip-1 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-1.active .tooltip-content {
  display: flex;
}

.tooltip-1 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-1 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-1 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-1 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-1 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-2 */

.tooltip-2 .pin {
  top: 9.9%;
  left: 75.35%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-2 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-2.active .tooltip-content {
  display: flex;
}

.tooltip-2 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-2 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-2 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-2 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-2 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-3 */

.tooltip-3 .pin {
  top: 31.03%;
  left: 45.4%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-3 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-3.active .tooltip-content {
  display: flex;
}

.tooltip-3 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-3 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-3 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-3 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-3 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-4 */

.tooltip-4 .pin {
  top: 59.9%;
  left: 24.6%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-4 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-4.active .tooltip-content {
  display: flex;
}

.tooltip-4 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-4 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-4 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-4 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-4 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-5 */

.tooltip-5 .pin {
  top: 59.6%;
  left: 67.5%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-5 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-5.active .tooltip-content {
  display: flex;
}

.tooltip-5 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-5 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-5 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-5 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-5 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-6 */

.tooltip-6 .pin {
  top: 58.4%;
  left: 86.5%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-6 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-6.active .tooltip-content {
  display: flex;
}

.tooltip-6 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-6 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-6 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-6 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-6 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-7 */

.tooltip-7 .pin {
  top: 74.96%;
  left: 37.9%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-7 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-7.active .tooltip-content {
  display: flex;
}

.tooltip-7 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-7 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-7 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-7 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-7 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}


/* tooltips for wing page */

/* Custom Style for tooltip-w1 */

.tooltip-w1 .pin {
  top: 49.8%;
  left: 19.6%;
  height: 15px;
  width: 15px;
  background-color: rgb(250, 0, 0);
}

.tooltip-w1 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-w1.active .tooltip-content {
  display: flex;
}

.tooltip-w1 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-w1 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-w1 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-w1 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-w1 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-w2 */

.tooltip-w2 .pin {
  top: 24.5%;
  left: 27.5%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-w2 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-w2.active .tooltip-content {
  display: flex;
}

.tooltip-w2 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-w2 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-w2 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-w2 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-w2 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-w3 */

.tooltip-w3 .pin {
  top: 7%;
  left: 58%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-w3 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-w3.active .tooltip-content {
  display: flex;
}

.tooltip-w3 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-w3 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-w3 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-w3 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-w3 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-w4 */

.tooltip-w4 .pin {
  top: 24.5%;
  left: 87%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-w4 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-w4.active .tooltip-content {
  display: flex;
}

.tooltip-w4 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-w4 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-w4 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-w4 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-w4 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}

/* Custom Style for tooltip-w5 */

.tooltip-w5 .pin {
  top: 49.9%;
  left: 96.1%;
  height: 15px;
  width: 15px;
  background-color: rgb(255, 0, 0);
}

.tooltip-w5 .tooltip-content {
  display: flex;
  max-width: 500px;
  align-items: stretch;
  justify-content: center;
  padding: 0;
  background-color: rgb(255, 255, 255);
}

.tooltip-w5.active .tooltip-content {
  display: flex;
}

.tooltip-w5 .tooltip-content .img {
  width: 25%;
  object-fit: cover;
}

.tooltip-w5 .tooltip-content .content {
  width: 75%;
  padding: 20px;
}

.tooltip-w5 .tooltip-content .content h1 {
  font-size: 24px;
}

.tooltip-w5 .tooltip-content .content p {
  font-size: 14px;
}

.tooltip-w5 .tooltip-content .content button {
  font-family: "Montserrat";
  font-size: 18px;
  font-weight: 400;
  border: none;
  outline: none;
  background-color: white;
  color: black;
  padding: 10px;
  cursor: pointer;
  margin-top: 20px;
  border-radius: 4px;
  box-shadow: 0px 0px 20px #00000020;
}



/* Puls Effect For Pins */

@keyframes puls-effect {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  100% {
    transform: scale(3);
    opacity: 0;
  }
}

How can I add a onclick event on an image created from js script? [duplicate]

My goal is to create an image from the javascript script, and to add a function when the said image is clicked.

let b = document.body;
let newIMG = document.createElement('img');
newIMG.src = 'img.jpg';
newIMG.onclick = 'clickImage()';
b.append(newIMG)

function clickImage() {
    console.log("clicked")
}

With the code I wrote, the image is properly created and displayed, but nothing happens when I click it and I can’t understand why. Thank you for you help !