AWS: find Lambda’s with deprecated runtimes and visualize that in a table.

Lambda offers managed runtimes for new language versions exclusively upon reaching the long-term support (LTS) phase within the language’s release cycle. As an illustration, in the case of the Node.js release cycle, this occurs when the release reaches the Active LTS phase.

During the period leading up to the long-term support phase, the release is in development and may undergo breaking changes. Lambda automatically implements runtime updates by default, meaning that breaking changes to a runtime version have the potential to disrupt the expected functionality of your functions.

It’s important to note that Lambda does not provide managed runtimes for language versions that are not scheduled for LTS release.

Full AWS Article here: https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html

Fetch the data

I will demonstrate a model here that fetches the data from an AWS account. The data will be stored in a .json file. The .json file is used to fill a table to show the results in a nice view. The view has a select box which let’s you switch between the results from the different accounts.

The complete solution uses a Shell script, PHP, JavaScript, HTML and CSS.

I work with a lot of AWS accounts and manage those accounts with Granted, which you can find here: https://docs.commonfate.io/granted/getting-started
The nice thing about Granted is that you can use it programatically.

This solution is only tested on macOS.

The script that fetches the data has a select option, to be able to select the AWS account you want to collect the data from. The script also uses awk: https://linuxhandbook.com/awk-command-tutorial/ to create some correct .json formatted files.

#!/bin/sh
# Set the terminal you use here: bash or zsh or another.
# For aws cli debug use: aws "command" --debug.

export TERM=xterm-256color

# Record the start time.
start_time=$(date +%s)

alias assume="source assume"
PROFILE="YOUR-FIRST-AWS-PROFILE YOUR-SECOND-AWS-PROFILE YOUR-THIRD-AWS-PROFILE YOUR-FOURTH-AWS-PROFILE YOUR-FIFTH-AWS-PROFILE"

# Display menu to the user
select profile in $PROFILE; do
case $profile in
YOUR-FIRST-AWS-PROFILE|YOUR-SECOND-AWS-PROFILE|YOUR-THIRD-AWS-PROFILE|YOUR-FOURTH-AWS-PROFILE|YOUR-FIFTH-AWS-PROFILE)

DATE=$( date +%Y-%m-%d-%H:%M:%S )
echo "$DATE"
echo "You selected profile: $profile"
echo
if ! assume "$profile"; then { echo "❌ ! Operation error SSO: GetRoleCredentials, StatusCode: 403.
❌ ! Api error ForbiddenException: No access.
❌ ! Check your profiles in .config! You are not authorized or not logged in to this account!  " ; exit 1; }
fi

echo "Process started at: $(date -r $start_time)"

cd ../logic/output-lambda-deprecated || exit

echo "[\"$DATE\"]" > "$profile"-LAMBDA-SCANDATE.json

ID=$(aws sts get-caller-identity --query Account --output text)
ALIAS=$(aws iam list-account-aliases --query AccountAliases --output text)

echo "Check Account ID and alias name: "id: " $ID " - alias: " $ALIAS"
echo "$ID" > "$profile"-lambdas-id.json
echo "$ALIAS" > "$profile"-lambdas-al.json

# Use AWK to create a .json formatted file.
awk ' BEGIN { print "[" ; }  { print " {\n" "   \"accountId\": \""   $1  "\"\n"  "  }" }   END { print "]" } ' "$profile"-lambdas-id.json > "$profile"-LAMBDA-ID.json
awk ' BEGIN { print "[" ; }  { print " {\n" "   \"alias\": \""   $1  "\"\n"  "  }" }   END { print "]" } ' "$profile"-lambdas-al.json > "$profile"-LAMBDA-ALIAS.json

rm -rvf "$profile"-LAMBDA-DEPRECATED.json "$profile"-LAMBDA-DETAIL.json
echo "Old files removed to prevent duplicates"

aws lambda list-functions | jq -c '{
  "Functions": [
    .Functions[] | select(
      .Runtime | test(
        "dotnet5.0|dotnet6|dotnet7|dotnetcore1.0|dotnetcore2.0|dotnetcore2.1|dotnetcore3.1|go1.x|java8|nodejs10.x|nodejs12.x|nodejs14.x|nodejs16.x|nodejs4.3|nodejs4.3-edge|nodejs6.10|nodejs8.10|python2.7|python3.6|python3.7|python3.8|ruby2.5|ruby2.7"
      )
    ) | select(
      .Runtime != "provide.al2023" and
      .Runtime != "provided.al2" and
      .Runtime != "nodejs18.x" and
      .Runtime != "nodejs20.x"
    ) | {
      "FunctionName": .FunctionName,
      "Runtime": .Runtime,
      "Description": .Description,
      "FunctionArn": .FunctionArn
    }
  ]
}' > "$profile"-LAMBDA-DEPRECATED.json


# format json file
jq . "$profile"-LAMBDA-DEPRECATED.json | less -R >> "$profile"-LAMBDA-DETAIL.json

# Use AWK to create a .json formatted file.
awk '/FunctionName/{++cnt} END {print cnt}' "$profile"-LAMBDA-DETAIL.json > "$profile"-lambda-functions.txt

