<html lang="en">

<head>
    <meta charset="utf-8">
    <title>Singular REST Commander</title>
    <link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
</head>

<body>
    <header>
            <div class="logo">
                <img src="https://static.wixstatic.com/media/7e7b4f_bd1a8a2e023c4329880c7bb12994f1fd~mv2.png/v1/crop/x_0,y_71,w_1578,h_155/fill/w_205,h_23,al_c,usm_0.66_1.00_0.01/7e7b4f_bd1a8a2e023c4329880c7bb12994f1fd~mv2.png" width="150" alt="Singular_Logo" title="">
            </div>
            <div class="logo2">
                <a href="https://www.singular.live/">
            <img src="https://static.wixstatic.com/media/7e7b4f_3ca9325e528747baabaa13dd349ad13b~mv2.png/v1/crop/x_83,y_0,w_580,h_517/fill/w_157,h_121,al_c,usm_0.66_1.00_0.01/7e7b4f_3ca9325e528747baabaa13dd349ad13b~mv2.png" width="30px">
        </a>
            </div>
    </header>

    <div class="container">
        <div class="wrapper">
            <div class="box box1">
                <a id="btnSend" onclick='sendRestCmd()' class="variantbutton">SEND<i class="fa fa-paper-plane" ></i></a>
                <a id="btnClear" onclick='clearUI()' class="variantbutton">CLEAR<i class="fa fa-undo"></i></a>
            </div>
            <div class="box box2">
                <div class="url-title">URL</div>
                <textarea id="requestURL" class="url">https://www.singular.live / ID: requestURL</textarea>
            </div>
            <div class="box box3">
                <div>
                    <form>
                        <select id="selectRestCmd" onchange="selectRestCmdChange()" size="8">
                            <option style="background-color: #ADD136; color: #000; border-radius:0px" disabled>Select Function</option>
                        <!-- Options will be insert here by the Script -->
                             
                        </select>
                    </form>
                </div>
            </div>
            <div class="box box4">
                <div class="boxheader">
                    <p>Request</p>
                </div>
                <textarea id="resourceURL" style="padding-left:7px; font-family: monospace;">Request Text... / ID = resourceURL</textarea>
            </div>
            <div class="box box5">
                <div class="boxheader">
                    <p>Response</p>
                </div>
                <textarea id="responseStatus" style="padding-left:7px; font-family: monospace;">Response Text... / ID = responseStatus</textarea>
            </div>
            <div class="box box6">
                <div class="boxheader">
                    <p>Request Body</p>
                </div>
                <textarea id="requestBody" style="padding-left:7px; font-family: monospace;">This is the area for JSON text, you can edit it. ID: requestBody</textarea>

            </div>
            <div class="box box7">
                <div class="boxheader">
                    <p>JSON Response</p>
                </div>
                <textarea id="responseJSON" style="padding-left:7px; font-family: monospace;" readonly>And this area here is for the LOG text, it is set to read only. ID: responseJSON</textarea>
            </div>
            <div class="box box8">
                <div>
                    <iframe class="iFrame" src="https://app.singular.live/output/35eUbv7rQO1zHGinkR0OWy/Output?aspect=16:9" id="appframe" src=""></iframe>
                </div>
            </div>
            <div class="box box9">
                <div class="boxheader">
                    <p>Debug Messages:</p>
                </div>
                <!-- debug output -->
                <textarea id="logMessage" style="overflow-y: scroll; padding-left:7px; font-family: monospace;" readonly> ... </textarea>
            </div>
        
        </div>
    </div>
</body>

</html>
@charset "utf-8";
/* CSS Document */

body {
    margin: 0;
    padding: 0;
    font-family: "Lato";
    color: #383838;
    background: #f2f2f2;
}

a {
    text-decoration: none;
    color: #333333;
}

p {
    color: #333333;
}

h3 {
    color: black;
    font-weight: 100;
    font-size: 13px;
    margin: 0px;
    padding: 13px;
    font-family: "Lato";

}

h2 {
    color: black;
    font-weight: 100;
    margin-left: 210px;
    margin-top: 60px;
}

td {
    text-align: right;
}

.container {
    width: 98%;
    margin: auto;
}

header {
    display: grid;
    grid-auto-columns: 1fr 7fr 1fr;
    background: #add136;
    margin-bottom: 20px;
    overflow: hidden;
    text-align: center;
    box-shadow: 0px 5px 15px #ccc;
}

.logo {
    float: left;
    margin-left: 30px;
    padding: 7px;
    grid-column: 1/2;
}

.logo2 {
    float: right;
    position: relative;
    padding-top: 2px;
    grid-column: 3/4;
}

