text: var $builtinmodule = function (name) {
      var mod = {};
  
      // Mathematical Constants
      mod.pi = new Sk.builtin.float_(Math.PI);
      mod.e = new Sk.builtin.float_(Math.E);
      mod.tau = new Sk.builtin.float_(2 * Math.PI);
      mod.nan = new Sk.builtin.float_(NaN);
      mod.inf = new Sk.builtin.float_(Infinity);
  
      // Number-theoretic and representation functions
      mod.ceil = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("ceil", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          if (Sk.__future__.ceil_floor_int) {
              return new Sk.builtin.int_(Math.ceil(Sk.builtin.asnum$(x)));
          };
  
          return new Sk.builtin.float_(Math.ceil(Sk.builtin.asnum$(x)));
      });
  
      mod.comb = new Sk.builtin.func(function (x, y) {
          throw new Sk.builtin.NotImplementedError("math.comb() is not yet implemented in Skulpt")
      });
  
      var get_sign = function (n) {
          //deals with signed zeros
          // returns -1 or +1 for the sign
          if (n) {
              n = n < 0 ? -1 : 1;
          } else {
              n = 1 / n < 0 ? -1 : 1;
          };
          return n
      };
  
      mod.copysign = new Sk.builtin.func(function (x, y) {
          // returns abs of x with sign y
          // does sign x * sign y * x which is equivalent
          Sk.builtin.pyCheckArgsLen("copysign", arguments.length, 2, 2);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          Sk.builtin.pyCheckType("y", "number", Sk.builtin.checkNumber(y));
  
          const _y = Sk.builtin.asnum$(y);
          const _x = Sk.builtin.asnum$(x);
          const sign_x = get_sign(_x);
          const sign_y = get_sign(_y);
          const sign = Sk.builtin.int_(sign_x * sign_y);
  
          return new Sk.builtin.float_(Sk.abstr.numberBinOp(x, sign, "Mult"));
  
      });
  
      mod.fabs = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("fabs", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          let _x = Sk.builtin.asnum$(Sk.builtin.float_(x)); //should raise OverflowError for large ints to floats
          _x = Math.abs(_x)
  
          return new Sk.builtin.float_(_x);
      });
  
      var MAX_SAFE_INTEGER_FACTORIAL = 18; // 19! > Number.MAX_SAFE_INTEGER
      mod.factorial = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("factorial", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          let _x = Sk.builtin.asnum$(x);
          x = Math.floor(_x);
  
          if (x != _x) {
              throw new Sk.builtin.ValueError("factorial() only accepts integral values");
          }
          if (x < 0) {
              throw new Sk.builtin.ValueError("factorial() not defined for negative numbers");
          }
  
          var r = 1;
          for (var i = 2; i <= x && i <= MAX_SAFE_INTEGER_FACTORIAL; i++) {
              r *= i;
          }
          if(x<=MAX_SAFE_INTEGER_FACTORIAL){
              return new Sk.builtin.int_(r);
          }else{
              // for big numbers (19 and larger) we first calculate 18! above
              // and then use bigintegers to continue the process.
  
              // This is inefficient as hell, but it produces correct answers.
  
              // promotes an integer to a biginteger
              function bigup(number){
                var n = Sk.builtin.asnum$nofloat(number);
                return new Sk.builtin.biginteger(number);
              }
  
              r = bigup(r);
              for (var i = MAX_SAFE_INTEGER_FACTORIAL+1; i <= x; i++) {
                  var i_bigup = bigup(i);
                  r = r.multiply(i_bigup);
              }
              return new Sk.builtin.lng(r);
          }
      });
  
      mod.floor = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("floor", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          if (Sk.__future__.ceil_floor_int) {
              return new Sk.builtin.int_(Math.floor(Sk.builtin.asnum$(x)));
          }
  
          return new Sk.builtin.float_(Math.floor(Sk.builtin.asnum$(x)));
      });
  
      mod.fmod = new Sk.builtin.func(function (x, y) {
          Sk.builtin.pyCheckArgsLen("fmod", arguments.length, 2, 2);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          Sk.builtin.pyCheckType("y", "number", Sk.builtin.checkNumber(y));
  
          const _x = Sk.builtin.asnum$(Sk.builtin.float_(x));
          const _y = Sk.builtin.asnum$(Sk.builtin.float_(y)); //should raise OverFlow for large ints to floats
  
          if ((_y == Infinity || _y == -Infinity) && isFinite(_x)) {
              return new Sk.builtin.float_(_x)
          };
          const r = _x % _y
          if (isNaN(r)) {
              if (!isNaN(_x) && !isNaN(_y)) {
                  throw new Sk.builtin.ValueError("math domain error");
              };
          };
          return Sk.builtin.float_(r);
      });
  
      mod.frexp = new Sk.builtin.func(function (x) {
          //  algorithm taken from https://locutus.io/c/math/frexp/
          Sk.builtin.pyCheckArgsLen("frexp", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          const arg = Sk.builtin.asnum$(x);
          const res = [arg, 0];
  
          if (arg !== 0 && Number.isFinite(arg)) {
              const absArg = Math.abs(arg);
              let exp = Math.max(-1023, Math.floor(Math.log2(absArg)) + 1);
              let m = absArg * Math.pow(2, -exp);
              // These while loops compensate for rounding errors that sometimes occur because of ECMAScript's Math.log2's undefined precision
              // and also works around the issue of Math.pow(2, -exp) === Infinity when exp <= -1024
              while (m < 0.5) {
                  m *= 2
                  exp--
              };
              while (m >= 1) {
                  m *= 0.5
                  exp++
              };
              if (arg < 0) {
                  m = -m
              };
              res[0] = m;
              res[1] = exp;
          };
          res[0] = new Sk.builtin.float_(res[0]);
          res[1] = new Sk.builtin.int_(res[1]);
          return new Sk.builtin.tuple(res)
      });
  
      mod.fsum = new Sk.builtin.func(function (iter) {
          // algorithm from https://code.activestate.com/recipes/393090/
          // as well as https://github.com/brython-dev/brython/blob/master/www/src/libs/math.js
          Sk.builtin.pyCheckArgsLen("fsum", arguments.length, 1, 1);
          if (!Sk.builtin.checkIterable(iter)) {
              throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(iter) + "' object is not iterable");
          }
  
          let partials = [];
          iter = Sk.abstr.iter(iter);
          let i, hi, lo;
          for (let x = iter.tp$iternext(); x !== undefined; x = iter.tp$iternext()) {
              Sk.builtin.pyCheckType("", "real number", Sk.builtin.checkNumber(x));
              i = 0;
              x = Sk.builtin.asnum$(Sk.builtin.float_(x));
              for (let j = 0, len = partials.length; j < len; j++) {
                  let y = partials[j]
                  if (Math.abs(x) < Math.abs(y)) {
                      let temp = x;
                      x = y;
                      y = temp;
                  }
                  hi = x + y;
                  lo = y - (hi - x);
                  if (lo) {
                      partials[i] = lo;
                      i++;
                  }
                  x = hi;
              }
              partials = partials.slice(0, i).concat([x])
          }
          const sum = partials.reduce(function (a, b) {
              return a + b;
          }, 0);
  
          return new Sk.builtin.float_(sum)
      });
  
      mod.gcd = new Sk.builtin.func(function (a, b) {
          Sk.builtin.pyCheckArgsLen("gcd", arguments.length, 2, 2);
          // non ints not allowed in python 3.7.x
          Sk.builtin.pyCheckType("a", "integer", Sk.builtin.checkInt(a));
          Sk.builtin.pyCheckType("b", "integer", Sk.builtin.checkInt(b));
  
          function _gcd(a, b) {
              if (b == 0) {
                  return a;
              };
              return _gcd(b, a % b);
          }
  
          function _biggcd(a, b) {
              if (b.trueCompare(Sk.builtin.biginteger.ZERO) === 0) {
                  return a;
              }
              return _biggcd(b, a.remainder(b));
          }
  
          if ((a instanceof Sk.builtin.lng) || (b instanceof Sk.builtin.lng)) {
              let _a = Sk.builtin.lng(a).biginteger;
              let _b = Sk.builtin.lng(b).biginteger;
              let res = _biggcd(_a, _b);
              res = res.abs(); // python only returns positive gcds
  
              return new Sk.builtin.lng(res);
          } else {
              let _a = Math.abs(Sk.builtin.asnum$(a));
              let _b = Math.abs(Sk.builtin.asnum$(b));
              let res = _gcd(_a, _b);
              res = res < 0 ? -res : res; // python only returns positive gcds
  
              return new Sk.builtin.int_(res);
          }
      });
  
  
      _isclose = function (a, b, rel_tol, abs_tol) {
          Sk.builtin.pyCheckArgsLen("isclose", arguments.length, 2, 4, true);
          Sk.builtin.pyCheckType("a", "number", Sk.builtin.checkNumber(a));
          Sk.builtin.pyCheckType("b", "number", Sk.builtin.checkNumber(b));
          Sk.builtin.pyCheckType("rel_tol", "number", Sk.builtin.checkNumber(rel_tol));
          Sk.builtin.pyCheckType("abs_tol", "number", Sk.builtin.checkNumber(abs_tol));
  
          const _a = Sk.builtin.asnum$(a);
          const _b = Sk.builtin.asnum$(b);
          const _rel_tol = Sk.builtin.asnum$(rel_tol);
          const _abs_tol = Sk.builtin.asnum$(abs_tol);
  
          if (_rel_tol < 0.0 || _abs_tol < 0.0) {
              throw new Sk.builtin.ValueError("tolerances must be non-negative");
          };
          if (_a == _b) {
              return Sk.builtin.bool.true$;
          };
  
          if (_a == Infinity || _a == -Infinity || _b == Infinity || _b == -Infinity) {
              // same sign infinities were caught in previous test
              return Sk.builtin.bool.false$;
          };
          const diff = Math.abs(_b - _a);
          const res = (((diff <= Math.abs(_rel_tol * _b)) ||
                  (diff <= Math.abs(_rel_tol * _a))) ||
              (diff <= _abs_tol));
          return new Sk.builtin.bool(res)
      };
  
      _isclose.co_name = new Sk.builtins.str("isclose");
      _isclose.co_varnames = ["a", "b", "rel_tol", "abs_tol"];
      _isclose.co_argcount = 2;
      _isclose.co_kwonlyargcount = 2;
      _isclose.$kwdefs = [1e-09, 0.0];
  
      mod.isclose = new Sk.builtin.func(_isclose);
  
      mod.isfinite = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("isfinite", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          let _x = Sk.builtin.asnum$(x);
          if (Sk.builtin.checkInt(x)) {
              return Sk.builtin.bool.true$; //deals with big integers returning False
          } else if (isFinite(_x)) {
              return Sk.builtin.bool.true$;
          } else {
              return Sk.builtin.bool.false$
          };
      });
  
      mod.isinf = new Sk.builtin.func(function (x) {
          /* Return True if x is infinite or nan, and False otherwise. */
          Sk.builtin.pyCheckArgsLen("isinf", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          let _x = Sk.builtin.asnum$(x);
          if (Sk.builtin.checkInt(x)) {
              return Sk.builtin.bool.false$; //deals with big integers returning True
          } else if (isFinite(_x) || isNaN(_x)) {
              return Sk.builtin.bool.false$;
          } else {
              return Sk.builtin.bool.true$;
          };
      });
  
      mod.isnan = new Sk.builtin.func(function (x) {
          // Return True if x is a NaN (not a number), and False otherwise.
          Sk.builtin.pyCheckArgsLen("isnan", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "float", Sk.builtin.checkFloat(x));
  
          const _x = Sk.builtin.asnum$(x);
          if (isNaN(_x)) {
              return Sk.builtin.bool.true$;
          } else {
              return Sk.builtin.bool.false$;
          }
      });
  
      mod.isqrt = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.isqrt() is not yet implemented in Skulpt")
      });
  
      mod.ldexp = new Sk.builtin.func(function (x, i) {
          // return x * (2**i)
          Sk.builtin.pyCheckArgsLen("ldexp", arguments.length, 2, 2);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          Sk.builtin.pyCheckType("i", "integer", Sk.builtin.checkInt(i));
  
          const _x = Sk.builtin.asnum$(Sk.builtin.float_(x));
          const _i = Sk.builtin.asnum$(i);
  
          if (_x == Infinity || _x == -Infinity || _x == 0 || isNaN(_x)) {
              return x;
          };
          const res = _x * Math.pow(2, _i);
          if (!isFinite(res)) {
              throw new Sk.builtin.OverflowError("math range error")
          };
          return new Sk.builtin.float_(res);
      });
  
      mod.modf = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("modf", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          let _x = Sk.builtin.asnum$(x)
          if (!isFinite(_x)) { //special cases
              if (_x == Infinity) {
                  return new Sk.builtin.tuple([Sk.builtin.float_(0.0), Sk.builtin.float_(_x)]);
              } else if (_x == -Infinity) {
                  return new Sk.builtin.tuple([Sk.builtin.float_(-0.0), Sk.builtin.float_(_x)]);
              } else if (isNaN(_x)) {
                  return new Sk.builtin.tuple([Sk.builtin.float_(_x), Sk.builtin.float_(_x)]);
              };
          };
          const sign = get_sign(_x);
          _x = Math.abs(_x);
          const i = sign * Math.floor(_x); //integer part
          const d = sign * (_x - Math.floor(_x)); //decimal part
  
          return new Sk.builtin.tuple([Sk.builtin.float_(d), Sk.builtin.float_(i)]);
      });
  
      mod.perm = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.perm() is not yet implemented in Skulpt")
      });
  
      mod.prod = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.prod() is not yet implemented in Skulpt")
      });
  
      mod.remainder = new Sk.builtin.func(function (x, y) {
          // as per cpython algorithm see cpython for details
          Sk.builtin.pyCheckArgsLen("reamainder", arguments.length, 2, 2);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          Sk.builtin.pyCheckType("y", "number", Sk.builtin.checkNumber(y));
          _x = Sk.builtin.asnum$(Sk.builtin.float_(x));
          _y = Sk.builtin.asnum$(Sk.builtin.float_(y));
  
          // deal with most common cases first
          if (isFinite(_x) && isFinite(_y)) {
              let absx, absy, c, m, r;
              if (_y == 0.0) {
                  throw new Sk.builtin.ValueError("math domain error");
              }
              absx = Math.abs(_x);
              absy = Math.abs(_y);
              m = absx % absy;
              c = absy - m;
              if (m < c) {
                  r = m;
              } else if (m > c) {
                  r = -c;
              } else {
                  if (m != c) {
                      throw new Sk.builtin.AssertionError();
                  }
                  r = m - 2.0 * ((0.5 * (absx - m)) % absy);
              }
              return Sk.builtin.float_(get_sign(_x) * r);
          }
          /* Special values. */
          if (isNaN(_x)) {
              return x;
          }
          if (isNaN(_y)) {
              return y;
          }
          if (_x == Infinity || _x == -Infinity) {
              throw new Sk.builtin.ValueError("math domain error");
          }
          if (!(_y == Infinity || _y == -Infinity)) {
              throw new Sk.builtin.AssertionError();
          }
          return Sk.builtin.float_(x);
      });
  
      mod.trunc = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("trunc", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          if (Sk.builtin.checkInt(x)) {
              return x //deals with large ints being passed 
          };
          return new Sk.builtin.int_(Sk.builtin.asnum$(x) | 0);
      });
  
  
      // Power and logarithmic functions
      mod.exp = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("exp", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          const _x = Sk.builtin.asnum$(Sk.builtin.float_(x));
          if (_x == Infinity || _x == -Infinity || isNaN(_x)) {
              return new Sk.builtin.float_(Math.exp(_x));
          }
          const res = Math.exp(_x);
          if (!isFinite(res)) {
              throw new Sk.builtin.OverflowError("math range error");
          }
  
          return new Sk.builtin.float_(res);
      });
  
      mod.expm1 = new Sk.builtin.func(function (x) {
          // as per python docs this implements an algorithm for evaluating exp(x) - 1 
          // for smaller values of x
          Sk.builtin.pyCheckArgsLen("expm1", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          const _x = Sk.builtin.asnum$(x);
  
          if (Math.abs(_x) < .7) {
              const _u = Math.exp(_x)
              if (_u == 1.0) {
                  return Sk.builtin.float_(_x)
              } else {
                  const res = (_u - 1.0) * _x / Math.log(_u);
                  return new Sk.builtin.float_(res)
              };
          } else {
              const res = Math.exp(_x) - 1.0;
              return new Sk.builtin.float_(res)
          };
      });
  
      mod.log = new Sk.builtin.func(function (x, base) {
          Sk.builtin.pyCheckArgsLen("log", arguments.length, 1, 2);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
  
          let _x = Sk.builtin.asnum$(x)
          let _base, res;
          if (_x <= 0) {
              throw new Sk.builtin.ValueError("math domain error")
          };
          if (base === undefined) {
              _base = Math.E;
          } else {
              Sk.builtin.pyCheckType("base", "number", Sk.builtin.checkNumber(base));
              _base = Sk.builtin.asnum$(base);
          };
  
          if (_base <= 0) {
              throw new Sk.builtin.ValueError("math domain error")
          } else if (Sk.builtin.checkFloat(x) || _x < Number.MAX_SAFE_INTEGER) {
              res = Math.log(_x) / Math.log(_base);
          } else { //int that is larger than max safe integer
              // use idea x = 123456789 = .123456789 * 10**9
              // log(x)  = 9 * log(10) + log(.123456789)
              _x = Sk.builtin.str(x).$jsstr();
              const digits = _x.length;
              const decimal = parseFloat("0." + _x);
              res = (digits * Math.log(10) + Math.log(decimal)) / Math.log(_base);
          }
          return new Sk.builtin.float_(res);
      });
  
      mod.log1p = new Sk.builtin.func(function (x) {
          // as per python docs this is an algorithm for evaluating log 1+x (base e)
          // designed to be more accurate close to 0
          Sk.builtin.pyCheckArgsLen("log1p", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          const _x = Sk.builtin.asnum$(new Sk.builtin.float_(x));
  
          if (_x <= -1.0) {
              throw new Sk.builtin.ValueError("math domain error")
          } else if (_x == 0.) {
              return new Sk.builtin.float_(_x); // respects log1p(-0.0) return -0.0
          } else if (Math.abs(_x) < Number.EPSILON / 2.) {
              return new Sk.builtin.float_(_x);
          } else if (-0.5 <= _x && _x <= 1.) {
              const _y = 1. + _x;
              const res = Math.log(_y) - ((_y - 1.) - _x) / _y;
              return new Sk.builtin.float_(res);
          } else {
              const res = Math.log(1 + _x);
              return new Sk.builtin.float_(res);
          };
      });
  
      mod.log2 = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("log2", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          let _x = Sk.builtin.asnum$(x)
          let res;
          if (_x < 0) {
              throw new Sk.builtin.ValueError("math domain error")
          } else if (Sk.builtin.checkFloat(x) || _x < Number.MAX_SAFE_INTEGER) {
              res = Math.log2(_x);
          } else { //int that is larger than max safe integer
              // use idea x = 123456789 = .123456789 * 10**9
              // log2(x)  = 9 * log2(10) + log2(.123456789)
              _x = Sk.builtin.str(x).$jsstr();
              const digits = _x.length;
              const decimal = parseFloat("0." + _x);
              res = digits * Math.log2(10) + Math.log2(decimal);
          }
          return new Sk.builtin.float_(res);
      });
  
      mod.log10 = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("log10", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          let _x = Sk.builtin.asnum$(x);
          let res;
          if (_x < 0) {
              throw new Sk.builtin.ValueError("math domain error")
          } else if (Sk.builtin.checkFloat(x) || _x < Number.MAX_SAFE_INTEGER) {
              res = Math.log10(_x);
          } else { //int that is larger than max safe integer
              // use idea x = 123456789 = .123456789 * 10**9
              // log10(x)  = 9 + log10(.123456789)
              _x = Sk.builtin.str(x).$jsstr();
              const digits = _x.length;
              const decimal = parseFloat("0." + _x);
              res = digits + Math.log10(decimal);
          }
          return new Sk.builtin.float_(res);
      });
  
      mod.pow = new Sk.builtin.func(function (x, y) {
          Sk.builtin.pyCheckArgsLen("pow", arguments.length, 2, 2);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          Sk.builtin.pyCheckType("y", "number", Sk.builtin.checkNumber(y));
  
          const _x = Sk.builtin.asnum$(Sk.builtin.float_(x));
          const _y = Sk.builtin.asnum$(Sk.builtin.float_(y));
  
          if (_x == 0 && _y < 0) {
              throw new Sk.builtin.ValueError("math domain error");
          } else if (_x == 1) {
              return new Sk.builtin.float_(1.0)
          } else if (Number.isFinite(_x) && Number.isFinite(_y) && _x < 0 && !Number.isInteger(_y)) {
              throw new Sk.builtin.ValueError("math domain error");
          } else if (_x == -1 && (_y == -Infinity || _y == Infinity)) {
              return new Sk.builtin.float_(1.0);
          };
  
          const res = Math.pow(_x, _y);
          if (!Number.isFinite(_x) || !Number.isFinite(_y)) {
              return new Sk.builtin.float_(res);
          } else if (res == Infinity || res == -Infinity) {
              throw new Sk.builtin.OverflowError("math range error")
          }
          return new Sk.builtin.float_(res);
      });
  
      mod.sqrt = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("sqrt", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          return new Sk.builtin.float_(Math.sqrt(Sk.builtin.asnum$(x)));
      });
  
      // Trigonometric functions and Hyperbolic
  
      mod.asin = new Sk.builtin.func(function (rad) {
          Sk.builtin.pyCheckArgsLen("asin", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("rad", "number", Sk.builtin.checkNumber(rad));
  
          return new Sk.builtin.float_(Math.asin(Sk.builtin.asnum$(rad)));
      });
  
      mod.acos = new Sk.builtin.func(function (rad) {
          Sk.builtin.pyCheckArgsLen("acos", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("rad", "number", Sk.builtin.checkNumber(rad));
  
          return new Sk.builtin.float_(Math.acos(Sk.builtin.asnum$(rad)));
      });
  
      mod.atan = new Sk.builtin.func(function (rad) {
          Sk.builtin.pyCheckArgsLen("atan", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("rad", "number", Sk.builtin.checkNumber(rad));
  
          return new Sk.builtin.float_(Math.atan(Sk.builtin.asnum$(rad)));
      });
  
      mod.atan2 = new Sk.builtin.func(function (y, x) {
          Sk.builtin.pyCheckArgsLen("atan2", arguments.length, 2, 2);
          Sk.builtin.pyCheckType("y", "number", Sk.builtin.checkNumber(y));
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          return new Sk.builtin.float_(Math.atan2(Sk.builtin.asnum$(y), Sk.builtin.asnum$(x)));
      });
  
      mod.sin = new Sk.builtin.func(function (rad) {
          Sk.builtin.pyCheckArgsLen("sin", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("rad", "number", Sk.builtin.checkNumber(rad));
  
          return new Sk.builtin.float_(Math.sin(Sk.builtin.asnum$(rad)));
      });
  
      mod.cos = new Sk.builtin.func(function (rad) {
          Sk.builtin.pyCheckArgsLen("cos", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("rad", "number", Sk.builtin.checkNumber(rad));
  
          return new Sk.builtin.float_(Math.cos(Sk.builtin.asnum$(rad)));
      });
  
      mod.tan = new Sk.builtin.func(function (rad) {
          Sk.builtin.pyCheckArgsLen("tan", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("rad", "number", Sk.builtin.checkNumber(rad));
  
          return new Sk.builtin.float_(Math.tan(Sk.builtin.asnum$(rad)));
      });
  
      mod.dist = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.dist() is not yet implemented in Skulpt")
      });
  
      mod.hypot = new Sk.builtin.func(function (x, y) {
          Sk.builtin.pyCheckArgsLen("hypot", arguments.length, 2, 2);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
          Sk.builtin.pyCheckType("y", "number", Sk.builtin.checkNumber(y));
  
          x = Sk.builtin.asnum$(x);
          y = Sk.builtin.asnum$(y);
          return new Sk.builtin.float_(Math.sqrt((x * x) + (y * y)));
      });
  
      mod.asinh = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("asinh", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          x = Sk.builtin.asnum$(x);
  
          var L = x + Math.sqrt(x * x + 1);
  
          return new Sk.builtin.float_(Math.log(L));
      });
  
      mod.acosh = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("acosh", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          x = Sk.builtin.asnum$(x);
  
          var L = x + Math.sqrt(x * x - 1);
  
          return new Sk.builtin.float_(Math.log(L));
      });
  
      mod.atanh = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("atanh", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          x = Sk.builtin.asnum$(x);
  
          var L = (1 + x) / (1 - x);
  
          return new Sk.builtin.float_(Math.log(L) / 2);
      });
  
      mod.sinh = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("sinh", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          x = Sk.builtin.asnum$(x);
  
          var e = Math.E;
          var p = Math.pow(e, x);
          var n = 1 / p;
          var result = (p - n) / 2;
  
          return new Sk.builtin.float_(result);
      });
  
      mod.cosh = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("cosh", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          x = Sk.builtin.asnum$(x);
  
          var e = Math.E;
          var p = Math.pow(e, x);
          var n = 1 / p;
          var result = (p + n) / 2;
  
          return new Sk.builtin.float_(result);
      });
  
      mod.tanh = new Sk.builtin.func(function (x) {
          Sk.builtin.pyCheckArgsLen("tanh", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("x", "number", Sk.builtin.checkNumber(x));
  
          const _x = Sk.builtin.asnum$(x);
  
          if (_x === 0) {
              return Sk.builtin.float_(x);
          };
  
          var e = Math.E;
          var p = Math.pow(e, _x);
          var n = 1 / p;
          var result = ((p - n) / 2) / ((p + n) / 2);
  
          return new Sk.builtin.float_(result);
      });
  
      // Angular Conversion
      mod.radians = new Sk.builtin.func(function (deg) {
          Sk.builtin.pyCheckArgsLen("radians", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("deg", "number", Sk.builtin.checkNumber(deg));
  
          var ret = Math.PI / 180.0 * Sk.builtin.asnum$(deg);
          return new Sk.builtin.float_(ret);
      });
  
      mod.degrees = new Sk.builtin.func(function (rad) {
          Sk.builtin.pyCheckArgsLen("degrees", arguments.length, 1, 1);
          Sk.builtin.pyCheckType("rad", "number", Sk.builtin.checkNumber(rad));
  
          var ret = 180.0 / Math.PI * Sk.builtin.asnum$(rad);
          return new Sk.builtin.float_(ret);
      });
  
      // Special Functions
      mod.erf = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.erf() is not yet implemented in Skulpt")
      });
  
      mod.erfc = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.erfc() is not yet implemented in Skulpt")
      });
  
      mod.gamma = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.gamma() is not yet implemented in Skulpt")
      });
  
      mod.lgamma = new Sk.builtin.func(function (x) {
          throw new Sk.builtin.NotImplementedError("math.lgamma() is not yet implemented in Skulpt")
      });
  
      return mod;
  }
  