# This awk command checks if the value in the first field is an empty string (""). If it is, it sets the count to zero; otherwise, it uses the value in the first field.
# This will result in a JSON structure with a count of zero (number format) when there are no occurrences of "FunctionName".
awk ' BEGIN { print "["; }   { print " {\n" "   \"lambdaFunction\": " ($1 == "" ? 0 : $1) "\n  }" } END { print "]" } ' "$profile"-lambda-functions.txt > "$profile"-LAMBDA-COUNT.json

echo "Removed following redundant files:"
rm -rvf "$profile"-lambdas-id.json "$profile"-lambdas-al.json "$profile"-lambda-functions.txt

# Print horizontal line.
printf '%.s─' $(seq 1 $(tput cols))
echo
echo "Done! ✨ ✨ "

# Record the end time.
end_time=$(date +%s)

# Calculate the duration.
duration=$((end_time - start_time))

# Display the timeline.
echo "Process finished at: $(date -r $end_time)"
echo "Total duration: $duration seconds"

echo
break
;;
*)
echo "Invalid AWS profile. Please select a valid AWS profile."
;;
esac
done

# Exit script after 2 seconds..
sleep 2
kill -15 $PPID

The select options when you run the script.

PHP

I use a webpage with PHP to run the script, on that webpage you can select the AWS account you want the fetch data from. I work with AWS-SSO and then use Granted (it’s called ‘assume’ in the code) to access a specific AWS account. It all runs local btw through my IDE, I do not want to expose anything to the internet, like for instance running a webserver.

The select box on the PHP page.

The code for the PHP page:

!DOCTYPE html>
<html lang='en'>
<head>
    <title>DEPRECATED RUNTIMES</title>
    <meta charSet='UTF-8'>
    <meta http-equiv='x-ua-compatible' content='IE=edge'>
    <meta http-equiv='content-Type' content='text/html; charset=iso-8859-1'>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <meta name='mobile-web-app-capable' content='yes'>
    <meta name='apple-mobile-web-app-capable' content='yes'>
    <meta name='apple-mobile-web-app-status-bar-style' content='black'>

    <!--FAVICONS-->
    <link rel="apple-touch-icon" sizes="180x180" href="../../_genericAssets/favicon_package/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="../../_genericAssets/favicon_package/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="192x192" href="../../_genericAssets/favicon_package/android-chrome-192x192.png">
    <link rel="icon" type="image/png" sizes="16x16" href="../../_genericAssets/favicon_package/favicon-16x16.png">
    <link rel="manifest" href="../../_genericAssets/favicon_package/site.webmanifest">
    <link rel="mask-icon" href="../../_genericAssets/favicon_package/safari-pinned-tab.svg" color="#5BBAD5">
    <meta name="msapplication-TileColor" content="#2B5797">
    <meta name="theme-color" content="#FFFFFF">

    <!--GOOGLE FONTS-->
    <link rel='preconnect' href='https://fonts.googleapis.com'>
    <link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>

    <!--LIBRARIES-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="../assets/css/tooltip.css" rel="stylesheet">
    <link rel="stylesheet" href="../../_genericAssets/css/php.css">
</head>
<body>

<div class="bumpDesignBox">
    <div>
        <a class="material-symbols-sharp toolTip" onclick="window.location.assign('../../compliance/compliance_db.html')"> <span> Dashboard </span>dashboard</a>
        <a class="material-symbols-sharp toolTip" onclick="window.location.assign('../../home.html')"> <span> Home </span>other_houses</a>
        <a class="material-symbols-sharp toolTip" onclick="window.location.assign('../web/lambda-deprecated.html')"> <span> Lambda Details </span>assignment_return </a>
        <a class="material-symbols-sharp toolTip" id="clear_storage" onclick="location.reload()"> <span> Clear Local Storage </span>delete_history</a>
    </div>

    <form action="../php-get/get-lambdas-deprecated.php" method="post">
        <label class="customLabel"></label>
        <select id="selector_value" name="choice" class="customSelector">
            <option value="01">YOUR-FIRST-AWS-PROFILE | 000000000000</option>
            <option value="02">YOUR-SECOND-AWS-PROFILE | 000000000000</option>
            <option value="03">YOUR-THIRD-AWS-PROFILE | 000000000000</option>
            <option value="04">YOUR-FOURTH-AWS-PROFILE | 000000000000</option>
            <option value="05">YOUR-FIFTH-AWS-PROFILE | 000000000000</option>
        </select>
        <button type="submit" class="customButton material-symbols-sharp">highlight_mouse_cursor</button>
    </form>

</div>

<script src="../../_genericAssets/js/keepSelectorInLocalStorage.js"></script>

<?php
putenv("TERM=xterm-256color");
error_reporting(-1);
ini_set('display_errors', 'On');

// Get the user's choice via a form
if (!empty($_POST['choice'])) {
    $userChoice = $_POST['choice'];

    // Execute the shell script and pass the user's choice as input
    $command = "echo $userChoice | ../logic/lambda-deprecated.sh";
    $output = shell_exec($command);

    echo "<br>";
    echo '<pre>' . $output . ' </pre>';
    exit;
}
?>

</body>
</html>

The table

The result is presented on a webpage in a table. See the picture on the top of the page. The webpage is integrated in a dashboard, but that is not shown here. There’s a lot of logic used, I’m not going over that in depth, but you will notice it when you inspect the code. This is the code for filling the table with data and the markup with stuff, like info pop-up buttons and a lot more.