.logo,
.logo2 {
    margin: 4px 10px;
}

textarea {
    resize: none;
    font-family: Lato;
    border-bottom-left-radius: 7px;
    border-bottom-right-radius: 7px;
    font-size: 10px;
    padding-top: 5px;
}

.buttons {
    padding-top: 30px;
    text-align: center;
    line-height: normal;
    color: #333333;
}

.iFrame {
    background-color: black;
    width: 100%;
    height: 100%;
    border: none;
    margin-top: 0px;
    margin-left: 0px;
    position: absolute;
}

#requestBody , #responseJSON, #logMessage{
    height: 275px;
    width: 100%;
}

#resourceURL , #responseStatus {
    width: 100%;
    height: 75px;
}

.variantbutton {
    font-family: "Lato";
    background-color: #add136;
    color: #333333;
    text-align: center;
    text-decoration: none;
    border-radius: 5px;
    cursor: default;
    align-self: center;
    padding: 10px 0px;
    font-size: 12px;
}

.fa {
    padding-left: 5px;
}

#btnSend {
    grid-column: 1/2;
}

#btnClear {
    grid-column: 3/4;
}

.variantbutton:hover {
    background-color: gray;
}

.url-title {
    background-color: #add136;
    border-bottom-left-radius: 7px;
    border-top-left-radius: 7px;
    align-self: center;
    padding: 10px 5px;
    font-size: 12px;
}

.url {
    border-radius: 0px 7px 7px 0px;
    resize: none;
    overflow: hidden;
    width: 100%;
    padding: 8px;
    font-size: 12px;
}

#logOutput {
    width: 100%;
}

/*GRID-----*/
/*---------*/
/*---------*/

.wrapper {
    display: grid;
    grid-template-columns: 200px 1fr 1fr 1fr 1fr;
    grid-template-rows: 35px 100px 300px 300px;
    grid-gap: 7px;
    /* justify-items:stretch; */
    /* align-items:stretch; */
}

.wrapper > div {
    padding: 0px;
}

.box1 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
    z-index: 1;
    grid-row: 1/2;
}

