4-rings or 4-squares puzzle

You are encouraged to solve this task according to the task description, using any language you may know.
Task

Replace       a, b, c, d, e, f,   and
  g        with the decimal
digits   LOW   ───►   HIGH

such that the sum of the letters inside of each of the four large squares add up to
the same sum.

            ╔══════════════╗      ╔══════════════╗
            ║              ║      ║              ║
            ║      a       ║      ║      e       ║
            ║              ║      ║              ║
            ║          ┌───╫──────╫───┐      ┌───╫─────────┐
            ║          │   ║      ║   │      │   ║         │
            ║          │ b ║      ║ d │      │ f ║         │
            ║          │   ║      ║   │      │   ║         │
            ║          │   ║      ║   │      │   ║         │
            ╚══════════╪═══╝      ╚═══╪══════╪═══╝         │
                       │       c      │      │      g      │
                       │              │      │             │
                       │              │      │             │
                       └──────────────┘      └─────────────┘

Show all output here.



   Show all solutions for each letter being unique with
        LOW=1     HIGH=7

   Show all solutions for each letter being unique with
        LOW=3     HIGH=9

   Show only the   number   of solutions when each letter can be non-unique
        LOW=0     HIGH=9



Related task

 Solve the no connection puzzle


(() => {
 
    // 4-rings or 4-squares puzzle ------------------------
 
    // rings :: noRepeatedDigits -> DigitList -> solutions
    // rings :: Bool -> [Int] -> [[Int]]
    const rings = (uniq, digits) => {
        return 0 < digits.length ? (() => {
            const
                ns = sortBy(flip(compare), digits),
                h = head(ns);
 
            // CENTRAL DIGIT :: d
            return bindList(
                ns,
                d => {
                    const ts = filter(x => (x + d) <= h, ns);
 
                    // LEFT OF CENTRE :: c and a
                    return bindList(
                        uniq ? delete_(d, ts) : ns,
                        c => {
                            const a = c + d;
 
                            // RIGHT OF CENTRE :: e and g
                            return a > h ? (
                                []
                            ) : bindList(uniq ? (
                                difference(ts, [d, c, a])
                            ) : ns, e => {
                                const g = d + e;
                                return ((g > h) || (uniq && (g === c))) ? (
                                    []
                                ) : (() => {
                                    const
                                        agDelta = a - g,
                                        bfs = uniq ? difference(
                                            ns, [d, c, e, g, a]
                                        ) : ns;
 
                                    // MID LEFT, MID RIGHT :: b and f
                                    return bindList(bfs, b => {
                                        const f = b + agDelta;
                                        return elem(f, bfs) && (
                                            !uniq || notElem(f, [
                                                a, b, c, d, e, g
                                            ])
                                        ) ? ([
                                            [a, b, c, d, e, f, g]
                                        ]) : [];
                                    });
                                })();
                            });
                        });
                });
        })() : []
    };
 
 
    // TEST -----------------------------------------------
    const main = () => {
        return unlines([
            'rings(true, enumFromTo(1,7))\n',
            unlines(map(show, rings(true, enumFromTo(1, 7)))),
 
            '\nrings(true, enumFromTo(3, 9))\n',
            unlines(map(show, rings(true, enumFromTo(3, 9)))),
 
            '\nlength(rings(false, enumFromTo(0, 9)))\n',
            length(rings(false, enumFromTo(0, 9)))
            .toString(),
            ''
        ]);
    };
 
    // GENERIC FUNCTIONS ----------------------------------
 
    // bindList (>>=) :: [a] -> (a -> [b]) -> [b]
    const bindList = (xs, mf) => [].concat.apply([], xs.map(mf));
 
    // compare :: a -> a -> Ordering
    const compare = (a, b) => a < b ? -1 : (a > b ? 1 : 0);
 
    // delete_ :: Eq a => a -> [a] -> [a]
    const delete_ = (x, xs) =>
        xs.length > 0 ? (
            (x === xs[0]) ? (
                xs.slice(1)
            ) : [xs[0]].concat(delete_(x, xs.slice(1)))
        ) : [];
 
    // difference :: Eq a => [a] -> [a] -> [a]
    const difference = (xs, ys) => {
        const s = new Set(ys);
        return xs.filter(x => !s.has(x));
    };
 
    // elem :: Eq a => a -> [a] -> Bool
    const elem = (x, xs) => xs.indexOf(x) !== -1;
 
    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = (m, n) =>
        Array.from({
            length: Math.floor(n - m) + 1
        }, (_, i) => m + i);
 
    // filter :: (a -> Bool) -> [a] -> [a]
    const filter = (f, xs) => xs.filter(f);
 
    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = f => (a, b) => f.apply(null, [b, a]);
 
    // head :: [a] -> a
    const head = xs => xs.length ? xs[0] : undefined;
 
    // length :: [a] -> Int
    const length = xs => xs.length;
 
    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) => xs.map(f);
 
    // notElem :: Eq a => a -> [a] -> Bool
    const notElem = (x, xs) => xs.indexOf(x) === -1;
 
    // show :: a -> String
    const show = x => JSON.stringify(x); //, null, 2);
 
    // sortBy :: (a -> a -> Ordering) -> [a] -> [a]
    const sortBy = (f, xs) => xs.sort(f);
 
    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');
 
 
    // MAIN ---
    return main();
})();