Google Sheet script to copy hyperlinked text into a new tab

The script that I’m using on GoogleSheet Appscript when moving one row to a new tab any hyperlinked text will not paste over to the new tab. How can I solve for this?

Google Sheet Link: https://docs.google.com/spreadsheets/d/1-ucJ0GmfbKIPvpwwneFVIoaM8orvAYt9NkT6m7UTDeo/edit?usp=sharing

If you look at the GoogleSheet in the leads tab I hyperlinked the word “Link” under column K. When I change the status to prospects in column A it only copies over the word text without the link attached.

Code:

function onEdit(e){
  let range = e.range;
  let col = range.getColumn();
  let row = range.getRow();
  let val = range.getValue();
  let source = e.source.getActiveSheet();

  if (col == 1 && val != '') {
    let ss = SpreadsheetApp.getActiveSpreadsheet();
    let sheet = ss.getSheetByName(source.getName());
    let data = sheet.getRange(row,1,1,sheet.getLastColumn()).getValues();
    
    let targetSheet = ss.getSheetByName(val);
    targetSheet.appendRow(data[0]);
    sheet.deleteRow(row);
  }
}

I followed a couple of tutorials via Youtube and even tried chatGPT for help but no success. Feel free to look at the googlesheet itself.

How do I find the branch of the last commit merged into master using the API?

I have a branch, e.g. my-branch, containing multiple commits.

I squash and merge the branch’s PR into master using the Github UI

I then use the Github API to get the last commit that was just merged into master by doing:

const [lastMergedCommit] = await fetch(`${githubApiBaseUrl}/repos/${owner}/${repo}/commits?sha=master&per_page=1`)

Now I’ve found solutions that try to extract the name of the branch from lastMergedCommit.commit.message by using a Regex and assuming that lastMergedCommit.commit.message will consist of:

Merge pull request #{PR ID} from ${branch name}

but this doesn’t seem bullerproof at all since I’ve noticed that “merge” commits don’t always contain the branch name or have the above structure at all.

So I’d like to know if there is a bulletproof way of discerning the name of the branch that lastMergedCommit belonged to before it was merged into master, by using the contents of lastMergedCommit.

Problem with decimals cases of JavaScript [closed]

I made an Excel spreadsheet that calculates compound interest, but I am receiving different values ​​using the calculation

I’m trying to calculate compound interest based on some factors:

an interval of days between each installment being an array such as: [3,6,9], [10,20,30,40,50], [30,60,90]

a total amount

number of installments

interest rate in percentage

In the following scenario, I made an example of code to try to calculate the values, however, when comparing with Excel, where I do the same calculation, I receive different values

const rate = 0.10; // 10%
const installments = 3;
const originalValue = 255.55;

// Set the interval of days between installments
const rangeDays = [3, 6, 9];

// Calculate the total loan amount
lettotalValue = originalValue; // Start with the original value

// Iterate over each installment and apply compound interest
for (let i = 0; i < installments; i++) {
  // Convert the range from days to months
  const rangeMonths = rangeDays[i] / 30;

  // Apply compound interest to each installment
  if (i === installments - 1) { // If it is the last installment
    totalvalue = totalvalue * (1 + rate * rangeMonths);
  } else {
    totalValue *= 1 + rate * rangeMonths;
  }
}

I should receive TotalValue = 260.67, but I am receiving 257.76, could this be a javascript decimal error?

React native: TextInput cannot be focused when there is Modal on screen

I have a screen with following:

{requestFailed && (<Modal
animationType="slide"
transparent={true}
visible={requestFailed}
onRequestClose={() => {
    // some code
    setTimeout(() => {
        textInputRef.current.focus();
    }, 100);
}}>
<View style={styles.centeredView}>
    <View style={styles.modalView}>
        <Text style={styles.modalText}>
            Failed to get info. Reason: <Text style={{ color: "red" }}>{failReason}</Text>
        </Text>

        <View style={{ flexDirection: 'row' }}>
            <Pressable
                style={[styles.button, styles.buttonOpen]}
                onPress={() => {
                    // some code
                    setTimeout(() => {
                        textInputRef.current.focus();
                    }, 100);
                }}>
                <Text style={styles.textStyle}>    Ok    </Text>
            </Pressable>
        </View>
    </View>
</View>
</Modal>)}