.box2 {
    grid-column: 2/6;
    display: grid;
    grid-template-columns: 45px 1fr;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.box3 {
    grid-column: 1/2;
    grid-row: 2/5;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.box4 {
    grid-column: 2/4;
    grid-row: 2/3;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.box5 {
    grid-column: 4/6;
    grid-row: 2/3;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.box6 {
    grid-column: 2/4;
    grid-row: 3/4;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.box7 {
    grid-column: 4/6;
    grid-row: 3/4;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.box8 {
    grid-column: 2/4;
    grid-row: 4/5;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.box9 {
    grid-column: 4/6;
    grid-row: 4/5;
    filter: drop-shadow(5px 1px 4px #cccccc);
    border-radius: 7px;
}

.nestedMain {
    display: grid;
    grid-template-rows: 25px auto;
    grid-gap: 0px;
}

.nestedButtons {
    display: grid;
    grid-template-rows: 45px 45px;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-gap: 7px;
}

.box {
    color: black;
}

.boxheader {
    background: #add136;
    border-top-left-radius: 7px;
    border-top-right-radius: 7px;
    grid-row: 1;
}

.boxheader > p {
    font-size: 11px;
    padding: 5px 10px;
    font-weight: bolder;
    height: 15px;
    margin: 0px;
}

/*LISTBOX*/
/*-------*/
/*-------*/

form {
    margin: 0;
    height: 715px;
}

#selectRestCmd {
    overflow-y: scroll;
    border-radius: 7px;
    width: 100%;
    height: 100%;
}

#selectRestCmd > option:first-child {
    width: 100%;
    height: 17px;
    padding: 5px 10px;
    border-radius: 7px 0px 0px 0px;
    font-size: 12px;
    background-color: #ADD136;
    color: #000;
}

#selectRestCmd > option {
    width: 100%;
    height: 17px;
    padding: 7px 3px 3px 3px;
    border-top: solid 1px #ccc;
    border-width: 80%;
    font-size: 10px;
    align-self: center;
    align-content: center;
    align-items: center;
}

/*Without the "Select Function" - Header*/

/*
    #mySelect > option:first-child{
        border-top-left-radius: 7px;
        border: none;
    }
*/

/*With the "Select Function" Header*/

#selectRestCmd > option:first-child:hover {
    border-right: solid 3px #add136;
}

#selectRestCmd > option:last-child {
    border-bottom-left-radius: 7px;
}

#selectRestCmd > option:hover {
    background-color: rgba(0, 0, 0, 0.1);
    border-right: solid 3px green;
    width: calc(100% - 9px);
    margin-left: 0;
}

/*SCROLLBAR*/

body ::-webkit-scrollbar {
    width: 6px;
    border-bottom-right-radius: 7px;
    border-top-right-radius: 7px;
}

body ::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
    border-bottom-right-radius: 7px;
    border-top-right-radius: 7px;
}

body ::-webkit-scrollbar-thumb {
    background-color: darkgrey;
    outline: 1px solid slategrey;
    border-bottom-right-radius: 7px;
    border-top-right-radius: 7px;
}
var restApiCalls = [];
var restApiCallMap = new Map();
var appInstanceId = '36766';
var dataNodeId = '1232';
var appAccessToken = '2CZziI55PpYD96bLPCvzon';
var credentials = 'YXBpc2RrQHNpbmd1bGFyLmxpdmU6c0RrQXBJ';

var urlSingularHome = 'https://app.singular.live';
var urlResourceAppInstances = '/apiv1/appinstances/';
var urlResourceDataNodes = '/apiv1/datanodes/';
var urlAppInstances = urlSingularHome + urlResourceAppInstances;
var urlDataNodes = urlSingularHome + urlResourceDataNodes;


//var urlAppId = "https://app.singular.live/apiv1/appinstances/8963/control";
//var urlAccessToken = "https://beta.singular.live/apiv1/control/3Wqax3fo6qXs0f7cASz61Y";

var requestMethod;
var requestURL;
var resourceURL;
var requestBody;

var plUpCtrlNode1 = [{
    "compositionName": "Baseline",
    "controlNode": {
        "payload": {
            "Title": "Title 1",
            "Text": "Baseline Information 1"
        }
    }
}];
var plUpCtrlNode2 = [{
    "compositionName": "Baseline",
    "controlNode": {
        "payload": {
            "Title": "Title 2",
            "Text": "Baseline Information 2"
        }
    }
}];

var plAnimIn = [{
    "compositionName": "Baseline",
    "animation": {
        "action": "play",
        "from": "Out",
        "to": "In"
    }
}];
var plAnimOUT = [{
    "compositionName": "Baseline",
    "animation": {
        "action": "play",
        "from": "In",
        "to": "Out"
    }
}];

var plEmpty = [{}];

/**************************************************************************
 * initialize 
 */

$(document).ready(function () {

    logOutput("[ready]: Start ...");

    // App Instance API Calls
    restApiCallMap.set('GET All App Instances', {
        'method': "GET",
        'resourceURL': urlResourceAppInstances,
        'requestURL': urlAppInstances,
        'requestBody': null
    });
    restApiCallMap.set('GET One App Instance', {
        'method': "GET",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}',
        'requestURL': urlAppInstances + appInstanceId,
        'requestBody': null
    });
    restApiCallMap.set('GET Outputs of App Instance', {
        'method': "GET",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/outputs',
        'requestURL': urlAppInstances + appInstanceId + '/outputs',
        'requestBody': null
    });
    restApiCallMap.set('GET Control Properties of App Instance', {
        'method': "GET",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': null
    });
    restApiCallMap.set('GET Subcompositions of an App Instance', {
        'method': "GET",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/subcompositions',
        'requestURL': urlAppInstances + appInstanceId + '/subcompositions',
        'requestBody': null
    });
    restApiCallMap.set('GET Subcompositions of an App Instance', {
        'method': "GET",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/subcompositions',
        'requestURL': urlAppInstances + appInstanceId + '/subcompositions',
        'requestBody': null
    });
    restApiCallMap.set('PUT Load "Blue" Composition into an App Instance', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/composition',
        'requestURL': urlAppInstances + appInstanceId + '/composition',
        'requestBody': {
            "refId": "85834"
        }
    });
    restApiCallMap.set('PUT Load "Green" Composition into an App Instance', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/composition',
        'requestURL': urlAppInstances + appInstanceId + '/composition',
        'requestBody': {
            "refId": "85836"
        }
    });

    restApiCallMap.set('PUT Jump Animation "Panel Left" to state "In"', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': [{
            "compositionName": "Panel Left",
            "animation": {
                "action": "jump",
                "to": "In"
            }
        }]
    });
    restApiCallMap.set('PUT Play Animation "Lower Topic" to state "In"', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': [{
            "compositionName": "Lower Topic",
            "animation": {
                "action": "play",
                "to": "In"
            }
        }]
    });
    restApiCallMap.set('PUT Play Animation "Lower Line" to state "In"', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': [{
            "compositionName": "Lower Line",
            "animation": {
                "action": "play",
                "to": "In"
            }
        }]
    });
    restApiCallMap.set('PUT Play Animation "Baseline Crawl" to state "In"', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': [{
            "compositionName": "Baseline Crawl",
            "animation": {
                "action": "play",
                "to": "In"
            }
        }]
    });
    restApiCallMap.set('PUT Play Animation All to state "Out"', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': [{
            "compositionName": "Lower Line",
            "animation": {
                "action": "play",
                "to": "Out"
            }
        }, {
            "compositionName": "Lower Topic",
            "animation": {
                "action": "play",
                "to": "Out"
            }
        }, {
            "compositionName": "Panel Left",
            "animation": {
                "action": "play",
                "to": "Out"
            }
        }, {
            "compositionName": "Baseline Crawl",
            "animation": {
                "action": "play",
                "to": "Out"
            }
        }]
    });
    restApiCallMap.set('PUT Update "Lower Topic" Content', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': [{
            "compositionName": "Lower Topic",
            "controlNode": {
                "payload": {
                    "Title": "Singular REST Commander",
                    "Subtitle": "Content updated using REST API PUT method..."
                }
            }
        }]
    });
    restApiCallMap.set('PUT Update "Lower Line" Content', {
        'method': "PUT",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}' + '/control',
        'requestURL': urlAppInstances + appInstanceId + '/control',
        'requestBody': [{
            "compositionName": "Lower Line",
            "controlNode": {
                "payload": {
                    "Text": "Singular.live - Graphics built for Streaming"
                }
            }
        }]
    });
    restApiCallMap.set('POST Create App Instance (min specs)', {
        'method': "POST",
        'resourceURL': urlResourceAppInstances,
        'requestURL': urlAppInstances,
        'requestBody': {
            "folder": "4e867728-b556-4d10-8761-afecf431614b",
            "apptemplate_id": "57",
            "apptemplate_version_status": "published",
            "name": "New Studio Control (no composition specified)"
        }
    });
    restApiCallMap.set('POST Create App Instance (full specs)', {
        'method': "POST",
        'resourceURL': urlResourceAppInstances,
        'requestURL': urlAppInstances,
        'requestBody': {
            "folder": "4e867728-b556-4d10-8761-afecf431614b",
            "apptemplate_id": "57",
            "apptemplate_version_status": "published",
            "name": "New Studio Control (composition specified)",
            "compositionList": [{
                "name": "Comp-for-DevDocs",
                "composition": {
                    "refId": "85834"
                }
            }],
            "account_id": "56",
            "user_id": "2290",
            "shareurl": "0"
        }
    });
    restApiCallMap.set('DELETE Delete App Instance', {
        'method': "DELETE",
        'resourceURL': urlResourceAppInstances + '{app_instance_id}',
        'requestURL': urlAppInstances + '39453',
        'requestBody': null
    });




    // Data Node API Calls
    restApiCallMap.set('GET All Data Nodes', {
        'method': "GET",
        'resourceURL': urlResourceDataNodes,
        'requestURL': urlDataNodes,
        'requestBody': null
    });
    restApiCallMap.set('GET Single Data Node', {
        'method': "GET",
        'resourceURL': urlResourceDataNodes + '{datanode_id}',
        'requestURL': urlDataNodes + dataNodeId,
        'requestBody': null
    });
    restApiCallMap.set('GET Single Data Node Definition', {
        'method': "GET",
        'resourceURL': urlResourceDataNodes + '{datanode_id}' + '/data',
        'requestURL': urlDataNodes + dataNodeId + '/data',
        'requestBody': null
    });
    restApiCallMap.set('PUT Update Data Node', {
        'method': "PUT",
        'resourceURL': urlResourceDataNodes + '{datanode_id}' + '/data',
        'requestURL': urlDataNodes + dataNodeId + '/data',
        'requestBody': {
          "payload": {
            "Crawl Title": "Title text here...",
            "Crawl Text": "Crawl text here...",
            "Crawl Speed": "10.0"
          }
        }
    });

    //    listApiCalls(restApiCallMap);
    initCommandSelector(restApiCallMap);

    logOutput("[ready]: ... End");
});