<!DOCTYPE html>
<html lang="en">
<head>
    <!--METADATA-->
    <title>DEPRECATED RUNTIMES </title>
    <meta charSet="UTF-8">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <meta content="yes" name="mobile-web-app-capable">
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="black" name="apple-mobile-web-app-status-bar-style">

    <!--FAVICONS-->
    <link color="#5BBAD5" href="../../_genericAssets/favicon_package/safari-pinned-tab.svg" rel="mask-icon">
    <link href="../../_genericAssets/favicon_package/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180">
    <link href="../../_genericAssets/favicon_package/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png">
    <link href="../../_genericAssets/favicon_package/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png">
    <link href="../../_genericAssets/favicon_package/android-chrome-192x192.png" rel="icon" sizes="192x192" type="image/png">
    <meta content="#DA532C" name="msapplication-TileColor">
    <meta content="rgba(255, 255, 255, 1)" name="theme-color">
    <link href="../../_genericAssets/favicon_package/site.webmanifest" rel="manifest">

    <!--GOOGLE FONTS-->
    <link href="https://fonts.googleapis.com" rel="preconnect">
    <link crossorigin href="https://fonts.gstatic.com" rel="preconnect">
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"/>

    <!--STYLESHEETS-->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet"/>
    <link href="../assets/css/main.css" rel="stylesheet">
    <link href="../assets/css/banner.css" rel="stylesheet">
    <link href="../assets/css/popup.css" rel="stylesheet">
    <link href="../assets/css/tooltip.css" rel="stylesheet">
    <link href="../assets/css/printstyle.css" rel="stylesheet">

    <!--GENERIC LIBRARIES-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="../../_genericAssets/js/toggleFullscreenLight.js"></script>
    <script src="../../_genericAssets/js/jspdf.umd.js" type="text/javascript"></script>
    <script src="../../_genericAssets/js/html2canvas.js" type="text/javascript"></script>
    <script src="../../_genericAssets/js/FileSaver.js" type="text/javascript"></script>

    <style>
        .copyable {
            cursor: pointer;
            position: relative;
            /*Set a max-width for the table cell*/
            max-width: 17vw;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            user-select: all; /* Allow text selection */
            text-align: left;
        }
    </style>
</head>
<body>
<!--Add this HTML for the copy popup-->
<div class="popupLambda" id="copy_popup">Lambda details copied!</div>

<!--pop-up info button-->
<div class="popupLambda" onclick="popUpFunction()" style="margin-top: -5vw;">
    <div class="popuptextLambda" id="popup_text" style="width: 85vw;">
        <h2 style="line-height: 0; text-align: center;">Supported Lambda runtimes and projected deprecation dates.</h2>
        <hr style="position: inherit; height: 0; margin-top: -4vw; margin-bottom: -2vw; opacity: 25%">
        <table style="width:100%">
            <tr>
                <th class="thLambda">Name</th>
                <th class="thLambda">Identifier</th>
                <th class="thLambda">SDK</th>
                <th class="thLambda">Operating system</th>
                <th class="thLambda">Deprecation date</th>
                <th class="thLambda">Block function create</th>
                <th class="thLambda">Block function update</th>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 20</td>
                <td class="tdLambda">nodejs20.x</td>
                <td class="tdLambda">3.362.0</td>
                <td class="tdLambda">Amazon Linux 2023</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 18</td>
                <td class="tdLambda">nodejs18.x</td>
                <td class="tdLambda">3.362.0</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 16</td>
                <td class="tdLambda">nodejs16.x</td>
                <td class="tdLambda">2.1374.0</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">Jun 12, 2024</td>
                <td class="tdLambda">Jul 15, 2024</td>
                <td class="tdLambda">Aug 15, 2024</td>
            </tr>
            <tr>
                <td class="tdLambda">Python 3.12</td>
                <td class="tdLambda">python3.12</td>
                <td class="tdLambda">boto3-1.28.72 botocore-1.31.72</td>
                <td class="tdLambda">Amazon Linux 2023</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Python 3.11</td>
                <td class="tdLambda">python3.11</td>
                <td class="tdLambda">boto3-1.27.1 botocore-1.30.1</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Python 3.10</td>
                <td class="tdLambda">python3.10</td>
                <td class="tdLambda">boto3-1.26.90 botocore-1.29.90</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Python 3.9</td>
                <td class="tdLambda">python3.9</td>
                <td class="tdLambda">boto3-1.26.90 botocore-1.29.900</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Python 3.8</td>
                <td class="tdLambda">python3.8</td>
                <td class="tdLambda">boto3-1.26.90 botocore-1.29.90</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">Oct 14, 2024</td>
                <td class="tdLambda">Nov 13, 2024</td>
                <td class="tdLambda">Jan 7, 2025</td>
            </tr>
            <tr>
                <td class="tdLambda">Java 21</td>
                <td class="tdLambda">java21</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2023</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Java 17</td>
                <td class="tdLambda">java17</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Java 11</td>
                <td class="tdLambda">java11</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">Java 8</td>
                <td class="tdLambda">java8.al2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">.NET 7 (container only)</td>
                <td class="tdLambda">dotnet7</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">May 14, 2024</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">.NET 6</td>
                <td class="tdLambda">dotnet6</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">Nov 12, 2024</td>
                <td class="tdLambda">Jan 11, 2025</td>
                <td class="tdLambda">Feb 11, 2025</td>
            </tr>
            <tr>
                <td class="tdLambda">Ruby 3.2</td>
                <td class="tdLambda">ruby3.2</td>
                <td class="tdLambda">3.1.0</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">ROS-only Runtime</td>
                <td class="tdLambda">provided.al2023</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2023</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">OS-only Runtime</td>
                <td class="tdLambda">provided.al2023</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2023</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">OS-only Runtime</td>
                <td class="tdLambda">provided.al2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
        </table>
    </div>
