{
    let fetchBinApp = async function (mod, cmd, args) {
        return fetch(`/binapp/${mod}/${cmd}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'text/plain'
            },
            body: JSON.stringify({args: args || []})
        }).then(response => response.text());
    }

    var binapp = {
        mode: 'file', 
        file:  function(cmd, args) {
            if (binapp.mode == 'http') {
                return fetchBinApp('file', cmd, args)
            }
            else if (window.BINAPP_CODE) {
                return binapp_file(window.BINAPP_CODE, cmd, args)
            }
        },
        http: function(cmd, args) {
            if (binapp.mode == 'http') {
                return fetchBinApp('http', cmd, args)
            }
            else if (window.BINAPP_CODE) {
                return binapp_http(window.BINAPP_CODE, cmd, args)
            }
        },
        dialog: function(cmd, args){
            if (binapp.mode == 'http') {
                if (cmd == "info") {
                    window.alert(args[0] + ': ' + args[1])
                }
                else {
                    return fetchBinApp('dialog', cmd, args)
                }
            }
            else if (window.BINAPP_CODE) {
                return binapp_dialog(window.BINAPP_CODE, cmd, args)
            }
        },
        data: function(cmd, args){
            if (binapp.mode == 'http') {
                return fetchBinApp('data', cmd, args)
            }
            else if (window.BINAPP_CODE) {
                return binapp_data(window.BINAPP_CODE, cmd, args)
            }
        },
        console: function(cmd, text) {
            if (binapp.mode == 'http') {
                console.log(text)
            }
            else if (window.BINAPP_CODE) {
                return binapp_console(cmd, text)
            }
        },
    }

    if (window.location.href.indexOf('http') == 0) binapp.mode = 'http'
    if (window.location.href.indexOf('data') == 0) binapp.mode = 'data'
}