<View style={{ position: 'absolute', top: 40, left: 10, right: 10 }}>
<TextInput
    ref={textInputRef}
    style={styles.input}
    placeholder="Enter or scan QR code"
    onChangeText={text => {
        if (text.length <= 12) {
            setText(text);
        }

        if (text.length === 12) {
            getInfo(text);
        }
    }}
    value={text}
    editable={true}
    autoFocus={true}
    keyboardType={'numeric'}
    blurOnSubmit={false}
/>

Problem: The TextInput cannot be focused programmatically after the Modal appears (no matter if I close it with the “back” or “Ok” button).

How can I fix this?

I tried getting rid of Modal and showing a regular Alert instead. There are two points here:

  1. If TextInput is set to editable={true}, then there are no problems, everything works well, but it’s ugly solution.
  2. If the TextInput is set to editable={loading}, and when closing the alert I call textInputRef.current.focus();, then
    • in the case when I use a regular keyboard, everything works well. BUT:
    • if I use a bluetooth scanner instead of a keyboard (works like bluetooth keyboard), then the application crashes (I don’t have access to logs so I can’t see the reason).

What could be wrong?

How come my code can’t draw ellipses according to JSON coordinate?

I’m trying a basic map drawing with JSON file.

What I’m trying to do is simply draw ellipse according the latitude and longitude in the JSON file. I’m creating a for loop to define the variable of [] arry, but when I print xgeo and ygeo, the error message shows “r is undefined”. And none of ellipse is drawn.

let bkgImage;
let urlMap, urlC;
let mapGeoLeft, mapGeoRight, mapGeoBottom, mapGeoTop;
let xgeo, ygeo;
let w, h;



function preload() {
  urlMap =
    "https://api.mapbox.com/styles/v1/mapbox/light-v11/static/[-123,29.7604267,-70.2553259,41]/600x400@2x?access_token=YOUR_MAPBOX_ACCESS_TOKEN";
  urlC = loadJSON("cities.json") 
  
  bkgImage = loadImage("US.Map.png");
}


function setup() {
  let u1 = split(urlMap,"/"); //string
  let u2 = u1[8]; //taking coordinate info.
  let coord = split(u2,","); // taking off ,
  coord[0] = coord[0].replace("[",""); //taking off []
  coord[3] = coord[3].replace("]","");
  
  mapGeoLeft = coord[0];
  mapGeoRight = coord[2];
  mapGeoTop = coord[1];
  mapGeoBottom = coord[3];

  createCanvas(600, 400);
  image(bkgImage, 0, 0, width, height);
  
  print(mapGeoRight);
  print(mapGeoLeft)
}

function draw() {
  for(let r = 0; r < urlC.length; r++){
    let lon = urlC[r].longitude
    let lat = urlC[r].latitude
    
    let xgeo = map(lon, mapGeoLeft, mapGeoRight, 0, width);
    let ygeo = map(lat, mapGeoTop, mapGeoBottom, 0, height);
    
    fill(255,0,0);
    ellipse(xgeo, ygeo, 5, 5)
    
  }

  // print(lon);
  
  noLoop();
}


Part of the JSON file I’m using:

