issue with Chrome’s garbage collector

I’ve been facing an issue with Chrome’s garbage collector not clearing nodes that are no longer in use, even after I manually remove the JavaScript scripts that reference them.

This was working fine in previous Chrome versions, but in the latest version (v.129), the garbage collector seems to be malfunctioning or behaving differently. I tested this with a basic JS script, and it still works as expected in MS Edge for now, but I’m concerned that this might also stop working in their next release.

Has anyone else noticed this change in behavior in Chrome’s GC? I’ve tried using Bootstrap’s dispose() method to manually clean up, im having same issue with other JS scripts also.

Any advice or insights on why Chrome’s GC is no longer handling this correctly would be greatly appreciated.

This is the test script:

function writeHtml() {
                var dynamicDiv = $('#dynamicDiv');
                var selectHtml = `
                    <a class="btn btn-primary" data-bs-toggle="offcanvas" href="#offcanvasExample" role="button" aria-controls="offcanvasExample">
                        Link with href
                        </a>
                        <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
                        Button with data-bs-target
                        </button>

                        <div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
                        <div class="offcanvas-header">
                            <h5 class="offcanvas-title" id="offcanvasExampleLabel">Offcanvas</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
                        </div>
                        <div class="offcanvas-body">
                            <div>
                            Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
                            </div>
                            <div class="dropdown mt-3">
                            <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
                                Dropdown button
                            </button>
                            <ul class="dropdown-menu">
                                <li><a class="dropdown-item" href="#">Action</a></li>
                                <li><a class="dropdown-item" href="#">Another action</a></li>
                                <li><a class="dropdown-item" href="#">Something else here</a></li>
                            </ul>
                            </div>
                        </div>
                        </div>
                `;
                dynamicDiv.append(selectHtml);
                
            }

            function destroy() {
                
                disposeBootstrapComponents();
                
                $('#dynamicDiv').empty();
                
                /* Tryed this, doesnt help
                var $dynamicDiv = $('#dynamicDiv');
                $dynamicDiv.empty(); // Empty the contents of dynamicDiv before replacing it

                var $clonedDiv = $dynamicDiv.clone(false);
                $dynamicDiv.replaceWith($clonedDiv);
                dynamicDiv = null;
                clonedDiv = null;

                */

            }
             
            function disposeBootstrapComponents() {
                $('[data-bs-toggle="dropdown"]').dropdown('dispose');
                $('.offcanvas').offcanvas('dispose');
            }

            $(document).on('click', '#addButton', function () {
                writeHtml();
            });
            $(document).on('click', '#destroyButton', function () {
                destroy();
            });

detached

How to list every methods/properties of an object? [duplicate]

I can’t list every keys of an object, this object is from Chrome API. I’m developing an extension and I’m using chrome API. Since chrome is an object that contains useful methods, I could just console.log(Object.keys(chrome)) on a background script and see every keys of that object.

That worked just fine, however, the logged keys are incomplete. Specifically, chrome.management have a method called getAll, but the logged result only have these keys:

Array(7)
   0: "getPermissionWarningsByManifest"
   1: "getSelf"
   2: "uninstallSelf"
   3: "ExtensionDisabledReason"
   4: "ExtensionInstallType"
   5: "ExtensionType"
   6: "LaunchType"length: 
   7[[Prototype]]: Array(0)

I don’t know where I’m doing wrong. I called the command in a right environment (background) and I’m properly logging the data. Any help would be appreciated!

Azure TTS audio is distorted

In Javascript, I’m attempting to stream audio created in the format Audio16Khz32KBitRateMonoMp3 by the “microsoft-cognitiveservices-speech-sdk” SpeechSynthesizer via express to a react frontend app. The first couple of sentences sounds just fine but after that the speech is very distorted.

Here is the code that sends the audio:

    synthesizer.synthesizing = function (s, e) {
    currentAudioChunk = {
      audio: Buffer.from(e.result.audioData),
      offset: e.result.audioDuration / 10000, // Convert to milliseconds
    };

    sendEvent("audioData", {
      audio: currentAudioChunk.audio.toString("base64"),

      //his audioOffset data is null, and I'm sending it as a placeholder for now
      audioOffset: "0",
    });

    currentAudioChunk = null;
  };

When the audio is good the string sent looks like this:

