JSFiddle - React, Tailwind, and code Playground

HTML

<body>
    <h1>MS Captcha Demo</h1>
    <div id="taskMessage"></div>
    <canvas id="captchaCanvas" width="320" height="200" style="border:1px solid black;"></canvas>
    <br/>
    <button id="refreshButton">Refresh</button>
    <button id="submitButton">Submit</button>
</body>
<script>
    $(document).ready(function () {
        var c = null;

        generateCaptcha = function () {
            if (c != null) {
                clearInterval(c.intervalFunction);
                delete c;
            }
                
            var options = {
                canvas: 'captchaCanvas',
                messageDiv: 'taskMessage',
                gameType: 'BinsAndBalls'
            };
            c = new MsCaptcha.CanvasCaptcha(options);
        }

        validate = function () {
            alert(c.isValid());
        }

        $('#refreshButton').click(function () {
            generateCaptcha();
        });

        $('#submitButton').click(function () {
            validate();
        });

        generateCaptcha();
    });
</script>

JavaScript

function deepCopy(o) {
    var copy = o, k;

    if (o && typeof o === 'object') {
        copy = Object.prototype.toString.call(o) === '[object Array]' ? [] : {};
        for (k in o) {
            copy[k] = deepCopy(o[k]);
        }
    }

    return copy;
}

function getIndexOfObjWithAttr(array, attr, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

function getIndexOfObjWithOwnAttr(array, attr, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i].hasOwnProperty(attr) && array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

function shuffle(array) { //Fisher-Yates Shuffle
    var counter = array.length, temp, index;

    while (counter > 0) {
        index = Math.floor(Math.random() * counter);
        counter--;
        temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    }

    return array;
}

var MsCaptcha;
(function (MsCaptcha) {

    var ObjectBall = (function ( option) {
        var self = this;
        this.position = option.position;
        this.color = option.hasOwnProperty("color")? option.color: 'red';
        this.radius = option.hasOwnProperty("radius")? option.radius : 10;
        this.dragable = option.hasOwnProperty("dragable") ? option.dragable : false;
        this.click = option.hasOwnProperty("click") ? option.click : null;
        this.dragStart = option.hasOwnProperty("dragStart") ? option.dragStart : null;
        this.dragEnd = option.hasOwnProperty("dragEnd") ? option.dragEnd : null;
        this.dragMove = option.hasOwnProperty("dragMove") ? option.dragMove : null;

        ObjectBall.prototype.render = function (context) {
            context.beginPath();
            context.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI, false);
            context.closePath();
            var specX = this.position.x + .3 * this.radius;
...