// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var List = require("bs-platform/lib/js/list.js");
var Curry = require("bs-platform/lib/js/curry.js");
var Js_int = require("bs-platform/lib/js/js_int.js");
var $$String = require("bs-platform/lib/js/string.js");
var Caml_obj = require("bs-platform/lib/js/caml_obj.js");
var Pervasives = require("bs-platform/lib/js/pervasives.js");
var Int$OptolithClient = require("./Int.bs.js");
var Ord$OptolithClient = require("./Ord.bs.js");
var Maybe$OptolithClient = require("./Maybe.bs.js");
var Function$OptolithClient = require("./Function.bs.js");

function $less$$great(f, xs) {
  if (xs) {
    return {
            hd: Curry._1(f, xs.hd),
            tl: $less$$great(f, xs.tl)
          };
  } else {
    return /* [] */0;
  }
}

function $less$amp$great(xs, f) {
  return $less$$great(f, xs);
}

var Functor = {
  $less$$great: $less$$great,
  $less$amp$great: $less$amp$great
};

function $less$star$great(fs, xs) {
  if (!fs) {
    return /* [] */0;
  }
  if (!xs) {
    return /* [] */0;
  }
  var x = xs.hd;
  return Pervasives.$at($less$$great((function (f) {
                    return Curry._1(f, x);
                  }), fs), $less$star$great(fs, xs.tl));
}

var Applicative = {
  $less$star$great: $less$star$great
};

function $less$pipe$great(xs, ys) {
  if (xs) {
    return xs;
  } else {
    return ys;
  }
}

function guard(pred) {
  if (pred) {
    return {
            hd: undefined,
            tl: /* [] */0
          };
  } else {
    return /* [] */0;
  }
}

var Alternative = {
  $less$pipe$great: $less$pipe$great,
  guard: guard
};

function $great$great$eq(xs, f) {
  if (xs) {
    return Pervasives.$at(Curry._1(f, xs.hd), $great$great$eq(xs.tl, f));
  } else {
    return /* [] */0;
  }
}

function $eq$less$less(f, mx) {
  return $great$great$eq(mx, f);
}

function $great$great(x, y) {
  return $great$great$eq(x, (function (param) {
                return Function$OptolithClient.$$const(y, param);
              }));
}

function $great$eq$great(f, g, x) {
  return $great$great$eq(Curry._1(f, x), g);
}

function join(x) {
  return $great$great$eq(x, Function$OptolithClient.id);
}

function liftM2(f, mx, my) {
  return $great$great$eq(mx, (function (x) {
                return $less$$great(Curry._1(f, x), my);
              }));
}

function liftM3(f, mx, my, mz) {
  return $great$great$eq(mx, (function (x) {
                return $great$great$eq(my, (function (y) {
                              return $less$$great(Curry._2(f, x, y), mz);
                            }));
              }));
}

function liftM4(f, mx, my, mz, ma) {
  return $great$great$eq(mx, (function (x) {
                return $great$great$eq(my, (function (y) {
                              return $great$great$eq(mz, (function (z) {
                                            return $less$$great(Curry._3(f, x, y, z), ma);
                                          }));
                            }));
              }));
}

var Monad = {
  $great$great$eq: $great$great$eq,
  $eq$less$less: $eq$less$less,
  $great$great: $great$great,
  $great$eq$great: $great$eq$great,
  join: join,
  liftM2: liftM2,
  liftM3: liftM3,
  liftM4: liftM4
};

function foldr(f, initial, xs) {
  if (xs) {
    return Curry._2(f, xs.hd, foldr(f, initial, xs.tl));
  } else {
    return initial;
  }
}

function foldr1(f, xs) {
  if (xs) {
    return foldr(f, xs.hd, xs.tl);
  } else {
    return Pervasives.invalid_arg("Cannot apply foldr1 to an empty list.");
  }
}

function foldl(f, _initial, _xs) {
  while(true) {
    var xs = _xs;
    var initial = _initial;
    if (!xs) {
      return initial;
    }
    _xs = xs.tl;
    _initial = Curry._2(f, initial, xs.hd);
    continue ;
  };
}

function foldl1(f, xs) {
  if (xs) {
    return foldl(f, xs.hd, xs.tl);
  } else {
    return Pervasives.invalid_arg("Cannot apply foldl1 to an empty list.");
  }
}

function toList(xs) {
  return xs;
}

function $$null(xs) {
  if (xs) {
    return false;
  } else {
    return true;
  }
}

var length = List.length;

function elem(e, xs) {
  return List.exists((function (x) {
                return Caml_obj.caml_equal(e, x);
              }), xs);
}

function sum(xs) {
  return foldr((function (prim, prim$1) {
                return prim + prim$1 | 0;
              }), 0, xs);
}

function product(xs) {
  return foldr((function (prim, prim$1) {
                return Math.imul(prim, prim$1);
              }), 1, xs);
}

function maximum(xs) {
  return foldr((function (prim, prim$1) {
                return Math.max(prim, prim$1);
              }), Js_int.min, xs);
}

