Getting invalid hook call in react native

ExceptionsManager.js:179 Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

Getting this error in Playbutton component

Playbutton.js

import { useNavigation } from "@react-navigation/native";
import React, { useEffect, useState, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import {
  View,
  Button,
  StyleSheet,
  Image,
  TouchableOpacity,
  Dimensions,
  NativeModules,
} from "react-native";

var deviceHeight = Dimensions.get("window").height;
var deviceWidth = Dimensions.get("window").width;
import useAppleFunction from "../CustomHooks/useAppleFunction";

const PlayButton = () => {
   
  useEffect(() => {
      useAppleFunction();
  }, []);

}

and here is the custom hook useApplefunction.js

import { StyleSheet, Text, View } from "react-native";
import React, { useEffect } from "react";
import { useSelector } from "react-redux";

const useAppleFunction = () => {
  const Playlist = useSelector((state) => state);
  console.log("reduxcheck=",Playlist);

  useEffect(() => {
    runtimer();
  }, []);

  const runtimer = () => {
     console.log("reduxcheck=1",Playlist);
  };
};

export default useAppleFunction;

const styles = StyleSheet.create({});

how to calender control click event effect in another text box in jquery

I have tried with mouse leave function in jquery with the following code

$(function () {
            $("#<%=txt_FromDate.ClientID %>").mouseleave(function () {
               // alert("Wow; Its Work!.")
               var txt_FromDate = document.getElementById('txt_FromDate');
               var txt_ToDate = document.getElementById('txt_ToDate');
               txt_ToDate.value = txt_FromDate.value;

           });
       });

The above code is working fine when mouse leave from the text box. but i need the effect when clicking calender txt_FromDate(from date) and it effect the same date in txt_ToDate(to date).

My html code is given below

<td style="text-align: left;" class="auto-style1">
                                                <asp:TextBox ID="txt_FromDate" runat="server" class="inputCalendar2_font14" Width="105px"
                                                    onfocus="showCalendarControl(this);" onkeypress="return false;" onpaste="return false;"
                                                    CssClass="inputCalendar2_font14"></asp:TextBox>
                                                &nbsp;&nbsp;&nbsp;&nbsp;
                                              <asp:TextBox ID="txt_ToDate" runat="server" class="inputCalendar2_font14" Width="105px" OnTextChanged="txt_ToDate_TextChanged"
                                                  onfocus="showCalendarControl(this);" onkeypress="return false;" onpaste="return false;"
                                                  CssClass="inputCalendar2_font14"></asp:TextBox>

My reference is given below,

<script src="../jScript/BrowserCompatibility.js" type="text/javascript"></script>
    <script src="../jScript/jquery-1.4.4.js" type="text/javascript"></script>
    <script src="../calenderCtr/CalendarControl.js" type="text/javascript" language="javascript"></script>
    <link href="../calenderCtr/CalendarControl.css" rel="stylesheet" type="text/css" />
    <script src="../jScript/Validator.js" type="text/javascript" language="javascript"></script>
    <link href="../style/dsi_mig.css" rel="stylesheet" type="text/css" />
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script type="text/javascript">

next build throws error related to webpack

When i run next build i get following error:


./node_modules/leaflet/dist/images/layers-2x.png
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)


> Build error occurred
Error: > Build failed because of webpack errors
    at /app/node_modules/next/dist/build/index.js:397:19
    at async Span.traceAsyncFn (/app/node_modules/next/dist/telemetry/trace/trace.js:60:20)
    at async Object.build [as default] (/app/node_modules/next/dist/build/index.js:77:25)
# 

my next.config.js seems to be configured to process .png files. Project uses leaflet and react-leaflet libraries. Error says nothing about images that I put in /public/images

const { i18n } = require('./next-i18next.config');
const theme = require('./app/styles/antdoverrides');

module.exports = {
    webpackDevMiddleware: (config) => {
        config.watchOptions = {
            poll: 800,
            aggregateTimeout: 300,
        };
        return config;
    },
    module: {
        loaders: [
            {
                test: /.(png|jpg|gif)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {},
                    },
                ],
            },
        ],
    }
};