</div>

<!--pop-up info button-->
<div class="popupLambda" onclick="popUpFunctionLambda()" style="margin-top: -5vw;">
    <div class="popuptextLambda" id="popup_lambda" style="width: 85vw;">
        <h2 style="line-height: 0; text-align: center;">Deprecated Lambda runtimes.</h2>
        <hr style="position: inherit; height: 0; margin-top: -4vw; margin-bottom: -2vw; opacity: 25%">
        <table style="width:100%">
            <tr>
                <th class="thLambda">Name</th>
                <th class="thLambda">Identifier</th>
                <th class="thLambda">Operating system</th>
                <th class="thLambda">Deprecation date</th>
                <th class="thLambda">Block function create</th>
                <th class="thLambda">Block function update</th>
            </tr>
            <tr>
                <td class="tdLambda">Java 8</td>
                <td class="tdLambda">java8</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Jan 8, 2024</td>
                <td class="tdLambda">Feb 8, 2024</td>
                <td class="tdLambda">Mar 12, 2024</td>
            </tr>
            <tr>
                <td class="tdLambda">Go 1.x</td>
                <td class="tdLambda">go1.x</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Jan 8, 2024</td>
                <td class="tdLambda">Feb 8, 2024</td>
                <td class="tdLambda">Mar 12, 2024</td>
            </tr>
            <tr>
                <td class="tdLambda">OS-only Runtime</td>
                <td class="tdLambda">provided</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Jan 8, 2024</td>
                <td class="tdLambda">Feb 8, 2024</td>
                <td class="tdLambda">Mar 12, 2024</td>
            </tr>
            <tr>
                <td class="tdLambda">Ruby 2.7</td>
                <td class="tdLambda">ruby2.7</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Dec 7, 2023</td>
                <td class="tdLambda">Jan 9, 2024</td>
                <td class="tdLambda">Feb 8, 2024</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 14</td>
                <td class="tdLambda">nodejs14.x</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Dec 4, 2023</td>
                <td class="tdLambda">Jan 9, 2024</td>
                <td class="tdLambda">Feb 8, 2024</td>
            </tr>
            <tr>
                <td class="tdLambda">Python 3.7</td>
                <td class="tdLambda">python3.7/td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Dec 4, 2023</td>
                <td class="tdLambda">Jan 9, 2024</td>
                <td class="tdLambda">Feb 8, 2024</td>
            </tr>
            <tr>
                <td class="tdLambda">.NET Core 3.1</td>
                <td class="tdLambda">dotnetcore3.1</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">Apr 3, 2023</td>
                <td class="tdLambda">Apr 3, 2023</td>
                <td class="tdLambda">May 3, 2023</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 12</td>
                <td class="tdLambda">nodejs12.x</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">Mar 31, 2023</td>
                <td class="tdLambda">Mar 31, 2023</td>
                <td class="tdLambda">Apr 30, 2023</td>
            </tr>
            <tr>
                <td class="tdLambda">Python 3.6</td>
                <td class="tdLambda">python3.6</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Jul 18, 2022</td>
                <td class="tdLambda">Jul 18, 2022</td>
                <td class="tdLambda">Aug 29, 2022</td>
            </tr>
            <tr>
                <td class="tdLambda">.NET 5 (container only)</td>
                <td class="tdLambda">dotnet5.0</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">May 10, 2022</td>
                <td class="tdLambda"></td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">.NET Core 2.1</td>
                <td class="tdLambda">dotnetcore2.1</td>
                <td class="tdLambda">Amazon Linux </td>
                <td class="tdLambda">Jan 5, 2022</td>
                <td class="tdLambda">Jan 5, 2022</td>
                <td class="tdLambda">Apr 13, 2022</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 10</td>
                <td class="tdLambda">nodejs10.x</td>
                <td class="tdLambda">Amazon Linux 2</td>
                <td class="tdLambda">Jul 30, 2021</td>
                <td class="tdLambda">Jul 30, 2021</td>
                <td class="tdLambda">Feb 14, 2022</td>
            </tr>
            <tr>
                <td class="tdLambda">Ruby 2.5</td>
                <td class="tdLambda">ruby2.5</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Jul 30, 2021</td>
                <td class="tdLambda">Jul 30, 2021</td>
                <td class="tdLambda">Mar 31, 2022</td>
            </tr>
            <tr>
                <td class="tdLambda">Python 2.7</td>
                <td class="tdLambda">python2.7</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Jul 15, 2021</td>
                <td class="tdLambda">Jul 15, 2021</td>
                <td class="tdLambda">Mar 30, 2022</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 8.10</td>
                <td class="tdLambda">nodejs8.10</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Mar 6, 2020</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Mar 6, 2020</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 4.3</td>
                <td class="tdLambda">nodejs4.3</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Mar 5, 2020</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Mar 5, 2020</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 4.3 edge</td>
                <td class="tdLambda">nodejs4.3-edge</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Mar 5, 2020</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Apr 30, 2019</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 6.10</td>
                <td class="tdLambda">nodejs6.10</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Aug 12, 2019</td>
                <td class="tdLambda">Aug 12, 2019</td>
                <td class="tdLambda"></td>
            </tr>
            <tr>
                <td class="tdLambda">.NET Core 1.0</td>
                <td class="tdLambda">dotnetcore1.0</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">Jun 27, 2019</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Jul 30, 2019</td>
            </tr>
            <tr>
                <td class="tdLambda">.NET Core 2.0</td>
                <td class="tdLambda">dotnetcore2.0</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">May 30, 2019</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">May 30, 2019</td>
            </tr>
            <tr>
                <td class="tdLambda">Node.js 0.10</td>
                <td class="tdLambda">nodejs</td>
                <td class="tdLambda">Amazon Linux</td>
                <td class="tdLambda">May 30, 2019</td>
                <td class="tdLambda"></td>
                <td class="tdLambda">Oct 31, 2016</td>
            </tr>
        </table>
    </div>