function minimum(xs) {
  return foldr((function (prim, prim$1) {
                return Math.min(prim, prim$1);
              }), Js_int.max, xs);
}

function concat(xss) {
  return $great$great$eq(xss, Function$OptolithClient.id);
}

function concatMap(f, xs) {
  return $great$great$eq(xs, f);
}

function con(_xs) {
  while(true) {
    var xs = _xs;
    if (!xs) {
      return true;
    }
    if (!xs.hd) {
      return false;
    }
    _xs = xs.tl;
    continue ;
  };
}

function dis(_xs) {
  while(true) {
    var xs = _xs;
    if (!xs) {
      return false;
    }
    if (xs.hd) {
      return true;
    }
    _xs = xs.tl;
    continue ;
  };
}

function any(f, _xs) {
  while(true) {
    var xs = _xs;
    if (!xs) {
      return false;
    }
    if (Curry._1(f, xs.hd)) {
      return true;
    }
    _xs = xs.tl;
    continue ;
  };
}

function all(f, _xs) {
  while(true) {
    var xs = _xs;
    if (!xs) {
      return true;
    }
    if (!Curry._1(f, xs.hd)) {
      return false;
    }
    _xs = xs.tl;
    continue ;
  };
}

function notElem(e, xs) {
  return !elem(e, xs);
}

function find(f, _xs) {
  while(true) {
    var xs = _xs;
    if (!xs) {
      return /* Nothing */0;
    }
    var y = xs.hd;
    if (Curry._1(f, y)) {
      return /* Just */{
              _0: y
            };
    }
    _xs = xs.tl;
    continue ;
  };
}

var Foldable = {
  foldr: foldr,
  foldr1: foldr1,
  foldl: foldl,
  foldl1: foldl1,
  toList: toList,
  $$null: $$null,
  length: length,
  elem: elem,
  sum: sum,
  product: product,
  maximum: maximum,
  minimum: minimum,
  concat: concat,
  concatMap: concatMap,
  con: con,
  dis: dis,
  any: any,
  all: all,
  notElem: notElem,
  find: find
};

function indexedAux(i, xs) {
  if (xs) {
    return {
            hd: [
              i,
              xs.hd
            ],
            tl: indexedAux(i + 1 | 0, xs.tl)
          };
  } else {
    return /* [] */0;
  }
}

function indexed(xs) {
  return indexedAux(0, xs);
}

function deleteAt(index, xs) {
  if (index < 0) {
    return xs;
  }
  if (!xs) {
    return /* [] */0;
  }
  var xs$1 = xs.tl;
  if (index === 0) {
    return xs$1;
  } else {
    return {
            hd: xs.hd,
            tl: deleteAt(index - 1 | 0, xs$1)
          };
  }
}

function setAt(index, e, xs) {
  if (index < 0) {
    return xs;
  }
  if (!xs) {
    return /* [] */0;
  }
  var xs$1 = xs.tl;
  if (index === 0) {
    return {
            hd: e,
            tl: xs$1
          };
  } else {
    return {
            hd: xs.hd,
            tl: setAt(index - 1 | 0, e, xs$1)
          };
  }
}

function modifyAt(index, f, xs) {
  if (index < 0) {
    return xs;
  }
  if (!xs) {
    return /* [] */0;
  }
  var xs$1 = xs.tl;
  var x = xs.hd;
  if (index === 0) {
    return {
            hd: Curry._1(f, x),
            tl: xs$1
          };
  } else {
    return {
            hd: x,
            tl: modifyAt(index - 1 | 0, f, xs$1)
          };
  }
}

function updateAt(index, f, xs) {
  if (index < 0) {
    return xs;
  }
  if (!xs) {
    return /* [] */0;
  }
  var xs$1 = xs.tl;
  var x = xs.hd;
  if (index === 0) {
    return Maybe$OptolithClient.maybe(xs$1, (function (x$prime) {
                  return {
                          hd: x$prime,
                          tl: xs$1
                        };
                }), Curry._1(f, x));
  } else {
    return {
            hd: x,
            tl: updateAt(index - 1 | 0, f, xs$1)
          };
  }
}

function insertAt(index, e, xs) {
  if (index < 0) {
    return xs;
  } else if (xs) {
    if (index === 0) {
      return {
              hd: e,
              tl: xs
            };
    } else {
      return {
              hd: xs.hd,
              tl: insertAt(index - 1 | 0, e, xs.tl)
            };
    }
  } else {
    return /* [] */0;
  }
}

function imapAux(f, i, xs) {
  if (xs) {
    return {
            hd: Curry._2(f, i, xs.hd),
            tl: imapAux(f, i + 1 | 0, xs.tl)
          };
  } else {
    return /* [] */0;
  }
}

function imap(f, xs) {
  return imapAux(f, 0, xs);
}

var Index = {
  indexed: indexed,
  deleteAt: deleteAt,
  setAt: setAt,
  modifyAt: modifyAt,
  updateAt: updateAt,
  insertAt: insertAt,
  imap: imap
};

function $less$plus$great(x, xs) {
  return {
          hd: x,
          tl: xs
        };
}