Why SCSS dint update the CSS file, I have to delete It each time?

I am using scss in the node project, I started the server and refresh the browser page everything is running, but when I do some changes in the scss file and refresh the page CSS file didn’t update, I have to delete the CSS file and then when I refresh the browser new CSS file is created with updated code. Why scss didn’t update the CSS file?

Redirect if element is shown in embedded form

I need your help redirecting the page which has embedded form and if the element is shown, I want it to redirect the a certain page. Thank you!

<script>
if ( receipt number (element) is shown it will redirect below ) {
  window.location.href = "https://www.example.com";
}
</script> ```
    

how to detect when geojson is fullly loaded in Google Maps

I have a google maps with a geojson that is loaded into the map.

Because the geojson takes 2-4 seconds to load, I want to put a loading circle.
However, when attempting the loading circle, the map comes up only when the tiles are loaded before the geojson is loaded. What is the proper lifecycle marker for waiting until the geojson is loaded?
Thanks

HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Simple Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <link rel="stylesheet" type="text/css" href="css/main.css" />
    <script src="js/main.js"></script>
</head>
<body>
<h1>Hex Map</h1>
<div id="map_wrapper">
    <div id="map"></div>
</div>
<div id="mapinfo">Testbox</div>

<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script
        src="https://maps.googleapis.com/maps/api/js?key=THEKEY&callback=initMap&v=weekly"
        async
></script>
</body>
</html>

JS:

let map;
var infowindow = null;

function initMap() {

    map = new google.maps.Map(document.getElementById("map"), {
        center: {lat: 30.1572523, lng: -92.0299477},
        zoom: 3,
    });

    google.maps.event.addListenerOnce(map, 'bounds_changed', function () {
        //alert(map.getBounds().getNorthEast().lat());
    });

    map.data.loadGeoJson(
      "hexmap.geojson"
    );

    google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
        document.getElementById('map').style.opacity = 1;
    })
    map.data.setStyle({
        fillColor: 'green',
        strokeWeight: 1
    })

    // map.data.addListener('mouseover', function(event) {
    //     console.log(event.feature.getProperty('_uid1_'))
    //     document.getElementById('mapinfo').innerHTML = event.feature.getProperty('_uid1_');
    // })

    const constentString = 'hex + '

    map.data.addListener('click', function(event) {
        message = 'hex id: ' + event.feature.getProperty('_uid1_');
        infowindow && infowindow.close();
        infowindow = new google.maps.InfoWindow();
        infowindow.setContent(message);
        infowindow.setPosition(event.latLng);
        infowindow.open(map);

    })


}
//"https://drive.google.com/file/d/1v-VZtbbz4H2KiMvkRcc7nL_6JKQqlHwM/view?usp=sharing'"

CSS:

#map {
    height: 600px;
    width:800px;
    opacity:0;
}

/* Optional: Makes the sample page fill the window. */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#map_wrapper {
    background:url(https://ressio.github.io/lazy-load-xt/dist/loading.gif) center center no-repeat;
    height: 600px;
    width:800px;
}

My onclick function is not working! What am I doing wrong?

I’ve been trying to write a Chess program with HTML, CSS, and Javascript. I cannot seem to be getting the onclick function for the “PLAY AS WHITE” button to be working. I’ve checked my syntax in the Javascript part and believe it looks fine to me. Is there anything I’m doing wrong with the code?

Here’s the code:

let info = document.getElementById("info");

function playAsWhite() {
  info.innerHTML = "the message I want to output";
}
<h1 id="info">Playing as White:</h1>
<h1>Best move:</h1>
<p>NaN</p>
<input type="text" placeholder="Your input:" id="inputId1">
<button onclick="player1Turn()">Enter</button>
<input type="text" placeholder="Enemy input:" id="inputId2">
<button onclick="player2Turn()">Enter</button>
<div class="functions">
  <button onclick="playAsWhite()">PLAY AS WHITE</button>
  <button onclick="playAsBlack()">PLAY AS BLACK</button>
  <button onclick="reset()">RESET</button>
</div>

I’ve defined the source file (“main.js”) correctly, and the script is loaded at the end of body.

Can’t Properly Download `MediaRecorder` Video Output [duplicate]

I’m building a simple React app (using Create React App + TypeScript) to record content from the user’s camera and mic, and save it to a downloadable video file (preferably mp4).

Currently, it seems like I can record video data, but when I download the file output it won’t open in QuickTimePlayer. Instead says the file is not compatible.

For reference, I’m on an M1 MacBook running MacOS BigSur Version 11.4. Also, I’m extremely new to React development and (although I’ve done a fair bit of TypeScript dev) I’ve never used the MediaRecorder API.

Kindly let me know what errors I made. Thank you!

import { FC, useRef, useState, useEffect } from 'react';

const App: FC = function () {

  /* ==== Component Data ==== */

  const recordingPreviewRef = useRef<HTMLVideoElement>(null!);
  const recordingDeviceRef = useRef<MediaRecorder>(null!);
  const recordingChunksRef = useRef<Blob[]>(null!);
  const [recordingURL, setRecordingURL] = useState("");
  const [isRecording, setRecordingState] = useState(false);
  

  /* ==== Helper Functions ==== */

  async function setUpRecording() {
    // Get User Media
    let recordingMedia = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });

    // Set Up Recording Preview
    recordingPreviewRef.current.srcObject = recordingMedia;
    recordingPreviewRef.current.play();
    
    // Set Up Recording Device
    recordingDeviceRef.current = new MediaRecorder(recordingMedia, { mimeType: 'video/mp4' });
    recordingDeviceRef.current.ondataavailable = (event) => {recordingChunksRef.current.push(event.data)};
  }

  function startRecording() {
    setRecordingState(true);
    recordingDeviceRef.current.start();
    recordingChunksRef.current = [];
    console.log('Recording...');
  }

  function stopRecording() {
    recordingDeviceRef.current.stop();
    setRecordingState(false);
    saveRecording();
    console.log('Recording stopped.');
  }
  
  function toggleRecording() {
    if (!isRecording) {
      startRecording();
    } else {
      stopRecording();
    }
    // recordingDeviceRef.current.requestData();
  }

  function storeRecordingChunks(event: BlobEvent) {
    if (event.data.size > 0) {
      recordingChunksRef.current.push(event.data);
    }
  }

  function saveRecording() {
    let videoFile = new Blob(recordingChunksRef.current, { type: 'video/mp4' });
    let videoURL = window.URL.createObjectURL(videoFile);
    setRecordingURL(videoURL)
    recordingChunksRef.current = [];
  }

  /* ==== Component Life-Cycle Events ==== */

  useEffect(() => { 
    setUpRecording()
  }, [])


  /* ==== JSX Markup ==== */

  return (
    <>
      <video ref={recordingPreviewRef} muted></video>
      <section>
        <h1>Hello: {MediaRecorder.isTypeSupported('video/webm') ? 'A' : 'B'}</h1>
        <button onClick={() => toggleRecording()}>{ !isRecording ? 'Start Recording' : 'Stop Recording'}</button>
        <a href={recordingURL} download={'RecordedVideo.webm'}>Download</a>
      </section>
    </>
  )
}

export default App;

Uncaught Error: getSessionData requires two non-null arguments

I want to load a JavaScript file in Webview with xamarin c#. while loading file, I am not getting content on webview, it just shows empty and in logs getting error

[chromium] [INFO:CONSOLE(2)] "Uncaught Error: getSessionData requires two non-null arguments (domain, keys).", source: https://sodexosms--univcrm.my.salesforce.com/embeddedservice/5.0/frame/session.esw.min.js (2)

Below file I am using

<html>
<head>
</head>
<body>
    <script type='text/javascript'>
        var initESW = function (gslbBaseURL) {
            embedded_svc.settings.displayHelpButton = true; //Or false
            embedded_svc.settings.language = ''; //For example, enter 'en' or 'en-US'
            embedded_svc.settings.enabledFeatures = ['LiveAgent'];
            embedded_svc.settings.entryFeature = 'LiveAgent';
            embedded_svc.init(
                'https://ulr.my.salesforce.com',
                'https://ulr.cs189.force.com/visualforce',
                gslbBaseURL,
                '00D7a00000055uj',
                'US_Universities',
                {
                    'baseLiveAgentContentURL': 'https://ulr.com/content',
                    'deploymentId': '5720Q08Oqg',
                    'buttonId': '570008PID',
                    'baseLiveAgentURL': 'https://ulr.salesforceliveagent.com/chat',
                    'eswLiveAgentDevName': 'EmbeddedServiceLiveAgent_Parent04I0UAQ_17d9a605e8e',
                    'isOfflineSupportEnabled': false
                }
            );
        };
        if (!window.embedded_svc) {
            var s = document.createElement('script');

            s.setAttribute('src', 'https://ulr/embeddedservice/5.0/esw.min.js');

            s.onload = function () {
                initESW(null);

            }
            document.body.appendChild(s);
        }
        else {
            initESW('https://service.force.com');
        }
    </script>
</body>
</html>

How can I fix it ?

Creating an array in React and populating with values

I’m trying to create an array and then populate it using a function. I’m basically working on a retirement calculator application and I have a couple of initial values including age, retirement age, salary, salary increase, contribution to savings, savings, and interest rate on savings which I’m getting through a form. Next using those values as a starting point I want to create a table which will show the salary, savings, increase, etc for each year starting from the user’s starting age up until their retirement age. Similar to on this website https://www.bankrate.com/retirement/retirement-plan-calculator/.

So basically showing the yearly savings balance until retirement. My idea was to calculate these values and store it in an array and then map it onto a table. I’m very new to React and web programming in general so I honestly have no idea what I’m doing. Any help or suggestions are appreciated.

const Results = ({results}) => {

var age = results.age;
var retAge = results.retAge;
//var yearsToRet = retAge - age;
var salary = results.salary;
var increase = results.increase;
var cont = results.cont;
var savings = results.savings;
var interest = results.interest;
var retSavings = savings;

//To format the results as dollar value
const formatter = new Intl.NumberFormat("en-US", {style: "currency", currency: "USD", minimumFractionDigits: 2})

//Calculating savings during retirement
for(var i = age; i < retAge; ++i)
{
    //new salary with increase
    salary += salary * (increase/100);
    retSavings +=  salary*(cont/100) + retSavings*(interest/100); 
}

const savingsList = [
    {
        age: results.age,
        retAge: results.retAge,
        salary: results.salary,
        increase: results.increase,
        cont: results.cont,
        savings: results.savings,
        interest: results.interest,
        retSavings: savings,
    }
];
console.log(savingsList);

return(
    <><div className='results'>
        <h3> At retirement age of {retAge}, {results.name} will have a total savings of {formatter.format(retSavings)}</h3>
    </div></>
)

}

what is the equivalent of python open(filepath, ‘rb’) in JavaScript

I can open the file in binary mode with Python and store it in a variable.
I have been researching this for two days, and I can’t seem to find a straightforward answer. I need this because I have been working on a project that we have completed in Python, but we need to convert it into JavaScript. The issue that I’m having is that I need to send a file through an API call. Still, every time I do, I get this error ‘ HTTP 415 Unsupported Media TypeThe provided media type is not supported for the requested URI. What I have is a JSON file that I need to pass to a post-call in binary

files = {'file': open(JSON_File, 'rb')}
response = requests.post(
    URL, 
    auth=(USERNAME, PASSWORD),
    files=files
    #files=files, verify = False
)

response.text

how can I do this in nodeJS? I completed the above already in Python.

How to store response data into an array out of the current function in node js?

How do i store all result data into pImages array i am getting the result but in that case i think async function will work but i dont know how to apply it. please help, my code is

exports.addImage = (req, res, next) => {
    let imageArray = req.files.productImageArray;

    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send("No files were uploaded.");
    }
    
    // here all images will be stored in array format
        let pImages = [];

         for (let f in imageArray) {
            imagekit.upload(
                {
                    file: imageArray[f].data, //required
                    fileName: imageArray[f].name, //required
                    customMetadata: {
                        color: req.body.productLabels[f],
                        default: req.body.defaultProduct[f]
                    }
                },
                function(error, result) {
                    if (error) console.log(error);
                    else {
                        console.log(result)
                        pImages.push(result)
                    }
                }
            );
        }

    console.log("p", pImages); //output p []
   
};

Thanks in Advance

h2 field not updating with values

I am trying to update the h2 field in index.html with the ID “summary” with the values inside of index.html (refer to line 87 in there, that is where I am having a problem).

I want the text that says “test” to change to a string with those four variables.

For context, this application is a health risk calculator for a class assignment that is supposed to calculate your supposed health risk based on BMI, blood pressure, family history, and age. We are supposed to have the calculations run on server side for the purposes of the assignment, which I have implemented successfully. However, I need to provide a summary of the values used in the calculation, which is for some reason, giving me a major headache. I thought this would be an easy fix but I am obviously missing something stupid.

Let me know what I am missing please.

HTML:

<h2 id="summary">test</h2>

In JavaScript file in an app.get block that is called from HTML vvv

document.getElementById("summary").innerHTML =  ("(Age Risk: " + ageNum + ", Family History Risk: " + famHistNum + ", BMI Risk: " + bmiNum + "Blood Risk: " + bloodRisk);

Fetch data from db into a HTML form

I’m new to PHP and SQL, so I’m doing a booking form. So far it POST’s into a database but the only thing missing is to show the available dates and hours for the appointments in the selector at the beginning of the form, and for those dates to be unselectable once booked by other user. I’ve already tried to do it by XMLHttpRequest but i haven’t been able to make it work.

I’ve already create a table in the DB in which the available dates are stored, this is the structure. When the date-time it’s available the state is 1, otherwise is 0.

https://drive.google.com/file/d/1ZqYAA-JZy0ed87KNuMzN7B326jhYuw3V/view?usp=sharing

This is my HTML form

<form class="needs-validation col-sm-11 col-md-6 col-lg-6 col-xl-6" style="border: solid black; padding:10px; border-radius: 5px; border-width: 1.5px; box-shadow: 5px 5px 5px rgb(0 0 0 / 0.2);" novalidate>


  <label for="exampleFormControlInput1" style="color:#9eb33e;"><b>Fecha y hora en que desea la charla</b></label>
  <div class="row">
    <div class="col-sm-6">
      <label for="exampleFormControlSelect2">Selecciona la fecha charla</label>
      <select multiple class="form-control" id="exampleFormControlSelect2" name="fecha">
        <option disabled="true"><b>--MARZO--</b></option>
        <option>2022-03-24</option>
        <option>2022-03-25</option>
        <option disabled="true"><b>--ABRIL--</b></option>

      </select>
    </div>
    <div class="col-sm-6">
      <label for="exampleFormControlSelect2">Selecciona hora de la charla</label>
      <select multiple class="form-control" id="exampleFormControlSelect2" name="hora">
        <option disabled="true"><b>--MARZO--</b></option>
        <option></option>
        <option>00:00:00</option>
        <option>12:00:00</option>
        <option disabled="true"><b>--ABRIL--</b></option>

      </select>
    </div>

  </div>

  <label for="exampleFormControlInput1" style="color:#9eb33e;"><b>Datos de la persona encargada</b></label>

  <div class="row">

    <div class="col-sm-6">
      <label for="exampleFormControlInput1">Nombres</label>
      <input type="text" class="form-control" placeholder="" name="nombre" required>
      <div class="invalid-feedback">
        Por favor escriba los nombres de la persona encargada
      </div>

    </div>


    <div class="col-sm-6">
      <label for="exampleFormControlInput1">Apellidos</label>
      <input type="text" class="form-control" placeholder="" name="apellido" required>
      <div class="invalid-feedback">
        Por favor escriba los apellidos de la persona encargada
      </div>
    </div>



  </div>

  <div class="row">
    <div class="col-sm-12">
      <div class="form-group">
        <label for="exampleFormControlInput1">Correo electrónico</label>
        <input type="email" class="form-control" name="email" placeholder="[email protected]" required>
        <div class="invalid-feedback">
          Por favor provea un correo electrónico valido
        </div>
      </div>
    </div>
  </div>

  <div class="row">
    <div class="col-sm-12">
      <div class="form-group">
        <label for="exampleFormControlInput1">Número de contacto</label>
        <input type="text" class="form-control" name="numero" placeholder="+57 --- --- ----" required>
        <div class="invalid-feedback">
          Por favor provea un número de contacto (Celular o fijo)
        </div>
      </div>
    </div>
  </div>

  <div class="row">
    <div class="col-sm-12">
      <div class="form-group">
        <label for="exampleFormControlInput1">Nombre del colegio</label>
        <input type="text" class="form-control" id="exampleFormControlInput1" name="colegio" required>
        <div class="invalid-feedback">
          Por favor escriba el nombre del colegio al que representa
        </div>
      </div>
    </div>
  </div>


  <div class="row">
    <div class="col-sm-12">
      <div class="form-group">
        <label for="exampleFormControlInput1">Número aproxmado de estudiantes</label>
        <input type="text" class="form-control" id="exampleFormControlInput1" placeholder="" name="numest" required>
        <div class="invalid-feedback">
          Por favor provea un número de estudiantes aproximados a asistir
        </div>
      </div>
    </div>
  </div>

  <div class="row">
    <div class="col-sm-12">
      <div class="form-group">
        <input type="checkbox" class="custom-control-input" id="customControlAutosizing" required>
        <label class="custom-control-label" for="customControlAutosizing" style="margin-left:15px;">Acepto
                        la política de tratamiento de datos</label>

        <div class="invalid-feedback">
          Es necesario aceptar la política de tratamiento de datos
        </div>
      </div>
    </div>
  </div>


  <div class="button-area">
    <button type="submit" class="btn btn-primary col-sm-12" style="background:#9eb33e; border-color:#9eb33e;">Enviar</button>
  </div>

</form>

This is the JS code

const form = document.querySelector("form"),
statusTxt = form.querySelector(".button-area");

form.onsubmit = (e)=>{
    e.preventDefault()
    
    let xhr = new XMLHttpRequest();
    xhr.open("POST", "public/php/registro.php",true);
    xhr.onload = ()=>{
        if(xhr.readyState == 4 && xhr.status == 200){
            let response = xhr.response;
            console.log(response);
        }
    }
    let formData = new FormData(form);
    xhr.send(formData);
 }
 

And this is the PHP that controls it


include_once 'conect_db.php';


$fecha = $_POST['fecha'];
$hora = $_POST['hora'];
$nombre = $_POST['nombre'];
$apellido = $_POST['apellido'];
$email = $_POST['email'];
$numero = $_POST['numero'];
$colegio = $_POST['colegio'];
$numest = $_POST['numest'];


if(!empty($fecha) && !empty($nombre) && !empty($apellido) && !empty($email) && !empty($numero) && !empty($colegio) && !empty($numest)){
$reciever = "[email protected]";
    $subject = "Mensaje de $nombre: Nueva cita UNaspirante.";
    $body = "Datos de la persona encargada:/n Nombre:$nombre/n Apellido:$apellido/n Correo Electronico:$email/n Numero de contacto:$numero/n Colegio:$colegio/n Numero de estudiantes:$numest/n FECHA:$fecha/n. HORA:$hora/n";
    $sender = "$email";
    
    $consulta = "INSERT INTO UNaspirante_form(nombre, apellido, email, numero, colegio, num_estudiantes, fecha_seleccionada, hora_seleccionada) VALUES ('$nombre','$apellido','$email','$numero','$colegio','$numest','$fecha','$hora')";
    $resultado = mysqli_query($mysqli , $consulta);
    
    
    if($resultado){
        echo "Tu info ha sido enviada";
    }else{
        echo "Tu info NO ha sido enviada";
    }
    
}else{
    echo "no se pudo enviar el mensaje";
}

?>``` 

**Thanks in advance for all the help**


  [1]: https://i.stack.imgur.com/M74PD.png