</div>

<!--pop-up info button-->
<div class="popupLambda" onclick="popUpFunctionLambdaConfig()" style="margin-top: -5vw;">
    <div class="popuptextLambda" id="popup_lambda_config" style="width: 45vw;">
        <br>
        <h2>Configuring Lambda function options.</h2>
        <hr style="position: inherit; height: 0; margin-top: -4vw; margin-bottom: -2vw; opacity: 25%">
        <h2 style="line-height: 1.5vw"> After you create a function, you can configure additional capabilities for the function, such as triggers, network access, and file system access. <br>
            <br>
                                        You can also create and edit test events to test your function using the console. <br>
                                        Check the link below for all configuration options <br>
            <br>
            <br>
            <a class="material-symbols-sharp toolTip" onclick="window.location.assign('https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html')"> <span> Configuration </span>info</a>
        </h2>
    </div>
</div>

<a class="material-symbols-sharp toolTip" onclick="window.location.assign('../../compliance/compliance_db.html')"> <span> Dashboard </span>dashboard</a>
<a class="material-symbols-sharp toolTip" onclick="window.location.assign('../../home.html')"> <span> Home </span>other_houses</a>
<a class="material-symbols-sharp toolTip" onclick="location.reload()"> <span> Refresh </span>autorenew</a>
<a class="material-symbols-sharp toolTip" id="clear_storage" onclick="location.reload()"> <span> Clear Local Storage </span>delete_history</a>
<a class="material-symbols-sharp toolTip" onclick="set_full_screen()"> <span> Full Screen </span>fullscreen</a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip" onclick="popUpFunction()"> <span> Lambda Runtimes </span>info</a>
<a class="material-symbols-sharp toolTip" onclick="popUpFunctionLambda()"> <span> Lambda Deprecated Runtimes </span>info</a>
<a class="material-symbols-sharp toolTip" onclick="popUpFunctionLambdaConfig()"> <span> Configuring Lambda function options </span>info</a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<span id="preview-container"> </span>
<a class="material-symbols-sharp toolTip" id="csv_preview_button"> <span> Download Preview </span> preview</a>
<a class="material-symbols-sharp toolTip" id="csv_download_button"> <span> Download .csv </span> csv</a>
<a class="material-symbols-sharp toolTip" onclick="window.print();"> <span> Download .pdf </span>picture_as_pdf</a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip" onclick="window.location.assign('../php-get/get-lambdas-deprecated.php')"> <span> Get New Data </span>cloud_download</a>
<a class="material-symbols-sharp toolTip" onclick="window.location.assign('../php-backup/backup-lambda-deprecated.php')"> <span> Back Up Data </span>backup_table</a>
<a class="material-symbols-sharp toolTip" onclick="window.location.assign('../php-restore/restore-lambda-deprecated.php')"> <span> Restore Data </span>restore_from_trash</a>
<a class="material-symbols-sharp toolTip" onclick="window.location.assign('../php-clear/clear-lambda-deprecated.php')"> <span> Delete Data </span>delete</a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip"> <span> </span> </a>
<a class="material-symbols-sharp toolTip" onclick="window.location.assign('../../auth.html')"> <span> Log In </span>login</a>
<a class="material-symbols-sharp toolTip"> <span> Settings </span>settings</a>
<a class="material-symbols-sharp toolTip"> <span> Apps </span>apps</a>
<a class="material-symbols-sharp toolTip" onclick="setTimeout(function() {window.close()}, 10000);"> <span> Close Window </span>close</a>

<hr style="position: inherit; height: 0; margin-top: 1vw; margin-bottom: 0; opacity: 25%">

<label for="selector_value">SELECT YOUR PROFILE:&nbsp;
    <select id="selector_value" onchange="saveDataSource()">
        <option value="YOUR-FIRST-AWS-PROFILE"> YOUR-FIRST-AWS-PROFILE</option>
        <option value="YOUR-SECOND-AWS-PROFILE"> YOUR-SECOND-AWS-PROFILE</option>
        <option value="YOUR-THIRD-AWS-PROFILE"> YOUR-THIRD-AWS-PROFILE</option>
        <option value="YOUR-FOURTH-AWS-PROFILE"> YOUR-FOURTH-AWS-PROFILE</option>
    </select>
                            &nbsp; &nbsp; GET LAMBDAS</label>
<hr style="position: inherit; height: 0; margin-top: .5vw; margin-bottom: 0; opacity: 25%; visibility: hidden">

