var {class_name} = function(hidden, output, layers, weights, bias) {{

    this.hidden = hidden.toUpperCase();
    this.output = output.toUpperCase();
    this.network = new Array(layers.length + 1);
    for (var i = 0, l = layers.length; i < l; i++) {{
        this.network[i + 1] = new Array(layers[i]).fill(0.);
    }}
    this.weights = weights;
    this.bias = bias;

    var compute = function(activation, v) {{
        switch (activation) {{
            case 'LOGISTIC':
                for (var i = 0, l = v.length; i < l; i++) {{
                    v[i] = 1. / (1. + Math.exp(-v[i]));
                }}
                break;
            case 'RELU':
                for (var i = 0, l = v.length; i < l; i++) {{
                    v[i] = Math.max(0, v[i]);
                }}
                break;
            case 'TANH':
                for (var i = 0, l = v.length; i < l; i++) {{
                    v[i] = Math.tanh(v[i]);
                }}
                break;
            case 'SOFTMAX':
                var max = Number.NEGATIVE_INFINITY;
                for (var i = 0, l = v.length; i < l; i++) {{
                    if (v[i] > max) {{
                        max = v[i];
                    }}
                }}
                for (var i = 0, l = v.length; i < l; i++) {{
                    v[i] = Math.exp(v[i] - max);
                }}
                var sum = 0.0;
                for (var i = 0, l = v.length; i < l; i++) {{
                    sum += v[i];
                }}
                for (var i = 0, l = v.length; i < l; i++) {{
                    v[i] /= sum;
                }}
                break;
        }}
        return v;
    }};

    this.{method_name} = function(neurons) {{
        this.network[0] = neurons;

        for (var i = 0; i < this.network.length - 1; i++) {{
            for (var j = 0; j < this.network[i + 1].length; j++) {{
                for (var l = 0; l < this.network[i].length; l++) {{
                    this.network[i + 1][j] += this.network[i][l] * this.weights[i][l][j];
                }}
                this.network[i + 1][j] += this.bias[i][j];
            }}
            if ((i + 1) < (this.network.length - 1)) {{
                this.network[i + 1] = compute(this.hidden, this.network[i + 1]);
            }}
        }}
        this.network[this.network.length - 1] = compute(this.output, this.network[this.network.length - 1]);

        if (this.network[this.network.length - 1].length == 1) {{
            if (this.network[this.network.length - 1][0] > .5) {{
                return 1;
            }}
            return 0;
        }} else {{
            var classIdx = 0;
            for (var i = 0, l = this.network[this.network.length - 1].length; i < l; i++) {{
                classIdx = this.network[this.network.length - 1][i] > this.network[this.network.length - 1][classIdx] ? i : classIdx;
            }}
            return classIdx;
        }}

    }};

}};

if (typeof process !== 'undefined' && typeof process.argv !== 'undefined') {{
    if (process.argv.length - 2 === {n_features}) {{

        // Features:
        var features = process.argv.slice(2);

        // Parameters:
        const {layers}
        const {weights}
        const {bias}

        // Prediction:
        var clf = new {class_name}('{hidden_activation}', '{output_activation}', layers, weights, bias);
        var prediction = clf.{method_name}(features);
        console.log(prediction);

    }}
}}