Javascript ctx.putImageData at an angle without saying to

I am writing a program to generate some orbital images. I decided to use js because I have a fair amount of experience with it and its fast to write for prototypes. The issue is that when I go to use ctx.putImageData it is rotated by a -45° angle and the image is stretched.
This is the actually important code:

  genImg(){
    let index = 0;
    for(let y = 0; y <= 400; y++){
      for(let x = 0; x <= 400; x++){
        let lx = (x - 200)*this.step;
        let ly = (200 - y)*this.step;
        this.points.push(this.value(Math.sqrt(Math.pow(lx, 2) + Math.pow(ly, 2)), this.t, Math.atan2(lx,ly))[0]);
      }
    }
    let sclFct = 1000/Math.max(...this.points);
    for(let i = 0; i<= 160000; i++){
      let val = Math.round(this.points[i]*sclFct);
      this.imgDataArr[index] = cmap[val*4]; // R value        
      this.imgDataArr[index + 1] = cmap[val*4 + 1]; // G value
      this.imgDataArr[index + 2] = cmap[val*4 + 2]; // B value
      this.imgDataArr[index + 3] = 255; // A value
      index += 4; 
    }
    let imgData = new ImageData(this.imgDataArr, 400, 400);
    ctx.putImageData(imgData, 0, 0);
  }

The Full code is here. Just off the bat I should mention this is all written in a class. The html is just a canvas element in the <main></main> area that is 400px by 400px. The CSS is just to center everything and give the canvas a border. The function this.value(r,t,p) takes the values r(radius), t(theta) and p(phi). Theta is a constant and radius and phi are calculated from (x,y) cords (see line 7 of the prior code).
enter image description here
In the image you can see where there is the diagonal. The black should be in the center with the other colors radiating out. So far I have tried a 45° rotation to the atan2 function, messing with the css and trying to add a rotation, and rotating the ctx element in code (i.e. using ctx.rotate(Math.PI/4)). This all is very strange to me because I have other projects where I have used the same method without issue. Any ideas would be wonderfull!

Publish to @google-cloud/pubsub topic from Firebase sdk is failing

With all nodejs packages updated, trying to publish message to topic ends on timeout with error:

GoogleError: Total timeout of API google.pubsub.v1.Publisher exceeded. Error: Getting metadata from plugin failed with error: fetchImpl is not a function.

Trying to publish from cloud function but fails as well from cli.

Example using storage trigger to reproduce (but any attmept to publish ends the same):

import {onObjectFinalized, StorageEvent} from 'firebase-functions/v2/storage';
import {logger} from 'firebase-functions/v2';
import {PubSub} from '@google-cloud/pubsub';

const pubSub = new PubSub();

export default onObjectFinalized({region: 'europe-west3'}, async (event: StorageEvent) => {
    logger.info('--- Storage Upload triggered', {data: event.data.name});

    const message = {uploadId: 'uploadId'};
    const topic = 'projects/---/topics/uploads';

    const pubRes = await pubSub.topic(topic).publishMessage({json: message});

    return pubRes;
});
  "dependencies": {
    "@google-cloud/pubsub": "^5.2.0",
    "firebase-admin": "^13.4.0",
    "firebase-functions": "^6.4.0",
    ...
  },

Never able to prevent the add to cart form submission

Here’s what I wrote to prevent add to cart form submission on product detail page, I intended to show a custom message or alert if some custom fields are empty, the strange thing is no matter what I tried, it still submits the form when clicking add to cart button, i don’t know what is wrong:

document.addEventListener('DOMContentLoaded', function () {
    const productForm = document.querySelector('form[action^="/cart/add"]');

    if (productForm) {
      productForm.addEventListener('submit', function (event) {
        event.preventDefault(); // Prevent form submission
        alert('Add to Cart submission prevented.');
      });
    }
  });

I use Danw. Can anyone help me? thanks

Nuxt 4: import aliases don’t work in test files

I have a vitest/Nuxt3 test setup that works fine and I’m trying to port it to Nuxt4 and I have import aliases issues.

The same imports that work from files in /app fail in my test file, which is located in /test/unit/.

/app/
    classes/
        Project.ts