<div>
    <div class="column">
        <table class="dataTable">
            <tbody id="scan_date">
            <tr>
                <th> Scan Date</th>
            </tr>

            <script>
                function loadDataForTableDate(tableId) {
                    const jsonFile = `../logic/output-lambda-deprecated/${globalValue}-LAMBDA-SCANDATE.json`;
                    const table = $(`#${tableId}`);

                    $("#scan_date td").parent().remove();
                    $.getJSON(jsonFile, function (data) {

                        let tableContent = '';
                        $.each(data, function (key, value) {
                            tableContent += '<tr>';
                            tableContent += '<td>' + value + '</td>';
                            tableContent += '</tr>';
                        });
                        table.append(tableContent);
                    }).fail(function () {
                        table.append('<td colspan="3" style="background: rgba(255,255,255,0.5); text-align: center; color: rgb(98,1,1,1); font-family: Courier New, Courier, mono, serif; font-weight: bold">Error loading resource!</td></tr>');
                    });
                }
            </script>
            </tbody>
        </table>
    </div>

    <!--=====TABLE 02====-->
    <div class="column">
        <table class="dataTable">
            <tbody id="this_id">
            <tr>
                <th> Account ID</th>
            </tr>

            <script>
                function loadDataForTableThisId(tableId) {
                    const jsonFile = `../logic/output-lambda-deprecated/${globalValue}-LAMBDA-ID.json`;
                    const table = $(`#${tableId}`);

                    $("#this_id td").parent().remove();
                    $.getJSON(jsonFile, function (data) {

                        let tableContent = '';
                        $.each(data, function (key, value) {
                            tableContent += '<tr>';
                            tableContent += '<td>' + value["accountId"];
                            tableContent += '</tr>';
                        });
                        table.append(tableContent);
                    }).fail(function () {
                        table.append('<td colspan="3" style="background: rgba(255,255,255,0.5); text-align: center; color: rgb(98,1,1,1); font-family: Courier New, Courier, mono, serif; font-weight: bold">Error loading resource!</td></tr>');
                    });
                }
            </script>
            </tbody>
        </table>
    </div>

    <!--=====TABLE 03====-->
    <div class="column">
        <table class="dataTable">
            <tbody id="this_alias">
            <tr>
                <th> Alias Name</th>
            </tr>

            <script>
                function loadDataForTableThisAlias(tableId) {
                    const jsonFile = `../logic/output-lambda-deprecated/${globalValue}-LAMBDA-ALIAS.json`;
                    const table = $(`#${tableId}`);

                    $("#this_alias td").parent().remove();
                    $.getJSON(jsonFile, function (data) {

                        let tableContent = '';
                        $.each(data, function (key, value) {
                            tableContent += '<tr>';
                            tableContent += '<td>' + value["alias"];
                            tableContent += '</tr>';
                        });
                        table.append(tableContent);
                    }).fail(function () {
                        table.append('<td colspan="3" style="background: rgba(255,255,255,0.5); text-align: center; color: rgb(98,1,1,1); font-family: Courier New, Courier, mono, serif; font-weight: bold">Error loading resource!</td></tr>');
                    });
                }
            </script>
            </tbody>
        </table>
    </div>

    <!--=====TABLE 04====-->
    <div class="column">
        <table class="dataTable">
            <tbody id="count_lambdas">
            <tr>
                <th>Deprecated Runtimes</th>
            </tr>

            <script>
                function loadDataForTableCountLambdas(tableId) {
                    const jsonFile = `../logic/output-lambda-deprecated/${globalValue}-LAMBDA-COUNT.json`;
                    const table = $(`#${tableId}`);

                    $("#count_lambdas td").parent().remove();
                    $.getJSON(jsonFile, function (data) {
                        let tableContent = '';

                        if (data.length > 0) {
                            $.each(data, function (key, value) {
                                let lambdaFunction = value["lambdaFunction"] ? value["lambdaFunction"] : value["lambdaFunction"];
                                // This is a variable backgroundStyle that dynamically sets the background style based on whether nonCompliance is equal to 'Compliant!'.
                                // This way, the background color will be green when the value is "Compliant!" and rgb(138, 24, 6) for other cases.
                                let backgroundStyle = lambdaFunction === lambdaFunction ? 'background: rgb(5,117,47);' : 'background: rgb(5,117,47);';
                                tableContent += '<tr>';
                                tableContent += '<td style="' + backgroundStyle + '">' + lambdaFunction;
                                tableContent += '</tr>';
                            });
                        } else {
                            tableContent += '<tr>';
                            tableContent += '<td colspan="1" style="background: rgb(5,117,47);">lambdaFunction</td>';
                            tableContent += '</tr>';
                        }
                        table.append(tableContent);
                    }).fail(function () {
                        table.append('<td colspan="1" style="background: rgba(255,255,255,0.5); text-align: center; color: rgb(98,1,1,1); font-family: Courier New, Courier, mono, serif; font-weight: bold">Failed to load resource!</td>');
                    });
                }
            </script>
            </tbody>
        </table>
    </div>

    <hr style="position: inherit; height: 0; margin-bottom: -1vw; opacity: 25%; visibility: hidden">

    <!--=====TABLE 05====-->
    <div class="column">
        <table class="dataTable" id="lambdaTable">
            <thead>
            <!--<tr> defines a tableRow of cells in a table-->
            <!--tableRow's cells can be established using <td> (data cell) and <th style="width: auto; height: .5vw; font-size: .8vw;"> (header cell)-->
            <!--both <th style="width: auto; height: .5vw; font-size: .8vw;"> and <td> time colspan, specify how many columns wide the cell is, default is 1-->
            <!--tableRowspan on cells indicate they should span more than one table tableRow-->
            <tr>
                <th style="cursor: pointer; width: 42vw"> Function Name</th>
                <th style="width: 7vw; cursor: pointer;"> Runtime</th>
                <th style="cursor: pointer"> Description</th>
                <th style="cursor: pointer"> Function Arn</th>
            </tr>
            </thead>
            <tbody id="lambda_details">
            <!--the script to fill the table with the .json data-->
            <script>
                function loadDataForTableLambdaDetails(tableId) {
                    const jsonFile = `../logic/output-lambda-deprecated/${globalValue}-LAMBDA-DETAIL.json`;
                    const table = $(`#${tableId}`);

                    $("#lambda_details td").parent().remove();
                    $.getJSON(jsonFile, function (data) {
                        let tableContent = '';

                        $.each(data["Functions"], function (key, value) {
                            let functionName = value.FunctionName || 'No Data!';
                            let runtime = value.Runtime || 'No Data!';
                            let description = value.Description || 'No Data!';
                            let functionArn = value.FunctionArn || 'No Data!';

                            tableContent += '<tr>';
                            if (functionName !== null && functionName !== undefined && functionName !== "") {
                                // If functionName is not empty, display the value
                                tableContent += `<td style="text-align: left;" class="copyable" data-resource-id="${functionName}"> ${functionName} </td>`;

                            } else {
                                // If functionName is empty, display "no data"
                                tableContent += '<td>No Data!</td>';
                            }

                            if (runtime !== null && runtime !== undefined && runtime !== "") {
                                // If runtime is not empty, display the value
                                tableContent += `<td style="text-align: left;" class="copyable" data-resource-id="${runtime}"> ${runtime} </td>`;
                            } else {
                                // If runtime is empty, display "no data"
                                tableContent += '<td>No Data!</td>';
                            }

                            if (description !== null && description !== undefined && description !== "") {
                                // If description is not empty, display the value
                                tableContent += '<td>' + description + '</td>';
                            } else {
                                // If description is empty, display "no data"
                                tableContent += '<td>No Data!</td>';
                            }

                            if (functionArn !== null && functionArn !== undefined && functionArn !== "") {
                                // If functionArn is not empty, display the value
                                tableContent += `<td style="text-align: left;" class="copyable" data-resource-id="${functionArn}"> ${functionArn} </td>`;
                            } else {
                                // If functionArn is empty, display "no data"Falias
                                tableContent += '<td>No Data!</td>';
                            }
                            tableContent += '</tr>';

                            // Function to sort the table by column index
                            function sortTable(columnIndex) {
                                const table = $('#lambdaTable');
                                const tbody = table.find('tbody');
                                const rows = tbody.find('tr').get();

                                rows.sort((a, b) => {
                                    const cellA = $(a).find(`td:eq(${columnIndex})`).text().toLowerCase();
                                    const cellB = $(b).find(`td:eq(${columnIndex})`).text().toLowerCase();
                                    return cellA.localeCompare(cellB);
                                });
                                tbody.empty().append(rows);
                            }

                            // Add click event listeners to table headers for sorting
                            $('#lambdaTable thead th').on('click', function () {
                                const columnIndex = $(this).index();
                                sortTable(columnIndex);
                            });
                        });
                        table.append(tableContent);

                        // Add click event to copyable elements
                        $(".copyable").click(function () {
                            const resourceIdToCopy = $(this).data("resourceId");

                            // Copy the text to the clipboard
                            navigator.clipboard.writeText(resourceIdToCopy).then(function () {
                                // Show the copy popup
                                $("#copy_popup").fadeIn().delay(1000).fadeOut("slow");
                            }).catch(function (err) {
                                console.error('Unable to copy to clipboard', err);
                            });
                        });
                    })
                }
            </script>
            </tbody>
        </table>
        <h1 style="visibility: hidden">extra whitespace</h1>
    </div>
