MUI Slider Component: different colour thumbs

quite a simple question but I’ve not been ablr to find an answer out there.

MUI has a slider component: https://mui.com/material-ui/react-slider/
I’m currently using it to allow users to pick a value range (so my slider has two thumbs)
multi thumb slider from mui docs: https://codesandbox.io/s/gptppq?file=/demo.js

The slider thumb can be styled as shown here: https://codesandbox.io/s/359l9t?file=/demo.tsx:3809-3812

My question: how do i make the two thumbs have a different style/color?

Unable to connect to mongoDB “Unable to connect on first connect”

After setting up my mongoconfiguration, I tried to connect to my mongodb, however an error keeps popping up, and I have not been able to set up the connection.I’ve attached a screenshot of the error. I’ve pasted the code of my index.js file here below.
Furthermore I’ve checked that my MONGO_URL is correct (in my .env file)
But i’ll paste it below the code of my index.js file just in case I may have missed something.
Another weird thing is that MongoDB provides me with a URL to connect to my application. The URL starts with “mongodb+srv://” but as soon as I try to make the connection my console logs this error:” throw new Error(‘Invalid mongodb uri “‘ + str + ‘”. Must begin with “mongodb://”‘);”

Index.Js file: 
`import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import cors from "cors";
import dotenv from "dotenv";
import helmet from "helmet"
import morgan from "morgan"

// CONFIGURATIONS
dotenv.config()
const app = express();
app.use(express.json());
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({policy: "cross-origin"}));
app.use(morgan("common"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(cors());




// MONGOOSE SETUP

const PORT = process.env.PORT || 9000;
mongoose.Promise = global.Promise;

mongoose.connect(process.env.MONGO_URL, {
    // useNewUrlParser: true,
    // useUnifiedTopology: true,
    useMongoClient: true,
})
.then(async () => {
    app.listen(PORT, ()=> console.log(`Server Port: ${PORT}`));
})
.catch((error) => console.log(`${error}: did not connect`));`

.ENV File:
MONGO_URL ="mongodb+srv://dummyUser:<password>@cluster0.mndwygw.mongodb.net/?retryWrites=true&w=majority"

I replaced with the actual password of the cluster of course ๐Ÿ™‚