“//NIxCElU/5IAY+IAYJ/2sMoSxHk0RH9BVzA0GTFmDQIAQ4Xv8iBn5oEqAUwtPDlBnyDh9f+ukXFoLdRAhSgoYRmQwQAIIJ0DVH/+eez/FwFkR+DcgYghGI/ImQQ0kU/////LRuTiDFw8fLRmk9Bv////v/+hTTN0Cuzk4TZ8qGCFf6UeMhhgB8BjVMd/t5V//NIxA4g2tqkAc9YAD7MqNv/AVisORkvL3sJA7Fje5e+5N7r/ZNxXO9991vl98n9A+bqGiY3myJPJAOEDjHGJfRMWtAsfGoO9ejd0GhoOy32zfEvfHvZL4vfvTvfV5xO2TeymMriv6//j+v5/j2MNzc+w4oEElx7v6u/2t/UcW0Tg+oDGEGSAs30kiaCvEsa//NIxA0f6tbFtGsQsB/wSwiDZ+tZaEobTf5rXCqf/XqycoAzWXtvSKlDpriVZX/mmfM+YFhrAo1ookTMDgiGJRKHii37Q6Eh+fFkyMUXF4c2/fTr+0rpvsyXQevBDueX8PPz/PPX88VXXxySFgZQJQqJRW71f/Ss+4XRpRipAO1XGSKjcylABX/VcJmGEBBG”

but when the distortion starts there are lots of repeated letters that appear to be junk, like this:

“//NIxHwAAANIAAAAAFVVVVVVVVVMQU1FMy4xMDBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//NIxHwAAANIAAAAAFVVVVVVVVVMQU1FMy4xMDBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//NIxHwAAANIAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV”

The repeated numbers are in the raw data received from Azure: it’s not an artefact of conversion to string.

How can I get clean audio from Azure TTS?

I tried stripping out the Vs but that just corrupted the data entirely.

Struggling to edit the innerHTML of text based on the hunger rating

I am having trouble figuring out how to get the innerHTML to change the displayed text based on the hunger rating. Below is the JS that I used to build the hunger tracker. At the very bottom is the function to drop in the innerHTML, and I’ve tried all of the different variables to try and get it to work. I have also tried dropping in the text as an array, using blood.forEach, but that didn’t work either.

