Why my drag and drop menu is not working?

I’m building an admin menu manager with Laravel Livewire and SortableJS. The drag-and-drop UI works perfectly but I can not reorder menus and nested submenus visually.

I have a recursive function in Livewire to save the menu hierarchy (parent_id and order) in the database based on the nested structure received from the frontend. The updateMenuOrder Livewire method is triggered on drag-end with the serialized menu structure.

The top-level menus do not load ordered by order, and the children relationship is not eager loaded with order by order as well.

Here is my html menu

<div class="w-2/3 p-4 bg-white rounded shadow">
    <h3 class="font-semibold mb-4 text-black">Menu Items (Drag and Drop to reorder)</h3>

    <ul id="menu-list">
    @foreach ($menuItems as $menu)
        <li data-id="{{ $menu->id }}" class="mb-2 border p-2 rounded bg-gray-100">
            <div class="flex justify-between items-center">
                <span class="handle cursor-move text-black">{{ $menu->title }}</span>
                <button wire:click="removeMenu({{ $menu->id }})" class="text-red-500 hover:text-red-700 font-bold">&times;</button>
            </div>

            @if ($menu->children->count())
                <ul>
                    @foreach ($menu->children as $child)
                        <li data-id="{{ $child->id }}" class="ml-6 mt-2 border p-2 rounded bg-gray-50">
                            <div class="flex justify-between items-center">
                                <span class="handle cursor-move text-black">{{ $child->title }}</span>
                                <button wire:click="removeMenu({{ $child->id }})" class="text-red-500 hover:text-red-700 font-bold">&times;</button>
                            </div>
                        </li>
                    @endforeach
                </ul>
            @endif
        </li>
    @endforeach
</ul>



</div>

and here is my js

@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"></script>
<script>
    document.addEventListener('livewire:load', function () {
        let menuList = document.getElementById('menu-list');

        new Sortable(menuList, {
            animation: 150,
            handle: '.handle', // this matches your <span class="handle">
            onEnd: function (evt) {
                let order = serializeMenu(menuList);
                Livewire.emit('updateMenuOrder', order);
            }
        });

        // Initialize sortable on all child ULs (if you want nested drag & drop)
        menuList.querySelectorAll('ul').forEach(function(childUl) {
            new Sortable(childUl, {
                group: 'nested',
                animation: 150,
                handle: '.handle',
                onEnd: function (evt) {
                    let order = serializeMenu(menuList);
                    Livewire.emit('updateMenuOrder', order);
                }
            });
        });
    });

    function serializeMenu(el) {
        let items = [];
        el.querySelectorAll(':scope > li').forEach((li, index) => {
            let item = {
                id: li.getAttribute('data-id'),
                order: index + 1,
                children: []
            };

            let childUl = li.querySelector('ul');
            if (childUl) {
                item.children = serializeMenu(childUl);
            }

            items.push(item);
        });
        return items;
    }
</script>




@endpush

My menu manager component is here

    public function loadMenu()
{
    $this->menuItems = Menu::whereNull('parent_id')->with('children')->orderBy('order')->get();
}
 #[On('updateMenuOrder')]
    public function updateMenuOrder(array $structure)
    {
        Log::info('updateMenuOrder called with:', $structure);

        $this->updateMenuHierarchy($structure);

        $this->loadMenu();

    }


    // Recursive update of order and parent_id
   public function updateMenuHierarchy(array $items, $parentId = null)
    {
        foreach ($items as $index => $item) {
            Menu::where('id', $item['id'])->update([
                'parent_id' => $parentId,
                'order' => $index
            ]);

            if (!empty($item['children'])) {
                $this->updateMenuHierarchy($item['children'], $item['id']);
            }
        }
    }

How to select an element from a dropdown menu?

I have a pop-up modal, in which I am creating a rule from, but when trying to select the elements from the select-menu, my test fails. I have this on the web page

<label class="form-label"> Group Granularity </label>
<select class="form-select"> 
<option selected disabled value>Select granularity</option>
<option value="per-metric">per-metric</option>
<option value="per-hostname">per-hostname</option>
<option value="per-group">per-group</option>
<option value="global">global</option>
</select>

I tried a few code options to handle it, but none of them seem to work i.e

await page.getByText('Group Granularity').click();
await page.getByRole('option', { name: 'per-hostname' }).click();

and the error is as follows, because it seems that the element doesn’t get identified within the timeout threshold:

Error: locator.click: Test timeout of 30000ms exceeded.

title not visible during overlappng scroll effect

I’m currently working on an overlapping scroll effect for a section on my page. The animation itself works fine, but I’m running into a specific issue: the section title scrolls out of view before the full effect is completed.

Ideally, I want the title to remain fixed or “sticky” until the entire overlapping effect finishes, and then scroll away normally.

I’ve tried wrapping the title inside the animated section and adjusting paddings and positioning, but that introduces layout issues. Sometimes the title appears static, but part of it still scrolls away too early, or it causes spacing glitches in the layout.

I’ve been experimenting with combinations of position: sticky, z-index, and conditional padding/margins, but nothing fully solves it.

Also tagging a collaborator here—we both hit the same wall trying multiple fixes with layout structuring, wrapping strategies, and sticky positioning, but none of them managed to keep the title in place correctly throughout the scroll sequence.

How can I keep localStorage in sync with server-side changes from a cron job?

I’m building a web app that has a concept of an accountType (e.g., “free”, “pro”, etc.). The user’s accountType is stored in the backend database and is updated A cron job runs every hour and may change the accountType based on some business logic (e.g., expiration of a free plan).

In the frontend, I cache the accountType in localStorage so that I can avoid unnecessary API calls. However, this creates a problem: the data in localStorage can become stale if the backend changes due to the cron job.

How to fix margin calculation and CSV-based net/net/net price import in JavaScript web app? [closed]

Margin calculation seems incorrect
I’m calculating margin like this:

const margin = ((totalBruttoWithCommission - (netNetNetPrice * 0.65)) / totalBruttoWithCommission) * 100;

But this sometimes results in values over 100%, or negative values, even when the data looks correct. I suspect the formula or the base values may be off.

net/net/net price not correctly imported from CSV
The CSV may contain a column labeled something like “Cena net / net / net” or “NetNetNet”. I try to detect it like this:

const netNetNetPriceIdx = headers.findIndex(h => h.replace(/[^a-zA-Z]/g, '').toLowerCase().includes('netnetnet'));

When reading values:

let rawNetNetNetPrice = row[netNetNetPriceIdx].trim();
rawNetNetNetPrice = rawNetNetNetPrice.replace(/[^0-9,.]/g, '').replace(',', '.');
netNetNetPrice = parseFloat(rawNetNetNetPrice);

But many values come out as NaN, especially when they contain currency symbols or spaces.

What I’m trying to achieve:

  • Accurately import the correct net/net/net unit price from CSV.

  • Multiply it by pack size.

  • Use it in the margin calculation reliably.

What I’ve tried:

  • Normalizing headers with regex.

  • Cleaning up values with replace().

  • Falling back to estimating the price as 65% of net if CSV value is invalid.

Still, the margin values are off and data inconsistencies are common.