</div>

<!--logic must be placed here-->
<script>
    function saveDataSource() {
        let selectedProfile = document.getElementById("selector_value").value;
        localStorage.setItem("selectedProfile", selectedProfile);
    }
</script>

<script src="../../_genericAssets/js/exportToCSVWithPreview.js"></script>
<script src="../../_genericAssets/js/keepSelectorInLocalStorage.js"></script>
<script src="../../_genericAssets/js/popup.js" type="text/javascript"></script>
<script src="../assets/js/globalValueLambdaDeprecated.js"></script>
</body>
</html>

Pop-up box with information regarding the deprecated runtimes:

Pop-up box with some information. Click on the box wil make it disappear.

Then there is a JavaScript function for the global variable used:

let globalValue; // Define a global variable to store the selected value

$(document).ready(function () {
    // Define a variable for the selector to prevent error
    const selectorValue = $('#selector_value')
    // Add change event listener to the global selector
    selectorValue.on('change', function () {
        globalValue = $(this).val();
        loadDataForTableDate('scan_date');
        loadDataForTableThisId('this_id');
        loadDataForTableThisAlias('this_alias');
        loadDataForTableCountLambdas('count_lambdas');
        loadDataForTableLambdaDetails('lambda_details');
    });

    // Load data for the tables based on the initial selection
    globalValue = selectorValue.val();
    loadDataForTableDate('scan_date');
    loadDataForTableThisId('this_id');
    loadDataForTableThisAlias('this_alias');
    loadDataForTableCountLambdas('count_lambdas');
    loadDataForTableLambdaDetails('lambda_details');
});