[
  {
    "city": "New York",
    "growth_from_2000_to_2013": "4.8%",
    "latitude": 40.7127837,
    "longitude": -74.0059413,
    "population": "8405837",
    "rank": "1",
    "state": "New York"
  },
  {
    "city": "Los Angeles",
    "growth_from_2000_to_2013": "4.8%",
    "latitude": 34.0522342,
    "longitude": -118.2436849,
    "population": "3884307",
    "rank": "2",
    "state": "California"
  },
  {
    "city": "Chicago",
    "growth_from_2000_to_2013": "-6.1%",
    "latitude": 41.8781136,
    "longitude": -87.6297982,
    "population": "2718782",
    "rank": "3",
    "state": "Illinois"
  },
  {
    "city": "Houston",
    "growth_from_2000_to_2013": "11.0%",
    "latitude": 29.7604267,
    "longitude": -95.3698028,
    "population": "2195914",
    "rank": "4",
    "state": "Texas"
  },
  {
    "city": "Philadelphia",
    "growth_from_2000_to_2013": "2.6%",
    "latitude": 39.9525839,
    "longitude": -75.1652215,
    "population": "1553165",
    "rank": "5",
    "state": "Pennsylvania"
  },
  {
    "city": "Phoenix",
    "growth_from_2000_to_2013": "14.0%",
    "latitude": 33.4483771,
    "longitude": -112.0740373,
    "population": "1513367",
    "rank": "6",
    "state": "Arizona"
  },
  {
    "city": "San Antonio",
    "growth_from_2000_to_2013": "21.0%",
    "latitude": 29.4241219,
    "longitude": -98.4936282,
    "population": "1409019",
    "rank": "7",
    "state": "Texas"
  },
  {
    "city": "San Diego",
    "growth_from_2000_to_2013": "10.5%",
    "latitude": 32.715738,
    "longitude": -117.1610838,
    "population": "1355896",
    "rank": "8",
    "state": "California"
  },
  {
    "city": "Dallas",
    "growth_from_2000_to_2013": "5.6%",
    "latitude": 32.7766642,
    "longitude": -96.7969879,
    "population": "1257676",
    "rank": "9",
    "state": "Texas"

Why is only a single label shown on hover even though i have split set to true?

Here’s my fiddle vs the one I want my chart to operate like:

Highcharts.chart('container', {
    "accessibility": {
        "enabled": false
    },
    "credits": {
        "enabled": false
    },
    "title": {
        "text": "fruits",
        "margin": 50,
    },
    "tooltip": {
        "split": true,
        "outside": true
    },
    "boost": {
        "useGPUTranslations": false,
        "seriesThreshold": 1,
        "enabled": true
    },
    "chart": {
        "spacingRight": 15,
        "spacingLeft": 5,
        "marginTop": 60,
        "width": 200,
        "zooming": {
            "mouseWheel": {
                "enabled": true
            },
            "type": "y"
        },
        "marginBottom": 100,
        "events": {}
    },
    "legend": {
        "width": 200,
        "maxHeight": 100,
        "x": 15,
    },
    "xAxis": {
        "minorTicks": true,
        "crosshair": {
            "snap": false
        },
        "maxPadding": 0,
        "minPadding": 0,
        "title": {
            "offset": 7,
            "style": {
                "fontSize": "11px"
            }
        },
        "labels": {
            "y": -7,
        },
        "tickLength": 0,
        "endOnTick": true,
        "lineWidth": 0,
        "startOnTick": true,
        "tickAmount": 2,
        "minorTickInterval": "auto",
        "tickPositions": [
            0,
            150
        ],
        "min": 0,
        "max": 150,
        "reversed": false,
        "opposite": true,
        "gridLineWidth": 0,
        "minRange": 0.1,
        "type": "linear"
    },
    "yAxis": {
        "min": 1067.62296,
        "max": 1097.18856,
        "minorTicks": true,
        "reversed": true,
        "crosshair": {
            "snap": false
        },
        "title": {
            "text": null
        },
        "maxPadding": 0,
        "minPadding": 0,
        "events": {},
        "labels": {
            "padding": 0,
            "rotation": -90,
            "format": "{value}",
        },
        "plotLines": []
    },
    "annotations": [],
    "exporting": {
        "enabled": false
    },
    "plotOptions": {
        "series": {
            "cursor": "pointer",
            "connectNulls": false,
            "findNearestPointBy": "xy",
            "pointStart": null,
            "allowPointSelect": true,
            "stickyTracking": false,
            "turboThreshold": 0,
            "events": {},
            "point": {
                "events": {}
            }
        }
    },
    "series": [
        {
            "id": "apples",
            "cropThreshold": 999999999,
            "data": [
                [
                    139.1992,
                    1067.62296
                ],
                [
                    103.4107,
                    1081.85712
                ],
                [
                    93.0917,
                    1097.18856
                ]
            ],
            "name": "apples",
            "lineWidth": 0.5,
            "visible": true,
            "allowPointSelect": true
        },
        {
            "id": "oranges",
            "cropThreshold": 999999999,
            "data": [
                [
                    103.4093,
                    1067.62296
                ],
                [
                    134.8164,
                    1082.71056
                ],
                [
                    48.788,
                    1097.18856
                ]
            ],
            "name": "oranges",
            "lineWidth": 0.5,
            "visible": true,
            "allowPointSelect": true
        },
        {
            "id": "grapes",
            "cropThreshold": 999999999,
            "data": [
                [
                    105.3344,
                    1067.62296
                ],
                [
                    103.497,
                    1079.96736
                ],
                [
                    98.965,
                    1097.18856
                ]
            ],
            "name": "grapes",
            "lineWidth": 0.5,
            "visible": true,
            "allowPointSelect": true
        }
    ]
});

How can I access localhost from multiple devices on the Wi-Fi network?

I recently learned about the JavaScript Geolocation API, and I want to view the output on my mobile phone while coding on my PC using VS Code and Live Server.

here is my code

const display = document.getElementById("display");

        function getLocation() {
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(showPosition, showError);
            } else {
                display.innerHTML = "Geolocation is not available in your browser!";
            }
        }
    
        function showPosition(position) {
            display.innerHTML = "Latitude: " + position.coords.latitude + "<br/> Longitude: " + position.coords.longitude;
        }
    
        function showError(error) {
            switch (error.code) {
                case error.PERMISSION_DENIED:
                    display.innerHTML = "User denied the request for Geolocation.";
                    break;
                case error.POSITION_UNAVAILABLE:
                    display.innerHTML = "Location information is unavailable.";
                    break;
                case error.TIMEOUT:
                    display.innerHTML = "The request to get user location timed out.";
                    break;
                case error.UNKNOWN_ERROR:
                    display.innerHTML = "An unknown error occurred.";
                    break;
            }
        }

How can I correctly access localhost from multiple devices on the same Wi-Fi network?
Are there any additional configurations or settings I need to adjust to make this work?

I attempted to access the localhost URL from my PC’s browser and then copied and pasted it into my mobile phone’s browser. However, this didn’t work.

Audio playback from a WebSockets endpoint on the Web

I have a web application with FastAPI backend and a web frontend. I would like to be able to play the audio via WebSockets on the client. The reason for that is that the user has a bunch of other interactions via WebSockets and I would like to use only one endpoint to keep track of the state.

The problem: the audio via WebSockets is very choppy, whereas when I load the same logic via streaming/audio request it’s just fine. So I am looking to make them equivalent.

Here’s the backend:

@router.websocket('/audio_ws')
async def audio_sockets(ws: WebSocket):
    await ws.accept()

    file = wave.open('my_file.wav', 'rb')
    CHUNK = 1024

    with open('paper_to_audio/data/paper.wav', 'rb') as file_like:
        while True:
            next = file_like.read(CHUNK)
            if next == b'':
                file_like.close()
                break
            await ws.send_bytes(next)


@router.get("/audio")
def read_audio():
    def iterfile():
        CHUNK = 1024
        with open('my_file.wav', 'rb') as file_like:
            while True:
                next = file_like.read(1024)
                if next == b'':
                    file_like.close()
                    break
                yield next
    return StreamingResponse(iterfile(), media_type="audio/wav")

As you can see, the logic for reading the file is basically identical.

Here’s the frontend code for reading from streaming, which works like a charm:

<audio preload="none" controls id="audio">
   <source src="/audio" type="audio/wav">
</audio>

Here’s the JavaScript for reading from WebSockets:

        function playAudioFromBackend() {
            const sample_rate = 44100; // Hz

            // Websocket url
            const ws_url = "ws://localhost:8000/audio_ws"

            let audio_context = null;
            let ws = null;

            async function start() {
                if (ws != null) {
                    return;
                }

                // Create an AudioContext that plays audio from the AudioWorkletNode  
                audio_context = new AudioContext();
                await audio_context.audioWorklet.addModule('audioProcessor.js');
                const audioNode = new AudioWorkletNode(audio_context, 'audio-processor');
                audioNode.connect(audio_context.destination);

                // Setup the websocket 
                ws = new WebSocket(ws_url);
                ws.binaryType = 'arraybuffer';

                // Process incoming messages
                ws.onmessage = (event) => {
                    // Convert to Float32 lpcm, which is what AudioWorkletNode expects
                    const int16Array = new Int16Array(event.data);
                    let float32Array = new Float32Array(int16Array.length);
                    for (let i = 0; i < int16Array.length; i++) {
                        float32Array[i] = int16Array[i] / 32768.;
                    }

                    // Send the audio data to the AudioWorkletNode
                    audioNode.port.postMessage({ message: 'audioData', audioData: float32Array });
                }

                ws.onopen = () => {
                    console.log('WebSocket connection opened.');
                };

                ws.onclose = () => {
                    console.log('WebSocket connection closed.');
                };

                ws.onerror = error => {
                    console.error('WebSocket error:', error);
                };
            }

            async function stop() {
                console.log('Stopping audio');
                if (audio_context) {
                    await audio_context.close();
                    audio_context = null;
                    ws.close();
                    ws = null;
                }
            }

            start()

And the associated worklet:

class AudioProcessor extends AudioWorkletProcessor {

    constructor() {
        super();
        this.buffer = new Float32Array();

        // Receive audio data from the main thread, and add it to the buffer
        this.port.onmessage = (event) => {
            let newFetchedData = new Float32Array(this.buffer.length + event.data.audioData.length);
            newFetchedData.set(this.buffer, 0);
            newFetchedData.set(event.data.audioData, this.buffer.length);
            this.buffer = newFetchedData;
        };
    }

    // Take a chunk from the buffer and send it to the output to be played
    process(inputs, outputs, parameters) {
        const output = outputs[0];
        const channel = output[0];
        const bufferLength = this.buffer.length;
        for (let i = 0; i < channel.length; i++) {
            channel[i] = (i < bufferLength) ? this.buffer[i] : 0;
        }
        this.buffer = this.buffer.slice(channel.length);
        return true;
    }
}

registerProcessor('audio-processor', AudioProcessor);

What am I doing wrong? Why is the audio choppy?

jQuery SVG Thermometer plugin not working

I tried to use the code on this page to use the thermometer in a code. But it doesn’t work.

Code:

$(function() {
  $('#demo').thermometer({
    height: 300,
    percent: 75,
    speed: 'slow',
    minValue: 0,
    maxValue: 100,
    liquidColour: '#aa00bb'
  });
})
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="bower/jquery.thermometer/js/jquery.thermometer.js"></script>
<div id='demo'></div>

Scroll to bottom works fine but scroll to top doesn’t on Google Chrome

I’ve made two JS functions. One that scrolls to top on click and the other that scrolls to bottom. The one that scrolls to bottom works 100% of the time. However, the scroll to top sometimes stops for no reason. It basically just scrolls a couple of pixels and then stops, then if I press the button again it will scroll to top. I’m only seeing this weird behaviour in Chrome and not in Firefox.

Functions:

function scrollToBottom() {
  const scrollHeight = document.documentElement.scrollHeight;
  const viewportHeight = window.innerHeight;
  const scrollTo = scrollHeight - viewportHeight;
  
  window.scrollTo({
      top: scrollTo,
      behavior: 'smooth'
  });
}

function scrollToTop() {
  // I've tried with the window.scrollTo({top:0}) approach but it's the same result
  document.body.scrollTop = 0;
  document.documentElement.scrollTop = 0;
}

I should note, this only happens when smooth scrolling is enabled in Chrome. Has anybody had a similar issue and how did you fix it?

Fine-Tuning Camera Control and Orientation / Culling issues in JS 3D Rendering without OpenGL

I’m trying to write a 3D “Engine” in JS and I’ve encountered some issues with rendering. I followed this wikipedia article and this other article on graphics pipelines on how to set up the model, view and projection matrices:

Note that I’m using two-dimensional arrays for vectors for now, so multiplying them with matrices is easier, which means that every value in a vector is an array; that’s annoying, but I’ll change that later on.

const near = 0.1, far = 100, fov = 90
const projection = [
    [1 / Math.tan(fov / 2) / aspectratio, 0,                     0,                      0],
    [0,                                   1 / Math.tan(fov / 2), 0,                      0],
    [0,                                   0,                     -(far+near)/(far-near), 0],
    [0,                                   0,                     -1,                     0]
]

let up = [[0], [1], [0], [1]] // universal up-vector
let camera = [[0], [0], [-4], [1]] // camera position
let cameraUp = [[0], [1], [0], [1]] // perpendicular up-vector for camera in case you're looking up
let target = [[0], [0], [0], [1]] // look-at, the point the camera is looking at
let direction = [[0], [0], [-1], [1]] // supposed to be the direction the camera is looking at
let zaxis = normal(minus(camera, target))
let xaxis = normal(cross(cameraUp, zaxis))
let yaxis = cross(zaxis, xaxis)
viewmatrix = [
    [xaxis[x], xaxis[y], xaxis[z], -dot(xaxis, camera)],
    [yaxis[x], yaxis[y], yaxis[z], -dot(yaxis, camera)],
    [zaxis[x], zaxis[y], zaxis[z], -dot(zaxis, camera)],
    [0,        0,        0,        1                  ]
]

let size = 1
let model = [
    [this.size, 0,         0,         this.position[x]],
    [0,         this.size, 0,         this.position[y]],
    [0,         0,         this.size, this.position[z]],
    [0,         0,         0,         1               ]
]

This is what I’m doing with these matrices:
use() takes in an array of vertices and multiplies the vertices with the matrix

let points = use(projection, use(viewmatrix, use(model, this.vertices)))

// delete points outside the frustum
let outside = []
points.forEach(v => {
   let planes = getFrustumPlanes(projection)
   for (let i = 0; i < planes.length; i++) {
       if (!vertexOutside(v, planes[i])) break
   }

   outside.push(v)
})
        
let divided = outside.map(v => [[v[x] / v[w]], [v[y] / v[w]], [v[z] / v[w]], [1]])
let transformed = divided.map(v => [[width / 2 * (v[x] + 1)], [height / 2 * (v[y] + 1)], [0.5 * v[z] + 0.5], [1]])

[1] For some reason I have to add (width / 2, height / 2) to all the vertices when drawing, even after applying the viewport-transform, otherwise the cube(s) aren’t in the middle of the screen, even if the cube’s position and center is (0, 0, 0) and the camera is looking down the z-axis.

Those pretty much work; when I load 9 cubes next to each other it looks like this:
9 1×1 cubes

[2] The weird thing is that I can see stuff that should be behind me, even though I’m determining whether a vertex is inside the camera frustum with this code:

function vertexOutside(vertex, plane) {
    // Calculate the signed distance from the vertex to the plane
    var distance = dot(vertex, plane.normal) - plane.distance;

    // If the distance is negative, the vertex is outside the frustum plane
    return distance < 0;
}

function getFrustumPlanes(projectionMatrix) {
    var planes = [];

    // Right plane
    planes[0] = {
        normal: [projectionMatrix[3][0] - projectionMatrix[0][0], projectionMatrix[3][1] - projectionMatrix[0][1], projectionMatrix[3][2] - projectionMatrix[0][2]],
        distance: projectionMatrix[3][3] - projectionMatrix[0][3]
    };

    // Left plane
    planes[1] = {
        normal: [projectionMatrix[3][0] + projectionMatrix[0][0], projectionMatrix[3][1] + projectionMatrix[0][1], projectionMatrix[3][2] + projectionMatrix[0][2]],
        distance: projectionMatrix[3][3] + projectionMatrix[0][3]
    };

    // Top plane
    planes[2] = {
        normal: [projectionMatrix[3][0] - projectionMatrix[1][0], projectionMatrix[3][1] - projectionMatrix[1][1], projectionMatrix[3][2] - projectionMatrix[1][2]],
        distance: projectionMatrix[3][3] - projectionMatrix[1][3]
    };

    // Bottom plane
    planes[3] = {
        normal: [projectionMatrix[3][0] + projectionMatrix[1][0], projectionMatrix[3][1] + projectionMatrix[1][1], projectionMatrix[3][2] + projectionMatrix[1][2]],
        distance: projectionMatrix[3][3] + projectionMatrix[1][3]
    };

    // Near plane
    planes[4] = {
        normal: [projectionMatrix[3][0] + projectionMatrix[2][0], projectionMatrix[3][1] + projectionMatrix[2][1], projectionMatrix[3][2] + projectionMatrix[2][2]],
        distance: projectionMatrix[3][3] + projectionMatrix[2][3]
    };

    // Far plane
    planes[5] = {
        normal: [projectionMatrix[3][0] - projectionMatrix[2][0], projectionMatrix[3][1] - projectionMatrix[2][1], projectionMatrix[3][2] - projectionMatrix[2][2]],
        distance: projectionMatrix[3][3] - projectionMatrix[2][3]
    };

    return planes;
}

[3] I’m trying to get the mouse-movement right such that I can look around with it. Right now I’m doing that like this:

 window.addEventListener('mousemove', e => {
        mouse.dx = e.x - mouse.x
        mouse.dy = e.y - mouse.y
        mouse.x = e.x
        mouse.y = e.y

        var sens = 0.2
        var rotX = mouse.dx * sens * 0.1
        var rotY = mouse.dy * sens * 0.1

        const rotYMat = [
            [1, 0,   0,    0],
            [0, Math.cos(rotY), -Math.sin(rotY), 0],
            [0, Math.sin(rotY), Math.cos(rotY),  0],
            [0, 0,   0,    1]
        ]
        
        const rotXMat = [
            [Math.cos(rotX),  0, Math.sin(rotX), 0],
            [0,    1, 0,   0],
            [-Math.sin(rotX), 0, Math.cos(rotX), 0],
            [0,    0, 0,   1]
        ]

        direction = mult(rotXMat, direction)
        direction = mult(rotYMat, direction)

        // this doesn't work yet
        // [1] How do I achieve targetting via mouse movement?
        target = add(camera, direction)
        //cameraUp = normal(cross(target, up))
    })

As you’ll see in the full code, this is super janky but I can’t think of any other way except rotating the direction.

Here’s the full code via pastebin.

Update sql table and refresh in html

So, I’m sorta new in this topic and was playing around with HTMX, I have this table representing some data from my db, when pressing the svg at the right side of the row, it enables to edit the fields from the table, when done, I want to make a query to update that record, but my question is how to update the record by the ID of the altered row, where should I store the ID to do the following update from that point?
Note: I already know how to make the endpoint, in the server and the request with HTMX, just need a hand with the id topic

This is the EJS template
I know is insecure to show the actual ID in the HTML (please overlook that)

thead>
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Phone</th>
    </tr>
</thead>
<tbody>
    <% for (let i = 0; i < data.length; i ++) { %>
        <tr class="row-<%= i %>">
            <td> <%= data[i].id %> </td>
            <td> <%= data[i].name %> </td>
            <td> <%= data[i].phone %> </td>
            <td class="editButton" style="cursor: pointer;"><img src="/public/img/edit.svg" alt="edit"></td>
        </tr>
    <% } %>
</tbody>

I tried to store an array with the id’s in front with js and get the altered row id from the click event in the edit button (I don’t think thats a good practice)
I tried to update the record by the name and phone before editing, but want to know if there’s a more efficient or proper way to do it

Failed to convert value of type ‘java.lang.String’ to required type ‘java.lang.Long’; For input string: “employeedetail.html”

I am trying display the employee details by searching for them through ID in my Springboot App.
I have a HTML form in my index.html, which takes the employee ID and returns employeedetail.html page, which has the corresponding details.
I am tring to do this in javascript as I was asked not to use Thymeleaf by my teacher.

and I am getting this error:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Apr 23 23:20:19 IST 2024
There was an unexpected error (type=Bad Request, status=400).
Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; For input string: "employeedetail.html"
org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; For input string: "employeedetail.html"
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.convertIfNecessary(AbstractNamedValueMethodArgumentResolver.java:302)
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:137)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:224)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:178)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:653)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:419)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:340)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:277)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:171)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1431)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1167)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NumberFormatException: For input string: "employeedetail.html"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
    at java.base/java.lang.Long.parseLong(Long.java:711)
    at java.base/java.lang.Long.valueOf(Long.java:1163)
    at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:206)
    at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:115)
    at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:439)
    at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:412)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:161)
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:80)
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53)
    at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:860)
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.convertIfNecessary(AbstractNamedValueMethodArgumentResolver.java:294)
    ... 77 more