/shared/
    types/
        project/
            project.ts

/test/
    unit/
        project.test.ts
        project.json

The types file is nested to avoid auto-imports.

In Project.ts, I can do

import type { Project } from '#shared/types/project/project'

This doesn’t work in project.test.ts.

Also, in project.test.ts, I can’t import my Project class. This fails.

import WorkProject from '@/classes/Project'

I have to use manual paths:

import type { Project } from '../../shared/types/project/project'
import WorkProject from '../../classes/Project'

My guess is that since Nuxt 4, the tsconfig is split in multiple files, each with its scope (app, node, server, shared) and there is none for the test folder.

Is that it? What should I do about it?

I could live with ../../paths but it sucks not to be able to write test files consistently with tested code.

How to keep .nuxt/imports.d.ts synchronized?

The magic in Nuxt auto-imports relies on .nuxt/imports.d.ts, which is automatically generated.

While trying to understand the auto-import feature, I’ve been moving a types file e.g. from /shared/types to /shared/types/subdir and back, to see how it impacts lint errors, etc. and I had strange results because .nuxt/imports.d.ts did not reflect those changes.

npm run dev does refresh .nuxt/imports.d.ts but it has to be run everytime those files change.

Is there a command that should be run so that auto-imports directories are watched to keep .nuxt/imports.d.ts synced?

Is this expected behaviour, acceptable because those type files are not meant to change so often?

(Using Nuxt 4, if that matters.)

Displaying Javascript array as HTML list with multiple elements within the same list item [closed]

I have this code

function pojeden() {

    const arrayClone = array.slice()

    let arrayLength = array.length

    let newArray = []

    for (let i = 0; i < 30; i++) {
        let arr = arrayClone[Math.floor(Math.random() * arrayLength)]

        arrayLength--

        let index = arrayClone.indexOf(arr)

        arrayClone.splice(index, 1)

        newArray.push(arr)
     }

const spacja = `${newArray.map(newArray =>
            `<li>${newArray}</li>`).join('')}`;

document.getElementById("miesiac").innerHTML = spacja
}

It creates a HTML list with 30 unique, non-repeating list items taken from the elements of an array.

That’s all good, but what if I want a list with the same amount of list items but TWICE or THRICE the elements from the array?

I do NOT mean a list with 60 or 90 list items. I mean a list with 30 items but each bullet has 2 or 3 array elements each instead of only 1.

Basically, the code above creates a list that looks like this:

  • banana
  • apple
  • orange

When I want a list that would look like this:

  • banana, apple
  • orange, berry
  • kiwi, peach

Or even:

  • banana, apple, orange
  • berry, kiwi, peach
  • pear, grape, pineapple

Same amount of list items (bullets) but under each there is more than one element (listed next to each other).

How to achieve this?

I assume array.join() and forEach() wouldn’t work with this so instead I have tried playing around with loops, appendChild and using modulo for it but I am very much a beginner so I didn’t manage to utilize this for my mini project and eventually gave up until I decided to pick it up again. I suppose this method would most likely work but because I am too inexperienced I couldn’t make it work for myself

Z-index and modal backdrop [closed]

I created a modal using the <dialog> tag. It works fine, but I also created a notification toasts with a higher z-index. Here is a code sample:

.notification {
  z-index: 1090;
  position: absolute;
  top: 0;
  right: 0;
  background-color: #afa;
}

.modal {
  z-index: 1055;
  background-color: #aaf;
  height: fit-content;
}

.modal::backdrop {
  background-color: #0000008f;
  backdrop-filter: blur(0.375rem);
}
<div class="notification">
  This notification should be on top of the modal backdrop.
</div>

<dialog id="modal" class="modal">
  <div class="modal-content">
    <div>Modal Content</div>
  </div>
</dialog>

I would like the notification to be over the modal backdrop. But I understood that even with a z-index of 9999, the notification will not be over the backdrop. I already read these answers :

I don’t want to implement my own backdrop + modal layering. Is there another clean solution?

Here is a JSFidle: https://jsfiddle.net/uhw4mj85/2/

Implementation of an actual asynchronous function in javascript? [closed]