I tried changing the network access of my cluster (adding different IP addresses[
ERROR that gets logged to the console after trying to set up connection
(https://i.stack.imgur.com/bg5he.png))
I tried removing the DNS cache of my laptop.
I checked that I have stable network connectivity
I checked that there aren’t any restrictions or firewalls on the network I’m connected to.

What I expected to happen is that the console would log the port number as written in the code.

I intend to have two periods in the fullcalendar

I have the following code to set mintime and maxtime in fullcalendar.

$('#calendarr').fullCalendar({
  defaultView: 'agendaWeek',
  minTime: "10:30:00",
  maxTime: "12:00:00",
  slotDuration: '00:45',
  header: {
    language: 'PT',
    left: 'prev,next today',
    center: 'title',
    right: 'month,agendaWeek,agendaDay,listWeek'
  },

  editable: false,
  eventLimit: true,
  selectable: true,
  selectHelper: true,
  
 
  events: '/visitas.php',
  
});

So far so good and works fine. I intend to put the mintime and a maxtime for the afternoon in the same calendar.
I’m trying this way:

$('#calendarr').fullCalendar({
  defaultView: 'agendaWeek',
  minTime: "10:30:00",
  maxTime: "12:00:00",
  slotDuration: '00:45',
  minTime: "14:30:00",
  maxTime: "19:00:00",
  header: {
    language: 'PT',
    left: 'prev,next today',
    center: 'title',
    right: 'month,agendaWeek,agendaDay,listWeek'
  },

  editable: false,
  eventLimit: true,
  selectable: true,
  selectHelper: true,
  
 
  events: '/visitas.php',
  
});

But in this way, the period defined for the morning disappears from the calendar. How can I put both periods on the same calendar?

Animation for images working on scroll up

This is my HTML

<section class="labs-hero__top-container sprinter-lab__common-bg">
    <div class="labs-hero__container ">
        <picture class="labs-hero__label">
            <source media="(min-width: 1100px)" srcset="./assets/images/label.png">
            
            <img src="./assets/images/label.png" />
          </picture>
        <!-- <h1 class="labs-hero__heading">voluptatem accusantium doloremque</h1> -->
        <div class="labs-hero__image labs-hero__image--hide animate__animated"></div>
        <div class="labs-hero__image--vans labs-hero__image--hide labs-hero__image--fade-out"></div>
    </div>
</section>
<section class="label-section__main-container">
        <picture class="label-section__image-label">
            <source media="(min-width: 1100px)" srcset="./assets/images/label-labs.png">
                
            <img src="./assets/images/label-labs.png" />
        </picture>
</section>
<section class="sprinter-lab__common-bg solid">
    <div class="main-animation__container">
        <div class="main-animation__frame"></div>
        <div class="main-animation__slider">
            <picture class="main-animation__slider-image">
                <source media="(min-width: 1100px)" srcset="./assets/images/front.png">    
                <img src="./assets/images/front.png" />
            </picture>
            <div class="main-animation__content">
                <h2 class="main-animation__slider-heading">voluptatem accusantium doloremque</h2>
                <p class="main-animation__slider-desc">TSed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab.</p>
            </div>
        </div>
    </div>
</section>
<section class="sprinter-lab__common-bg solid">
    <div class="main-animation__container">
        <div class="main-animation__slider">
            <div class="main-animation__content">
                <h2 class="main-animation__slider-heading">from dream to drive</h2>
                <p class="main-animation__slider-desc">TSed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab.</p>
            </div>
            <picture class="main-animation__slider-image">
                <source media="(min-width: 1100px)" srcset="./assets/images/front.png">    
                <img src="./assets/images/front.png" />
            </picture>
        </div>
    </div>
</section>
<section class="labs-hero sprinter-lab__common-bg solid">
    <div class="labs-hero__text-container">
        <image src='assets/images/MSV-logo.png'/>
        <p class="labs-hero__sub-heading">de Finibus Bonorum et Malorum</p>
        <h2 class="labs-hero__title">de Finibus Bonorum et Malorum</h2>
        <p class="labs-hero__description">TSed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab.</p>
        <button class="labs-hero__button">de Finibus Bonorum et Malorum</button>
    </div>
</section>
<section class="sprinter-lab__common-bg solid">
    <div class="main-animation__container">
        <div class="main-animation__slider">
            <div class="main-animation__content">
                <h2 class="main-animation__slider-heading">Sed ut perspiciatis</h2>
                <p class="main-animation__slider-desc">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>
            </div>
            <picture class="main-animation__slider-image">
                <source media="(min-width: 1100px)" srcset="./assets/images/front.png">    
                <img src="./assets/images/front.png" />
            </picture>
        </div>
    </div>
</section>

This the scss code I have written where I have the animation for before and after image.

  .labs-hero {
  &__text-container {
width: 81.25%;
max-width: 1170px;
height: 100vh;
margin: 0 auto;
text-align: center;
color: #fff;
padding-top: 30px;
@media screen and (max-width: 768px) {
  padding: 50px 20px;
  height:unset;
}
&.animation{
  &::before {
    content: "";
    background: url("/assets/images/football-desktop.png") no-repeat;
    position: absolute;
    width: 40%;
    // height:100%;
    background-size: 100%;
    transform: translateY(-25%);
    z-index: 1;
    text-align: center;
    display: flex;
    animation: 3s;
    animation-iteration-count: 1;
    animation-name: football;
    animation-fill-mode: forwards;
    @media screen and (max-width: 768px) {
      content: "";
      background: url("/assets/images/football-image.png") no-repeat;
      width: 100%;
      height: 250px;
      background-position: center;
      background-size: contain;
      animation: none;
      transform: translateY(0);
      position: unset;
      margin-bottom: 81px;
    }
    @media screen and (min-width: 769px) and (max-width: 860px) {
      background-size: 130%;
      z-index:-1;
    }
  }

  &::after {
    content: "";
    background: url("/assets/images/wrench-desktop.png") no-repeat;
    position: absolute;
    right: -6%;
    transform: translateY(-51%);
    width: 40%;
    height: 100%;
    background-size: contain;
    display: flex;
    background-position: right;
    margin-top: 75px;
    z-index: 1;
    animation: 3s;
    animation-name: wrench;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
    @media screen and (max-width: 768px) {
      width: 100%;
      height: 273px;
      transform: translate(12%, -20%);
      animation: none;
      content: "";
      background: url("/assets/images/Wrench-mb.png") no-repeat;
      position: unset;
      margin-top: 131px;
      right: 0%;
      background-position: right;
      display: flex;
    }
    @media screen and (min-width:769px) and (max-width: 946px) {
      margin-top: 35px;
      width:50%;
      // z-index:-1;
    }
  }
}
&.up-animation{
  &::before {
    content: "";
    background: url("/assets/images/football-desktop.png") no-repeat;
    position: absolute;
    width: 40%;
    // height:100%;
    background-size: 100%;
    // transform: translateY(-25%);
    z-index: 1;
    text-align: center;
    display: flex;
    animation: 3s;
    animation-iteration-count: 1;
    animation-name: football-up;
    // animation-fill-mode: forwards;
    @media screen and (max-width: 768px) {
      content: "";
      background: url("/assets/images/football-image.png") no-repeat;
      width: 100%;
      height: 250px;
      background-position: center;
      background-size: contain;
      animation: none;
      transform: translateY(0);
      position: unset;
      margin-bottom: 81px;
    }
    @media screen and (min-width: 769px) and (max-width: 860px) {
      background-size: 130%;
      z-index:-1;
    }
  }

  &::after {
    content: "";
    background: url("/assets/images/wrench-desktop.png") no-repeat;
    position: absolute;
    right: -6%;
    transform: translateY(-51%);
    width: 40%;
    height: 100%;
    background-size: contain;
    display: flex;
    background-position: right;
    margin-top: 75px;
    z-index: 1;
    animation: 3s;
    animation-name: wrench-up;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
    @media screen and (max-width: 768px) {
      width: 100%;
      height: 273px;
      transform: translate(12%, -20%);
      animation: none;
      content: "";
      background: url("/assets/images/Wrench-mb.png") no-repeat;
      position: unset;
      margin-top: 131px;
      right: 0%;
      background-position: right;
      display: flex;
    }
    @media screen and (min-width:769px) and (max-width: 946px) {
      margin-top: 35px;
      width:50%;
      // z-index:-1;
    }
  }
}

   }

  }

 @keyframes football {
from {
    top: 10px;
    left:-15%;
    }
to {
    top: 350px;
    transform: rotate(60deg);
    left:-10%;
    }
    }

 @keyframes wrench {
    to {
    top: -280px;
    transform: rotate(-40deg);
    }
    from {
    top: 70px;
    transform: rotate(10deg);
    }
   }

 @keyframes football-up {
   from {
  top: 350px;
  left:-15%;
  }
  to {
  top: 10px;
  transform: rotate(60deg);
  left:-10%;
  }
  }

 @keyframes wrench-up {
   to {
  top: 280px;
  transform: rotate(-40deg);
  }
  from {
  top: 10px;
  transform: rotate(10deg);
  }
 }

This is my javascript code to apply animation on scroll up and scroll down but the animation for before and after image is not getting applied on scroll up.

    function scrollTrigger(selector, options = {}) {
      let els = document.querySelectorAll(selector);
       els = Array.from(els);
        els.forEach((el) => {
        addObserver(el, options);
      });
     }

      function addObserver(el, options) {
         if (!("IntersectionObserver" in window)) {
           if (options.cb) {
             options.cb(el);
            } else {
             entry.target.classList.add("active");
              setTimeout(() => {
             entry.target.classList.remove("active");
             }, 1000);
            }
            return;
         }

let observer = new IntersectionObserver(
  (entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        if (options.cb) {
          options.cb(el);
        } else {
          entry.target.classList.add("active");
        }
        // observer.unobserve(entry.target);
        console.log("root entry",entry);
      } else if (entry.boundingClientRect.y < entry.rootBounds.y) {
          console.log("bound",entry.boundingClientRect.y)
          console.log("root",entry.rootBounds.y)
          console.log('hello')
        // Added condition for scrolling from bottom to top
        if (options.upCb) {
          options.upCb(el);
        } else {
          entry.target.classList.add("up-active");
        }
        // observer.unobserve(entry.target);
      }
    });
  },
  options
);
     observer.observe(el);
     }

    scrollTrigger('.labs-section-host__image-container',{cb:(el) =>{
      el.classList.add('host-animation')
      },threshold:0.5})

     scrollTrigger('.labs-section-host__image-container--right-variation',{cb:(el) =>{
      el.classList.add('host-animation')
      },threshold:0.5})

      // Example usage:
       scrollTrigger(".labs-hero__text-container", {
         cb: (el) => {
          el.classList.add("animation");
         },
         upCb: (el) => {
         el.classList.add("up-animation");
         },
        threshold: 0.5,
      });