this is my index.html form where i am searching for employee by their ID


<div class="card">
            <div class="card-body">
                <h5 class="card-title">Search Employee By ID</h5>
                <p class="card-text">Enter employee ID to search</p>
                <form class="d-flex" role="search" action="/employees/{id}" method="get">
                    <input
                            class="form-control me-2"
                            type="search"
                            placeholder="Search"
                            aria-label="Search"
                            name="id"
                            value="0"
                    />

                    <button class="btn btn-outline-success" type="submit">
                        Search
                    </button>
                </form>


            </div>
        </div>

along with its corresponding javascript

<script>
    // Get the form and input element by their IDs
const form = document.querySelector('form'); // Selecting the form element
const input = document.querySelector('input[type="search"]'); // Selecting the input element

// Add event listener for form submission
form.addEventListener('submit', function(event) {
  // Prevent default form submission
  event.preventDefault();

  // Get the ID value from the input field
  const id = input.value.trim();

  // Regular expression to match only digits
  const numberRegex = /^d+$/;

  // Validate if the ID consists only of digits
  if (!numberRegex.test(id)) {
    alert("Please enter a valid numeric ID.");
    return; // Prevent form submission if validation fails
  }

  // Rest of the code for constructing URL and submitting the form (unchanged)
  const url = '/employees/' + encodeURIComponent(id);
  form.action = url;
  form.submit();
});