<!DOCTYPE html>html lang="pl"><ead>et charset="UTF-8" /><maname="viewport" content="width=device-width, initial-scale=1" /><titKalkulator Wielopaków </title><stylbody {ffamil:e UI', Arial, sans-serif;padding 2.5rem;bund: liear-gradi0deg, #e0e7ff 0%, #f7f7f7 100%);color: #22;}.calculatr{bund: white;ng5rem 2.5re 2rrem;max-width: 110rgin: 2rem auto;border-radius: 8p-shadow: 0 8px 32px44,62,80,0.13);borpx solid #e3ef0;}hxt-align: cente;argin-bottom: 2remfont-2.2rem;color: #d3a5a;letspg 1pabel {font-wight: argin-top:1.2rem;di block;color: #2d3ette-spacing:0}input[type=number],ute=tex],[type=file] {padd.55rem 0.7rem;width;boxsizing: boox;margi-top: border: 1px solid#bf;er-radius 6px;font-size: 1rem;bckground: #f8faf;tran: border 02s;}input[tmber]:focs, type=text]:focu bordepx solid #2978b5;ou none;backgroud: #f0f6ff;le {border-ollapsease;width: 100%in-top: 1.rem;font-1.05rem;bacground: #fffrdadius: 8px;oerflow: hidde;box-shadow: 0 2px 8px44,62,8,0.06);}th, td {p 0.7rem 0.5rem;r: 1px solid #e3e8f0;-: centeh{background: #e6f0fa;co2d3a5a;font-: 700;letter-spainpx;}tbody tr:hoverground-coor: #f0tranition: backgrous}utton {marg: 1rem;padding: 0.6rem 1.3rem;cursor: poi;gond: lgraient(90deg,#2978b5 4fc3f7 100%);coor: white;r:none;border-radi6pont-s.05rem;font-weight: ox-hadow: 0 2pxgba(44,6280,0.08)sition: backgroun 0.2sx-ow 0.2s;}button {background: linear-gradideg, #225c8a 60%, #29b6f6 100boao: 0 4x rba(44,62,80,0.button.delete-btn {bacd: #d9534f;colore;font-weight: 500;padding: 0.rem 1rem;border-radus: 5px;-top: ;box-s one;transitackgrond 0.2s;}buelete-btn:over {band: #b52a26}.fl {diplay: flex;ap: 2rem;}.flex-row > lx: 1;}#productImage{max-width: 22p;mei 20px;margin:m uto 0 autodsplay: block;border:15px solid #bfc9a;bordius: 12px;bx-shadow:  2px 8px rgba(44,620.ackground: #f8fffroductName {text-alinter;fnt-weiold;margn-top: 0font-size: 1.15rem;c#2978b;letter-spac.5px;display: }#imprtSection {n-op: 2.5rem;pdding-top: 1mder-top: 2px solid e3e8f0grond: #f8faff;bordd 0 0 12px12x-shadow: 0 2pxgba(44,62,804xt-align: center;portSectinpype=file] {dispnline-block;widh;margin: 0.7rem aurem auto;}#importSection pt-align: center;n-left: auto;margin-right a#importedFilesist {syle-type: none;padding: 0;agin-top: 1ext-align: left;}#iteesList li {martom: 0.5rem;}#cmonSection {margin-.5rem;padding: 1.5rder-top: 2x solid 0;background: #;borde-adius: 12px;ado: 0 2px 8pxa(2,8,.04);}#coionSecion h3 {marg:0;margin-bottom: 1color: #2d3a5a;}#ompetition{marin-top: 1.5rem;mpetiionTable a {color: #297ext-dcration: none;}#cometitionTble a {text-decoation: rl}#sortsBtn, #sortDesBtn {marght: 0.5rem;padding: 01rem;fot-si9rem;}.loading {display: inlncidth: 20px;height:boder: 3px solid #;bodr-top: 3px s2978b5;border-rdiu0%imation: sin 1s lineinitemargin-right .}@keyframs{0% { transform: (0deg); }00% { torotate(360deg); }}.eaatus {margin-top: 1remd 1rem;background: #f0border-radius: 8px;left: 4px solid 5display: noe;}@media (max: 900px) {.lex-row -direction: column;2em;}.calcuator {padding: 1.2rem 0.re#uctImage {max-width: 100-height 180px;/style></hea><body>class="aculato<hlkulator Wielpaków<<div class="flex-rowyllgn-itesflex-start;re;"><div stylx:2; min-idth:260px;>ber="basePrice">Cena bazowa brzł za1 sztuk):</lael><intynumber" id="basePrice" valuetep="0.01" min="0" />l for="vatRate">Stawka%):</labe><input ="er" id="vatvalue="8" step="0.1" midisabled/><for="commissiowizja sklepu (%):/label><type="number" id="commission" v13" step="0.1" in="</div><div style="flex:3; minwidth;"><h3>EAN produktu:<<class="flex-row" salign-its:center;"><div style:3;"><input type="txt" id="eanInpulalder="np. 5905341" /></div><div sflex:1;"<butt"setProductBtn">Ustawkt</buton></div><<img id"productImage" alt="Zdjęoduktu" src="" eplay:none;" /><iv id="prode" style="te:center; font-weight:boln-top:.5rem;y"></div></div<3>Wyniki kalkulacji<tathead><tr><th>pczki</h><th>R</th><th>Cena jedna toth><th>Cena całkowita bt + prowizja/th><th>Wagaduktu (kg)</th><th>Cena net/net><th>Marża (%)</th></tr></thed><tby id="packTable"></tbodyble><h>Proi wielopaków (rzmiar i r/3><table id="discounTable"><thead><tr><th>Rozmiar paczki szt<th>Rabat (%)</th><t>Usuń</th></tr></head><tbody></tbod></tatddThresoldBtn">Dodaj próg</button><h3>Po finansowe</h3><table><thead><tr><th>ozmiar paczki</th><th>Cenacałkuowzja<th><th>Kwota</th><th>Zysk</th><th>Marża (/tr></thead><body d="summayTable"></tbody</table><div id="imption">portuj dane proktów z pliku CSV</h3>yp="file"id="csvileIept=".csv,text/csv" />< style="font-size: 0.9rem55; margin-top0.5reml id="iportedFilesList"style="lst-style-type:none; padding:0; maem; texf"></ul></div><diitonSection" style="display: none;"><h3>yszukiwrencji<v classow" style="align-items:ceter; margin-bottom:1rem;"><div style="flex:2;"><la"competitionEan">EAN produktu do wyszukania:</label><input type="text" id="competitinEan" aceholder="np3412345/></didtyle="flex:1;><button id=rchCompeBtn">Wysutton/div><div style="margirem;"><label for="nName>Nazwa produktu:</labl><i"text" id="competitionName" placeholder="Nktu" /><lbel for="competi>Cena (zł):</label><inputber" id="competitioste="min="0" plder="0.0" /><label for="comtionShop"elabel><iut type="text" id="comptitionShop"ceholder="Nazwa sklepu" />l for"conUrlsklepu:</label><input type="tempetitionUrl" acetps://..." /> id="aetitionBtaj do prównaniatton></d<div style="margin-bottom:1rem;"><labeSortuj uny:</label><button id="ortAscBRosnąco<n><buttortDeejąco</button></div><archStatus" class"search-status"><div idssage>Wyszukiwktów...</div>able id="competitio<thea>th>Nazduktu</th><th>Cena (zł)</th><t>p<th><tnh><th>Akcje</th></tr><><tboy></tbody></table></div></iv><scconst basePriceInput = dcument.getElementById('bsePric);cotRateInput = document.getElemenById('vatRate');const commissi=ent.entById('commission);cons discountTableBod = document.querySlector('#dscounTable tbody');onst ace = doctElementyId('pacTable';constummaryTable = documeElementById('summaryTable');constresholdBtn= document.getElementById('addThresholdBtn');consteanInpument.getElementById('econst setProdtBtn = document.getElementById('setProductBtn');ductImage = document.getEementById('productImage');const productName= dgetElem'productName');constput = document.getElementyId('csvFileInput');constdFilesLdocumenlyId('importedFilesLis);// Elemcji konkurencjiconst compeitionEanInput = document.ntById('competitionEan');const competitionNameInput = document.getElemeconName');const cometitionPriceInput = document.ntById('competionPrice');const competitionShopInput = document.geElementById('comSonst competitionUrlInput = dument.getElemecompetitonUrl');const searchCompetitionBtn = document.getElementByIdCoBtn');const addCompetitionBtn = document.getElemeaddComptitionBtn');const sortAscBtn = document.getElementById('sor)sortDecBtn = document.getElementById('sortDescBtn');const itionTadt.getElementById('competitionTablet competitionTableBody = ompetitiouerySelector('tbody');const searchStatusent.getElemetById('searchStatus');const sessage mtElementById('searchMessag');// Mapa produkAN: { ean: { price: Number, image: String } }let produc {};/iych konkurencjilet comptitio[];// rogi et packConfigs = [{ siznt: 0 },{ size: 6,.03 },{ size: : 0.07 },{ siount: 0.10 },{ disco5},{ sidiscount: 0.18 }unction ceThreshdRow(pa,ndex) { tr = document.createElement('tr');// RozmiarpakowaniacosizeTd = document.createElement('td');const sizenput = ment.crteElement('input';sizeInput.type =number';sizeInpi1;sizeInpu.value = packsize;sizeInput.syle.width = '80px;sizeInput.ventLitener('chane', () => {const val = parseInt(sizet.value);if (va >= 1) {packConfigs[index].size = vapackCgs = sortPackConigs(packConfigs);renderDiscountTable();rnderTabl;sizeTd.appendChild(sizeInput);// Raba %const distTd = document.reateElemet('td');const discountInput  documereateElement('input');dicountInput.type = 'number';discountt.min= 0;discountInput.max = 100;discoutInput.step = 00intInput.value = (pack.discout * 100).toFixed(2);discountInpuyle.widh = '80px';discountInpt.addEventitener('change', () => {let rseoat(discoutInput.value);val < 0) val = 0;if (val > 100 val = 100;packConfigs[index].discountal / 100;disountInput.value = val.toFixed();renderTable();})discou.appendChild(discontInput);// Usuńconst delTd = document.createElement();const delBtn = docuent.createElement('button');deltn.textContent = ń';delBtn.className = 'delete-bn';delBtn.addEventListener('click' ( {packConfigs.slice(index, 1);renderDiscuntTable();renderTable();});delppendhild(delBtn);tr.appendChild(sizeTd);t.appendChild(dscontTd);appendChild(delTd);return trfunctio renderDiscounte() {discountTableBody.inerHTML = '';packConfigs = sortPanfigs(packConfis);packConfigs.forEach((ack, index) => {discountTabdy.apendChild(createThresholdRow(pack, inex));});}function sortPonfigsarr) {return arr.sort(a,b) => a.size- bsize);}fuon renderTabl) {const baseBrutto = prseFloat(basePriceInput.e 0;const vatRate = paeFloat(vataInput.value) || 0;const commnRate = (parseFloat(csInput.value || 0) / 100;conatFactor = 1 + (vatRate/ ;st baseNetto = baseBrutto / vctor;pckTable.innML = '';packConfigs.forEpack => {const netUnitPrce etto * (1 - pack.discount);s netUnitWithCommission = netPrice * (1 + cmssionRate);t bruttoUitPrice = netUnitPr* vc // Cena jednostkowa brutt bez prowizjicotalBruttoWithCommission = bruttoUnitPice+ssionRate) * pack.sizeOblicz net/net/net: najpierw sprdź CSV, poticz jako 65% ceny nettolet netNetNetPrice;const cEan eanInput.value.trim()e.log(productMap[tEan])neNetNetPrice = producurrentEan].netNetNetPrice * pac;// Calculate marginconst margin = ((totalthCommission - netNetNetPrice *0.65)) ruttoWithCommiss;const row = document.createE');le totalWeight = '-';if (currentEan &&p[currentEan] && producntEan].weight !{eighroductMap[currentEan].weight * iFixed(3) + }row.innerHTL = `<td>${pack.siz} szt.</td><pack.discount * 100).toFixed(2)}%</td><td>${brutoUnittoFixed(2)} zł</td><td>${totalWithCommission.toFid(</td><td>${totalWight}<td>${netNetNetPrice.toFixedł</td><td>${margin.toFixed(2)}%</td>`;packTab.appen(row);if (pack.size > 50){const ow = document.ceateElement('tr');extraRow.inner<td colspan="7">Dodatkow wiersz dla ilośc ${pack.size}</td>`;e.appendChl(extraRow);}rgin  18) {const marginCell = dcument.ement('td');const marginInput = ocumteElement('inpuargi.type = 'numer';marginInput.value = mt(2);marut.stye.width = '80px';marginInput.addEvenner('change', ()=> {const newMargin = parseFloinnput.value);if (!isNanen)) {const newProfi = totalBrutCommission * (newMargin / 10);const newtPrce = totalBruttoWithCommisewProfit;// Update throw with new ao.cn[5].textContent = `${ewNettoFixed()} zł`;row.chi6].textContent = `${newMarixed(2)}%`;// PrzerendaenderSummarle}marginCell.appendChild(mrginInpow.appendChild(margnCell);}});nderuj tabelę posumowania finansowegorenderyTable();}funtion renderSummaryTabonst baseBrutto = pareFloat(basePriceInut.value) || 0;const v = pFlvteInput.value) || 0;const comiate = (parseFloat(commissionInput.value) ||/ statFactor = 1 + (vatRa00);const baseNetto = baseBrutto / vatFactor;summaryTaerHTML = '';packConfigs.forEach(pack => {consnetice = baseNetto * (1 - ack.discount);const bruttoUnitPrice = baseBrutnalBruttoWithomision = bruttoUnitPric + commissionRate)* pack.size;// bcze najpierw sprawdź CSV, potio 65% ceny nettolet netNetNetonst currentEan = eanIput.value.trim();if (currentEaductap[currentEan] && productMap[currentEan].netNetNetPrice == nu Użyj wartości z CSV (cea jednostkowa * rozmiar paczki)netNetNetPce = productMap[curreeetNetPrice * pack.size;} else{// Oblicz jako 65% ceny nettonetNetNetPrice = ete* pack.size;}const profit = totalBruttoWithCommission - netNetNetPrice;conn = ((profit) / totaithComssion) * 100;const row = documenElement('tr');row.innrHTML = `<tdsize} szt.</td><td>${totalBruttoWithCommision.toFixed(2)} zł</td>tice.toFixed(2)} zł</${profit.toFixed(2)} zł</td><td>${margin.toFixed(2)}%</td>`;summaryTable.appendChild(row);};}addTBentListener('click', () => {// Znajdź max paczkilet axSize =1ckConfigs.length > 0) {maxSie = Math.max(...packConfigs.map(p=p.size));}// Dodóg z rozmiarem max+1 i rabatem 0%packConfis.push({ size: maxSize + 1, discou;scountTab();ren;});// Aktualizuj tabelęrzyzmianie bazowych anychbasePriceInpu.addner('input', renderTable);vatRateInput.adener('nput', renderTable);commissionInput.addEventinput, renderTable);/CSVcsvFileInpu.adEventListener('change{const fles=rray.from(e.taes)iles.length) retrn;files.( {const reder = new ();reader.onload = function(vent) {const textarget.result;parseCSVdaj plik do lit zaimportowanych plikówconst listItem =document.cr'liem.textContent = file.name;liste.t.5rem';// Ddaj uwaaconst deleteButton = document.createElemen);deeteButton.textContent = 'Usuń';deleteButton.l'delete-btn';deleteButton.stLeft = '1rem'deleteButton.addEventLisck', () => {listItem.move);})m.appendChild(deleteButton);importdFilesList.listItem);};reader.readAsText(file);});})eProductDta(existingDataor (cont [key, value] of Object.entries(ewData)) {if (!existineistingData[key] = value;} else {// Sprawdź, czy ierwsze 4 inadzająconst existing = existingData[key]s = (eisting.price ==value.price &&exsting.margin === value.mang.image === value.mage &&existing.name === value.nam &geight);if (matches)  brakjące daneexisti= xist|| valueprice,margin: existing.marge.margin,mage: existing.imaue,nx.name || value.name,weigh: existing.weightlue.weight,;}}} Zano funkcję parseCSVuncionarcsvText) {const lines = csvText.split(/r?n/).filter((l)trim() !== '');if (ines.length < 2) {alert('Plik Ct pustylub niepprawny.');return;}// Wykryj separatr: jeśli w nagjęcej przecinków niż średików, użyj prz, w przeciwnym razi średnikconst headerLl];let separator = ';';if ((Ltch(//g) || []).length > (heamatch(/;/g) | ).length) {separator = ',';}/ Fu bezpiecznego splitowana linii CSV łowamifunction spltCSVLine(line, sep) {cost result = [];let curent = '';let inQfr (let i = 0; i <lielnth; i++) {const char = ine[i];if (char === '") es = !inQuotes;} elhar === sep && !inQuotes) {result.push(cuurrent = '';} else {curent += char;}}result.push(current);retur result} Nagłówky opcjonalnych kolumnconst headers = splitCSVLine(lines[0]r).map((h) => h.trim().toLowerCase));const eanIdx  headers.findIn=> h == an');const priceIdx = headers((h) => h === 'cena srp');const arginIdx = headedarża');let imageIdx = headers.findIndex((h) =>  === 'zdjif (imageIdx === -1) imagIdx = headers.findndex((h) => h ==it nameIdx = headers.findIndex((h) => h ==kt_nzwa');const = headersfindIndex((h) => a');const gramatraIdx = headers.findIndex((h) = hse().includes('gramatura');// Kolmny encjiconst cmeitionNameIdx = ndInde((h) => h === kkurenc');ompetitionPriceIdx = haders.fix((h h kurencja_cena');const competitionShopIdx = headerIndex((h) = h === 'konkurencep');const compeUrlIdx = haders.findIndex((h)= 'konkurencja_url');// Kolumnadla ceny net/net/nezugłówka zawierjącego 3x 'net' (niezależnie od wielliter, spacji, ukośników itp.)console.log('Headers:',rs);const netNetNetPri= headers.findI((h)h 'cena net/net/net');console.log(ntNetNetPriceIdx)consrcodeHeader = heaers.findIndex((h) => h === 'kod kresk);if (barcodeHeader === -1) {headers.ph('kod kres');}fr (let i = 1; i < lines.length; i++) {const rosCSVLine(lines[ieparator);const ean = row[eanIdx]?.trim();if (erow[bacodeHeader] = ean;}}for (let i  < lines.length; i++) {if sim()) coninue;const row SVLine(lines[i], separator);letull;if (eanIdx ! -1 && row.lengx) {const rawEAN = row[eanIdx].tr= parseEAN(rawEA ll;if (priceIdx !== -1 && row.length > priceIraPrice = row[priceIdx].trim(;rawPrice = rawace(/[^0-9,.]/g, '').replace(',',ce = parseloat(rawPrice);}let marginfx ! -1 && row.length > malet rawMargin = row[marginIdx].trim();rwMargin = rawlace(/[^0-9,.-]/g, '').replace(',argin=arseFloat(rawMargin);if (isNa {margin = ull; // Jeśli wartość nie j, ustawna null}}let imgUrl = '';if (imae& row.length > imaggUrlg();}ltpdName = '';if (nameId& row.length  nameIdx) {prodName= row[.trlet weight = null;if (pe &&ig/sługa ormatów typu "6 szt (60g)", "3x(20 g)", "12 itd.const sztGramMatch = prodName.matc(/(d+)s*(sz-9]*(d+[.,]?d*)s*(kg|gsztGramMatch) {const szt =t(sztGramonst val = sztGramMatch[3].replace(',', '.');const unit = szt4].toLowerCas(const num = parseFif (!isNaN(num) & {cnst singleWeight = unit === ': num / 100;weight = singleWeight // Fallback — np. "250g" bez licif (!weight) {const wagMatch =math(/(d+[.,]?d*)s*(kg|g)/i)MattaMatch[1].repla;contut = wagaMatch[2]);const num = parseFl!isNaN(num)) {wit = unit === 'kg' 000;}}}}if (weight === null && wei& row.length > weigtIdx) {const raweihtIdx].trim();const wagaMatch =ch(/(d+[.,]?d*)s*(kg|g)/i);if (wagat vatpl',);sit = wagaMatch[2].toLowerCase();t num = parseFloat(val);if ((num)) {weight = nit === 'kg' ? num :num / 1000;}}}if (weightull && gramaturaIdx != w.length > gramaturaIdx) {const awGramatura =maturIdm(saturaMatch = rwGramatura.match(/(d+[.,]?d*)s*(kg|g)/i)if (gramaturaMatch) {cst val = gramaturaMatch[1].replac '.');const uit = gramatura2].toLowerCase();con = parseFloat(val);if (!isNaN(num)) weight = unit === 'kg' ? num: num / 1000;}}netNetNetPrice = ieiceIdx !== -1) {console.log'eNttPriceIdx:', netNetNetPricconsole.log('row[netNetNetPrceIdx[netNetNetPriceIdx]awetNetNetPrice =NetNetPriceIdx]?.trim(rawNetNetNePrice = rawNetNetNetPrice.r/g, '').replace(',', 'e(/[d.]/g, '').rep');consol.log('Raw nie:', rawNetNetNetPrice);const parsed (rawNteNPrice);cParsed netNetN parsed);ice = parsed;} =`p{i}`;if (!poductMap[productMap[key]rirmage: imgUrl, name: prodName, weight, netNrice };} else {productap[key] = {price: prouctMap[key].price || price,margin: prap[ke].margin || margin,image: productMap[ke].image || imgUme: prouctMap[key].name | prodName,weight: productMap[key]t || weigtnetNetNetPrice: productMap[key].netNeNetPricetNetNetPrice,};}// Obsługa danych konkuencjiif (compnNameIdx !== -1 && competitionPriceIdx !== -1 && competitionShopIdx !== -1)st copName = row[competitionNameIdx]?.trim();const compPriceRaw[competitionPriceIdx]?.tri();const compShop = row[compethopIdx]?.trim(;const compUrl = competitionUrlId !== -1 ? row[competitionUrlIdx]?.tr (ompName & compPriceRawmpShop) {const compPriceClean = compPriceRaw.replace(/[^0-9,.]/g, '')replace(');const compPrice  parseFloat(compPriceClean);if (!isNaNcompPrice)) {// ź czy ten produkt jż istnieje w danych konkurencjiconst existingIndex = competata.findIndex(tem => item.name === compName && itm.shop === compShop);isdex === -1) {competitionData.puame: omNe,price: compPrice,shop: comphop,url: compUrl || ''});}}}}}alert(`Wczytano ct.keys(productMap).length} produkpliku CSV.`);console.log('Załadowane produkty:', roductMap); // Debugif (coionData.length > 0) {rnderComo();alert(`Dodatkowo wczytano ${comptitionData.length} pozycji konkur`);}}// Zamienia np. 5,2 lub 5.90534E+12 na normalny EA function parseEANraw) {if (!raw) retur// Usuń cudzysłowy i spacjeraw = raw.replace(/.trim()// Spróbuj zinterpretowliczbę, jeśnotacji nauwejlet num =raac if (!isaN(num)) {// Zamień na string bjilet str = num.toFixed0);if gth >= 8 && str.length <= 14) return str;}//  ciąg znaków EANma długość 8-14, zwróć bez zmiaif/^d{8,(raw)) rturn raw;return null;}knięciu usaw produkt poPr.Lstener('click',const ean = eanInpt.vleti(if (!ean) {az EAN produktu.');return;}const p ap[ean];if (!p) {lert('Nie znaleziono produktu o podanym EAN wwanym pliku.);productImage.splnuctName.tyle.displne'return;}// Ustaw cenę bazową brutto z CSVbput.value = p.price.toFixed2;Pok i nazwę produktu, jeśli sąif (p.image) {let imgrc = p.image;if (///.tst(imgSrc) && !imgSrc.st/')) {imgSrc = './ productImage.src = imgSrc;oductImage.style.display = 'block'pagd 'none';}// yśzwę produktupod zdjęciemif (p.ame) {productNntent = pname;productName.styayke productName.tex = '';productName.style.disply= 'none';}e();});// InicjalizacjarendetTrle();// Funcje oonkurencjifunction rendeTable() {comeitionTableBody.innerHTML = '';competitionData.forE index) => {const row = documnt.createElment('tr');const naeCell =dcument.created')nameCell.extCo.name;row.appendChild(nameCell);cons= document.createEleent('td');priceCell.textCm.price.toFixed2);row.pendChild(priceCelhopCell = documet.createElemhopCell.textContent item.shohild(shopCell);const linkell = documentcreateElementem.url) const link = documemliiink.target = '_blan';link.textContent = linkCell.append} ele {linkCell.textContent = '-';}row.apendChild(likeactionsCell = docement('td');cnst deleteBtn= document.creaton');deeteBtn.textContent = Usuń';deame = 'deletebtn';deleteBtnner('click', () => a.pce(idex1);renderCompetiionTable(CeldendtionsCell);competitonTableBody.appendChild(rw);});}function aionItem() {const na = competitionNameI.trim();constprice = parseFloat(competitionPriceInput.lue);p = competitionShe.trim();consturl = competitionUrlIput.vaif (!name || isNaN(pce) || !shop) {alj wszystkie wymagae pola (naklep).');return;}ata.pus({name: name,price: price,shop: rlycmupameInput.value = '';competitionPriceInput.value = '';competionShopInput';competitionUrlInput.value = '';renerCompee();}function searchCompetitionByEan(){const ean = competitionEanI.trim(;if (!ea) {aEAN produktu.');return;/ Pokaż wskaźnik ładhStatus.style.display = 'block';earchMessage '<div class="loading"></iv> produktów w internZablokuj rzycisk wyszukiwaniasarchCompetab;mptntent = 'Wyszukiwanie...';lacjawyszukiwania w internecieuctsOnline(ean).th(results => {if (results.length =archMssaennerHTML = '❌ Nie znaeziono produktów o podanym EAecie.';stTimeout(() => {searchStatus.style.display = 'none';return;}// Dodaj wszystkie zalezione produkty do tabeli konkurncjilet addedCount = 0;results.forEac(productprawdź czy produkt już istnieje  tabelikonkurencjiongProduct  competitionDta.find(item => itemproduct.name & item.shop === product.shop);ingroduct) {competition{re product.price,shop: product.sp,oduct.url});adCountrenderCompetitionTable();// Poaż komunikat o sukcesiesearchMessag.innerHTML  `✅ Znaleresults.duktów,dano ${addych pozycji do tabeli konkurencji.`;/formulaz danymi z pierwszego produktuif gth > 0) {const firstProduct = results[ionNameInput.value  firstProduct.nme;riceInput.value = firstProuct.price.toFixtitionShopInput.alue = firstProduct.shop;competitonUrlInput.valPro;rs po 5 sekundachsetTimeout(()archStatus.style.display = 'none';}, 5000);).catch(error => {onsole.error('Błąd podczaania:', errr);searhssage.innerHTML = '❌ Wystąodczas wyszukiwania produktów.';seTimeout(() => {seasyle.display = 'none';}, 3000);}).finally(() =>okuj przycisk wyszukiwaniaseachCompetitionBtn.disabled = false;searchCometitt'Wyszukaj';});}// Funkcja do pobierania  rokcie z API bacodeasync function getProductIfoFromBarcode(ean) {try {//mweg API UPC Dtabaseconst response = awtsemdb.com/prod/trial/looku;cnst data = await response.json();if (data.code === 'OK' && data.items.length > 0) {const item = datitems[0]; item.title || item.brand || `rodukt ${ean},brd |iiption || '',image: item.imges.length > 0 ? item.i} catch (eror)Błąd podczas pobiektu:', error);}// Symulacja wyszuk w ic rcnl {n oresolve) => {/ Symulacja opóźnienia zapytnia do APIsetTimeut(() => {//dź czy mamy dane dla tego EAN w nasej baziecst localPr= productap[ean];const productNaalProduct ? localPoduct.nrodukt EAN: ${ean}`;// Symulowane dane z różnych sklepówcont mockResultsn pcece: 15.99,shop: 'Allegro',rl: `http://allegro.pl/search?string=${ean}`},ame: roductName,price: shop: 'OLX',url: `htww.olx.pl/oferty/q-${ean}/ame oductName,price: 14.25,shopel: `https://www.ceneopl/search;szukaj-${ean}`},{name: productNamee: 6.80,hop: 'Amazon',url: `https//wzon.pl/s?k=${ean}`e: productName,price: 13.99,hik',url: `https://www.empearch?q=$an}`},{name: productName,price: 18.45, '',url: `htps://www.morele.net/search/q=${ean}`},{name: productName,pri.75,shop: 'Euo RTV AGD',url: `htps:/u.pl/search.bhkedan}`}];if (localroduct) {// Użyjczywistej ceny jako bazowej i ddaj losową wariaonst basePrice = localProduct.prce;mockResulth(result => {result.price =b + (Mathm(5) * 8;esult.price = Mathesult.pric; // Nie może być jemnaresult.price = Math.round(esult.price * 100) / Zaokrąglij do 2 miejsc po przecinkuse {/Jeśli nie ma lokalnych danycpodstawoyą losowościąmockesults.forEach(r> {result.price  10 + Math.random() * 20e10 do 30 złresult.prie = Math.round(resut * 100 / 100;esolv(mockResults);} // Symulacja 1 sekuny opóźnienia});}/ Funkcja do reczywzukiwania (wymaga API kec  searchProductsOnlinRelenst results = [];try {// rzykład wwania  Awymaga API key)// const allegroespoawtch(`http://api.allegr.pl/serch?ean=$);// const ala = await alleroeponse.json();kład yszukiwania w Ceno (wymaga APIub web sc// const ceneoResponse =awihttps://www.ceneo.l/api/sarch?ean=`)oneoData =awaiteoReson();// Dodaj wi do tablc rults}ch (error) {coor('Błąd podczas wyszukiwania:'ror);}return results;}functionompetitionData(ascending = tru) {coi.sort((a, b) => {f (ascending) {return a b.price;}else {return b.price - a.pricmpetitionTable();}// Evet listenery dla sekurencjisearchCompetitionBtn.addEvner('click', searchCompetit)pettiontn.addEventListener('click', addCompeti);sortAscBtn.adEventListener('click', ( => stitionData(true));sortDescBeer('click', () =>sortCompetitionData(false));matyczne wyszukiwaie przy zmianiepetitonEanInput.addEventLii) => {const en =cpetitionEanInput.value.trnsole.log('WyszuN:', ean); // Debugconsole.log('Dostępne ect.keys(oductap));if (ean && productMap[est produc = productMap[ean];og('Znaleziono produkt:', pr// Debugct.name) {ompetitionNameIne t.name;}if (product.priceeceInput.value = product.price.toFixed(2);}// Usślną nazwę sklepuif (!competitionShopInput.value.trcompetitionShopInput.value = 'Na';}} else / Wyczyść pola jeśli został znezionycompetiionNameInput.valuepetitionPriceInput.vau= '';if nsole.lgNie znaleziono  dlaean); // Debug}}});// Atomatycukiwanie przynaciśnięciu EnteetitionEanInput.adEventLitener('keypr(e) i.=== 'nter') {searchCometion);}});</script></body></html>

How to spawn a react element through vite?

I’m trying to code a weak core without typescript

import { useState } from 'react';
import { ReactElement } from 'react'
vite.spawn?this.state(<ReactElement spell="btn"/>)

and getting a type conflict:

index-DIIg0VsU.js:49 3
index-DIIg0VsU.js:49 NaN

preview

Rollup: Error: Cannot find package all rollup plugins packages

I’m having issue with Rollup finding all Rollup plugin packages. It used to work some months ago but now I get the following error. I tried some isolation testing by disabling one module at a time, thinking maybe a module could be the issue, I also updated all modules, still no resolution. I started a new project, the issue persists. I also updated all modules,In another existing project there no problem.

All recommended solutions do not work.

Error: Cannot find package ‘@rollup/plugin-node-resolve’ imported from P:devProjectseSvrAppsrollup-testrollup.config.js

If I remove one imported plugin, it shows error for the next imported plugin package.

From the affected

  "devDependencies": {
    "@rollup/plugin-commonjs": "^28.0.1",
    "@rollup/plugin-json": "^6.1.0",
    "@rollup/plugin-node-resolve": "^15.3.1",
    "@rollup/plugin-terser": "^0.4.4",
    "rollup-plugin-copy": "^3.5.0",
    "rollup-plugin-delete": "^2.1.0",
    "rollup-plugin-execute": "^1.1.1"
  }
import json from '@rollup/plugin-json'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import terser from '@rollup/plugin-terser'
import del from 'rollup-plugin-delete'
import copy from 'rollup-plugin-copy'
import execute from 'rollup-plugin-execute'

My fear is that the current working project may start to fail.
Thanks for any help.

Difference between iterating node.children and node.querySelectorAll?

Perhaps I am misunderstanding this example, but I had what appears to be the misconception that querying the DOM could be relatively rather slow and was looking for a “good” way to remove all selections from a variable-sized list.

The thought was that if a reference was held in memory to the children collection of a parent node, it would quicker to iterate the children and remove the selection (method_2) class than it would be to use querySelectorAll to iterate the DOM to locate selected children and then iterate that collection to remove the selection class (method_1).

However, that appears to be incorrect. Why is this the case? Or did I make a mistake?

Is the native method of querySelectorAll that much faster the a JS script loop?

Thank you.

let 
   p = document.querySelector('.parent'),
   f = document.createDocumentFragment(),
   c = p.children
;
function populate(n,mod) {
  for (let d, i =0; i < n; i++) {
    d = document.createElement("DIV");
    if ( i % mod === 0 ) d.className = "sel";
    f.append(d);
  }
  p.append(f);
  console.log(`populated total of ${n} having ${p.querySelectorAll('.sel').length} selected.`);
}
function method_1() {
  let n = Date.now();
  p.querySelectorAll('.sel').forEach( v => v.classList.remove('sel'));
  console.log(`method_1 elapsed: ${Date.now() - n}`);
}
function method_2() {
  let 
     n = Date.now(),
     i,
     l = c.length
  ;
  for (i =0; i < l; i++) {
    c[i].classList.remove('sel');
  }
  console.log(`method_2 elapsed: ${Date.now() - n}`);

}

populate(100000,250);
method_1()
console.log(`Remaining selected after method_1: ${p.querySelectorAll('.sel').length} selected.`);
populate(100000,250);
method_2();
console.log(`Remaining selected after method_2: ${p.querySelectorAll('.sel').length} selected.`);
<div class="parent"></div>

My results are similar to:

populated total of 100000 having 400 selected.
method_1 elapsed: 1
Remaining selected after method_1: 0 selected.
populated total of 100000 having 400 selected.
method_2 elapsed: 84
Remaining selected after method_2: 0 selected.

VS Code: Quokka Extension Won’t Work After I Save My File

I’m new to VS Code. I recently downloaded a bunch of extensions including Quokka and Code Runner. Everything works great until I save my file to my desktop. After saving, the Quokka tab disappears from the lower panel and I get a message in the Output panel saying

[Running] node “c:UsersmynameOneDriveDesktopmyfile.js”
‘node’ is not recognized as an internal or external command, operable program or batch file.

This only happens after saving the file. What can I do to fix this? Please explain like I’m 5, I’m new to coding.

TLDR: Thanks to the extensions I downloaded (Quokka and Code Runner) I can see the results of my code right away. This works as expected until I save my work. After saving the file, I get an error about nodes in the Output panel. I’m not sure what to do.

Problem trying to sort images alphabetically by file name that have been loaded into a div via file reader

I am trying to load images into an html document using the file reader API, and then sorting them alphabetically. The code I have written loads the images into the div just fine, however it doesn’t sort the images in alphabetical order, instead it loads them into the document seemingly at random. I have tried using the following code to sort the images but to no avail: files.sort((a, b) => a.name.localeCompare(b.name)); Would appreciate any help that you can provide.

document.getElementById('loadImageButton').addEventListener('click', () => {
    document.getElementById('imageInput').click(); 
});

document.getElementById('imageInput').addEventListener('change', (event) => {
    let files = Array.from(event.target.files);
    const imageContainer = document.getElementById('imageContainer');
    imageContainer.innerHTML = '';
    
    console.log('Before Sort: ', files);
    
  // Sort files alphabetically by name
    files.sort((a, b) => a.name.localeCompare(b.name));
    
    
    console.log('After Sort: ', files);
    

    files.forEach(file => {
        if (file.type.startsWith('image/')) {
            const reader = new FileReader();

            reader.onload = (e) => {
                const img = document.createElement('img');
                img.src = e.target.result;
                img.alt = file.name; // Use file name as alt text
                imageContainer.appendChild(img);
            console.log('Image as appended: ', img);
            };

            reader.readAsDataURL(file);
        }
    });
});
#imageContainer {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    border: 1px solid #ccc;
    padding: 10px;
    min-height: 100px;
  }
  #imageContainer img {
    width: 150px;
    height: auto;
  }