document.addEventListener("DOMContentLoaded", function (event) {
    // copy code here
    const makeHungerRating = function (noOfBlood = 5) {
        let rating = 0;
        let bloodComponent;

        function changeHunger(newRating) {
            rating = newRating;
        }

        function getBloodComponent() {
            if (!bloodComponent) {
                bloodComponent = document.createElement(`ul`);
                bloodComponent.className = `hunger-rating`;
                for (let i = 0; i < noOfBlood; i++) {
                    const li = document.createElement(`li`);
                    li.setAttribute(`data-rating`, i + 1)
                    li.className = `blood`;
                    if (i === 0) li.tabIndex = 0;
                    bloodComponent.append(li);
                }
                bloodComponent.addEventListener(`mouseover`, onMouseOver);
                bloodComponent.addEventListener(`mouseLeave`, onMouseLeave);
                bloodComponent.addEventListener(`click`, onMouseClick);
                bloodComponent.addEventListener(`keyup`, onKeyUp)
            }
            return bloodComponent;
        }

        function renderChanges(rating) {
            for (let i = 0; i < rating; ++i) {
                bloodComponent.children[i].classList.add(`blood-filled`);
            }
            for (let i = rating; i < noOfBlood; ++i) {
                bloodComponent.children[i].classList.remove(`blood-filled`);
            }
        }

        function onMouseOver(e) {
            let isBlood = e.target.classList.contains(`blood`);
            if (isBlood) {
                const { rating } = e.target.dataset;
                renderChanges(rating)
            }
        }

        function onMouseLeave(e) {
            renderChanges(rating);
        }

        function onMouseClick(e) {
            let blood = e.target ?? e;
            let isBlood = blood.classList.contains(`blood`);
            if (isBlood) {
                activate(blood)
                let { rating } = blood.dataset;
                if (e.key !== `Tab` && rating === getRating()) {
                    rating = 0;
                    resetTabIndex();
                    bloodComponent.firstElementChild.tabIndex = 0;
                }
                changeHunger(rating);
                renderChanges(rating);
            }
        }

        function focusPrevBlood() {
            let focusedBlood = document.activeElement;
            if (focusedBlood.previousElementSibling) {
                onMouseClick(focusedBlood.previousElementSibling);
            }
        }

        function focusNextBlood() {
            let focusedBlood = document.activeElement;
            if (focusedBlood.nextElementSibling) {
                onMouseClick(focusedBlood.nextElementSibling);
            }
        }

        function activate(element) {
            resetTabIndex();
            element.tabIndex = 0;
            element.focus();
        }

        function resetTabIndex() {
            bloodComponent.childNodes.forEach((blood) => {
                blood.tabIndex = -1;
            })
        }

        function onKeyUp(e) {
            switch (e.key) {
                case `Tab`: {
                    onMouseClick(e);
                    break;
                }
                case `ArrowLeft`: {
                    focusPrevBlood()
                    break;
                }
                case `ArrowRight`: {
                    focusNextBlood();
                    break;
                }
                default:
                    return;
            }
        }

        function getRating() {
            return rating;
        }

        return { getRating, getBloodComponent };
    }



    const ratingModule = makeHungerRating();

    const bloodComponent = ratingModule.getBloodComponent();
    const container = document.querySelector("ul");

    container.append(bloodComponent);

    const ratingText = document.querySelector(".hunger__level--description")

    ratingText.innerHTML = getRatingTextHTML(container)

    function getRatingTextHTML(ratingModule) {
        let hunger = ratingModule

        if (hunger = 0) {
            return `<div class="hunger__level--description">"I sleep, for now. You have satisfied me... but never forget, I am always here. Enjoy your peace, little one - it never lasts."</div>
        </div>`
        }
        else if (hunger = 1) {
            return `<div class="hunger__level--description">"I feel the pull again. Just a taste... you can manage that, can't you? Just enough to remind me that you know what I need"</div>
        </div>`
        }
        else if (hunger = 2) {
            return `<div class="hunger__level--description">"You're making me wait too long. Don't you feel it? That ache in your veins... I do. It's time. Find them. Feed. I won't ask nicely again."</div>
        </div>`
        }
        else if (hunger = 3) {
            return `<div class="hunger__level--description">"I'm starving! Do you really think you can hold me back? I can smell them all around us, their warmth, their blood. I will have it, one way or another... you won't stop me!"</div>
        </div>`
        }
        else if (hunger = 4) {
            return `<div class="hunger__level--description">"ENOUGH! You're nothing without me! I will tear them apart! They're just cattle, waiting to be slaughtered, and you're a fool if you think you can resist me any longer! YOU. WILL. FEED!"</div>
        </div>`
        }
    }

});

So I posted the JS above, and I will reiterate that I have tried targeting ratingModule, bloodComponent, container, blood, and I have run it as

blood.forEach [
    "I sleep, for now. You have satisfied me... but never forget, I am always here. Enjoy your peace, little one - it never lasts.",
    "I feel the pull again. Just a taste... you can manage that, can't you? Just enough to remind me that you know what I need",
    "You're making me wait too long. Don't you feel it? That ache in your veins... I do. It's time. Find them. Feed. I won't ask nicely again."
    "I'm starving! Do you really think you can hold me back? I can smell them all around us, their warmth, their blood. I will have it, one way or another... you won't stop me!"
    "ENOUGH! You're nothing without me! I will tear them apart! They're just cattle, waiting to be slaughtered, and you're a fool if you think you can resist me any longer! YOU. WILL. FEED!"
]

But to be honest, I don’t know if I implemented that correctly. The idea is to get the text to appear underneath the Hunger Rating as I change it.

The HTML and CSS already gives the text status showing up under the Hunger Rating, but it doesn’t change when I click on the different ratings.

here is the codepen as well: https://codepen.io/rkbraniff/pen/ZEgWYbb

Possible to have WorkerGlobalScope.crossOriginIsolated == true when browser tab’s top level window.crossOriginIsolated == false? If so, how to do?

I am trying to use SharedArrayBuffer, which requires the COOP and COEP headers to be set so that window.crossOriginIsolated==true.
I’ve done that, and it works fine. But for reasons I can’t go into, I may not be able to set those headers for our entire site. The site is served by an express JS web server, and I’ve been working in my simpler example of that so I have unlimited control just for testing.

In reading the MDN page for WorkerGlobalScope, it mentions that crossOriginIsolated (cOI) is a property of it. It isn’t explicit whether WorkerGlobalScope’s cOI is tied to the top level window’s cOI, although (especially after testing) I suspect that may be the case.