// Add event listener for input changes
input.addEventListener('keyup', function() {
  const id = input.value.trim();
  const numberRegex = /^d+$/;
  if (!numberRegex.test(id)) {
    // Add visual cue or display an error message if validation fails
    input.classList.add('invalid'); // Example class for styling
  } else {
    input.classList.remove('invalid'); // Remove error class on valid input
  }
});
</script>

here is the controller for “/employees/{id}”

@GetMapping("/employees/{id}")
    public String getEmployeeDetail(@PathVariable("id") Long id, Model model) {
        Optional<Employee> employee;
            employee = employeeService.getEmployeeById(id);
        if (employee.isPresent()) {
            model.addAttribute("employee", employee.get());
            return "employeedetail.html";
        } else {
            return "error.html";
        }
    }

and here is the javascript code from employeedetail.html page where i am trying to display the details

<script>
    // Function to fetch employee details by ID
    function fetchEmployeeDetailsById(id) {
      fetch(`/employees/${id}`)
        .then(response => {
          if (!response.ok) {
            throw new Error('Failed to fetch employee details');
          }
          return response.json();
        })
        .then(employee => {
          // Display employee details
          const employeeDetails = document.getElementById('employeeDetails');
          employeeDetails.innerHTML = `
            <p><strong>First Name:</strong> ${employee.firstName}</p>
            <p><strong>Last Name:</strong> ${employee.lastName}</p>
            <p><strong>Department:</strong> ${employee.department}</p>
            <p><strong>Gender:</strong> ${employee.gender}</p>
            <p><strong>Street Address:</strong> ${employee.streetAddress}</p>
            <p><strong>City:</strong> ${employee.city}</p>
            <p><strong>State:</strong> ${employee.state}</p>
            <p><strong>Country:</strong> ${employee.country}</p>
            <p><strong>Phone:</strong> ${employee.phone}</p>
            <p><strong>Email:</strong> ${employee.email}</p>
          `;
        })
        .catch(error => console.error('Error fetching employee details:', error));
    }

    // Get employee ID from the URL parameter
    const urlParams = new URLSearchParams(window.location.search);
    const employeeId = urlParams.get('id');

    // Call the function to fetch and display employee details
    if (employeeId) {
      console.log(employeeId);
      fetchEmployeeDetailsById(employeeId);
    } else {
      // Handle case when employee ID is not provided
      console.error('Employee ID is missing');
    }