I have 2 images that is in before and after pseudo elements. The before element is in the left side of the page and after image is in right side of the page. Now when I’m trying to scroll down animation for these 2 images are coming up like before image is sliding down and after image is sliding up. but when I scroll up again the animation should come in reverse order Like the before image should move on the top and after image should move down. But according to my logic the scroll up animation is not coming up.

‘Syntaxerror: invalid shorthand property initializer’ for anonymous type in Microsoft ClearScript

I would like to create a basic .NET wrapper for the markdown-it JavaScript library (see markdown-it.js source-code here). To accomplish this, I am using Microsoft ClearScript.

Please note that my knowledge of JavaScript is quite limited, and this is only the second JavaScript library I am attempting to integrate into .NET. So, similarly, my experience with Microsoft’s ClearScript is also limited.

Well. After a simple research I understand that the Invalid shorthand property initializer error, in JavaScript, comes when we use equals operator (=) rather than colon (:) to separate key-values(properties) in object, that’s ok, but the question is: how to solve the issue when trying to create and use that kind of key-values(properties) object in Microsoft ClearScript?.

This is what I have:

Public Shared Function ConvertMarkdownToHtml(str As String,
                                             Optional presetName As String = Nothing,
                                             Optional options As Object = Nothing) As String

    presetName = "commonmark"
    options = New With {.html = True, .linkify = True, .typographer = True}

    Dim htmlOutput As String
    Using engine As New V8ScriptEngine("markdownit_engine", V8ScriptEngineFlags.DisableGlobalMembers)

        ' https://raw.githubusercontent.com/markdown-it/markdown-it/master/dist/markdown-it.js
        Dim markdownItCode As String = My.Resources.markdown_it
        engine.Execute(markdownItCode)
        engine.Execute($"md = new markdownit('{presetName}', {options});
                         var renderResult = md.render('{str}');")

        htmlOutput = CStr(engine.Evaluate("renderResult"))

        engine.CollectGarbage(exhaustive:=True)
    End Using

    Return htmlOutput
End Function

As you can see in the code above, I’m using an anonymous type to create the options object. I think that object is sent and translated to the render function with “=” separators instead of “:”, but I don’t have idea how to solve that in this situation.


Finally, and if helpful, this is what the render function documentation says:

* new MarkdownIt([presetName, options])
* - presetName (String): optional, `commonmark` / `zero`
* - options (Object)
*
* Creates parser instanse with given config. Can be called without `new`.
*
* ##### presetName
*
* MarkdownIt provides named presets as a convenience to quickly
* enable/disable active syntax rules and options for common use cases.
*
* - ["commonmark"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) -
*   configures parser to strict [CommonMark](http://commonmark.org/) mode.
* - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -
*   similar to GFM, used when no preset name given. Enables all available rules,
*   but still without html, typographer & autolinker.
* - ["zero"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) -
*   all rules disabled. Useful to quickly setup your config via `.enable()`.
*   For example, when you need only `bold` and `italic` markup and nothing else.
*
* ##### options:
*
* - __html__ - `false`. Set `true` to enable HTML tags in source. Be careful!
*   That's not safe! You may need external sanitizer to protect output from XSS.
*   It's better to extend features via plugins, instead of enabling HTML.
* - __xhtmlOut__ - `false`. Set `true` to add '/' when closing single tags
*   (`<br />`). This is needed only for full CommonMark compatibility. In real
*   world you will need HTML output.
* - __breaks__ - `false`. Set `true` to convert `n` in paragraphs into `<br>`.
* - __langPrefix__ - `language-`. CSS language class prefix for fenced blocks.
*   Can be useful for external highlighters.
* - __linkify__ - `false`. Set `true` to autoconvert URL-like text to links.
* - __typographer__  - `false`. Set `true` to enable [some language-neutral
*   replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js) +
*   quotes beautification (smartquotes).
* - __quotes__ - `โ€œโ€โ€˜โ€™`, String or Array. Double + single quotes replacement
*   pairs, when typographer enabled and smartquotes on. For example, you can
*   use `'ยซยปโ€žโ€œ'` for Russian, `'โ€žโ€œโ€šโ€˜'` for German, and
*   `['ยซxA0', 'xA0ยป', 'โ€นxA0', 'xA0โ€บ']` for French (including nbsp).
* - __highlight__ - `null`. Highlighter function for fenced code blocks.
*   Highlighter `function (str, lang)` should return escaped HTML. It can also
*   return empty string if the source was not changed and should be escaped
*   externaly. If result starts with <pre... internal wrapper is skipped.
*
* ##### Example
*
* ```javascript
* // commonmark mode
* var md = require('markdown-it')('commonmark');
*
* // default mode
* var md = require('markdown-it')();
*
* // enable everything
* var md = require('markdown-it')({
*   html: true,
*   linkify: true,
*   typographer: true
* });
* ```

The font values in css

What is a fallback value in css and how to use it?
Can I add the fallback value for the font family by adding another font names separated by a comma..and then adding the fallback font serif after the Impact font ?

I cant take advantage of this font. When using css

How to stop progress bar from filling to 100% every calculation?

I am currently making a progress bar for my application and I am facing a problem with every entry in a list, the progress bar fills 100%, then chances back to the actual progress (for example 34% if 34/100 calculations done).

I would like it to just show the actual progress.

Here is the code:

function readLines() {

    let progress = 0;
    let percentage = 0;
    const file = document.getElementById("fileList").value;

    fetch(`/application/${file}/lines`, {

        method: 'GET'

    }).then(response => response.json())
        .then(data => {

            const keys = Object.keys(data)
            let html = `<tr><th>Word</th><th>Occurrence</th></tr>`;

            const progressBar = document.getElementById("progress-bar");
            const updateButton = document.getElementById("fileList");

            function updateProgressBar(progress) {

                progressBar.innerHTML = "<div id='loading-bar'></div>";
                const progressBarFill = document.getElementById("loading-bar");
                progressBarFill.style.width = `${progress}%`;

            }

            keys.forEach(key => {

                updateButton.addEventListener("change", function () {

                    progress += 1;
                    const length = Object.keys(data).length;
                    percentage = (progress / length) * 100;

                    updateProgressBar(percentage);

                })

                if (key.substring(0, 1) !== "1") {

                    html += `<tr><td>${key}</td><td>${data[key]}</td></tr>`

                } else {

                    html += `<tr><td>${key}</td><td>${data[key]}</td></tr>`

                }

            })

            document.getElementById("showTable").innerHTML = html;

            percentage = 0;

        });

}

How to prevent re-rendering in react-native-calendars

Usecase: at the top level, my app has a tab navigator with a Calendar tab and a Camera tab. In the Calendar tab, it displays an infinitely scrollable CalendarList using react-native-calendars. The app state maintains an object with date strings as keys and sorted arrays of images as values. The calendar’s parent view passes it a memoized object containing the last image for each date via context:

const latestImagesByDateString = useMemo(
    () => mapLatestImagesByDateString(imagesByDateString),
    [imagesByDateString]
)

// ...

<ImageContext.Provider value={latestImagesByDateString}>
    <Stack.Screen
        name="CalendarView"
        component={CalendarView}
                            
    />
</ImageContext.Provider>

The CalendarView renders a component for each date, which may have an image:

const getDayComponent = useCallback(
    ({ date, state }) => (
        <CalendarDayView
            imageUri={latestImagesByDateString[date.dateString]?.uri}
            imageId={latestImagesByDateString[date.dateString]?.id}
            isToday={state === 'today'}
            dateString={date.dateString}
            day={date.day}
         />
     ),
     [latestImagesByDateString]
)

// ...

return (
   <CalendarList
       dayComponent={getDayComponent}
   />
)

The Calendar tab has a stack navigator which renders a detail view for a given day when it gets pressed. This is all working as intended.

However, if I navigate to the Camera tab, the user can take a photo, which they can then save or discard. If they save the photo, I update app state with the new photo, then navigate back to the Calendar tab’s detail view for that day, showing the new photo.

This also works as intended, except: when I save the photo and navigate to the appropriate detail view, the Calendar will re-render every date in its grid before the detail view gets displayed. This causes a long delay between pressing the “Save photo” button and the detail view being rendered onscreen. When a user saves a new photo, all of the dayComponents except one should be the same as on the previous render. I can’t figure out why all the other dayComponents are re-rendering in this case. How can I prevent that from happening?

How to validate numeric input in jQuery for mobile and web browsers uniformly?

So I’ve an input field of type text, and I want to limit the input to numbers only and maybe a decimal point as well. This form will be accessed from desktops and mobile devices as well.

I used the following JQuery code:

$(document).on("keypress", ".number-only", function(event){
    var charCode = (event.which) ? event.which : event.keyCode;
    if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    } else {
        // If the number field already has . then don't allow to enter . again.
        if (event.target.value.search(/./) > -1 && charCode == 46) {
            return false;
        }
        return true;
    }
});

But it isn’t working for mobile browsers as the keypress event is not recognized by those browsers. I need a single event or method that works for both types of browsers alike. What are my options here?

How can I get the requests to my page using React? If not possible solutions?

I’d like to link my frontend(React) to my backend(Express) using Spotify API

Hi, I’d like to connect my React application to an Express one that uses Spotify Developer API.
The problem is that I’d like the user to connect going to that link(localhost:3001 in this case) and after the successful login to Spotify return to my React page(localhost:3000) but I don’t know how to get the body of the request to the frontend to finally use the Spotify functionalities.

How to put a label in the center of a UMAP scatter series when using echarts for ploting?

I want to plot a cluster scatter using echarts, the current plot i draw is like this:
enter image description here

Each series respresent a cluset, and now i want to put the legend label of each series in its own center, some my current code snippet is like this:

var series = [];
  for (var i = 0; i < cell_type.length; i++) {
    series.push({
      name: cell_type[i],
      label: {
        show: true,
        position: "top",
        color: "#000",
        fontSize: 10,
        formatter: function (params) {
          if (params.dataIndex === 0) {
            // show labels only at points with data index 0
            return params.data[2];
          } else {
            return "";
          }
        },
      },
      type: "scatter",
      emphasis: {
        focus: "series",
      },
      datasetIndex: i + 1,
      symbolSize: 2,
      encode: {
        x: "x",
        y: "y",
      },
    });
  }

And my dataset of each series is like this:

[‘-4.03’, ‘-1.99’, ‘1.Normal.Gpr182.Stab2’]

[‘0.31’, ‘5.25’, ‘5.Irf1.Cxcl10’]

[‘9.24’, ‘-6.13’, ‘8.Cycling.Mki67’]

Currently i just put the label in the first index. So how can I modify the formatter function above so that i can put the label in the center of each series๏ผŸ

Javascript perform operation on an object based on nested string value

I have a Javascript object as below;

grouped = {
    "field1": [{
        "path": "field1",
        "type": "min",
        "message": "Invalid"
    }, {
        "path": "field1",
        "type": "api-error",
        "message": "Invalid"
    }],
    "field2": [{
        "path": "field2",
        "type": "min",
        "message": "Invalid length"
    }, {
        "path": "field2",
        "type": "api-error",
        "message": "API error"
    }]
}

I want to combine them based on unique “message” value and then run the following code on the result

for (const {path,type,message} of result) {
    setError(path, type, message);
}

So, in the above case,

  1. For “field1”, since “Invalid” is common string message, setError should be called on result with message “Invalid”,
  2. while for “field2”, since the string messages are different, the message string should be concatenated and then passed to setError as “Invalid lengthnInvalid”

Again, the number of fields within “grouped” are dynamic. I have shown here just as an example with 2 fields.

Is there an ES6 way of getting this?

Problems with jittery collision detection in JavaScript

So I’ve been working on a js game engine, and as a part of that I’ve also been working on line vs line collision detection.
In my engine colliders are implementing an IGNCollider interface, which requires the checkCollisionWith(...colliders) method.
The following is the GNLineCollider class:

class GNLineCollider extends IGNCollider {
    /**
     * @param {Object} params
     * @param {Vec2D} params.p1
     * @param {Vec2D} params.p2
     */
    constructor({ p1, p2, ...args }) {
        super(args);
        this.p1 = p1;
        this.p2 = p2;
    }

    checkCollisionWith(...colliders) {
        for (const collider of colliders) {
            if (collider instanceof GNLineCollider) {
                const collision = checkLineVsLineCollision(
                    this,
                    collider
                );
                if (!collision.collision) continue;
                return {
                    collision: true,
                    collider: collision.colliders[1],
                    normal: collision.normal,
                };
            }
        }
        return { collision: false };
    }
}

And this is the checkLineVsLineCollision function it calles:

checkLineVsLineCollision(line1Points, line2Points) {
    /*
    For line AB which goes through A(x, y), B(X, Y), the equation is:
    ax + by = c
    Such that:
    a = Y - y
    b = x - X
    c = ax + by

    For two lines of form ax + by = c that intersect at P(x,y), we shall find their intersection like so:
    1) ax + by = c  *B
    2) Ax + By = C  *b

    1) Bax + bBy = Bc
    2) bAx + bBy = bC

    1-2) (Ba - bA)x = Bc - bC
                Bc - bC
            x = โ€”โ€”โ€”โ€”โ€”โ€”โ€”
                Ba - bA
    
    1) ax + by = c  *A
    2) Ax + By = C  *a

    1) aAx + Aby = Ac
    2) aAx + aBy = aC

    1-2) (Ab - aB)y = Ac - aC
                Ac - aC
            y = โ€”โ€”โ€”โ€”โ€”โ€”โ€”
                Ab - aB
    
        โ•ญ Bc - bC   Ac - aC โ•ฎ
    P | โ€”โ€”โ€”โ€”โ€”โ€”โ€”   โ€”โ€”โ€”โ€”โ€”โ€”โ€” |
        โ•ฐ aB - Ab , Ab - aB โ•ฏ
    */
    const { a, b, c } = findLineEquation(line1Points);
    const { a: A, b: B, c: C } = findLineEquation(line2Points);
    if (a * B == A * b) return { collision: false };
    const P = new Vec2D(
        (B * c - b * C) / (a * B - A * b),
        (A * c - a * C) / (A * b - B * a)
    );
    if (
        between({
            val: P.x,
            min: line1Points.p1.x,
            max: line1Points.p2.x,
            matchMinMax: true,
            equalsMinMax: true,
        }) &&
        between({
            val: P.y,
            min: line1Points.p1.y,
            max: line1Points.p2.y,
            matchMinMax: true,
            equalsMinMax: true,
        }) &&
        between({
            val: P.x,
            min: line2Points.p1.x,
            max: line2Points.p2.x,
            matchMinMax: true,
            equalsMinMax: true,
        }) &&
        between({
            val: P.y,
            min: line2Points.p1.y,
            max: line2Points.p2.y,
            matchMinMax: true,
            equalsMinMax: true,
        })
    )
        return {
            collision: true,
            colliders: [line1, line2],
            normal: line1.p1
                .sub(line1.p2)
                .sub(line2.p1.sub(line2.p2))
                .normalize(),
        };
    return { collision: false };
}

I’ve also made a GNColliderGroup class, which also implements the IGNCollider interface, and is meant to have other colliders as it’s children, and then be able to check collisions with all of them when the checkCollisionsWith function is called, like so:

export class GNColliderGroup extends IGNCollider {
    /**
     * @param {...IGNCollider} colliders
     */
    checkCollisionWith(...colliders) {
        // This function can get all of the colliders which are children of the current collider.
        const subColliders = this.getChildrenOfType(IGNCollider);
        for (const collider of subColliders) {
            const collision = collider.checkCollisionWith(...colliders);
            if (!collision.collision) continue;
            return collision;
        }
        return { collision: false };
    }
}

I’ve then made a test scene with a player and a floor. Where both of them are instences of the GNColliderGroup class, so that they can have multiple line colliders as their children. And the update function for the player looks like this:

update({ deltaTime }) {
    this.velocity.y += 0.004 * deltaTime;

    // Originally there was some irrelevant movement code here which I removed

    for (const axis of ['x', 'y']) {
        this.transform.position[axis] +=
            this.velocity[axis] * deltaTime;
        const collider = floor;
        if (!this.checkCollisionWith(collider).collision) continue;
        while (this.checkCollisionWith(collider).collision) {
            this.transform.position[axis] -= normalize(
                this.velocity[axis]
            );
        }
        this.velocity[axis] = 0;
    }
    super.update({ deltaTime, ...args });
}

But, sometimes I have problem where on some frames the collision detection functions return false on frames where the 2 objects are very clearly intersecting, like you can see in the following video:
https://streamable.com/lpt8dm
(I added lines to the player and the floor which represent the collision lines, and made it so the lines of the player turn red whenever they detect a collision).

In addition, here are some of the utility functions I used, for those wondering:

/**
 * @param {Object} params
 * @param {number} params.val
 * @param {number} params.min
 * @param {number} params.max
 * @param {boolean} params.equalsMinMax - use <=/>= instead of </>.
 * @param {boolean} params.matchMinMax - check if min is smaller than max, and if it isn't - switch them.
 */
function between({
    val,
    min,
    max,
    equalsMinMax = false,
    matchMinMax = false,
}) {
    if (matchMinMax && min > max) [max, min] = [min, max];
    if (equalsMinMax && (val == min || val == max)) return true;
    return min < val && val < max;
}

/**
 * @param {Object} params
 * @param {Vec2D} params.p1
 * @param {Vec2D} params.p2
 */
function findLineEquation({ p1, p2 }) {
    const a = p2.y - p1.y;
    const b = p1.x - p2.x;
    const c = a * p1.x + b * p1.y;
    return { a, b, c };
}

const normalize = (val) => (val ? val / Math.abs(val) : 0);

scroll the color line along with the circle along the background line

I have a block on the page where there is a background line, on the line itself there is a circle that scrolls along with the main scroll

const circle = document.querySelector(".circle");
const cases = document.querySelectorAll(".case");

circle.style.transition = ""

const handleScroll = () => {
  const {
    height: blockHeight
  } = document.querySelector(".block2").getBoundingClientRect()

  const maxTop = cases[cases.length - 1].offsetTop + cases[cases.length - 1].offsetHeight - 200
  const minTop = cases[0].offsetTop

  let {
    height: startTop
  } = cases[0].getBoundingClientRect()

  const scrollDist = Math.min(maxTop, Math.max(startTop / 2 + window.scrollY, minTop))

  circle.style.top = `${scrollDist}px`
  circle.style.backgroundSize = `17px ${blockHeight}px`
  circle.style.backgroundPosition = `0 ${-scrollDist}px`
}

const handleWindowSizeAndScroll = () => {
  window.removeEventListener("scroll", handleScroll)
  window.removeEventListener("resize", handleScroll)
  window.addEventListener("scroll", handleScroll)
  window.addEventListener("resize", handleScroll)
}

handleScroll()
handleWindowSizeAndScroll()
window.addEventListener("resize", handleWindowSizeAndScroll)
.block1 {
  height: 200px;
  background-color: gray;
}

.block3 {
  height: 600px;
  background-color: gray;
}

.block2 {
  height: 100%;
  position: relative;
}

.block2,
.block2 .circle {
  background: linear-gradient(214deg, rgba(79, 142, 255, 0) 0%, #f5e550 10%, #f5e550 90%, rgba(79, 142, 255, 0) 100%) center/3px calc(100% - 100px) no-repeat;
}

.block2 .circle {
  background: #4f8eff;
  width: 17px;
  height: 17px;
  left: 50%;
  transform: translate(-50%, -50%);
}

.block2 .circle,
.block2 .circle::before {
  position: absolute;
  border-radius: 50%;
}

.block2 .circle::before {
  content: "";
  inset: 3px;
  background-color: white;
}

.text {
  text-align: center;
  padding: 200px 50px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="block1"></div>
<div class="block2">
  <div class="circle"></div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 1</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 1</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 2</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 2</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 3</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 3</div>
    </div>
  </div>
</div>
<div class="block3"></div>

The question is, how can you make it so that, along with the circle, another line of the same color as the circle scrolls along the line, and it all would look something like this

enter image description here