/**************************************************************************
 * 
 */
function initCommandSelector(callMap) {
    var x = document.getElementById("selectRestCmd");
    for (var [key, value] of callMap) {
//        logOutput("[initCommandSelector]: [key] = [" + key + "] [value] = [" + JSON.stringify(value) + "]");
        var option = document.createElement("option");
        option.text = key;
        x.add(option);
    }
}

/**************************************************************************
 * 
 */
function selectRestCmdChange() {
    var x = document.getElementById("selectRestCmd");
    if (x.selectedIndex >= 0) {
        var sel = x.options[x.selectedIndex];
        logOutput("[selectRestCmdChange]: [sel.text] = [" + sel.text + "]");

        requestMethod = restApiCallMap.get(sel.text).method;
        requestURL = restApiCallMap.get(sel.text).requestURL;
        resourceURL = restApiCallMap.get(sel.text).resourceURL;
        requestBody = restApiCallMap.get(sel.text).requestBody;

        document.getElementById("requestURL").innerHTML = requestURL;
        document.getElementById("resourceURL").innerHTML = requestMethod + ':   ' + resourceURL;
        document.getElementById("requestBody").innerHTML = JSON.stringify(requestBody, undefined, 2);

        document.getElementById("responseStatus").innerHTML = '';
        document.getElementById("responseJSON").innerHTML = '';
    }
}