</script>

my Employee Entity

package com.example.proj.entity;

import jakarta.persistence.*;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Entity
@Data
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String firstName;
    private String lastName;
    private String department;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    private enum Gender {
        MALE,
        FEMALE,
        OTHER
    }

    private String streetAddress;
    private String city;
    private String state;
    private String country;
    private String phone;
    private String countryCode;
    private String email;
    private String password;

}

what could I be doing wrong?

How to send images through whatsapp business api from base64 image data?

const EPIC = message.text.body;
          await axios({
            method: "POST",
            url: `https://graph.facebook.com/v18.0/${business_phone_number_id}/messages`,
            headers: {
              Authorization: `Bearer ${GRAPH_API_TOKEN}`,
            },
            data: {
              messaging_product: "whatsapp",
              to: message.from,
              text: { body: response.data.id },
            },
          });

Can anyone tell me how do I send images if i have the base64 encoded image data? Like how would I have to change the POST request to make this work?

Error every time I try to run a node express project

Hello first time here and I am practicing node and express js with a udemy course project. I initially ran the solution code and it worked fine. When i started to create my own file and followed the steps of the solution code I started getting this weird type error. Then i tried running the solution code again and now the solution has the same type error even though it worked fine before.
I do have the json packages installed and npm i as well. Is there something I haven’t installed, node is up to date and I have not reassigned the constant variable; since nothing has changed i don’t understand how it ran fine before and now its not.