I’m relatively new to javascript, and I’ve just now started deepening my knowledge of how javascript handles asynchronous tasks.

However, I feel like I miss something, because if I think of all the asynchronous things (callbacks, promises, async/await), none of them actually stop the execution of code to delegate an asynchronous task to some other agent.

I’ll be a bit more specific taking the example of the fs library. At which point does the code actually stops and waits for the file to be loaded from the disk? and how? Furthermore, does that operation require a new thread?

Displaying Javascript array as HTML list with multiple elements within the same list item

I have this code

function pojeden() {

    const arrayClone = array.slice()

    let arrayLength = array.length

    let newArray = []

    for (let i = 0; i < 30; i++) {
        let arr = arrayClone[Math.floor(Math.random() * arrayLength)]

        arrayLength--

        let index = arrayClone.indexOf(arr)

        arrayClone.splice(index, 1)

        newArray.push(arr)
     }

const spacja = `${newArray.map(newArray =>
            `<li>${newArray}</li>`).join('')}`;

document.getElementById("miesiac").innerHTML = spacja
}

It creates a HTML list with 30 unique, non-repeating list items taken from the elements of an array.

That’s all good, but what if I want a list with the same amount of list items but TWICE or THRICE the elements from the array?

I do NOT mean a list with 60 or 90 list items. I mean a list with 30 items but each bullet has 2 or 3 array elements each instead of only 1.

Basically, the code above creates a list that looks like this:

  • banana
  • apple
  • orange

When I want a list that would look like this:

  • banana, apple
  • orange, berry
  • kiwi, peach

Or even:

  • banana, apple, orange
  • berry, kiwi, peach
  • pear, grape, pineapple

Same amount of list items (bullets) but under each there is more than one element (listed next to each other).

How to achieve this?

I assume array.join() and forEach() wouldn’t work with this so instead I have tried playing around with loops, appendChild and using modulo for it but I am very much a beginner so I didn’t manage to utilize this for my mini project and eventually gave up until I decided to pick it up again. I suppose this method would most likely work but because I am too inexperienced I couldn’t make it work for myself

Z-index and modal backdrop

I created a modal using the <dialog> tag. It works fine, but I also created a notification toasts with a higher z-index. Here is a code sample:

<div class="notification">
  This notification should be on top of the modal backdrop.
</div>

<dialog id="modal" class="modal">
  <div class="modal-content">
    <div>Modal Content</div>
  </div>
</dialog>

Here is the associated CSS:

.notification {  
  z-index: 1090;  
  position: absolute;
  top: 0;
  right: 0;
  background-color: #afa;
}

.modal {
  z-index: 1055;  
  background-color: #aaf;
  height: fit-content;  
}

.modal::backdrop {
  background-color: #0000008f;
  backdrop-filter: blur(0.375rem);
}

I would like the notification to be over the modal backdrop. But I understood that even with a z-index of 9999, the notification will not be over the backdrop. I already read these answers :

I don’t want to implement my own backdrop + modal layering. Is there another clean solution?

Here is a JSFidle: https://jsfiddle.net/uhw4mj85/2/

How to restore a nested object type after type narrowing?

I am using web workers for my heavy computations. Passing data to the worker is implicitly done by serializing the objects, so their types are narrowed down to simple objects, meaning that an object Foo defined like this:

class Foo {
  name: string
  child: Bar

  constructor(name: string, child: Bar) {
    this.name = name
    this.child = child
  }
}

class Bar {
  name: string

  constructor(name: string) {
    this.name = name
  }

  sayHello() {
    console.log("Hello!")
  }
}

is narrowed down to an object like this:

{ name: "foo", child: { name: "bar" } }

So to use the method sayHello, the actual type has to be restored in the worker, e.g. by using the constructor:

const newFoo = new Foo(other.name, new Bar(other.child.name)

Which, as you can see, can become very verbose and a likely source of errors.

You could also define copy constructors in the actual constructors or static methods like:

class Foo {
  // ...
  static from(other: Foo) {
    const child = Bar.from(other.child)
    return new Foo(other.name, child)
  }
}

class Bar {
  // ...
  static from(other: Bar) {
    return new Bar(other.name)
  }
}

This might be possible, but is also very verbose and prone to errors.

Therefore I have created a copy function, that creates a new class instance from the prototype and copies the properties:

function copy<T>(obj: any, prototype: T): T {
    if (!obj) return obj

    const clone = Object.create(prototype)
    Reflect.ownKeys(obj).forEach((key) => {
        const desc = Object.getOwnPropertyDescriptor(obj as T, key)
        if (desc) {
            Object.defineProperty(clone, key, desc)
        }
    })
    return clone as T
}

This works well for flat classes, but nested types are still narrowed to plain objects, meaning the function sayHello in Bar is missing, when calling:

const fooFromObj = copy({ name: "foo", child: { name: "bar" } }, Foo.prototype)

because this creates this object:

Foo { name: "foo", child: { name: "bar" } }
// instead of:
Foo { name: "foo", child: Bar { name: "bar" } }

Can I get the type of a nested class from the parent type to recursively restore the nested types?

Does GSAP Can be adapted for Elementor?

I’m working on a WordPress site using Elementor and I want to add some advanced animations using GSAP. I’ve successfully loaded the GSAP library, but I’m running into issues with responsive behavior and performance.

Current setup:

  • WordPress 6.3
  • Elementor Pro 3.16
  • GSAP 3.12 loaded via CDN

Code I’m using:

gsap.registerPlugin(ScrollTrigger);

gsap.from(".elementor-widget-heading h2", {
  duration: 1,
  y: 50,
  opacity: 0,
  scrollTrigger: ".elementor-widget-heading"
});

Issues I’m facing:

  1. Animations don’t work properly on mobile devices
  2. Sometimes animations trigger multiple times when scrolling back up
  3. Performance seems sluggish on older devices

I’ve seen some impressive implementations on sites like https://laplumerp.com/ or https://studiojae.fr/ where GSAP animations work flawlessly with Elementor. Their animations are smooth and responsive across all devices.

Questions:

  • What’s the best way to ensure GSAP animations are responsive in Elementor?
  • How can I optimize performance for mobile devices?
  • Should I use Elementor’s custom CSS or add scripts in functions.php?
  • Is Any Plugin Can make it easier.

Any help or code examples would be greatly appreciated!

Tags: javascript, wordpress, elementor, gsap, css-animations

I attempted to implement GSAP ScrollTrigger animations on Elementor heading widgets. I loaded GSAP via CDN and added the animation code in Elementor’s custom CSS section.

I expected smooth fade-in animations from bottom to top when elements come into viewport, working consistently across all devices and screen sizes.

LMStudio not connecting to API react

I have built an application in React and suddenly it just won’t connect to LMStudio, no reaction in the logs of the app. Curl requests for models do reply, CORS is turned on and never gave me any issues.

Here is my code:

 const llmModelName = "lmstudio-community/gpt-oss-20b-MXFP4.gguf/"
  const [chatHistory, setChatHistory] = useState([]);
  const [chatInput, setChatInput] = useState('');
  const [isChatting, setIsChatting] = useState(false);

  const handleFetch = () => {
    fetch('http://127.0.0.1:1234/v1/chat/completions')
      .then(response => response.json())
      .then(data => {
        console.log(data);
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  };

messages.push({
  "role": "user",
  "content": userMessageContent
});

try {
  setStatus("Sending to LLM...");
  const response = await fetch(lmStudioApiUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      model: llmModelName,
      messages: messages,
      temperature: 0.7,
    }),
  });
  if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
  const data = await response.json();
  const llmSummary = data.choices[0].message.content;

  setReport(llmSummary);
  setChatHistory([
    ...messages,
    { "role": "assistant", "content": llmSummary }
  ]);

} catch (error) {
  console.error("Failed to call local LLM API:", error);
  setReport(`Failed to get summary from local LLM. Error: ${error.message}`);
} finally {
  setLoading(false);
  setStatus("Final report ready. You can now chat below.");
  setIsChatting(true);
}
  };

An error occured while loading javascript modules, you may find more information in the devtools console (Odoo)

I overrided the default js method onDownloadButtonClicked (odoo/addons/web/static/src/views/pivot/pivot_render.js) for downloading xlsx files