To test, I’ve tried sending, the COOP & COEP headers only for files under the subdirectory ./dist such that the JavaScript file defining the worker is obtained by the browser with those headers properly set – which I’ve confirmed.

app.use( "/dist/*", ( req, res, next ) => {
    console.log( `Requesting file: ${req.baseUrl}` );
    res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
    res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
    next();
} );

From the Chrome Devtools’ Network tab:

Request URL: http://localhost/dist/mainworker.mjs
Request Method: GET
Status Code: 200 OK
Referrer Policy: strict-origin-when-cross-origin
. . .
content-type: application/javascript; charset=UTF-8
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin

However, WorkerGlobalScope.crossOriginIsolated is false.
Is my suspicion correct – that WorkerGlobalScope.crossOriginIsolated is inextricably tied to the top level window? Or has anyone been able to create a Web Worker with cOI true while the main tab’s window’s cOI is false?

Thanks

A Mysterious Code Found in My Website Header. Is My Site Compromised?

There was a javascript code in the header of my website from very long time. Only today I saw it and commented it out.

Can someone please check the code and tell me what it has been doing. Is it some malicious code?

The code is too big to paste here so I have kept it commented in the header of my website.

Please check – My Website Link

I have tried search on the net but found nothing

Why is My Nested Route Layout in React Router Dom Causing an Infinite Loading State?

I’m using createBrowserRouter to define nested routes in my React project, and I’ve set up a layout component (AppLayout) to be shared across several child routes. However, when I start the application, the page just keep loading and shows nothing.

Here are project dependencies:

"dependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0",
  "react-router-dom": "^6.11.0"
},

Here is my code:

const router = createBrowserRouter([
  {
    element: <AppLayout />, // Common layout for all child routes
    children: [
      {
        path: "/",
        element: <Home />,
      },
      {
        path: "menu", // This will resolve to "/menu"
        element: <Menu />,
      },
      {
        path: "cart", // This will resolve to "/cart"
        element: <Cart />,
      },
      {
        path: "order/new", // This will resolve to "/order/new"
        element: <CreateOrder />,
      },
      {
        path: "order/:orderId", // This will resolve to "/order/:orderId"
        element: <Order />,
      },
    ],
  },
]);

When I don’t use nested route it works.

A way to make a browse for file dialog display with await async?

There is working code that opens a browse for file dialog in another question. I’d like to make this an await async call.

Here is the original question and it works in my tests.

I’ve added the snipper here for convenience:

// wait for window to load
window.addEventListener("load", windowLoad);

// open a dialog function
function openFileDialog (accept, multy = false, callback) { 
    var inputElement = document.createElement("input");
    inputElement.type = "file";
    inputElement.accept = accept; // Note Edge does not support this attribute
    if (multy) {
        inputElement.multiple = multy;
    }
    if (typeof callback === "function") {
         inputElement.addEventListener("change", callback);
    }
    inputElement.dispatchEvent(new MouseEvent("click")); 
}

// onload event
function windowLoad () {
    // add user click event to userbutton
    userButton.addEventListener("click", openDialogClick);
}

// userButton click event
function openDialogClick () {
    // open file dialog for text files
    openFileDialog(".txt,text/plain", true, fileDialogChanged);
}

// file dialog onchange event handler
function fileDialogChanged (event) {
    [...this.files].forEach(file => {
        var div = document.createElement("div");
        div.className = "fileList common";
        div.textContent = file.name;
        userSelectedFiles.appendChild(div);
    });
}
.common {
    font-family: sans-serif;
    padding: 2px;
    margin : 2px;
    border-radius: 4px;
 }
.fileList {
    background: #229;
    color: white;
}
#userButton {
    background: #999;
    color: #000;
    width: 8em;
    text-align: center;
    cursor: pointer;
}

#userButton:hover {
   background : #4A4;
   color : white;
}
<a id = "userButton" class = "common" title = "Click to open file selection dialog">Open file dialog</a>
<div id = "userSelectedFiles" class = "common"></div>

Here is what I have:

async browseForFile(acceptedTypes: string, multiple?: boolean): Promise<array> {
      var element = document.createElement("input");
      element.type = "file";
      element.accept = acceptedTypes;
      if (multiple) {
         element.multiple = multiple;
      }

      new Promise((resolve, reject) => {
         element.addEventListener("change", resolveCallback);
      })

      var resolveCallback = (event)=> {
         return event.currentTarget.files;
      }
      
      element.dispatchEvent(new MouseEvent("click")); 
   }