function reverse(xs) {
  return foldl((function (param, param$1) {
                return Function$OptolithClient.flip($less$plus$great, param, param$1);
              }), /* [] */0, xs);
}

function intercalate(separator, xs) {
  if (!xs) {
    return "";
  }
  var xs$1 = xs.tl;
  var x = xs.hd;
  if (xs$1) {
    return x + (separator + intercalate(separator, xs$1));
  } else {
    return x;
  }
}

function permutationsPick(xs) {
  return imapAux((function (i, x) {
                return [
                        x,
                        deleteAt(i, xs)
                      ];
              }), 0, xs);
}

function permutations(xs) {
  if (xs) {
    if (xs.tl) {
      return $great$great$eq(permutationsPick(xs), (function (param) {
                    var x$prime = param[0];
                    return $less$$great((function (param) {
                                  return {
                                          hd: x$prime,
                                          tl: param
                                        };
                                }), permutations(param[1]));
                  }));
    } else {
      return {
              hd: {
                hd: xs.hd,
                tl: /* [] */0
              },
              tl: /* [] */0
            };
    }
  } else {
    return /* [] */0;
  }
}

function lookup(k, xs) {
  return Maybe$OptolithClient.Functor.$less$amp$great(find((function (param) {
                    return Caml_obj.caml_equal(k, param[0]);
                  }), xs), (function (prim) {
                return prim[1];
              }));
}

function take(n, xs) {
  if (n <= 0 || !xs) {
    return /* [] */0;
  } else {
    return {
            hd: xs.hd,
            tl: take(n - 1 | 0, xs.tl)
          };
  }
}

function isInfixOf(x, y) {
  return x.includes(y);
}

function filter(pred, xs) {
  return foldr((function (x) {
                if (Curry._1(pred, x)) {
                  return function (param) {
                    return {
                            hd: x,
                            tl: param
                          };
                  };
                } else {
                  return Function$OptolithClient.id;
                }
              }), /* [] */0, xs);
}

function $less$bang$bang$great(xs, i) {
  return Maybe$OptolithClient.optionToMaybe(List.nth_opt(xs, i));
}

function $$delete(e, _xs) {
  while(true) {
    var xs = _xs;
    if (!xs) {
      return /* [] */0;
    }
    var xs$1 = xs.tl;
    if (Caml_obj.caml_equal(e, xs.hd)) {
      return xs$1;
    }
    _xs = xs$1;
    continue ;
  };
}

function sortBy(f) {
  return function (param) {
    return List.sort((function (a, b) {
                  return Ord$OptolithClient.fromOrdering(Curry._2(f, a, b));
                }), param);
  };
}

function countBy(f, xs) {
  return foldr((function (x) {
                if (Curry._1(f, x)) {
                  return Int$OptolithClient.inc;
                } else {
                  return Function$OptolithClient.id;
                }
              }), 0, xs);
}

var lower = $$String.lowercase_ascii;

function notNull(xs) {
  return !(
          xs ? false : true
        );
}

function list(def, f, xs) {
  if (xs) {
    return Curry._2(f, xs.hd, xs.tl);
  } else {
    return def;
  }
}

function unsnoc(xs) {
  if (!xs) {
    return /* Nothing */0;
  }
  var xs$1 = xs.tl;
  var x = xs.hd;
  if (!xs$1) {
    return /* Just */{
            _0: [
              /* [] */0,
              x
            ]
          };
  }
  var match = unsnoc(xs$1);
  if (!match) {
    return /* Nothing */0;
  }
  var match$1 = match._0;
  return /* Just */{
          _0: [
            {
              hd: x,
              tl: match$1[0]
            },
            match$1[1]
          ]
        };
}

var partial_arg = /[.*+?^${}()|[\]\\]/gu;

function escapeRegex(param) {
  return param.replace(partial_arg, "\\$&");
}

function replaceStr(old_subseq, new_subseq, x) {
  return x.replace(new RegExp(Curry._1(escapeRegex, old_subseq), "gu"), new_subseq);
}

var Extra = {
  lower: lower,
  notNull: notNull,
  list: list,
  unsnoc: unsnoc,
  escapeRegex: escapeRegex,
  replaceStr: replaceStr
};

var map = $less$$great;

var $bang$bang = List.nth;

exports.Functor = Functor;
exports.Applicative = Applicative;
exports.Alternative = Alternative;
exports.Monad = Monad;
exports.Foldable = Foldable;
exports.Index = Index;
exports.$less$plus$great = $less$plus$great;
exports.map = map;
exports.reverse = reverse;
exports.intercalate = intercalate;
exports.permutations = permutations;
exports.elem = elem;
exports.notElem = notElem;
exports.lookup = lookup;
exports.take = take;
exports.isInfixOf = isInfixOf;
exports.filter = filter;
exports.$bang$bang = $bang$bang;
exports.$less$bang$bang$great = $less$bang$bang$great;
exports.$$delete = $$delete;
exports.sortBy = sortBy;
exports.countBy = countBy;
exports.Extra = Extra;
/* No side effect */