(it`s my method) statis/src/js/views/my_render.js

/** @odoo-module **/

import { patch } from "@web/core/utils/patch";
import { PivotRenderer } from "@web/views/pivot/pivot_renderer";
import { _t } from "@web/core/l10n/translation";
import { download } from "@web/core/network/download";

patch(PivotRenderer.prototype, {
    onDownloadButtonClicked() {
        if (this.model.getTableWidth() > 16384) {
            throw new Error(
                _t(
                    "For Excel compatibility, data cannot be exported if there are more than 16384 columns.nnTip: try to flip axis, filter further or reduce the number of measures."
                )
            );
        }
        const table = this.model.exportData();
        download({
            url: "/web/pivot/export_xlsx1",  
            data: { data: JSON.stringify(table) },
        });
    },
});

I need this to add a string field to a report generated from a pivot table (it is not possible to add a string field to it directly in views).
Therefore, I wrote my own http.route(export_xlsx1) (copied from the original odoo/addons/web/controllers/pivot.py and modified).

controllers/my_pivot.py

from collections import deque
import io
import json

from werkzeug.datastructures import FileStorage

from odoo import http, _
from odoo.http import content_disposition, request
from odoo.tools import osutil
from odoo.tools.misc import xlsxwriter

from my_import import get_all_picking_notes

class TableExporter(http.Controller):

    @http.route('/web/pivot/export_xlsx1', type='http', auth="user", readonly=True)
    def export_xlsx(self, data, **kw):
        jdata = json.load(data) if isinstance(data, FileStorage) else json.loads(data)
        output = io.BytesIO()
        workbook = xlsxwriter.Workbook(output, {'in_memory': True})
        worksheet = workbook.add_worksheet(jdata['title'])

        header_bold = workbook.add_format({'bold': True, 'pattern': 1, 'bg_color': '#AAAAAA'})
        header_plain = workbook.add_format({'pattern': 1, 'bg_color': '#AAAAAA'})
        bold = workbook.add_format({'bold': True})

        measure_count = jdata['measure_count']
        origin_count = jdata['origin_count']

        # Step 1: writing col group headers
        col_group_headers = jdata['col_group_headers']

        # x,y: current coordinates
        # carry: queue containing cell information when a cell has a >= 2 height
        #      and the drawing code needs to add empty cells below
        x, y, carry = 1, 0, deque()
        for i, header_row in enumerate(col_group_headers):
            worksheet.write(i, 0, '', header_plain)
            for header in header_row:
                while (carry and carry[0]['x'] == x):
                    cell = carry.popleft()
                    for j in range(measure_count * (2 * origin_count - 1)):
                        worksheet.write(y, x+j, '', header_plain)
                    if cell['height'] > 1:
                        carry.append({'x': x, 'height': cell['height'] - 1})
                    x = x + measure_count * (2 * origin_count - 1)
                for j in range(header['width']):
                    worksheet.write(y, x + j, header['title'] if j == 0 else '', header_plain)
                if header['height'] > 1:
                    carry.append({'x': x, 'height': header['height'] - 1})
                x = x + header['width']
            while (carry and carry[0]['x'] == x):
                cell = carry.popleft()
                for j in range(measure_count * (2 * origin_count - 1)):
                    worksheet.write(y, x+j, '', header_plain)
                if cell['height'] > 1:
                    carry.append({'x': x, 'height': cell['height'] - 1})
                x = x + measure_count * (2 * origin_count - 1)
            x, y = 1, y + 1

        # Step 2: writing measure headers
        measure_headers = jdata['measure_headers']
        measure_headers.append({'title': 'My header','width': 1, 'height': 1, 'is_bold': True}) <--custom

        if measure_headers:
            worksheet.write(y, 0, '', header_plain)
            for measure in measure_headers:
                style = header_bold if measure['is_bold'] else header_plain
                worksheet.write(y, x, measure['title'], style)
                for i in range(1, 2 * origin_count - 1):
                    worksheet.write(y, x+i, '', header_plain)
                x = x + (2 * origin_count - 1)
            x, y = 1, y + 1
            # set minimum width of cells to 16 which is around 88px
            worksheet.set_column(0, len(measure_headers), 16)

        # Step 3: writing origin headers
        origin_headers = jdata['origin_headers']

        if origin_headers:
            worksheet.write(y, 0, '', header_plain)
            for origin in origin_headers:
                style = header_bold if origin['is_bold'] else header_plain
                worksheet.write(y, x, origin['title'], style)
                x = x + 1
            y = y + 1

        notes = get_all_picking_notes(request.env) <--custom

        # Step 4: writing data
        x = 0
        for row in jdata['rows']:
            worksheet.write(y, x, f"{row['indent'] * '     '}{row['title']}", header_plain)
            if row['title'] in notes:    <-- custom 
                row['values'].append({'is_bold': True, 'value': notes[row['title']]})
            for cell in row['values']:
                x = x + 1
                if cell.get('is_bold', False):
                    worksheet.write(y, x, cell['value'], bold)
                else:
                    worksheet.write(y, x, cell['value'])
            x, y = 0, y + 1

      
        workbook.close()
        xlsx_data = output.getvalue()
        filename = osutil.clean_filename(_("Pivot %(title)s (%(model_name)s)", title=jdata['title'], model_name=jdata['model']))
        response = request.make_response(xlsx_data,
            headers=[('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'),
                    ('Content-Disposition', content_disposition(filename + '.xlsx'))],
        )

        return response

In devtools console only one error, and it exists even if i off debug mode (this error occurs even if remove my_render from manifest file)

Content Security Policy of your site blocks the use of 'eval' in JavaScript`  
The Content Security Policy (CSP) prevents the evaluation of arbitrary strings as JavaScript to make it more difficult for an attacker to inject unathorized code on your site.

To solve this issue, avoid using eval(), new Function(), setTimeout([string], ...) and setInterval([string], ...) for evaluating strings.

If you absolutely must: you can enable string evaluation by adding unsafe-eval as an allowed source in a script-src directive.

⚠️ Allowing string evaluation comes at the risk of inline script injection.

1 directive
Source location Directive   Status
script-src  blocked

An error in the client (maybe module conflict or somthing else)

web.assets_web.min.js:26 The following modules could not be loaded because they have unmet dependencies, this is a secondary error which is likely caused by one of the above problems: 
Array(1)
0
: 
"@module_name/js/views/my_render.js"
length
: 
1
[[Prototype]]
: 
Array(0)
at
: 
ƒ at()
concat
: 
ƒ concat()
constructor
: 
ƒ Array()
copyWithin
: 
ƒ copyWithin()
entries
: 
ƒ entries()
every
: 
ƒ every()
fill
: 
ƒ fill()
filter
: 
ƒ filter()
find
: 
ƒ find()
findIndex
: 
ƒ findIndex()
findLast
: 
ƒ findLast()
findLastIndex
: 
ƒ findLastIndex()
flat
: 
ƒ flat()
flatMap
: 
ƒ flatMap()
forEach
: 
ƒ forEach()
includes
: 
ƒ includes()
indexOf
: 
ƒ indexOf()
join
: 
ƒ join()
keys
: 
ƒ keys()
lastIndexOf
: 
ƒ lastIndexOf()
length
: 
0
map
: 
ƒ map()
pop
: 
ƒ pop()
push
: 
ƒ push()
reduce
: 
ƒ reduce()
reduceRight
: 
ƒ reduceRight()
reverse
: 
ƒ reverse()
shift
: 
ƒ shift()
slice
: 
ƒ slice()
some
: 
ƒ some()
sort
: 
ƒ sort()
splice
: 
ƒ splice()
toLocaleString
: 
ƒ toLocaleString()
toReversed
: 
ƒ toReversed()
toSorted
: 
ƒ toSorted()
toSpliced
: 
ƒ toSpliced()
toString
: 
ƒ toString()
unshift
: 
ƒ unshift()
values
: 
ƒ values()
with
: 
ƒ with()
Symbol(Symbol.iterator)
: 
ƒ values()
Symbol(Symbol.unscopables)
: 
{at: true, copyWithin: true, entries: true, fill: true, find: true, …}
[[Prototype]]
: 
Object

Maybe someone know how to fix this problem, or know different method to add strings to pivot value