/**************************************************************************
 * 
 */
function sendRestCmd() {
    var x = document.getElementById("selectRestCmd");
    if (x.selectedIndex >= 0) {
        var sel = x.options[x.selectedIndex];
        logOutput("[sendRestCmd]: [sel.text] = [" + sel.text + "]");
        requestURL  = document.getElementById("requestURL").value;
        requestBody = JSON.parse(document.getElementById("requestBody").value);


        switch (requestMethod) {
        case "GET":
//            singularRestGet(requestURL, credentials);
            singularRestCommand(requestURL, requestMethod, requestBody, credentials);
            break;
        case "PUT":
            singularRestCommand(requestURL, requestMethod, requestBody, credentials);
            break;
        case "POST":
            singularRestCommand(requestURL, requestMethod, requestBody, credentials);
            break;
        case "PATCH":
            //                singularRestPatch(requestURL, requestBody, credentials);
            break;
        case "DELETE":
            singularRestCommand(requestURL, requestMethod, requestBody, credentials);
            break;
        default:
            logOutput("[sendRestCmd]: UNKNOWN [restRequest] = [" + restRequest + "]");
        }
    }
}

/**************************************************************************
 * listApiCalls
 */
function clearUI() {
    document.getElementById("requestURL").innerHTML = '';
    document.getElementById("resourceURL").innerHTML = '';
    document.getElementById("requestBody").innerHTML = '';
    document.getElementById("responseStatus").innerHTML = '';
    document.getElementById("responseJSON").innerHTML = '';
    document.getElementById("logMessage").innerHTML = '';
}
/**************************************************************************
 * listApiCalls
 */
function listApiCalls(callMap) {
    for (var [key, value] of callMap) {
        logOutput("[listApiCalls]: [key] = [" + key + "] [value] = [" + JSON.stringify(value) + "]");
    }
}

/**************************************************************************
 * logOutput
*/
function logOutput(message) {
    var logText = document.getElementById("logMessage").innerHTML;
    document.getElementById("logMessage").innerHTML = logText + "\n" + message;
}

/**************************************************************************
 * singularRestCommand
*/
function singularRestCommand(url, method, body, auth) {
    var responseMessage;
    var options;

    // setup the HTTP call

    if (method == 'GET' || method == 'DELETE') {
        options = {
            'method': method,
            'contentType': 'application/json',
            'mode': 'cors',
            //		'muteHttpExceptions': true,
            "headers": {
                "Authorization": "Basic " + auth
            }
        }
    } else if (method == 'PUT' || method == 'POST') {
        options = {
            'method': method,
            'mode': 'cors',
            "headers": {
                "Authorization": "Basic " + auth,
                'content-type': 'application/json'
            },
            'body': JSON.stringify(body)
        };
    }

    fetch(url, options)
        .then((httpResponse) => {
            if (httpResponse.ok) {
                //                logOutput(httpResponse.status + "\n" + httpResponse.ok + "\n" + httpResponse.statusText);
                responseMessage = httpResponse.status + "   " + httpResponse.ok + "   " + httpResponse.statusText;
                document.getElementById("responseStatus").innerHTML = responseMessage;
                if (method != 'PUT') {
                  return httpResponse.json();
                }
            } else {
                responseMessage = httpResponse.status + "   " + httpResponse.ok + "   " + httpResponse.statusText;
                document.getElementById("responseStatus").innerHTML = responseMessage;
                return Promise.reject("Fetch did not succeed");
            }
        })
        .then(json => {
            console.log(json)
            document.getElementById("responseJSON").innerHTML = JSON.stringify(json, undefined, 2);
        })
        .catch((err) => {
            logOutput("ERROR: " + err);
            console.log("ERROR: " + err);
        });
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.