Suggested usage:

try {
   var files = await browseForFile("*.txt");
}
catch(error) {
   // no files selected
}

Second attempt:

   browseForFile(callback: any, acceptedTypes: string, multiple?: boolean): Promise<array> {
      var element = document.createElement("input");
      element.type = "file";
      element.accept = acceptedTypes;
      if (multiple) {
         element.multiple = multiple;
      }

      new Promise((resolve, reject) => {
         
         var resolveCallback = (event)=> {
            var input = event.currentTarget;
            if (input.files==null) {
               reject();
            }
            else {
               resolve(input.files);
            }
         }

         element.addEventListener("change", resolveCallback);
      });
      
      
      element.dispatchEvent(new MouseEvent("click")); 
   }

CSS content aligns incorrectly when only one line of text

I’ve got the below code. Everything is working pretty great except when the browser is wide enough that the text is only one line, the “posts” get misaligned.

Example:

misaligned row

I’ve messed with all the CSS I can think of and I can’t get it to align correctly. Thanks in advance for your help!

Link to jsfiddle: https://jsfiddle.net/BHolm/n68r5xst/167/

/*Feed*/
 
.feed-row {
  padding-bottom: 40px;
  padding-right: 20px;
}

.feed-mt .post-submitted-info {  
  font-weight: 700; 
  text-align: center; 
  line-height: 1; 
  position: relative; 
   
}

.post-submitted-info { 
  column-width: 55px; 
  margin-left: 10px;
}

.submitted-date { 
  border-right: 1px solid #c2c2c2; 
}

.submitted-date { 
  margin-top: 12px; 
}

.post-submitted-info .year { 
  padding-bottom: 8px 
}

.post-submitted-info .month, .post-submitted-info .year {  
  font-size: 14px; 
  text-transform: uppercase; 
}

.feed-mt .post-submitted-info .day { 
  font-size: 29px; 
  font-weight: 900; 
  padding-bottom: 2px; 
}

.feed-main-content {
  padding-left: 75px;
  margin-top: -75px;
}

.field-item{  
  font-weight: normal;
  border-bottom: 1px solid #acacac;
  
}