<input type="file" id="imageInput" accept="image/*" multiple style="display: none;">
<button id="loadImageButton">Import Images</button>
<div id="imageContainer"></div>

Wrote the above code expecting the images to be loaded into the imageContainer div in alphabetical order, instead they seem to be loaded in a random order.

Thunderbird: opening emails in an external text editor

I would like to edit the source code of emails stored locally in Thunderbird (as .eml files) inside an external text editor (Notepad++).

(My current workflow of searching for the file manually is too cumbersome for regular usage.)

I spent a week unsuccessfully talking to an AI trying to code a javascript add-on, that opens the currently selected email in Notepad++.

If there is a simple solution, could you post a code snippet ?
Or else should I post the dysfunctional code for you to salvage ?

JavaScript deobfuscate

Can anyone help, I can’t deobfuscate the code, I can’t even understand what its meaning is. Some binary data is sent, how to decode it, please help.

!function(e,d){!function(){function n(){var n={};return function(n){window[d("b25lcnJvcg")]=function(c,b,u,t,Z){Array[d("aXNBcnJheQ")](n[162])||(n[162]=[]),n[162][n[162][d("bGVuZ3Ro")]]=[c,b,u,t,Z][d("am9pbg")](d("LCA"))}}(n),n}function c(n,c){c[d("Zm9yRWFjaA")]((function(c){var b=c[0],u=c[1];try{n[b]=u()}catch(c){n[b]=c&&c[d("bWVzc2FnZQ")]}}))}var b=window[d("cGVyZm9ybWFuY2U")]?function(){return window[d("cGVyZm9ybWFuY2U")][d("bm93")]()}:function(){return Date[d("bm93")]()},u=[22,function(){return e(d("dHlwZW9mIHdpbmRvdy5jaHJvbWU"))[d("dG9TdHJpbmc")]()}],t=[24,function(){return e(d("ZG9jdW1lbnQuaGlkZGVu"))[d("dG9TdHJpbmc")]()}],Z=[26,function(){return e(d("ISh0b3A9PXdpbmRvdyk"))[d("dG9TdHJpbmc")]()}],l=[35,function(){return e(d("dG9wLmZyYW1lcy5sZW5ndGg"))[d("dG9TdHJpbmc")]()}],m=[36,function(){return e(d("d2luZG93Lmhpc3RvcnkubGVuZ3Ro"))[d("dG9TdHJpbmc")]()}],G=[210,function(){return e(d("d2luZG93LmlubmVyV2lkdGg"))[d("dG9TdHJpbmc")]()}],a=[211,function(){return e(d("d2luZG93LmlubmVySGVpZ2h0"))[d("dG9TdHJpbmc")]()}],V=[60,function(){return e(d("c2NyZWVuLndpZHRo"))[d("dG9TdHJpbmc")]()}],o=[61,function(){return e(d("c2NyZWVuLmhlaWdodA"))[d("dG9TdHJpbmc")]()}],W=[126,function(){return e(d("bmF2aWdhdG9yLnVzZXJBZ2VudA"))[d("dG9TdHJpbmc")]()}],i=[138,function(){return e(d("bmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3k"))[d("dG9TdHJpbmc")]()}],r=[139,function(){return e(d("bmF2aWdhdG9yLm1heFRvdWNoUG9pbnRz"))[d("dG9TdHJpbmc")]()}],R=[146,function(){return e(d("bmF2aWdhdG9yLm9uTGluZQ"))[d("dG9TdHJpbmc")]()}],X=[73,function(){return e(d("d2luZG93Lm9wZW5lci5zY3JlZW5YfHx3aW5kb3cub3BlbmVyLnNjcmVlbkxlZnQ"))[d("dG9TdHJpbmc")]()}],y=[80,function(){return e(d("KG5ldyBEYXRlKS5nZXRUaW1lem9uZU9mZnNldCgp"))[d("dG9TdHJpbmc")]()}],Y=[160,function(){return e(d("bmF2aWdhdG9yLnBsdWdpbnM"))[d("dG9TdHJpbmc")]()}],f=[104,function(){return e(d("SFRNTENhbnZhc0VsZW1lbnQucHJvdG90eXBlLnRvRGF0YVVSTA"))[d("dG9TdHJpbmc")]()}],h=[125,function(){return e(d("d2luZG93Lk5vdGlmaWNhdGlvbi5wZXJtaXNzaW9u"))[d("dG9TdHJpbmc")]()}],p=[214,function(){try{return(void 0)[d("eA")],d("LQ")}catch(n){return n[d("bWVzc2FnZQ")]}}],F=[215,function(){var n;try{null[0]()}catch(c){n=c[d("c3RhY2s")][d("dG9TdHJpbmc")]()}return/:(d+:d+)/[d("ZXhlYw")](n)[1]}],v=[217,function(){var n=e(d("bmF2aWdhdG9yLnBsdWdpbnM")),c=e(d("UGx1Z2luQXJyYXk")),b=e(d("UGx1Z2lu"));return c[d("cHJvdG90eXBl")]===n[d("X19wcm90b19f")]&&(!n[d("bGVuZ3Ro")]||n[0][d("X19wcm90b19f")]===b[d("cHJvdG90eXBl")])?1:[c[d("cHJvdG90eXBl")],n[d("X19wcm90b19f")],n[d("bGVuZ3Ro")]?n[0][d("X19wcm90b19f")]:null]}],J=[218,function(){if(navigator[d("dXNlckFnZW50RGF0YQ")])return navigator[d("dXNlckFnZW50RGF0YQ")][d("YnJhbmRz")][d("ZmlsdGVy")]((function(n){return n[d("YnJhbmQ")]===d("Q2hyb21pdW0")}))[0][d("dmVyc2lvbg")]}],w=[124,function(n){var c=[d("YXNkamZsYXN1dG9wZmh2Y1pMbWNmbF8"),d("YXN5bmNTY3JpcHRJbmZv"),d("YXN5bmNFeGVjdXRvcg"),d("QlJPV1NFUlRPT0xT"),d("Y2hyb21lRHJpdmVy"),d("Y29tbWFuZExpbmU"),d("ZG9tQXV0b21hdGlvbg"),d("ZHJpdmVy"),d("ZHJpdmVyX2V2YWx1YXRl"),d("RUxFTV9DQUNIRQ"),d("ZXZhbHVhdGU"),d("ZXZhbHVhdGVfcmVzcG9uc2U"),d("ZXhlY3V0b3I"),d("RmlyZWJ1Zw"),d("Znhkcml2ZXI"),d("SURFX1JlY29yZGVy"),d("anVnZ2xlcg"),d("bGFzdFdhdGly"),d("bmlnaHRtYXJl"),d("cGhhbnRvbQ"),d("cGxheXdyaWdodA"),d("c2NyaXB0X2Zu"),d("c2NyaXB0X2Z1bmM"),d("c2NyaXB0X2Z1bmN0aW9u"),d("c2NyaXB0SW5mbw"),d("c2VsZW5pdW0"),d("dW53cmFwcGVk"),d("V0VCX1ZJRVc"),d("d2ViQ29udGVudHM"),d("d2ViZHJpdmVy"),d("eHdhbGs"),d("Y2RjXw")],b=[d("ZHJpdmVy"),d("bmlnaHRtYXJl"),d("cGhhbnRvbQ"),d("cGxheXdyaWdodA"),d("c2VsZW5pdW0"),d("d2ViZHJpdmVy")],u=[d("X0FycmF5"),d("X1Byb21pc2U"),d("X1N5bWJvbA")];!function(n,c){var b=c[124]={};function u(c){try{var u=c[d("YWRkRXZlbnRMaXN0ZW5lcg")];c[d("YWRkRXZlbnRMaXN0ZW5lcg")]=function(){var c=arguments[0];return n[d("Zm9yRWFjaA")]((function(n){new RegExp(n,d("aQ"))[d("dGVzdA")](c)&&(b[d("bGlzdGVuZXIg")+c]=1)})),u[d("YXBwbHk")](this,arguments)}}catch(n){b[c[d("dG9TdHJpbmc")]()+d("Lmxpc3RlbmVyIGVycm9yOiA")+(n&&n[d("bWVzc2FnZQ")])]=1}}u(window),u(document)}(c,n),function(n,c,b,u){var t=u[124];try{var Z=e(d("d2luZG93Lm5hdmlnYXRvci53ZWJkcml2ZXI"));void 0!==Z&&!1!==Z&&(t[d("d2ViZHJpdmVy")]=1),c[d("Zm9yRWFjaA")]((function(n){window[d("ZG9jdW1lbnQ")][d("ZG9jdW1lbnRFbGVtZW50")][d("Z2V0QXR0cmlidXRl")](n)&&(t[d("YXR0cnMg")+n]=1)})),l(window),l(document),l(navigator),m(),G()}catch(n){t[d("ZG9DaGVjayBlcnJvciA")+(n&&n[d("bWVzc2FnZQ")])]=1}function l(c){var u=Object[d("a2V5cw")](c);n[d("Zm9yRWFjaA")]((function(n){var b=new RegExp(n,d("aQ"));for(var Z in u)b[d("dGVzdA")](u[Z])&&(t[c+d("IA")+u[Z]]=1)})),d("")[d("ZW5kc1dpdGg")]&&u[d("Zm9yRWFjaA")]((function(n){b[d("Zm9yRWFjaA")]((function(b){n[d("ZW5kc1dpdGg")](b)&&(t[c+d("IA")+b]=1)}))}))}function m(){var n=d("Y2FjaGVf");for(var c in window[d("ZG9jdW1lbnQ")])try{window[d("ZG9jdW1lbnQ")][c][n]&&(t[n+d("IA")+(c||d("X18"))]=1)}catch(n){}}function G(){var n=d("U2VxdWVudHVt"),c=e(d("d2luZG93LmV4dGVybmFs"));c&&c[d("dG9TdHJpbmc")]&&-1<c[d("dG9TdHJpbmc")]()[d("aW5kZXhPZg")](n)&&(t[n]=1)}}(c,b,u,n)}];function Q(n){return n[d("ZmlsdGVy")]((function(n){return n}))[d("bGVuZ3Ro")]}var H=[118,function(n){n[118]=d("dw");var c=[];c[d("dGhyZXNob2xk")]=[0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1];var b=new IntersectionObserver((function(c){n[118]=100*c[0][d("aW50ZXJzZWN0aW9uUmF0aW8")],b[d("dW5vYnNlcnZl")](document[d("ZG9jdW1lbnRFbGVtZW50")]),b[d("ZGlzY29ubmVjdA")]()}),c);b[d("b2JzZXJ2ZQ")](document[d("ZG9jdW1lbnRFbGVtZW50")])}],g=[117,function(n){var c=e(d("bmF2aWdhdG9yLmdldEJhdHRlcnkoKQ"));function b(c){n[117]=[Math[d("cm91bmQ")](100*c[d("bGV2ZWw")]),c[d("Y2hhcmdpbmc")]]}function u(c){n[117]=c[d("dG9TdHJpbmc")]()||d("ZXJyb3I")}c[d("Y2F0Y2g")](u)[d("dGhlbg")](b),c[d("Y2F0Y2g")](u)[d("dGhlbg")](b),c[d("Y2F0Y2g")](u)[d("dGhlbg")](b)}],N=[212,function(){var n=document[d("Y3JlYXRlRWxlbWVudA")](d("Y2FudmFz")),c=n[d("Z2V0Q29udGV4dA")](d("d2ViZ2wy"))||n[d("Z2V0Q29udGV4dA")](d("d2ViZ2w")),b=c[d("Z2V0RXh0ZW5zaW9u")](d("V0VCR0xfZGVidWdfcmVuZGVyZXJfaW5mbw"));return c[d("Z2V0UGFyYW1ldGVy")](b[d("VU5NQVNLRURfVkVORE9SX1dFQkdM")])}];var I=[213,function(){var n=[];function c(c,b){b[d("Zm9yRWFjaA")]((function(b){try{var u=e(c+d("Lg")+b+d("LnRvU3RyaW5nKCk")),t=b[d("c3BsaXQ")](d("Lg"))[d("cG9w")]();u[d("cmVwbGFjZQ")](/[srn]/g,d(""))[d("cmVwbGFjZQ")](t,d(""))!==d("ZnVuY3Rpb24oKXtbbmF0aXZlY29kZV19")&&n[d("cHVzaA")]([b,u[d("dG9TdHJpbmc")]()])}catch(c){n[d("cHVzaA")]([b,c[d("bWVzc2FnZQ")]])}}))}return c(d("d2luZG93"),[d("b3Blbg"),d("YWxlcnQ"),d("SFRNTENhbnZhc0VsZW1lbnQucHJvdG90eXBlLnRvRGF0YVVSTA"),d("ZXZhbA"),d("WE1MSHR0cFJlcXVlc3Q")]),c(d("ZG9jdW1lbnQ"),[d("aGFzRm9jdXM"),d("Y3JlYXRlRWxlbWVudA")]),c(d("bG9jYWxTdG9yYWdl"),[d("Z2V0SXRlbQ"),d("c2V0SXRlbQ"),d("cmVtb3ZlSXRlbQ")]),navigator[d("dXNlckFnZW50RGF0YQ")]&&c(d("bmF2aWdhdG9y"),[d("dXNlckFnZW50RGF0YS5nZXRIaWdoRW50cm9weVZhbHVlcw")]),[d("c2NyZWVu"),d("bmF2aWdhdG9y"),d("d2luZG93"),d("aGlzdG9yeQ"),[d("bmF2aWdhdG9yLnBsdWdpbnM"),d("UGx1Z2luQXJyYXk")],[d("bG9jYWxTdG9yYWdl"),d("U3RvcmFnZQ")],[d("c2Vzc2lvblN0b3JhZ2U"),d("U3RvcmFnZQ")]][d("Zm9yRWFjaA")]((function(c){var b=typeof c===d("c3RyaW5n")?[c,c[0][d("dG9VcHBlckNhc2U")]()+c[d("c2xpY2U")](1)]:c;try{var u=e(b[0]+d("LnRvU3RyaW5nKCk"));u!==d("W29iamVjdCA")+b[1]+d("XQ")&&n[d("cHVzaA")]([b[0],u[d("dG9TdHJpbmc")]()])}catch(c){n[d("cHVzaA")]([b[0],c[d("bWVzc2FnZQ")]])}})),window[d("UlRDUGVlckNvbm5lY3Rpb24")]||window[d("d2Via2l0UlRDUGVlckNvbm5lY3Rpb24")]||window[d("bW96UlRDUGVlckNvbm5lY3Rpb24")]||n[d("cHVzaA")]([d("UlRDUGVlckNvbm5lY3Rpb24"),1]),n[d("cmVkdWNl")]((function(n,c){return n[c[0]]=c[1],n}),{})}],U=null;function k(){return U||((U=document[d("Y3JlYXRlRWxlbWVudA")](d("aWZyYW1l")))[d("c3JjZG9j")]=d("YmxhbmsgcGFnZQ"),U[d("c3R5bGU")][d("ZGlzcGxheQ")]=d("bm9uZQ"),document[d("Ym9keQ")][d("YXBwZW5kQ2hpbGQ")](U)),U}var A=[216,function(n){window[d("YWRkRXZlbnRMaXN0ZW5lcg")](d("bG9hZA"),(function(){var c=k();n[216]=c[d("Y29udGVudFdpbmRvdw")]!==window}))}];function B(n){return d("QGJhYmVsL2hlbHBlcnMgLSB0eXBlb2Y"),B=d("ZnVuY3Rpb24")==typeof Symbol&&d("c3ltYm9s")==typeof Symbol[d("aXRlcmF0b3I")]?function(n){return typeof n}:function(n){return n&&d("ZnVuY3Rpb24")==typeof Symbol&&n.constructor===Symbol&&n!==Symbol[d("cHJvdG90eXBl")]?d("c3ltYm9s"):typeof n},B(n)}var T=+new Date;function z(n,c,b,u){var t={};for(var Z in n)n[d("aGFzT3duUHJvcGVydHk")](Z)&&(t[Z]=n[Z]);t[109]=T,o(1,(function(){return+new Date-T})),o(48,(function(){return window[d("aW5uZXJXaWR0aA")]})),o(49,(function(){return window[d("aW5uZXJIZWlnaHQ")]})),o(35,(function(){return window[d("dG9w")][d("ZnJhbWVz")][d("bGVuZ3Ro")]-(U?1:0)}));var l,m,G=JSON[d("c3RyaW5naWZ5")](t,(function(n,c){return B(c)!==d("b2JqZWN0")&&null!==c?c+d(""):n!==d("")?JSON[d("c3RyaW5naWZ5")](c):c})),a=b?G:(l=G,m=d("Z0hSZmR2OG1iZQ"),new Function(d("YQ"),d("Yg"),d("dmFyIHMgPSB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoYSkpOw")+d("dmFyIGFiID0gbmV3IEFycmF5QnVmZmVyKHMubGVuZ3RoKTs")+d("dmFyIGMgPSBuZXcgVWludDhBcnJheShhYik7")+d("dmFyIGwgPSBiLmxlbmd0aDs")+d("Zm9yICh2YXIgaSA9IDA7IGkgPCBzLmxlbmd0aDsgaSsrKWNbaV0gPSBzLmNoYXJDb2RlQXQoaSkgXiBiLmNoYXJDb2RlQXQoaSAlIGwpOw")+d("cmV0dXJuIGFiOw"))(l,m));if(d("ZmV0Y2g")in window)fetch(c,{method:"POST",headers:{"Accept-Language":"*","Content-Type":"application/octet-stream"},body:a})[d("dGhlbg")]((function(n){return 200===n[d("c3RhdHVz")]?Promise[d("YWxs")]([n,n[d("dGV4dA")]()]):Promise[d("cmVqZWN0")](n)}))[d("dGhlbg")]((function(n){var c=n[0],b=n[1];b&&u(b,c[d("aGVhZGVycw")])}));else{var V=new XMLHttpRequest;V[d("b3Blbg")](d("UE9TVA"),c,!0),V[d("c2V0UmVxdWVzdEhlYWRlcg")](d("QWNjZXB0LUxhbmd1YWdl"),d("Kg")),V[d("c2V0UmVxdWVzdEhlYWRlcg")](d("Q29udGVudC1UeXBl"),d("YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFt"));try{V[d("d2l0aENyZWRlbnRpYWxz")]=!0}catch(n){}V[d("b25sb2Fk")]=function(){if(200===V[d("c3RhdHVz")]&&V[d("cmVzcG9uc2VUZXh0")]){var n={get:function(n){return V[d("Z2V0UmVzcG9uc2VIZWFkZXI")](n)}};u(V[d("cmVzcG9uc2VUZXh0")],n)}},V[d("c2VuZA")](a)}function o(n,c){try{t[n]=c()}catch(c){t[n]=c[d("bWVzc2FnZQ")]}}}var s=!1;function S(n,c){s||(s=!0,function(n,c,u,t){if(window[d("aW5uZXJXaWR0aA")]>0)z(n,c,u,t);else var Z=b(),l=setInterval((function(){(window[d("aW5uZXJXaWR0aA")]>0||b()-Z>1e3)&&(clearInterval(l),z(n,c,u,t))}),10)}(n,d(config[d("ZFhKcw")])+(c||d("")),config[d("WkdSbA")],(function(n){return n&&window[d("bG9jYXRpb24")][d("cmVwbGFjZQ")](n)})))}!function(b,U){var k=n();(function(n,c){c[d("Zm9yRWFjaA")]((function(c){var b=c[0],u=c[1];try{u(n)}catch(c){n[b]=c&&c[d("bWVzc2FnZQ")]||d("ZXJyb3I")}}))})(k,[(U=U||{})[d("ZWRh")]||w,H,g,A]),c(k,[l,G,a,Z,u,X,m,h,Y,f,t,i,r,R,V,o,y,W,I,p,F,v,J]),-1!==navigator[d("cGxhdGZvcm0")][d("aW5kZXhPZg")](d("V2lu"))&&c(k,[N]);try{!function(n){var c=Q([e(d("IndlYmtpdFBlcnNpc3RlbnRTdG9yYWdlIiBpbiBuYXZpZ2F0b3I")),e(d("IndlYmtpdFRlbXBvcmFyeVN0b3JhZ2UiIGluIG5hdmlnYXRvcg")),e(d("MCA9PT0gbmF2aWdhdG9yLnZlbmRvci5pbmRleE9mKCJHb29nbGUiKQ")),e(d("IndlYmtpdFJlc29sdmVMb2NhbEZpbGVTeXN0ZW1VUkwiIGluIHdpbmRvdw")),e(d("IkJhdHRlcnlNYW5hZ2VyIiBpbiB3aW5kb3c")),e(d("IndlYmtpdE1lZGlhU3RyZWFtIiBpbiB3aW5kb3c")),e(d("IndlYmtpdFNwZWVjaEdyYW1tYXIiIGluIHdpbmRvdw"))])>=5;n[172]=+c;var b=c&&Q([e(d("Im9ub3JpZW50YXRpb25jaGFuZ2UiIGluIHdpbmRvdw")),e(d("Im9yaWVudGF0aW9uIiBpbiB3aW5kb3c")),e(d("IlNoYXJlZFdvcmtlciIgaW4gd2luZG93"))])>=2;n[170]=+b}(k)}catch(n){}setTimeout((function(){return b(k)}),10)}((function(n){!function(n){n[2]=d(config[d("Wlc1a2NHOXBiblE9")]),n[3]=d(config[d("WTJsaw")]),n[4]=d(config[d("WVdsaw")]),n[5]=d(config[d("Y21WbVpYSmxjZz09")]),n[6]=null!==config[d("ZEdsdFpWUnZRMnhwWTJzPQ")]?d(config[d("ZEdsdFpWUnZRMnhwWTJzPQ")]):null,n[7]=d(config[d("YVc1MFpYSnRaV1JwWVhSbFVHRm5aVXB6Y0U1aGJXVT0")]),n[198]=config[d("YVhORGJHbGphMUpsWTI5MlpYSmxaRVp5YjIxSlkyOXU")],n[219]=d(config[d("ZEE9PQ")])}(n),S(n)}))}()}(eval(atob("ZXZhbA")),eval(atob("YXRvYg")));