A JavaScript function to preview and download the data:

// to show a preview of the file before initiating the download.
// to achieve this is by creating a Blob (Binary Large Object) with the CSV content and creating a temporary URL for that Blob.
// This URL can be used to create a preview link.
// This code creates two links: one for preview and one for download.
// The preview link is opened in a new tab/window, showing the CSV content.
// After a short delay (1 second in this example), the download link is automatically clicked to initiate the download.
// Finally, both links are removed, and the Blob URL is revoked to free up resources.


function getTimestamp() {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    const hours = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    return `${year}${month}${day}_${hours}${minutes}${seconds}`;
}

function exportToCSVWithPreview() {
    const timestamp = getTimestamp();
    let csvContent = 'data:text/csv;charset=utf-8,';
    const tables = document.querySelectorAll('.dataTable');

    tables.forEach(function (table) {
        const rows = table.querySelectorAll('tr');

        rows.forEach(function (row, rowIndex) {
            const data = [];
            const columns = row.querySelectorAll('td, th');
            columns.forEach(function (column, columnIndex) {
                data.push(column.innerText);
            });

            csvContent += data.join(',') + '\n';
        });
    });

    const select = document.querySelector('#selector_value option:checked');
    console.log('value: ', select.value);
    console.log('text: ', select.text);

    // Create Blob
    const blob = new Blob([csvContent], {type: 'text/csv'});

    // Create a temporary URL for the Blob
    const blobUrl = URL.createObjectURL(blob);

    // Create a download link
    const downloadLink = document.createElement('a');
    downloadLink.setAttribute('id', 'csv_download_link');
    downloadLink.setAttribute('href', blobUrl);
    downloadLink.setAttribute('download', `${select.text}_${timestamp}.csv`);
    downloadLink.innerText = '';

    // Append the download link to the document body
    document.body.appendChild(downloadLink);

    // Open a new window with the preview HTML
    const previewWindow = window.open();
    previewWindow.document.write('<html lang="en"><head><title>Preview</title></head><body>');

    // Add your styles here
    previewWindow.document.write('<style>body { font-family: \'Roboto\', sans-serif; margin: 2vw; color: rgba(255, 255, 255, 0.5); background-color: rgb(10, 23, 100); }</style>');
    previewWindow.document.write('</head> <body>');
    previewWindow.document.write('<h2> CSV Download Preview </h2>  <br> <pre>' + csvContent + '</pre>');
    previewWindow.document.write('</body></html>');
    previewWindow.document.close();
}

// Add event listener to the preview button
document.getElementById('csv_preview_button').addEventListener('click', exportToCSVWithPreview);

// Add event listener to the download button
document.getElementById('csv_download_button').addEventListener('click', function () {
    const downloadLink = document.getElementById('csv_download_link');
    if (downloadLink) {
        // Trigger a click on the download link
        downloadLink.click();

        // Remove the download link and revoke the Blob URL after a short delay
        setTimeout(() => {
            document.body.removeChild(downloadLink);
            URL.revokeObjectURL(downloadLink.href);
        }, 1000);
    }
});

A JavaScript function for the popup:

function popUpFunction() {
    let popup = document.getElementById("popup_text");
    popup.classList.toggle("show");
}

function popUpFunctionLambda() {
    let popup = document.getElementById("popup_lambda");
    popup.classList.toggle("show");
}

function popUpFunctionLambdaConfig() {
    let popup = document.getElementById("popup_lambda_config");
    popup.classList.toggle("show");
}

A JavaScript function to keep the selected value in local storage:

$(document).ready(function () {
    // Get the saved value from local storage (if available)
    let savedValue = localStorage.getItem('selectedValue');
    let selector = $('#selector_value')
    // Set the selected value (if available)
    if (savedValue) {
        selector.val(savedValue);
    }

    // Listen for changes in the selection
    selector.on('change', function () {
        // Save the selected value to local storage
        localStorage.setItem('selectedValue', $(this).val());

        // Refresh the page
        location.reload();
    });

    // Add click event for the clear storage button
    $('#clear_storage').on('click', function () {
        // Clear the local storage
        localStorage.removeItem('selectedValue');
        // Optionally, you can also reload the page
        location.reload();
    });
});

A JavaScript function to toggle a fullscreen view of the webpage:

// Toggle fullscreen with the click of a button.
function set_full_screen() {
    if (!document.fullscreenElement && !document.webkitFullscreenElement) {  // current working methods
        if (document.documentElement.requestFullscreen) {
            document.documentElement.requestFullscreen();

        } else if (document.documentElement.webkitRequestFullscreen) {
            document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
        }
    } else {
        if (document.cancelFullScreen) {
            document.cancelFullScreen();
        } else if (document.webkitCancelFullScreen) {
            document.webkitCancelFullScreen();
        }
    }
}

There’s also a JavaScript function to copy certain data to the clipboard, like function-name and function-arn.

I also made use of the jquery library: https://jquery.com/, font awesome: https://fontawesome.com/search?c=social&o=r and Google Material fonts: https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Sharp and some other libraries.

Stay Safe! ☘️