import express from "express";
import bodyParser from "body-parser";
import { dirname } from "path";
import { fileURLToPath } from "url";
const __dirname = dirname(fileURLToPath(import.meta.url));

const app = express();
const port = 3000;

var userIsAuthorised = false;

app.use(bodyParser.urlencoded({ extended: true }));

function passwordCheck(req, res, next) {
  const password = req.body["password"];
  if ((password = "ILoveProgramming")) {
    userIsAuthorised = true;
  }
  next();
}
app.use(passwordCheck);

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/public/index.html");
});

app.post("/check", (req, res) => {
  if (userIsAuthorised) {
    res.sendFile(__dirname + "/public/secret.html");
  } else {
    res.sendFile(__dirname + "/public/index.html");
    //Alternatively res.redirect("/");
  }
});

app.listen(port, () => {
  console.log(`Listening on port ${port}`);
});

This is the error:
TypeError: Assignment to constant variable.
at passwordCheck (file:///Users/cassidypriestley/Desktop/3.5%20Secrets%20Project%202/solution.js:16:17)
at Layer.handle [as handle_request] (/Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/index.js:328:13)
at /Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/index.js:286:9
at Function.process_params (/Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/index.js:346:12)
at next (/Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/index.js:280:10)
at urlencodedParser (/Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/body-parser/lib/types/urlencoded.js:91:7)
at Layer.handle [as handle_request] (/Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/index.js:328:13)
at /Users/cassidypriestley/Desktop/3.5 Secrets Project 2/node_modules/express/lib/router/index.js:286:9

I have verified the node version i am currently using and even tried the direct solution given by the course instructor and it seems the instructor’s solution file is now giving me the same type error as my index.js file.