I tried to sniff the traffic, there is binary data, deobfuscation tools do not help.

Hook SSL_write on child process via Frida

With Frida Javascript I wait for fork

Interceptor.attach(Module.findExportByName("libc.so", "fork"), {
    onEnter: function (args) {
        try {
            // Get the current module calling fork
            const caller = Process.getModuleByAddress(this.returnAddress);
            console.log("[*] fork called by:", caller.name, "at", this.returnAddress);
            console.log("[*] Path to module:", caller.path);
        } catch (e) {
            console.log("[!] Error resolving module for return address:", this.returnAddress, e);
        }
    },
    onLeave: function (retval) {
        console.log("[*] fork returned PID:", retval.toInt32());
        setTimeout(inner, 100);

    }
});

Now into inner function I want to hook SSL_write function.

The problem is that SSL_write function exist in parent and in the child process, and when I try to hook I hook only SSL_write into child process.

What can I do?

conditional regex for VScode syntax highlighting not working

I’ve created a toy scripting language and managed to configure basic syntax highlighting for the very simple things like keywords, comments and strings, But when I tried more complex logic it didn’t work.

I want it so that the identifier after the ‘func’ keyword will be a different color than normal identifiers, Here’s my code .json file:

{
    "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
    "name": "samir_script",
    "patterns": [
        {
            "include": "#keywords"
        },
        {
            "include": "#strings"
        },
        {
            "include": "#comments"
        },
        {
            "include": "#digits"
        },
        {
            "include": "#opperators"
        },
        {
            "include": "#reserved_words"
        },
        {
            "include": "#func_declre"
        },
        {
            "include": "#identifiers"
        }

        

    ],
    "repository": {
        "keywords": {
            "patterns": [{
                "name": "keyword.control.smr",
                "match": "\b(if|while|for|return|func|match|elif|else|case|var|do|lambda|then|with|break|continue|in|print|println|import|as)\b"
            }]
        },
        "strings": {
            "name": "string.quoted.double.smr",
            "begin": """,
            "end": """,
            "patterns": [
                {
                    "name": "constant.character.escape.smr",
                    "match": "\\."
                }
            ]
        },
        "comments":{
            "name": "comment.line",
            "begin": "#",
            "end": "n"
        },
        "digits":{
            "name":"constant.numeric",
            "match": "\b(\d+)\b"
        },
        "opperators":{
            "name": "keyword.operator",
            "match": "\b(\+|-|=|\*|/==)\b"
        },
        "identifiers":{
            "name": "support.variable",
            "match": "\b(\w+)\b"
        },
        "reserved_words":{
                "name": "constant.language",
                "match": "\b(true|false|nil)\b"
        },
         // This doesn't do anything:
        "func_declre":{
            "name": "comment.block", // Chose comment color to make debugging this easier.
            "begin": "\b(func)(\s+)(\w+)\b", //'func sum(x, y)' sum would be different.
            "beginCaptures": {
                "1": {
                "name": "comment.block"
                },
                "2": {
                "name": "comment.block"
                }
            },
            "end": "\b(\s+)\b" // Ends after a white space.
        }
    },
    "scopeName": "source.smr"
}