.feed-main-content .header {
    
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<!-- Load Handlebars.js from Unpkg. -->
<script src="https://unpkg.com/[email protected]/dist/handlebars.min.js"></script>

<!-- Load jQuery and Sheetrock from Unpkg -->
<script src="https://unpkg.com/[email protected]/dist/jquery.slim.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/sheetrock.min.js"></script>
<body>
  <div id="hf">
    <script id="hf-template" type="text/x-handlebars-template">

<!-- Post Date Section -->
      <div class="row feed-row feed-mt">
        <div class="post-submitted-info">
            <div class="submitted-date">
            <div class="month">{{cells.Month}}</div>
            <div class="day">{{cells.Day}}</div>
            <div class="year">{{cells.Year}}</div>         
            </div>
        </div>
        
<!-- Post Content Section -->
        <div class="feed-main-content">
            <div class="header">
            <h2>{{cells.Header}}</h2>
          </div>
            <div class="field-item">
            <p>{{cells.Content}}</p>
            </div>
        </div>
      </div>
    </script>
  </div>
</body>

Unable to switch cloths on an avatar using three.js [closed]

I am currently working on a project with three.js. I want to switch different types of clothes on a human avatar(model).
I am also new to three.js.
I have tried using ray casting but not working. Does anyone know how I can fix this?
Also, when I try to load the different clothes (models), they appear very tiny on the plane while the Human model appears very large.

Detect if browser can render HEIC image

Is there an easy way to detect if a browser can render HEIC image?

I can think of one way, render a pixel heic image and check the color of the pixel post render. Something like:

const myImg = new Image();
myImg.crossOrigin = "Anonymous";
myImg.onload = () => {
  const context = document.createElement('canvas').getContext('2d');
  context.drawImage(myImg, 0, 0);
  const {
    data
  } = context.getImageData(10, 10, 1, 1);
  console.log(data)
}
myImg.src = 'https://picsum.photos/200/300';

Wondering, if there is a better way?

Awaiting a promise that I constructed exits code with no errors

I verified in the console that coordinator.setupPromise is a Promise, but when I run await coordinator.setupPromise , the code never gets to the print statement after the await and instead of waiting it just exits immediately. Example console output:

$ tsx main.ts 
setup 
await setup Promise { <pending> }

Heres my code:

import { ChildProcessWithoutNullStreams, spawn } from "child_process";
import { getPortFree, sleep } from "../utils";
import 'child_process'
import fetch, { RequestInit } from "node-fetch";
import { SocksProxyAgent } from "socks-proxy-agent";

class TorInstance {

    socksPort: number;
    controlPort: number;
    dataDir: string = `./datadirs/${Math.random().toString(36).slice(2)}`;

    torProcess: ChildProcessWithoutNullStreams;
    agent;
    setupRes;
    setupPromise = new Promise(res => { this.setupRes = res });

    constructor(socksPort?, controlPort?) {
        this.setup();
    }

    private async setup(socksPort?, controlPort?) {
        let port1 = await getPortFree();
        let port2 = await getPortFree();

        this.socksPort = socksPort ?? port1.port
        this.controlPort = controlPort ?? port2.port

        port1.server.close();
        port2.server.close();

        // tor --SocksPort 11111 --ControlPort 11112 --DataDirectory test1
        this.torProcess = spawn(`tor`, ['--SocksPort', this.socksPort, '--ControlPort', this.controlPort, '--DataDirectory', this.dataDir].map(String));
        this.torProcess.stdout.setEncoding('utf8');
        this.torProcess.stdout.on('data', (data) => {
            if (data.toString().includes(`[notice] Bootstrapped 100% (done): Done`)) { this.setupRes() }
        })
        this.agent = new SocksProxyAgent(`socks5h://127.0.0.1:${this.socksPort}`);
    }

    public fetch(url: string, options?: RequestInit) {
        return fetch(url, {
            ...options,
            agent: this.agent
        })
    }

    public dispose() {
        this.torProcess.kill();
    }


}

class TorCoordinator {
    instances: TorInstance[] = [];
    currentIndex = 0;
    setupRes;
    setupPromise = new Promise(res => { this.setupRes = res; })

    constructor(num: number) {
        this.createInstances(num);
    }

    fetch(url: string, options?: RequestInit) {
        return this.instances[this.currentIndex++].fetch(url, options);
    }

    createInstances(num) {
        let newInstances: TorInstance[] = [];
        for (let i = 0; i < num; i++) {
            let newInstance = new TorInstance();
            newInstances.push(newInstance);
            newInstance.setupPromise.then(() => {
                console.log('setup!!')
                this.instances.push(newInstance)
                this.setupRes();
            })
            // todo  monitor console output for [notice] Bootstrapped 100% (done): Done, and only add to main list then
        }
    }

}


async function test() {
    console.log('setup')
    let coordinator = new TorCoordinator(10);
    console.log('await setup',coordinator.setupPromise)

    await coordinator.setupPromise;
    console.log('done await')

    coordinator.fetch('https://api.ipify.org?format=json').then(res => res.text().then(console.log))
    coordinator.fetch('https://api.ipify.org?format=json').then(res => res.text().then(console.log))
    await sleep(10000)
}
test();

And utils.ts is:

import { SocksProxyAgent } from "socks-proxy-agent"

export function sleep(m) { return new Promise(r => setTimeout(r, m)) }
export const torAgent = new SocksProxyAgent('socks5h://127.0.0.1:9050');


import { Readable } from 'stream';

export async function streamToBuffer(stream) {
    const chunks = [];

    for await (const chunk of stream) {
        chunks.push(chunk); // Collect each Uint8Array chunk
    }

    // Concatenate all chunks into a single Buffer
    const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
    const buffer = Buffer.alloc(totalLength);
    let position = 0;

    for (const chunk of chunks) {
        buffer.set(chunk, position);
        position += chunk.length;
    }

    return buffer;
}


export async function streamToString(stream: ReadableStream) {
    const reader = stream.getReader()
    let html = ''
    while (true) {
        const { value, done } = await reader.read()
        if (value) {
            html += new TextDecoder().decode(value)
        }
        if (done) {
            return html
        }
    }
}

export async function streamToStringOld(stream: ReadableStream<Uint8Array<ArrayBufferLike>>) {
    const chunks: any = [];

    // Use async iteration to read from the stream
    for await (const chunk of stream) {
        chunks.push(chunk);  // Collect each Uint8Array chunk
    }

    // Concatenate all chunks into a single Uint8Array
    const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
    const resultArray = new Uint8Array(totalLength);

    let position = 0;
    for (const chunk of chunks) {
        resultArray.set(chunk, position);
        position += chunk.length;
    }

    // Convert the Uint8Array to a string
    return new TextDecoder().decode(resultArray);
}

import net from "net"

export async function getPortFree():Promise<{port:number,server:net.Server}> {
    return new Promise( res => {
        const srv = net.createServer();
        srv.listen(0, () => {
            // @ts-ignore
            const port = srv.address().port
            res({port,server:srv});
            
        });
    })
}

I tried awaiting a promise that I had constructed earlier, but instead of awaiting for passing to the next line, the code just exists with no error thrown.

What am I not understanding about finding the value of a checked radio option with javascript?

I’m learning how to use javascript with html and css right now, and I’m having a problem that I don’t think I should be at all. I have a form that I want to use in the future to have the user select a video they want to see on a little test website I’m making, and I wanna use a form to get that input. I struggled at first to make it work with checkboxes, but it eventually functioned. But now that I know a radio menu would work better, I tried swapping to that and it won’t function how I want.

I’m following a course on sololearn.com for javascript, and it says that you can access all of the radio options with one variable should they have the same name. But nothing I’m doing is having any effect at all right now. Here’s my code, HTML and then Javascript:

    <div class="card">
        <form id="form">
            <label for="video"><h1>What video would you like to watch?</h1></label>
            
            <input type="radio" id="video1" name="video" value="red">Mario Recreation</input><br>
            <input type="radio" id="video2" name="video" value="blue">Zelda Recreation</input><br>
            <input type="radio" id="video3" name="video" value="green">Castlevania Recreation</input><br>
            
            <input type="button" value="submit" onclick="video()"/>
            
            <input type="button" value="Reset Colors" onclick="undoColor()">
        </form>
    </div>

(The card class is used for some flexbox organization, this is in the body tags and I am 100% sure the script is properly added into the html)

function video() {
let background = document.getElementById("background");

/*Check if the checkboxes in the site are checked off, and then apply color to all the text depending on 
which is chosen*/

let form = document.getElementById("form");
let check = form.elements.video;

if(check.checked == true){
    background.style.color = check.value;
}

}

I don’t have video files right now, so the code currently changes the color of the whole page’s text. The body class as the body id element, and the only code I’ve changed is the type of input each choice was from a checkbox to a radio button, giving them all the same name, and trying to access them using .elements in a variable in the js script. Please help!

Side note, I’m programming this in school as a side project because I’m very ahead in my web design class, and I don’t know what version of javascript I have or if I can use jQuery, let alone HOW to use it. If it helps, I’ve found that if I don’t put (… == true) in my if statements, it won’t work.

How can I get rid of the lines over my drawing? Also how can I reduce the amount of lines needed to create the drawing?

I am trying to make a python code that takes an image and converts it into JavaScript so my Blot by Hack Club can read that JS and create that image. Blot documentation Currently my code does that but draws random lines over the code. Also the code generates way to many lines for the blot to handle. How could I find the sweet spot of highest quality with least amount of lines generated

from PIL import Image, ImageOps
import numpy as np
import cv2
from skimage import measure, transform
import math

# Set the detail level (1 for maximum detail, 0 for minimal detail)
detail_level = 0.4

# Function to process the image and extract edges with higher precision
def process_image(image_path):
    # Load image and convert to grayscale
    image = Image.open(image_path).convert("L")
    image = ImageOps.mirror(image)  # Mirror the image horizontally
    image = ImageOps.invert(image)  # Invert to make the background black and foreground white
    image = image.rotate(180)  # Rotate the image by 180 degrees
    image_array = np.array(image)

    # Calculate ksize (ensuring it's odd and positive)
    ksize_value = max(3, int(round(-3.333333333333 * detail_level + 5.666666666666666667)))
    if ksize_value % 2 == 0:
        ksize_value += 1
    ksize = (ksize_value, ksize_value)

    # Apply a slight blur to reduce noise
    blurred = cv2.GaussianBlur(image_array, ksize, 0)

    # Use Canny edge detection with lower thresholds for more sensitivity
    canny_threshold1 = int(round(-33.333333333 * detail_level + 56.6666666666667))
    canny_threshold2 = int(round(-83.33333333 * detail_level + 166.666666667))
    edges = cv2.Canny(blurred, canny_threshold1, canny_threshold2)

    # Optionally, thicken the edges slightly
    edges = transform.rescale(edges, 1.0, anti_aliasing=True)
    edges = cv2.dilate(edges, np.ones((2,2),np.uint8), iterations=1)

    # Use contours to find connected components
    contours = measure.find_contours(edges, 0.8)
    
    return contours, image_array.shape

# Function to generate the Blot code
def generate_blot_code(contours, dimensions, detail_level=0.8, min_distance_threshold=5):
    print("Generating Blot code...")
    lines = []
    
    # Set a fixed tolerance for fine control over details
    max_tolerance = 0.5  # More detail
    min_tolerance = 0.1  # Minimal simplification
    tolerance = (1 - detail_level) * (max_tolerance - min_tolerance) + min_tolerance
    
    # Calculate bounding box of all contours
    all_points = np.concatenate(contours)
    min_y, min_x = np.min(all_points, axis=0)
    max_y, max_x = np.max(all_points, axis=0)
    
    # Calculate scale and translation to center the drawing
    scale_x = (dimensions[1] - 1) / (max_x - min_x)
    scale_y = (dimensions[0] - 1) / (max_y - min_y)
    scale = min(scale_x, scale_y)  # Maintain aspect ratio by using the smallest scale factor
    
    translate_x = (dimensions[1] - (max_x - min_x) * scale) / 2 - min_x * scale
    translate_y = (dimensions[0] - (max_y - min_y) * scale) / 2 - min_y * scale

    # Initialize line counter
    line_counter = 0
    
    for contour in contours:
        # Smooth the contour and simplify based on the detail level
        smoothed_contour = measure.approximate_polygon(contour, tolerance=tolerance)
        
        if len(smoothed_contour) >= 2:  # Only consider meaningful contours
            prev_x, prev_y = smoothed_contour[0]  # Initialize with the first point
            for i in range(1, len(smoothed_contour)):
                y1, x1 = prev_y, prev_x
                y2, x2 = smoothed_contour[i]
                
                # Scale and translate coordinates
                x1_scaled = int(x1 * scale + translate_x)
                y1_scaled = int(y1 * scale + translate_y)
                x2_scaled = int(x2 * scale + translate_x)
                y2_scaled = int(y2 * scale + translate_y)
                
                # Calculate the Euclidean distance between consecutive points
                distance = math.sqrt((x2_scaled - x1_scaled) ** 2 + (y2_scaled - y1_scaled) ** 2)

                # Only draw the line if the distance is greater than the threshold
                if distance > min_distance_threshold:
                    lines.append(f"finalLines.push([[{x1_scaled}, {y1_scaled}], [{x2_scaled}, {y2_scaled}]]);n")
                    prev_x, prev_y = x2, y2  # Update the previous point to the current point
                
                # Increment line counter
                line_counter += 1
                if line_counter % 50 == 0:
                    lines.append(f"console.log('{line_counter} lines completed');n")

    blot_code = [
        "// Produced by Aditya Anand's Blotinator, not human-writtenn",
        f"setDocDimensions({dimensions[0]}, {dimensions[1]});n",
        "const finalLines = [];n"
    ]
    blot_code.extend(lines)
    blot_code.append("drawLines(finalLines);")

    return blot_code

# Main function
if __name__ == "__main__":
    # Use the correct image path
    image_path = '/Users/vivaanshahani/Downloads/IMG_9654 3.jpg'
    # Process the image
    contours, dimensions = process_image(image_path)

    # Generate the Blot code with the specified detail level
    blot_code = generate_blot_code(contours, dimensions, detail_level)

    # Write the Blot code to a file
    output_path = "/Users/vivaanshahani/Downloads/Blotcode.js"
    with open(output_path, "w") as file:
        file.writelines(blot_code)

    print(f"Blot code generated and saved to {output_path}")

Javascript function not found in Edge but works in chrome

I have a web app in VS2019 using angular.js.

If I try to add or edit a function in “mySvc.js”, the change will work in Edge in “Debug Mode”. But I get an error “TypeError: ‘mySvc.MyNewFunction’ is not a function” when running in Edge “Without Debug”.

If I run the code using Chrome, the new or modified functions work fine in either “Debug Mode” or “Without Debug”.

Why is Edge giving an error when running in “Without Debug”?