text:
#ifndef XTL_COMPLEX_HPP
#define XTL_COMPLEX_HPP

#if !defined(_MSC_VER)
#include <cmath>
using std::copysign;
#endif

#include <complex>
#include <cstddef>
#include <limits>
#include <type_traits>
#include <utility>
#include <sstream>
#include <string>

#ifdef __CLING__
#include <nlohmann/json.hpp>
#endif

#include "xclosure.hpp"
#include "xtl_config.hpp"
#include "xtype_traits.hpp"

namespace xtl
{
    template <class CTR, class CTI = CTR, bool ieee_compliant = false>
    class xcomplex;

    /**************
     * is_complex *
     **************/

    namespace detail
    {
        template <class T>
        struct is_complex : std::false_type
        {
        };

        template <class T>
        struct is_complex<std::complex<T>> : std::true_type
        {
        };
    }

    template <class T>
    struct is_complex
    {
        static constexpr bool value = detail::is_complex<std::decay_t<T>>::value;
    };

    /***************
     * is_xcomplex *
     ***************/

    namespace detail
    {
        template <class T>
        struct is_xcomplex : std::false_type
        {
        };

        template <class CTR, class CTI, bool B>
        struct is_xcomplex<xcomplex<CTR, CTI, B>> : std::true_type
        {
        };
    }

    template <class T>
    struct is_xcomplex
    {
        static constexpr bool value = detail::is_xcomplex<std::decay_t<T>>::value;
    };

    /******************
     * is_gen_complex *
     ******************/

    template <class T>
    using is_gen_complex = disjunction<is_complex<std::decay_t<T>>, is_xcomplex<std::decay_t<T>>>;

    /****************************
     * enable / disable complex *
     ****************************/

    template <class E, class R = void>
    using disable_xcomplex = std::enable_if_t<!is_gen_complex<E>::value, R>;

    template <class E, class R = void>
    using enable_xcomplex = std::enable_if_t<is_gen_complex<E>::value, R>;

    /*****************
     * enable_scalar *
     *****************/

    template <class E, class R = void>
    using enable_scalar = std::enable_if_t<xtl::is_arithmetic<E>::value, R>;

    /*******************
     * common_xcomplex *
     *******************/

    template <class CTR1, class CTI1, bool ieee1, class CTR2, class CTI2, bool ieee2>
    struct common_xcomplex
    {
        using type = xcomplex<std::common_type_t<CTR1, CTI1>, std::common_type_t<CTR2, CTI2>, ieee1 || ieee2>;
    };

    template <class CTR1, class CTI1, bool ieee1, class CTR2, class CTI2, bool ieee2>
    using common_xcomplex_t = typename common_xcomplex<CTR1, CTI1, ieee1, CTR2, CTI2, ieee2>::type;

    /**********************
     * temporary_xcomplex *
     **********************/

    template <class CTR, class CTI, bool ieee>
    struct temporary_xcomplex
    {
        using type = xcomplex<std::decay_t<CTR>, std::decay_t<CTI>, ieee>;
    };

    template <class CTR, class CTI, bool ieee>
    using temporary_xcomplex_t = typename temporary_xcomplex<CTR, CTI, ieee>::type;

    /************
     * xcomplex *
     ************/

    template <class CTR, class CTI, bool ieee_compliant>
    class xcomplex
    {
    public:

        static_assert(std::is_same<std::decay_t<CTR>, std::decay_t<CTI>>::value,
                      "closure types must have the same value type");

        using value_type = std::common_type_t<CTR, CTI>;
        using self_type = xcomplex<CTR, CTI, ieee_compliant>;
        using temporary_type = temporary_xcomplex_t<CTR, CTI, ieee_compliant>;

        using real_reference = std::add_lvalue_reference_t<CTR>;
        using real_const_reference = std::add_lvalue_reference_t<std::add_const_t<CTR>>;
        using real_rvalue_reference = std::conditional_t<std::is_reference<CTR>::value, apply_cv_t<CTR, value_type>&, value_type>;
        using real_rvalue_const_reference = std::conditional_t<std::is_reference<CTR>::value, const value_type&, value_type>;

        using imag_reference = std::add_lvalue_reference_t<CTI>;
        using imag_const_reference = std::add_lvalue_reference_t<std::add_const_t<CTI>>;
        using imag_rvalue_reference = std::conditional_t<std::is_reference<CTI>::value, apply_cv_t<CTI, value_type>&, value_type>;
        using imag_rvalue_const_reference = std::conditional_t<std::is_reference<CTI>::value, const value_type&, value_type>;

        constexpr xcomplex() noexcept
            : m_real(), m_imag()
        {
        }

        template <class OCTR,
            std::enable_if_t<
                conjunction<
                    negation<is_gen_complex<OCTR>>,
                    std::is_constructible<CTR, OCTR&&>,
                    std::is_convertible<OCTR&&, CTR>
                >::value,
                bool
            > = true>
        constexpr xcomplex(OCTR&& re) noexcept
            : m_real(std::forward<OCTR>(re)), m_imag()
        {
        }

        template <class OCTR,
            std::enable_if_t<
                conjunction<
                    negation<is_gen_complex<OCTR>>,
                    std::is_constructible<CTR, OCTR&&>,
                    negation<std::is_convertible<OCTR&&, CTR>>
            >::value,
            bool
        > = true>
        explicit constexpr xcomplex(OCTR&& re) noexcept
            : m_real(std::forward<OCTR>(re)), m_imag()
        {
        }

        template <class OCTR, class OCTI>
        explicit constexpr xcomplex(OCTR&& re, OCTI&& im) noexcept
            : m_real(std::forward<OCTR>(re)), m_imag(std::forward<OCTI>(im))
        {
        }

        template <class OCTR, class OCTI, bool OB>
        explicit constexpr xcomplex(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept
            : m_real(rhs.real()), m_imag(rhs.imag())
        {
        }

        template <class OCTR, class OCTI, bool OB>
        explicit constexpr xcomplex(xcomplex<OCTR, OCTI, OB>&& rhs) noexcept
            : m_real(std::move(rhs).real()), m_imag(std::move(rhs).imag())
        {
        }

        template <class T>
        constexpr xcomplex(const std::complex<T>& rhs) noexcept
            : m_real(rhs.real()), m_imag(rhs.imag())
        {
        }

        template <class T>
        constexpr xcomplex(std::complex<T>&& rhs) noexcept
            : m_real(std::move(rhs).real()), m_imag(std::move(rhs).imag())
        {
        }

        template <class OCTR>
        disable_xcomplex<OCTR, self_type&> operator=(OCTR&& rhs) noexcept;
        template <class OCTR, class OCTI, bool OB>
        self_type& operator=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept;
        template <class OCTR, class OCTI, bool OB>
        self_type& operator=(xcomplex<OCTR, OCTI, OB>&& rhs) noexcept;

        operator std::complex<std::decay_t<CTR>>() const noexcept;

        template <class OCTR, class OCTI, bool OB>
        self_type& operator+=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept;
        template <class OCTR, class OCTI, bool OB>
        self_type& operator-=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept;
        template <class OCTR, class OCTI, bool OB>
        self_type& operator*=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept;
        template <class OCTR, class OCTI, bool OB>
        self_type& operator/=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept;

        template <class T>
        disable_xcomplex<T, self_type&> operator+=(const T& rhs) noexcept;
        template <class T>
        disable_xcomplex<T, self_type&> operator-=(const T& rhs) noexcept;
        template <class T>
        disable_xcomplex<T, self_type&> operator*=(const T& rhs) noexcept;
        template <class T>
        disable_xcomplex<T, self_type&> operator/=(const T& rhs) noexcept;

        real_reference real() & noexcept;
        real_rvalue_reference real() && noexcept;
        constexpr real_const_reference real() const & noexcept;
        constexpr real_rvalue_const_reference real() const && noexcept;

        imag_reference imag() & noexcept;
        imag_rvalue_reference imag() && noexcept;
        constexpr imag_const_reference imag() const & noexcept;
        constexpr imag_rvalue_const_reference imag() const && noexcept;

        xclosure_pointer<self_type&> operator&() & noexcept;
        xclosure_pointer<const self_type&> operator&() const & noexcept;
        xclosure_pointer<self_type> operator&() && noexcept;

    private:

        CTR m_real;
        CTI m_imag;
    };

    /**********************
     * xcomplex operators *
     **********************/

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    bool operator==(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept;

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    bool operator!=(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept;

    template <class OC, class OT, class CTR, class CTI, bool B>
    std::basic_ostream<OC, OT>& operator<<(std::basic_ostream<OC, OT>& out, const xcomplex<CTR, CTI, B>& c) noexcept;

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    operator+(const xcomplex<CTR, CTI, B>& rhs) noexcept;

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    operator-(const xcomplex<CTR, CTI, B>& rhs) noexcept;

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator+(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator+(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator+(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept;

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator-(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator-(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator-(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept;

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator*(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator*(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator*(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept;

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator/(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator/(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept;

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator/(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept;

    /*****************
     * real and imag *
     *****************/

    template <class E>
    decltype(auto) real(E&& e) noexcept;

    template <class E>
    decltype(auto) imag(E&& e) noexcept;

    /***************************
     * xcomplex free functions *
     ***************************/

    template <class CTR, class CTI, bool B>
    typename xcomplex<CTR, CTI, B>::value_type
    abs(const xcomplex<CTR, CTI, B>& rhs);

    template <class CTR, class CTI, bool B>
    typename xcomplex<CTR, CTI, B>::value_type
    arg(const xcomplex<CTR, CTI, B>& rhs);

    template <class CTR, class CTI, bool B>
    typename xcomplex<CTR, CTI, B>::value_type
    norm(const xcomplex<CTR, CTI, B>& rhs);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    conj(const xcomplex<CTR, CTI, B>& rhs);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    proj(const xcomplex<CTR, CTI, B>& rhs);

    /**********************************
     * xcomplex exponential functions *
     **********************************/

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    exp(const xcomplex<CTR, CTI, B>& rhs);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    log(const xcomplex<CTR, CTI, B>& rhs);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    log10(const xcomplex<CTR, CTI, B>& rhs);

    /****************************
     * xcomplex power functions *
     ****************************/

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    pow(const xcomplex<CTR1, CTI1, B1>& x, const xcomplex<CTR2, CTI2, B2>& y);

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    pow(const xcomplex<CTR, CTI, B>& x, const T& y);

    template <class CTR, class CTI, bool B, class T>
    enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    pow(const T& x, const xcomplex<CTR, CTI, B>& y);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    sqrt(const xcomplex<CTR, CTI, B>& x);

    /************************************
     * xcomplex trigonometric functions *
     ************************************/

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    sin(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    cos(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    tan(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    asin(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    acos(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    atan(const xcomplex<CTR, CTI, B>& x);

    /*********************************
     * xcomplex hyperbolic functions *
     *********************************/

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    sinh(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    cosh(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    tanh(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    asinh(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    acosh(const xcomplex<CTR, CTI, B>& x);

    template <class CTR, class CTI, bool B>
    temporary_xcomplex_t<CTR, CTI, B>
    atanh(const xcomplex<CTR, CTI, B>& x);

    /***************************
     * xcomplex implementation *
     ***************************/

    template <class CTR, class CTI, bool B>
    template <class OCTR>
    inline auto xcomplex<CTR, CTI, B>::operator=(OCTR&& rhs) noexcept -> disable_xcomplex<OCTR, self_type&>
    {
        m_real = std::forward<OCTR>(rhs);
        m_imag = std::decay_t<CTI>();
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class OCTR, class OCTI, bool OB>
    inline auto xcomplex<CTR, CTI, B>::operator=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept -> self_type&
    {
        m_real = rhs.m_real;
        m_imag = rhs.m_imag;
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class OCTR, class OCTI, bool OB>
    inline auto xcomplex<CTR, CTI, B>::operator=(xcomplex<OCTR, OCTI, OB>&& rhs) noexcept -> self_type&
    {
        m_real = std::move(rhs.m_real);
        m_imag = std::move(rhs.m_imag);
        return *this;
    }

    template <class CTR, class CTI, bool B>
    inline xcomplex<CTR, CTI, B>::operator std::complex<std::decay_t<CTR>>() const noexcept
    {
        return std::complex<std::decay_t<CTR>>(m_real, m_imag);
    }

    template <class CTR, class CTI, bool B>
    template <class OCTR, class OCTI, bool OB>
    inline auto xcomplex<CTR, CTI, B>::operator+=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept -> self_type&
    {
        m_real += rhs.m_real;
        m_imag += rhs.m_imag;
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class OCTR, class OCTI, bool OB>
    inline auto xcomplex<CTR, CTI, B>::operator-=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept -> self_type&
    {
        m_real -= rhs.m_real;
        m_imag -= rhs.m_imag;
        return *this;
    }

    namespace detail
    {
        template <bool ieee_compliant>
        struct xcomplex_multiplier
        {
            template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
            static auto mul(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs)
            {
                using return_type = temporary_xcomplex_t<CTR1, CTI1, B1>;
                using value_type = typename return_type::value_type;
                value_type a = lhs.real();
                value_type b = lhs.imag();
                value_type c = rhs.real();
                value_type d = rhs.imag();
                return return_type(a*c - b*d, a*d + b*c);
            }

            template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
            static auto div(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs)
            {
                using return_type = temporary_xcomplex_t<CTR1, CTI1, B1>;
                using value_type = typename return_type::value_type;
                value_type a = lhs.real();
                value_type b = lhs.imag();
                value_type c = rhs.real();
                value_type d = rhs.imag();
                value_type e = c*c + d*d;
                return return_type((c*a + d*b) / e, (c*b - d*a) / e);
            }
        };

        template <>
        struct xcomplex_multiplier<true>
        {
            template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
            static auto mul(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs)
            {
                using return_type = temporary_xcomplex_t<CTR1, CTI1, B1>;
                using value_type = typename return_type::value_type;
                value_type a = lhs.real();
                value_type b = lhs.imag();
                value_type c = rhs.real();
                value_type d = rhs.imag();
                value_type ac = a * c;
                value_type bd = b * d;
                value_type ad = a * d;
                value_type bc = b * c;
                value_type x = ac - bd;
                value_type y = ad + bc;
                if (std::isnan(x) && std::isnan(y))
                {
                    bool recalc = false;
                    if (std::isinf(a) || std::isinf(b))
                    {
                        a = copysign(std::isinf(a) ? value_type(1) : value_type(0), a);
                        b = copysign(std::isinf(b) ? value_type(1) : value_type(0), b);
                        if (std::isnan(c))
                        {
                            c = copysign(value_type(0), c);
                        }
                        if (std::isnan(d))
                        {
                            d = copysign(value_type(0), d);
                        }
                        recalc = true;
                    }
                    if (std::isinf(c) || std::isinf(d))
                    {
                        c = copysign(std::isinf(c) ? value_type(1) : value_type(0), c);
                        d = copysign(std::isinf(c) ? value_type(1) : value_type(0), d);
                        if (std::isnan(a))
                        {
                            a = copysign(value_type(0), a);
                        }
                        if (std::isnan(b))
                        {
                            b = copysign(value_type(0), b);
                        }
                        recalc = true;
                    }
                    if (!recalc && (std::isinf(ac) || std::isinf(bd) || std::isinf(ad) || std::isinf(bc)))
                    {
                        if (std::isnan(a))
                        {
                            a = copysign(value_type(0), a);
                        }
                        if (std::isnan(b))
                        {
                            b = copysign(value_type(0), b);
                        }
                        if (std::isnan(c))
                        {
                            c = copysign(value_type(0), c);
                        }
                        if (std::isnan(d))
                        {
                            d = copysign(value_type(0), d);
                        }
                        recalc = true;
                    }
                    if (recalc)
                    {
                        x = std::numeric_limits<value_type>::infinity() * (a * c - b * d);
                        y = std::numeric_limits<value_type>::infinity() * (a * d + b * c);
                    }
                }
                return return_type(x, y);
            }

            template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
            static auto div(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs)
            {
                using return_type = temporary_xcomplex_t<CTR1, CTI1, B1>;
                using value_type = typename return_type::value_type;
                value_type a = lhs.real();
                value_type b = lhs.imag();
                value_type c = rhs.real();
                value_type d = rhs.imag();
                value_type logbw = std::logb(std::fmax(std::fabs(c), std::fabs(d)));
                int ilogbw = 0;
                if (std::isfinite(logbw))
                {
                    ilogbw = static_cast<int>(logbw);
                    c = std::scalbn(c, -ilogbw);
                    d = std::scalbn(d, -ilogbw);
                }
                value_type denom = c*c + d*d;
                value_type x = std::scalbn((a*c + b*d) / denom, -ilogbw);
                value_type y = std::scalbn((b*c - a*d) / denom, -ilogbw);
                if (std::isnan(x) && std::isnan(y))
                {
                    if ((denom == value_type(0)) && (!std::isnan(a) || !std::isnan(b)))
                    {
                        x = copysign(std::numeric_limits<value_type>::infinity(), c) * a;
                        y = copysign(std::numeric_limits<value_type>::infinity(), c) * b;
                    }
                    else if ((std::isinf(a) || std::isinf(b)) && std::isfinite(c) && std::isfinite(d))
                    {
                        a = copysign(std::isinf(a) ? value_type(1) : value_type(0), a);
                        b = copysign(std::isinf(b) ? value_type(1) : value_type(0), b);
                        x = std::numeric_limits<value_type>::infinity() * (a*c + b*d);
                        y = std::numeric_limits<value_type>::infinity() * (b*c - a*d);
                    }
                    else if (std::isinf(logbw) && logbw > value_type(0) && std::isfinite(a) && std::isfinite(b))
                    {
                        c = copysign(std::isinf(c) ? value_type(1) : value_type(0), c);
                        d = copysign(std::isinf(d) ? value_type(1) : value_type(0), d);
                        x = value_type(0) * (a*c + b*d);
                        y = value_type(0) * (b*c - a*d);
                    }
                }
                return std::complex<value_type>(x, y);
            }
        };
    }

    template <class CTR, class CTI, bool B>
    template <class OCTR, class OCTI, bool OB>
    inline auto xcomplex<CTR, CTI, B>::operator*=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept -> self_type&
    {
        *this = detail::xcomplex_multiplier<B || OB>::mul(*this, rhs);
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class OCTR, class OCTI, bool OB>
    inline auto xcomplex<CTR, CTI, B>::operator/=(const xcomplex<OCTR, OCTI, OB>& rhs) noexcept -> self_type&
    {
        *this = detail::xcomplex_multiplier<B || OB>::div(*this, rhs);
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class T>
    inline auto xcomplex<CTR, CTI, B>::operator+=(const T& rhs) noexcept -> disable_xcomplex<T, self_type&>
    {
        m_real += rhs;
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class T>
    inline auto xcomplex<CTR, CTI, B>::operator-=(const T& rhs) noexcept -> disable_xcomplex<T, self_type&>
    {
        m_real -= rhs;
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class T>
    inline auto xcomplex<CTR, CTI, B>::operator*=(const T& rhs) noexcept -> disable_xcomplex<T, self_type&>
    {
        m_real *= rhs;
        m_imag *= rhs;
        return *this;
    }

    template <class CTR, class CTI, bool B>
    template <class T>
    inline auto xcomplex<CTR, CTI, B>::operator/=(const T& rhs) noexcept -> disable_xcomplex<T, self_type&>
    {
        m_real /= rhs;
        m_imag /= rhs;
        return *this;
    }

    template <class CTR, class CTI, bool B>
    auto xcomplex<CTR, CTI, B>::real() & noexcept -> real_reference
    {
        return m_real;
    }

    template <class CTR, class CTI, bool B>
    auto xcomplex<CTR, CTI, B>::real() && noexcept -> real_rvalue_reference
    {
        return m_real;
    }

    template <class CTR, class CTI, bool B>
    constexpr auto xcomplex<CTR, CTI, B>::real() const & noexcept -> real_const_reference
    {
        return m_real;
    }

    template <class CTR, class CTI, bool B>
    constexpr auto xcomplex<CTR, CTI, B>::real() const && noexcept -> real_rvalue_const_reference
    {
        return m_real;
    }

    template <class CTR, class CTI, bool B>
    auto xcomplex<CTR, CTI, B>::imag() & noexcept -> imag_reference
    {
        return m_imag;
    }

    template <class CTR, class CTI, bool B>
    auto xcomplex<CTR, CTI, B>::imag() && noexcept -> imag_rvalue_reference
    {
        return m_imag;
    }

    template <class CTR, class CTI, bool B>
    constexpr auto xcomplex<CTR, CTI, B>::imag() const & noexcept -> imag_const_reference
    {
        return m_imag;
    }

    template <class CTR, class CTI, bool B>
    constexpr auto xcomplex<CTR, CTI, B>::imag() const && noexcept -> imag_rvalue_const_reference
    {
        return m_imag;
    }

    template <class CTR, class CTI, bool B>
    inline auto xcomplex<CTR, CTI, B>::operator&() & noexcept -> xclosure_pointer<self_type&>
    {
        return xclosure_pointer<self_type&>(*this);
    }

    template <class CTR, class CTI, bool B>
    inline auto xcomplex<CTR, CTI, B>::operator&() const & noexcept -> xclosure_pointer<const self_type&>
    {
        return xclosure_pointer<const self_type&>(*this);
    }

    template <class CTR, class CTI, bool B>
    inline auto xcomplex<CTR, CTI, B>::operator&() && noexcept -> xclosure_pointer<self_type>
    {
        return xclosure_pointer<self_type>(std::move(*this));
    }

    /*************************************
     * xcomplex operators implementation *
     *************************************/

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    inline bool operator==(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept
    {
        return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
    }

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    inline bool operator!=(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept
    {
        return !(lhs == rhs);
    }

    template <class OC, class OT, class CTR, class CTI, bool B>
    inline std::basic_ostream<OC, OT>& operator<<(std::basic_ostream<OC, OT>& out, const xcomplex<CTR, CTI, B>& c) noexcept
    {
        out << "(" << c.real() << "," << c.imag() << ")";
        return out;
    }

#ifdef __CLING__
    template <class CTR, class CTI, bool B>
    nlohmann::json mime_bundle_repr(const xcomplex<CTR, CTI, B>& c)
    {
        auto bundle = nlohmann::json::object();
        std::stringstream tmp;
        tmp << c;
        bundle["text/plain"] = tmp.str();
        return bundle;
    }
#endif

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    operator+(const xcomplex<CTR, CTI, B>& rhs) noexcept
    {
        return rhs;
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    operator-(const xcomplex<CTR, CTI, B>& rhs) noexcept
    {
        return temporary_xcomplex_t<CTR, CTI, B>(-rhs.real(), -rhs.imag());
    }

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    inline common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator+(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept
    {
        common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2> res(lhs);
        res += rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator+(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res += rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator+(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res += rhs;
        return res;
    }

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    inline common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator-(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept
    {
        common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2> res(lhs);
        res -= rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator-(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res -= rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator-(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res -= rhs;
        return res;
    }

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    inline common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator*(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept
    {
        common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2> res(lhs);
        res *= rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator*(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res *= rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator*(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res *= rhs;
        return res;
    }

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    inline common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    operator/(const xcomplex<CTR1, CTI1, B1>& lhs, const xcomplex<CTR2, CTI2, B2>& rhs) noexcept
    {
        common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2> res(lhs);
        res /= rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator/(const xcomplex<CTR, CTI, B>& lhs, const T& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res /= rhs;
        return res;
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    operator/(const T& lhs, const xcomplex<CTR, CTI, B>& rhs) noexcept
    {
        temporary_xcomplex_t<CTR, CTI, B> res(lhs);
        res /= rhs;
        return res;
    }

    /***************************
     * xcomplex free functions *
     ***************************/

    template <class CTR, class CTI, bool B>
    inline typename xcomplex<CTR, CTI, B>::value_type
    abs(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::abs(std::complex<value_type>(rhs));
    }

    template <class CTR, class CTI, bool B>
    inline typename xcomplex<CTR, CTI, B>::value_type
    arg(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::arg(std::complex<value_type>(rhs));
    }

    template <class CTR, class CTI, bool B>
    inline typename xcomplex<CTR, CTI, B>::value_type
    norm(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::norm(std::complex<value_type>(rhs));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    conj(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::conj(std::complex<value_type>(rhs));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    proj(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::proj(std::complex<value_type>(rhs));
    }

    /*************************************************
     * xcomplex exponential functions implementation *
     *************************************************/

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    exp(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::exp(std::complex<value_type>(rhs));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    log(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::log(std::complex<value_type>(rhs));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    log10(const xcomplex<CTR, CTI, B>& rhs)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::log10(std::complex<value_type>(rhs));
    }

    /*******************************************
     * xcomplex power functions implementation *
     *******************************************/

    template <class CTR1, class CTI1, bool B1, class CTR2, class CTI2, bool B2>
    inline common_xcomplex_t<CTR1, CTI1, B1, CTR2, CTI2, B2>
    pow(const xcomplex<CTR1, CTI1, B1>& x, const xcomplex<CTR2, CTI2, B2>& y)
    {
        using value_type1 = typename xcomplex<CTR1, CTI1, B1>::value_type;
        using value_type2 = typename xcomplex<CTR2, CTI2, B2>::value_type;
        return std::pow(std::complex<value_type1>(x), std::complex<value_type2>(y));
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    pow(const xcomplex<CTR, CTI, B>& x, const T& y)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::pow(std::complex<value_type>(x), y);
    }

    template <class CTR, class CTI, bool B, class T>
    inline enable_scalar<T, temporary_xcomplex_t<CTR, CTI, B>>
    pow(const T& x, const xcomplex<CTR, CTI, B>& y)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::pow(x, std::complex<value_type>(y));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    sqrt(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename xcomplex<CTR, CTI, B>::value_type;
        return std::sqrt(std::complex<value_type>(x));
    }

    /***************************************************
     * xcomplex trigonometric functions implementation *
     ***************************************************/

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    sin(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::sin(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    cos(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::cos(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    tan(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::tan(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    asin(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::asin(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    acos(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::acos(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    atan(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::atan(std::complex<value_type>(x));
    }

    /************************************************
     * xcomplex hyperbolic functions implementation *
     ************************************************/

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    sinh(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::sinh(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    cosh(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::cosh(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    tanh(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::tanh(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    asinh(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::asinh(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    acosh(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::acosh(std::complex<value_type>(x));
    }

    template <class CTR, class CTI, bool B>
    inline temporary_xcomplex_t<CTR, CTI, B>
    atanh(const xcomplex<CTR, CTI, B>& x)
    {
        using value_type = typename temporary_xcomplex_t<CTR, CTI, B>::value_type;
        return std::atanh(std::complex<value_type>(x));
    }

    /*********************************
     * forward_offset implementation *
     *********************************/

    namespace detail
    {

        template <class T, class M>
        struct forward_type
        {
            using type = apply_cv_t<T, M>;
        };

        template <class T, class M>
        struct forward_type<T&, M>
        {
            using type = apply_cv_t<T, M>&;
        };

        template <class T, class M>
        using forward_type_t = typename forward_type<T, M>::type;
    }

    template <class M, std::size_t I, class T>
    constexpr detail::forward_type_t<T, M> forward_offset(T&& v) noexcept
    {
        using forward_type = detail::forward_type_t<T, M>;
        using cv_value_type = std::remove_reference_t<forward_type>;
        using byte_type = apply_cv_t<std::remove_reference_t<T>, char>;

        return static_cast<forward_type>(
            *reinterpret_cast<cv_value_type*>(
                reinterpret_cast<byte_type*>(&v) + I
            )
        );
    }

    /**********************************************
     * forward_real & forward_imag implementation *
     **********************************************/

    // forward_real

    template <class T>
    auto forward_real(T&& v)
        -> std::enable_if_t<!is_gen_complex<T>::value, detail::forward_type_t<T, T>>  // real case -> forward
    {
        return static_cast<detail::forward_type_t<T, T>>(v);
    }

    template <class T>
    auto forward_real(T&& v)
        -> std::enable_if_t<is_complex<T>::value, detail::forward_type_t<T, typename std::decay_t<T>::value_type>>  // complex case -> forward the real part
    {
        return forward_offset<typename std::decay_t<T>::value_type, 0>(v);
    }

    template <class T>
    auto forward_real(T&& v)
        -> std::enable_if_t<is_xcomplex<T>::value, decltype(std::forward<T>(v).real())>
    {
        return std::forward<T>(v).real();
    }

    // forward_imag

    template <class T>
    auto forward_imag(T &&)
        -> std::enable_if_t<!is_gen_complex<T>::value, std::decay_t<T>>  // real case -> always return 0 by value
    {
        return 0;
    }

    template <class T>
    auto forward_imag(T&& v)
        -> std::enable_if_t<is_complex<T>::value, detail::forward_type_t<T, typename std::decay_t<T>::value_type>>  // complex case -> forwards the imaginary part
    {
        using real_type = typename std::decay_t<T>::value_type;
        return forward_offset<real_type, sizeof(real_type)>(v);
    }

    template <class T>
    auto forward_imag(T&& v)
        -> std::enable_if_t<is_xcomplex<T>::value, decltype(std::forward<T>(v).imag())>
    {
        return std::forward<T>(v).imag();
    }

    /******************************
     * real & imag implementation *
     ******************************/

    template <class E>
    inline decltype(auto) real(E&& e) noexcept
    {
        return forward_real(std::forward<E>(e));
    }

    template <class E>
    inline decltype(auto) imag(E&& e) noexcept
    {
        return forward_imag(std::forward<E>(e));
    }

    /**********************
     * complex_value_type *
     **********************/

    template <class T>
    struct complex_value_type
    {
        using type = T;
    };

    template <class T>
    struct complex_value_type<std::complex<T>>
    {
        using type = T;
    };

    template <class CTR, class CTI, bool B>
    struct complex_value_type<xcomplex<CTR, CTI, B>>
    {
        using type = xcomplex<CTR, CTI, B>;
    };

    template <class T>
    using complex_value_type_t = typename complex_value_type<T>::type;

    /******************************************************
     * operator overloads for complex and closure wrapper *
     *****************************************************/

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator+(const std::complex<C>& c, const T& t)
    {
        std::complex<C> result(c);
        result += t;
        return result;
    }

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator+(const T& t, const std::complex<C>& c)
    {
        std::complex<C> result(t);
        result += c;
        return result;
    }

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator-(const std::complex<C>& c, const T& t)
    {
        std::complex<C> result(c);
        result -= t;
        return result;
    }

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator-(const T& t, const std::complex<C>& c)
    {
        std::complex<C> result(t);
        result -= c;
        return result;
    }

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator*(const std::complex<C>& c, const T& t)
    {
        std::complex<C> result(c);
        result *= t;
        return result;
    }

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator*(const T& t, const std::complex<C>& c)
    {
        std::complex<C> result(t);
        result *= c;
        return result;
    }

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator/(const std::complex<C>& c, const T& t)
    {
        std::complex<C> result(c);
        result /= t;
        return result;
    }

    template <class C, class T, std::enable_if_t<!xtl::is_complex<T>::value, int> = 0>
    std::complex<C> operator/(const T& t, const std::complex<C>& c)
    {
        std::complex<C> result(t);
        result /= c;
        return result;
    }
}

#endif


text:
'use strict'
const StorageServiceInterface = require('./storage-service-client')
    , LocalStorageService = require('./local-storage-service')
    , Messaging_Gateway = require('../../core/messaging-gateway')

var bucket
var TIMEOUT_PERIOD = 25
var dbType = 0
var mediaType = 1
var dataLink = "www.x-in-y.com"   // Default link for now
var bucketName = "ONR"
var client = StorageServiceInterface(null, bucketName)
var storage = LocalStorageService("StorageService", null)
var keyExists = "Mad Max"
var keyExistsName = keyExists + "_NAME"
var keyExistsVal = "Mel Gibson"
var mediaKeyExists = "IMDB"
var tag1 = "Cop"
var tag2 = "Movie"
var keyMissing = "Missing"
var keys = [keyExists, "IMDB", "Pallindrome"]
var tags1 = [keyExists]
var tags2 = [keyExists, "IMDB"]
Messaging_Gateway.MessagingGateway("ProcessGateway", [client, storage])

describe("Local Storage Unit Tests", function () {
    beforeEach(function () {
        storage.addBucket(bucketName)
        bucket = storage._getBucket(bucketName)
        bucket.setValue(keyExists, keyExistsVal, keyExistsName, "Guy in a leather jacket", [tag1, tag2], dbType)
        bucket.setValue(mediaKeyExists, "www.imdb.com", mediaKeyExists, "", [tag2], mediaType)
        bucket.setValue("Pallindrome", "Emordnillap", null, "", null, dbType)
    })

    afterEach(function () {
        storage.delBucket(bucketName)
    })

    it("Add Data", function (done) {
        this.timeout(TIMEOUT_PERIOD * 2)
        var result, callback
        callback = function (val) {
            result = val
        }
        client.addDataValue(callback, "Big", "Ben")
        setTimeout(function () {
            expect(result).to.be.ok        //truthy value
            done()
        }, TIMEOUT_PERIOD)
    })
    it("Test Set Data", function (done) {
        var result, callback
        callback = function (val) {
            result = val
        }
        client.setDataValue(callback, "Big", "Ben")
        setTimeout(function () {
            expect(result).to.be.ok
            done()
        }, TIMEOUT_PERIOD)
    })
    it("Test Get Data", function (done) {

        var result, callback
        callback = function (val) {
            result = val
        }
        client.setDataValue(null, "Big", "Ben")
        client.getDataValue(callback, "Big")
        setTimeout(function () {
            expect(result === "Ben").to.be.true
            done()
        }, TIMEOUT_PERIOD)
    })
    it("testGetData_Exists", function (done) {

        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = keyExistsVal
        client.getDataValue(callback, keyExists)
        setTimeout(function () {
            expect(result === expectedResult).to.be.true
            done()
        }, TIMEOUT_PERIOD)
    })
    it("testGetData_Missing", function (done) {

        var result, callback
        callback = function (val) {
            result = val
        }
        client.getDataValue(callback, keyMissing)
        setTimeout(function () {
            expect(result).to.not.be.ok
            done()
        }, TIMEOUT_PERIOD)
    })
    it("testDelData_Exists", function (done) {

        var result, callback
        callback = function (val) {
            result = val
        }
        client.delDataValue(callback, keyExists)
        setTimeout(function () {
            expect(result).to.be.ok
            done()
        }, TIMEOUT_PERIOD)
    })
    it("testDelData_Missing", function (done) {

        var result, callback
        callback = function (val) {
            result = val
        }
        client.delDataValue(callback, keyMissing)
        setTimeout(function () {
            expect(result).to.not.be.ok
            done()
        }, TIMEOUT_PERIOD)
    })
    it("testHasDataKey_True", function (done) {

        var result, callback
        callback = function (val) {
            result = val
        }
        client.hasDataKey(callback, keyExists)
        setTimeout(function () {
            expect(result).to.be.ok
            done()
        }, TIMEOUT_PERIOD)
    })
    it("testHasDataKey_False", function (done) {
        var result, callback
        callback = function (val) {
            result = val
        }
        client.hasDataKey(callback, keyMissing)
        setTimeout(function () {
            expect(result).to.not.be.ok
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testGetDataKeys', function (done) {
        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = keys
        client.getDataKeys(callback)
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testGetDataKeys_Tags1', function (done) {
        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = tags1
        client.getDataKeys(callback, [tag1])
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it("testGetDataKeys_Tags2", function (done) {
        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = tags2
        client.getDataKeys(callback, [tag2])
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testGetDataKeys_Tags2_DB', function (done) {
        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = [keyExists]
        client.getDataKeys(callback, [tag2], dbType)
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testGetDataKeys_Tags2_Media', function (done) {
        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = [mediaKeyExists]
        client.getDataKeys(callback, [tag2], mediaType)
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testGetDataLink', function (done) {
        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = dataLink
        client.getDataLink(callback, mediaKeyExists)
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testGetDataLink_NonMedia', function (done) {
        var result, callback, expectedResult
        callback = function (val) {
            result = val
        }
        expectedResult = null
        client.getDataLink(callback, keyExists)
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testGetDataName', function (done) {
        var result, callback, expectedResult
        expectedResult = keyExistsName
        callback = function (val) {
            result = val
        }
        client.getDataName(callback, keyExists)
        setTimeout(function () {
            expect(result).to.eql(expectedResult)
            done()
        }, TIMEOUT_PERIOD)
    })
    it('testRename', function (done) {
        var key, result, callback, expectedResult
        key = keyExists
        expectedResult = "SomeNewName"
        callback = function (val) {
            result = val
        }
        client.renameData(callback, key, null, expectedResult)
        setTimeout(function () {
            var callback2, newName
            callback2 = function (val) {
                newName = val
            }
            expect(result).to.be.ok
            client.getDataName(callback2, key)
            setTimeout(function () {
                expect(newName).to.eql(expectedResult)
                done()
            }, TIMEOUT_PERIOD * 2)
        }, TIMEOUT_PERIOD)
    })
})

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>D-Index</title>
<meta name="date" content="2014-04-16">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Letter

Next Letter

Frames

No Frames

All Classes

A C D E F G H I J L M N O P R S T U V

D

DBBackupRunner - Class in de.uniba.kinf.jerusalem.gui.helper

Backups database; information of backuplocation, interval, maxNumber of
 backups, cutoff time via properties file.

DBBackupRunner(JerMainModel) - Constructor for class de.uniba.kinf.jerusalem.gui.helper.DBBackupRunner

de.uniba.kinf.jerusalem - package de.uniba.kinf.jerusalem

de.uniba.kinf.jerusalem.gui.controller - package de.uniba.kinf.jerusalem.gui.controller

de.uniba.kinf.jerusalem.gui.helper - package de.uniba.kinf.jerusalem.gui.helper

de.uniba.kinf.jerusalem.gui.helper.subclasses - package de.uniba.kinf.jerusalem.gui.helper.subclasses

de.uniba.kinf.jerusalem.gui.model - package de.uniba.kinf.jerusalem.gui.model

de.uniba.kinf.jerusalem.gui.model.helper - package de.uniba.kinf.jerusalem.gui.model.helper

de.uniba.kinf.jerusalem.gui.model.subclasses - package de.uniba.kinf.jerusalem.gui.model.subclasses

de.uniba.kinf.jerusalem.gui.view - package de.uniba.kinf.jerusalem.gui.view

de.uniba.kinf.jerusalem.gui.view.helper - package de.uniba.kinf.jerusalem.gui.view.helper

de.uniba.kinf.jerusalem.gui.view.map - package de.uniba.kinf.jerusalem.gui.view.map

de.uniba.kinf.jerusalem.gui.view.tablepanels - package de.uniba.kinf.jerusalem.gui.view.tablepanels

de.uniba.kinf.jerusalem.gui.view.workpanels - package de.uniba.kinf.jerusalem.gui.view.workpanels

de.uniba.kinf.jerusalem.gui.view.workpanels.helper - package de.uniba.kinf.jerusalem.gui.view.workpanels.helper

de.uniba.kinf.jerusalem.gui.view.workpanels.helper.subclasses - package de.uniba.kinf.jerusalem.gui.view.workpanels.helper.subclasses

de.uniba.kinf.jerusalem.gui.view.workpanels.subclasses - package de.uniba.kinf.jerusalem.gui.view.workpanels.subclasses

DEBUG - Static variable in class de.uniba.kinf.jerusalem.Main

Set DEBUG to false if deploy.

DEFCOLOROK - Static variable in class de.uniba.kinf.jerusalem.Main

DEFCOLORPROBLEM - Static variable in class de.uniba.kinf.jerusalem.Main

DEFSIZEADD - Static variable in class de.uniba.kinf.jerusalem.Main

DEFUNITINCREMENT - Static variable in class de.uniba.kinf.jerusalem.Main

del() - Method in class de.uniba.kinf.jerusalem.gui.model.JerModel

delete(JerModel) - Method in class de.uniba.kinf.jerusalem.gui.model.JerMainModel

displayInfo(HashMap<String, Object>) - Method in class de.uniba.kinf.jerusalem.gui.view.workpanels.helper.JerComboBox

displayInfo(HashMap<String, Object>) - Method in interface de.uniba.kinf.jerusalem.gui.view.workpanels.helper.JerFieldInfoIF

displayInfo(HashMap<String, Object>) - Method in class de.uniba.kinf.jerusalem.gui.view.workpanels.helper.JerMultiField

displayInfo(HashMap<String, Object>) - Method in class de.uniba.kinf.jerusalem.gui.view.workpanels.helper.JerTextField

A C D E F G H I J L M N O P R S T U V

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Letter

Next Letter

Frames

No Frames

All Classes


text:
package retrofit.http;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * Encoded query parameter appended to the URL.
 * <p>
 * Values are converted to strings using {@link String#valueOf(Object)}. Values are not URL
 * encoded. {@code null} values will not include the query parameter in the URL. See
 * {@link Query @Query} for URL-encoding equivalent.
 *
 * @see Query
 * @see QueryMap
 * @deprecated Use {@link Query} with {@link Query#encodeValue() encodeValue = false}.
 */
@Documented
@Deprecated
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface EncodedQuery {
  String value();
}


text:
import { fromJS } from 'immutable';
import { goBack, push } from 'react-router-redux';
import api from '../../common/api';

export const GET_CATEGORIES = 'GET_CATEGORIES';
export const POST_CHALLENGE = 'POST_CHALLENGE';

function receiveCategories(categories) {
    return {
        type: GET_CATEGORIES,
        categories
    };
}

function receiveChallenge(challenge) {
    return {
        type: POST_CHALLENGE,
        challenge
    };
}

export function fetchCategories() {
    return function innerFetchCategories(dispatch) {
        api('/api/categories')
            .then((categories) => {
                dispatch(receiveCategories(categories));
            });
    };
}

export function sendChallenge(challenge) {
    return function innerSendChallenge(data) {
        if (challenge && challenge.size) {
            const ignoredFields = ['user', '_id'];
            const immutableData = fromJS({
                ...data,
                categories: [data.category]
            });
            const formData = immutableData
                .filter((value, key) => ignoredFields.indexOf(key) === -1)
                .filter((value, key) => (challenge.get(key) && (challenge.get(key) !== value)));

            return updateChallenge(formData, challenge.get('_id'));
        }
        const formData = data;
        formData.categories = [data.category];
        formData.location = 'Kyiv';
        formData.level = 'easy';

        return postChallenge(formData);
    };
}

function postChallenge(formData) {
    return function innerPostChallenge(dispatch) {
        api('/api/challenges', {
            method: 'POST',
            body: JSON.stringify(formData)
        })
            .then((response) => {
                dispatch(receiveChallenge(response));
                dispatch(goBack());
            });
    };
}

function updateChallenge(formData, id) {
    return function innerUpdateChallenge(dispatch) {
        if (formData.size) {
            api(`/api/challenges/${id}`, {
                method: 'PUT',
                body: JSON.stringify(formData)
            })
                .then((response) => {
                    dispatch(receiveChallenge(response));
                    dispatch(goBack());
                });
        } else {
            dispatch(push('/main/challenges'));
        }
    };
}


text:
<?php

namespace Piplin\Bus\Jobs\Task;

use Carbon\Carbon;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Queue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Cache;
use Piplin\Bus\Jobs\AbortTaskJob;
use Piplin\Bus\Jobs\Job;
use Piplin\Bus\Jobs\UpdateGitReferencesJob;
use Piplin\Models\Command as Stage;
use Piplin\Models\Task;
use Piplin\Models\TaskStep;
use Piplin\Models\Environment;
use Piplin\Models\BuildPlan;
use Piplin\Models\Project;
use Piplin\Models\Release;
use Piplin\Models\Server;
use Piplin\Models\ServerLog;
use Piplin\Models\User;
use Piplin\Services\Scripts\Parser as ScriptParser;
use Piplin\Services\Scripts\Runner as Process;
use Illuminate\Bus\Queueable;

/**
 * Abstract class of run task steps.
 */
abstract class BaseRunTaskStepsJob
{
    /*
    |--------------------------------------------------------------------------
    | Queueable Jobs
    |--------------------------------------------------------------------------
    |
    | This job base class provides a central location to place any logic that
    | is shared across all of your jobs. The trait included with the class
    | provides access to the "onQueue" and "delay" queue helper methods.
    |
    */

    use Queueable, SerializesModels, DispatchesJobs;

    /**
     * @var int
     */
    public $timeout = 0;

    /**
     * @var Task
     */
    protected $task;

    /**
     * @var mixed
     */
    protected $plan;

    /**
     * @var Project
     */
    protected $project;

    /**
     * @var string
     */
    protected $cache_key;

    /**
     * @var string
     */
    protected $private_key;

    /**
     * @var string
     */
    protected $release_archive;

    /**
     *
     * @var bool
     */
    protected $isBuild;

    /**
     * Create a new job instance.
     *
     * @param Task   $task
     * @param string $private_key
     * @param string $release_archive
     *
     * @return void
     */
    public function __construct(Task $task, $private_key, $release_archive)
    {
        $this->task            = $task;
        $this->plan            = $task->targetable;
        $this->project         = $task->project;
        $this->private_key     = $private_key;
        $this->cache_key       = AbortTaskJob::CACHE_KEY_PREFIX . $task->id;
        $this->release_archive = $release_archive;
        if ($this->plan instanceof BuildPlan) {
            $this->isBuild = true;
        } else {
            $this->isBuild = false;
        }
    }

    /**
     * Overwrite the queue method to push to a different queue.
     *
     * @param Queue $queue
     * @param Job   $command
     */
    public function queue(Queue $queue, $command)
    {
        $queue->pushOn('piplin-high', $command);
    }

    /**
     * Sends a file to a remote server.
     *
     * @param  string           $local_file
     * @param  string           $remote_file
     * @param  ServerLog        $log
     * @throws RuntimeException
     */
    protected function sendFile($local_file, $remote_file, ServerLog $log)
    {
        $process = new Process('deploy.SendFileToServer', [
            'port'        => $log->server->port,
            'private_key' => $this->private_key,
            'local_file'  => $local_file,
            'remote_file' => $remote_file,
            'username'    => $log->server->user,
            'ip_address'  => $log->server->ip_address,
        ]);

        $output = '';
        $process->run(function ($type, $output_line) use (&$output, &$log) {
            if ($type === \Symfony\Component\Process\Process::ERR) {
                $output .= $this->logError($output_line);
            } else {
                $output .= $this->logSuccess($output_line);
            }

            $log->output = $output;
            $log->save();
        });

        if (!$process->isSuccessful()) {
            throw new \RuntimeException($process->getErrorOutput());
        }
    }

    /**
     * Generates the list of tokens for the scripts.
     *
     * @param TaskStep $step
     * @param Server     $server
     */
    protected function getTokenList(TaskStep $step)
    {
        $project_path = $this->project->clean_deploy_path;

        $releases_dir       = $project_path . '/releases';
        $builds_dir         = $project_path . '/builds';
        $release_shared_dir = $project_path . '/shared';
        $remote_archive     = $project_path . '/' . $this->release_archive;

        $tokens = [
            'project_path'    => $project_path,
            'branch'          => $this->task->branch,
            'sha'             => $this->task->commit,
            'short_sha'       => $this->task->short_commit,
            'committer_email' => $this->task->committer_email,
            'committer_name'  => $this->task->committer,
        ];

        if ($this->isBuild === true) {
            $tokens = array_merge($tokens, [
                'build'         => $this->task->release_id,
                'build_path'    => $builds_dir . '/' . $this->task->release_id,
            ]);
        } else {
            $author_email = '';
            $author_name  = 'webhook';
            if ($this->task->user) {
                $author_name  = $this->task->user->name;
                $author_email = $this->task->user->email;
            } elseif ($this->task->is_webhook && !empty($this->task->source)) {
                $author_name = $this->task->source;
            }

            $tokens = array_merge($tokens, [
                'release'         => $this->task->release_id,
                'release_path'    => $releases_dir . '/' . $this->task->release_id,
                'author_email'  => $author_email,
                'author_name'   => $author_name,
            ]);

            if ($this->task->payload && $this->task->payload->source == 'release') {
                $release = Release::findOrFail($this->task->payload->source_release);
                $tokens = array_merge($tokens, [
                    'build_release' => $release->name,
                ]);
            }
        }

        if (!$step->isCustom()) {
            $tokens = array_merge($tokens, [
                'remote_archive' => $remote_archive,
                'builds_to_keep' => $this->project->builds_to_keep + 1,
            ]);

            if ($this->isBuild === true) {
                $tokens = array_merge($tokens, [
                    'builds_path'  => $builds_dir,
                ]);
            } else {
                $tokens = array_merge($tokens, [
                    'shared_path'   => $release_shared_dir,
                    'releases_path' => $releases_dir,
                ]);
            }
        }

        return $tokens;
    }

    /**
     * Generates an error string to log to the DB.
     *
     * @param string $message
     */
    protected function logError($message)
    {
        return '<error>' . $message . '</error>';
    }
    /**
     * Generates an general output string to log to the DB.
     *
     * @param string $message
     */
    protected function logSuccess($message)
    {
        return '<info>' . $message . '</info>';
    }
}


text:
<?php

abstract class BasesfAssetPeer {

	const DATABASE_NAME = 'propel';

	const TABLE_NAME = 'sf_asset';

	const CLASS_DEFAULT = 'plugins.sfAssetsLibraryPlugin.lib.model.sfAsset';

	const NUM_COLUMNS = 9;

	const NUM_LAZY_LOAD_COLUMNS = 0;

	const ID = 'sf_asset.ID';

	const FOLDER_ID = 'sf_asset.FOLDER_ID';

	const FILENAME = 'sf_asset.FILENAME';

	const DESCRIPTION = 'sf_asset.DESCRIPTION';

	const AUTHOR = 'sf_asset.AUTHOR';

	const COPYRIGHT = 'sf_asset.COPYRIGHT';

	const TYPE = 'sf_asset.TYPE';

	const FILESIZE = 'sf_asset.FILESIZE';

	const CREATED_AT = 'sf_asset.CREATED_AT';

	private static $phpNameMap = null;

	private static $fieldNames = array (
		BasePeer::TYPE_PHPNAME => array ('Id', 'FolderId', 'Filename', 'Description', 'Author', 'Copyright', 'Type', 'Filesize', 'CreatedAt', ),
		BasePeer::TYPE_COLNAME => array (sfAssetPeer::ID, sfAssetPeer::FOLDER_ID, sfAssetPeer::FILENAME, sfAssetPeer::DESCRIPTION, sfAssetPeer::AUTHOR, sfAssetPeer::COPYRIGHT, sfAssetPeer::TYPE, sfAssetPeer::FILESIZE, sfAssetPeer::CREATED_AT, ),
		BasePeer::TYPE_FIELDNAME => array ('id', 'folder_id', 'filename', 'description', 'author', 'copyright', 'type', 'filesize', 'created_at', ),
		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, )
	);

	private static $fieldKeys = array (
		BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'FolderId' => 1, 'Filename' => 2, 'Description' => 3, 'Author' => 4, 'Copyright' => 5, 'Type' => 6, 'Filesize' => 7, 'CreatedAt' => 8, ),
		BasePeer::TYPE_COLNAME => array (sfAssetPeer::ID => 0, sfAssetPeer::FOLDER_ID => 1, sfAssetPeer::FILENAME => 2, sfAssetPeer::DESCRIPTION => 3, sfAssetPeer::AUTHOR => 4, sfAssetPeer::COPYRIGHT => 5, sfAssetPeer::TYPE => 6, sfAssetPeer::FILESIZE => 7, sfAssetPeer::CREATED_AT => 8, ),
		BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'folder_id' => 1, 'filename' => 2, 'description' => 3, 'author' => 4, 'copyright' => 5, 'type' => 6, 'filesize' => 7, 'created_at' => 8, ),
		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, )
	);

	public static function getMapBuilder()
	{
		include_once 'plugins/sfAssetsLibraryPlugin/lib/model/map/sfAssetMapBuilder.php';
		return BasePeer::getMapBuilder('plugins.sfAssetsLibraryPlugin.lib.model.map.sfAssetMapBuilder');
	}

	public static function getPhpNameMap()
	{
		if (self::$phpNameMap === null) {
			$map = sfAssetPeer::getTableMap();
			$columns = $map->getColumns();
			$nameMap = array();
			foreach ($columns as $column) {
				$nameMap[$column->getPhpName()] = $column->getColumnName();
			}
			self::$phpNameMap = $nameMap;
		}
		return self::$phpNameMap;
	}

	static public function translateFieldName($name, $fromType, $toType)
	{
		$toNames = self::getFieldNames($toType);
		$key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null;
		if ($key === null) {
			throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true));
		}
		return $toNames[$key];
	}

	static public function getFieldNames($type = BasePeer::TYPE_PHPNAME)
	{
		if (!array_key_exists($type, self::$fieldNames)) {
			throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . $type . ' was given.');
		}
		return self::$fieldNames[$type];
	}

	public static function alias($alias, $column)
	{
		return str_replace(sfAssetPeer::TABLE_NAME.'.', $alias.'.', $column);
	}

	public static function addSelectColumns(Criteria $criteria)
	{

		$criteria->addSelectColumn(sfAssetPeer::ID);

		$criteria->addSelectColumn(sfAssetPeer::FOLDER_ID);

		$criteria->addSelectColumn(sfAssetPeer::FILENAME);

		$criteria->addSelectColumn(sfAssetPeer::DESCRIPTION);

		$criteria->addSelectColumn(sfAssetPeer::AUTHOR);

		$criteria->addSelectColumn(sfAssetPeer::COPYRIGHT);

		$criteria->addSelectColumn(sfAssetPeer::TYPE);

		$criteria->addSelectColumn(sfAssetPeer::FILESIZE);

		$criteria->addSelectColumn(sfAssetPeer::CREATED_AT);

	}

	const COUNT = 'COUNT(sf_asset.ID)';
	const COUNT_DISTINCT = 'COUNT(DISTINCT sf_asset.ID)';

	public static function doCount(Criteria $criteria, $distinct = false, $con = null)
	{
				$criteria = clone $criteria;

				$criteria->clearSelectColumns()->clearOrderByColumns();
		if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
			$criteria->addSelectColumn(sfAssetPeer::COUNT_DISTINCT);
		} else {
			$criteria->addSelectColumn(sfAssetPeer::COUNT);
		}

				foreach($criteria->getGroupByColumns() as $column)
		{
			$criteria->addSelectColumn($column);
		}

		$rs = sfAssetPeer::doSelectRS($criteria, $con);
		if ($rs->next()) {
			return $rs->getInt(1);
		} else {
						return 0;
		}
	}

	public static function doSelectOne(Criteria $criteria, $con = null)
	{
		$critcopy = clone $criteria;
		$critcopy->setLimit(1);
		$objects = sfAssetPeer::doSelect($critcopy, $con);
		if ($objects) {
			return $objects[0];
		}
		return null;
	}

	public static function doSelect(Criteria $criteria, $con = null)
	{
		return sfAssetPeer::populateObjects(sfAssetPeer::doSelectRS($criteria, $con));
	}

	public static function doSelectRS(Criteria $criteria, $con = null)
	{

    foreach (sfMixer::getCallables('BasesfAssetPeer:addDoSelectRS:addDoSelectRS') as $callable)
    {
      call_user_func($callable, 'BasesfAssetPeer', $criteria, $con);
    }

		if ($con === null) {
			$con = Propel::getConnection(self::DATABASE_NAME);
		}

		if (!$criteria->getSelectColumns()) {
			$criteria = clone $criteria;
			sfAssetPeer::addSelectColumns($criteria);
		}

				$criteria->setDbName(self::DATABASE_NAME);

						return BasePeer::doSelect($criteria, $con);
	}

	public static function populateObjects(ResultSet $rs)
	{
		$results = array();

				$cls = sfAssetPeer::getOMClass();
		$cls = Propel::import($cls);
				while($rs->next()) {

			$obj = new $cls();
			$obj->hydrate($rs);
			$results[] = $obj;

		}
		return $results;
	}

	public static function doCountJoinsfAssetFolder(Criteria $criteria, $distinct = false, $con = null)
	{
				$criteria = clone $criteria;

				$criteria->clearSelectColumns()->clearOrderByColumns();
		if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
			$criteria->addSelectColumn(sfAssetPeer::COUNT_DISTINCT);
		} else {
			$criteria->addSelectColumn(sfAssetPeer::COUNT);
		}

				foreach($criteria->getGroupByColumns() as $column)
		{
			$criteria->addSelectColumn($column);
		}

		$criteria->addJoin(sfAssetPeer::FOLDER_ID, sfAssetFolderPeer::ID);

		$rs = sfAssetPeer::doSelectRS($criteria, $con);
		if ($rs->next()) {
			return $rs->getInt(1);
		} else {
						return 0;
		}
	}

	public static function doSelectJoinsfAssetFolder(Criteria $c, $con = null)
	{
		$c = clone $c;

				if ($c->getDbName() == Propel::getDefaultDB()) {
			$c->setDbName(self::DATABASE_NAME);
		}

		sfAssetPeer::addSelectColumns($c);
		$startcol = (sfAssetPeer::NUM_COLUMNS - sfAssetPeer::NUM_LAZY_LOAD_COLUMNS) + 1;
		sfAssetFolderPeer::addSelectColumns($c);

		$c->addJoin(sfAssetPeer::FOLDER_ID, sfAssetFolderPeer::ID);
		$rs = BasePeer::doSelect($c, $con);
		$results = array();

		while($rs->next()) {

			$omClass = sfAssetPeer::getOMClass();

			$cls = Propel::import($omClass);
			$obj1 = new $cls();
			$obj1->hydrate($rs);

			$omClass = sfAssetFolderPeer::getOMClass();

			$cls = Propel::import($omClass);
			$obj2 = new $cls();
			$obj2->hydrate($rs, $startcol);

			$newObject = true;
			foreach($results as $temp_obj1) {
				$temp_obj2 = $temp_obj1->getsfAssetFolder(); 				if ($temp_obj2->getPrimaryKey() === $obj2->getPrimaryKey()) {
					$newObject = false;
										$temp_obj2->addsfAsset($obj1); 					break;
				}
			}
			if ($newObject) {
				$obj2->initsfAssets();
				$obj2->addsfAsset($obj1); 			}
			$results[] = $obj1;
		}
		return $results;
	}

	public static function doCountJoinAll(Criteria $criteria, $distinct = false, $con = null)
	{
		$criteria = clone $criteria;

				$criteria->clearSelectColumns()->clearOrderByColumns();
		if ($distinct || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
			$criteria->addSelectColumn(sfAssetPeer::COUNT_DISTINCT);
		} else {
			$criteria->addSelectColumn(sfAssetPeer::COUNT);
		}

				foreach($criteria->getGroupByColumns() as $column)
		{
			$criteria->addSelectColumn($column);
		}

		$criteria->addJoin(sfAssetPeer::FOLDER_ID, sfAssetFolderPeer::ID);

		$rs = sfAssetPeer::doSelectRS($criteria, $con);
		if ($rs->next()) {
			return $rs->getInt(1);
		} else {
						return 0;
		}
	}

	public static function doSelectJoinAll(Criteria $c, $con = null)
	{
		$c = clone $c;

				if ($c->getDbName() == Propel::getDefaultDB()) {
			$c->setDbName(self::DATABASE_NAME);
		}

		sfAssetPeer::addSelectColumns($c);
		$startcol2 = (sfAssetPeer::NUM_COLUMNS - sfAssetPeer::NUM_LAZY_LOAD_COLUMNS) + 1;

		sfAssetFolderPeer::addSelectColumns($c);
		$startcol3 = $startcol2 + sfAssetFolderPeer::NUM_COLUMNS;

		$c->addJoin(sfAssetPeer::FOLDER_ID, sfAssetFolderPeer::ID);

		$rs = BasePeer::doSelect($c, $con);
		$results = array();

		while($rs->next()) {

			$omClass = sfAssetPeer::getOMClass();

			$cls = Propel::import($omClass);
			$obj1 = new $cls();
			$obj1->hydrate($rs);

			$omClass = sfAssetFolderPeer::getOMClass();

			$cls = Propel::import($omClass);
			$obj2 = new $cls();
			$obj2->hydrate($rs, $startcol2);

			$newObject = true;
			for ($j=0, $resCount=count($results); $j < $resCount; $j++) {
				$temp_obj1 = $results[$j];
				$temp_obj2 = $temp_obj1->getsfAssetFolder(); 				if ($temp_obj2->getPrimaryKey() === $obj2->getPrimaryKey()) {
					$newObject = false;
					$temp_obj2->addsfAsset($obj1); 					break;
				}
			}

			if ($newObject) {
				$obj2->initsfAssets();
				$obj2->addsfAsset($obj1);
			}

			$results[] = $obj1;
		}
		return $results;
	}

	public static function getTableMap()
	{
		return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
	}

	public static function getOMClass()
	{
		return sfAssetPeer::CLASS_DEFAULT;
	}

	public static function doInsert($values, $con = null)
	{

    foreach (sfMixer::getCallables('BasesfAssetPeer:doInsert:pre') as $callable)
    {
      $ret = call_user_func($callable, 'BasesfAssetPeer', $values, $con);
      if (false !== $ret)
      {
        return $ret;
      }
    }

		if ($con === null) {
			$con = Propel::getConnection(self::DATABASE_NAME);
		}

		if ($values instanceof Criteria) {
			$criteria = clone $values; 		} else {
			$criteria = $values->buildCriteria(); 		}

		$criteria->remove(sfAssetPeer::ID);

				$criteria->setDbName(self::DATABASE_NAME);

		try {
									$con->begin();
			$pk = BasePeer::doInsert($criteria, $con);
			$con->commit();
		} catch(PropelException $e) {
			$con->rollback();
			throw $e;
		}

    foreach (sfMixer::getCallables('BasesfAssetPeer:doInsert:post') as $callable)
    {
      call_user_func($callable, 'BasesfAssetPeer', $values, $con, $pk);
    }

    return $pk;
	}

	public static function doUpdate($values, $con = null)
	{

    foreach (sfMixer::getCallables('BasesfAssetPeer:doUpdate:pre') as $callable)
    {
      $ret = call_user_func($callable, 'BasesfAssetPeer', $values, $con);
      if (false !== $ret)
      {
        return $ret;
      }
    }

		if ($con === null) {
			$con = Propel::getConnection(self::DATABASE_NAME);
		}

		$selectCriteria = new Criteria(self::DATABASE_NAME);

		if ($values instanceof Criteria) {
			$criteria = clone $values;
			$comparison = $criteria->getComparison(sfAssetPeer::ID);
			$selectCriteria->add(sfAssetPeer::ID, $criteria->remove(sfAssetPeer::ID), $comparison);

		} else { 			$criteria = $values->buildCriteria(); 			$selectCriteria = $values->buildPkeyCriteria(); 		}

				$criteria->setDbName(self::DATABASE_NAME);

		$ret = BasePeer::doUpdate($selectCriteria, $criteria, $con);

    foreach (sfMixer::getCallables('BasesfAssetPeer:doUpdate:post') as $callable)
    {
      call_user_func($callable, 'BasesfAssetPeer', $values, $con, $ret);
    }

    return $ret;
  }

	public static function doDeleteAll($con = null)
	{
		if ($con === null) {
			$con = Propel::getConnection(self::DATABASE_NAME);
		}
		$affectedRows = 0; 		try {
									$con->begin();
			$affectedRows += BasePeer::doDeleteAll(sfAssetPeer::TABLE_NAME, $con);
			$con->commit();
			return $affectedRows;
		} catch (PropelException $e) {
			$con->rollback();
			throw $e;
		}
	}

	 public static function doDelete($values, $con = null)
	 {
		if ($con === null) {
			$con = Propel::getConnection(sfAssetPeer::DATABASE_NAME);
		}

		if ($values instanceof Criteria) {
			$criteria = clone $values; 		} elseif ($values instanceof sfAsset) {

			$criteria = $values->buildPkeyCriteria();
		} else {
						$criteria = new Criteria(self::DATABASE_NAME);
			$criteria->add(sfAssetPeer::ID, (array) $values, Criteria::IN);
		}

				$criteria->setDbName(self::DATABASE_NAME);

		$affectedRows = 0;
		try {
									$con->begin();

			$affectedRows += BasePeer::doDelete($criteria, $con);
			$con->commit();
			return $affectedRows;
		} catch (PropelException $e) {
			$con->rollback();
			throw $e;
		}
	}

	public static function doValidate(sfAsset $obj, $cols = null)
	{
		$columns = array();

		if ($cols) {
			$dbMap = Propel::getDatabaseMap(sfAssetPeer::DATABASE_NAME);
			$tableMap = $dbMap->getTable(sfAssetPeer::TABLE_NAME);

			if (! is_array($cols)) {
				$cols = array($cols);
			}

			foreach($cols as $colName) {
				if ($tableMap->containsColumn($colName)) {
					$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
					$columns[$colName] = $obj->$get();
				}
			}
		} else {

		}

		$res =  BasePeer::doValidate(sfAssetPeer::DATABASE_NAME, sfAssetPeer::TABLE_NAME, $columns);
    if ($res !== true) {
        $request = sfContext::getInstance()->getRequest();
        foreach ($res as $failed) {
            $col = sfAssetPeer::translateFieldname($failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
            $request->setError($col, $failed->getMessage());
        }
    }

    return $res;
	}

	public static function retrieveByPK($pk, $con = null)
	{
		if ($con === null) {
			$con = Propel::getConnection(self::DATABASE_NAME);
		}

		$criteria = new Criteria(sfAssetPeer::DATABASE_NAME);

		$criteria->add(sfAssetPeer::ID, $pk);

		$v = sfAssetPeer::doSelect($criteria, $con);

		return !empty($v) > 0 ? $v[0] : null;
	}

	public static function retrieveByPKs($pks, $con = null)
	{
		if ($con === null) {
			$con = Propel::getConnection(self::DATABASE_NAME);
		}

		$objs = null;
		if (empty($pks)) {
			$objs = array();
		} else {
			$criteria = new Criteria();
			$criteria->add(sfAssetPeer::ID, $pks, Criteria::IN);
			$objs = sfAssetPeer::doSelect($criteria, $con);
		}
		return $objs;
	}

}
if (Propel::isInit()) {
			try {
		BasesfAssetPeer::getMapBuilder();
	} catch (Exception $e) {
		Propel::log('Could not initialize Peer: ' . $e->getMessage(), Propel::LOG_ERR);
	}
} else {
			require_once 'plugins/sfAssetsLibraryPlugin/lib/model/map/sfAssetMapBuilder.php';
	Propel::registerMapBuilder('plugins.sfAssetsLibraryPlugin.lib.model.map.sfAssetMapBuilder');
}


text:
@interface NSString (DropboxStringToDate)

- (nullable NSDate *)date;

@end


text:
static NSOperationQueue * download_manager_creation_queue() {
    static NSOperationQueue *pg_url_manager_creation_queue = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        pg_url_manager_creation_queue = [[NSOperationQueue alloc] init];
        pg_url_manager_creation_queue.maxConcurrentOperationCount = 5;
    });

    return pg_url_manager_creation_queue;
}

////////////////////////////////////////////////////////////////
@interface RMDownTask : NSObject
@property(nonatomic, strong)NSURLSessionDownloadTask *task;
@property(nonatomic, strong)NSData *resumeData;
@property(nonatomic, assign)int64_t totalBytesWritten;
@property(nonatomic, assign)int64_t totalBytesExpectedToWrite;
@property(nonatomic, strong)NSString *fileDirectory;
@property(atomic, strong)NSMutableArray *arrayDelegate;
@end

@implementation RMDownTask

- (id)init {
    if(self = [super init]) {
        self.arrayDelegate = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)addDelegate:(id<PGDownloadManagerDelegate>)delegate {
    if(delegate != nil) {
        BOOL bFlag = YES;
        for(id aDelegate in self.arrayDelegate) {
            if(aDelegate == delegate) {
                bFlag = NO;
                break;
            }
        }

        if(bFlag) {
            [self.arrayDelegate addObject:delegate];
        }
    }
}

- (void)delDelegate:(id<PGDownloadManagerDelegate>)delegate {
    if(delegate != nil) {
        [self.arrayDelegate removeObject:delegate];
    }
}

@end

////////////////////////////////////////////////////////////////
@interface PGDownloadManager ()<NSURLSessionDownloadDelegate>
@property(atomic, strong)NSMutableDictionary *mTasks;
@property(readwrite, nonatomic, strong)NSLock *lock;
@property(nonatomic, strong)NSURLSession *session;
@end

@implementation PGDownloadManager
+ (PGDownloadManager *)shareInstance {
    static dispatch_once_t onceToken;
    static PGDownloadManager *s_downloadManager = nil;
    dispatch_once(&onceToken, ^{
        s_downloadManager = [[PGDownloadManager alloc] init];
        s_downloadManager.mTasks = [[NSMutableDictionary alloc] init];
    });

    return s_downloadManager;
}

- (id)init {
    if(self = [super init]) {
        _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:download_manager_creation_queue()];
        _lock = [[NSLock alloc] init];
        _lock.name = @"PGDownloadManagerLock";
    }
    return self;
}

- (void)addTask:(NSString *)url fileDirectory:(NSString *)fileDirectory  delegate:(id<PGDownloadManagerDelegate>)delegate {
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [self.mTasks objectForKey:downKey];
    if(downTask) {
        [downTask addDelegate:delegate];
        switch (downTask.task.state) {
            case NSURLSessionTaskStateSuspended:
            {
                [downTask.task resume];
                break;
            }
            case NSURLSessionTaskStateCanceling:
            {
                NSURLSessionDownloadTask *task = [self.session downloadTaskWithResumeData:downTask.resumeData];
                downTask.task = task;
                [task resume];
                break;
            }
            case NSURLSessionTaskStateCompleted:
            {
                if(downTask.totalBytesWritten != downTask.totalBytesExpectedToWrite) {
                    NSURLSessionDownloadTask *task = [self.session downloadTaskWithResumeData:downTask.resumeData];
                    downTask.task = task;
                    [task resume];
                }
                break;
            }
            default:
                break;
        }
    } else {
        NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
        downTask = [[RMDownTask alloc] init];
        downTask.task = task;
        [downTask addDelegate:delegate];
        downTask.fileDirectory = fileDirectory;
        [self.lock lock];
        [self.mTasks setObject:downTask forKey:downKey];
        [self.lock unlock];
        [task resume];
    }
}

+ (void)addDownloadTask:(NSString *)url fileDirectory:(NSString *)fileDirectory delegate:(id<PGDownloadManagerDelegate>)delegate {

    if(url == nil || url.length < 1) {
        if(delegate && [delegate respondsToSelector:@selector(download:error:)]) {
            NSError *error = [[NSError alloc] initWithDomain:@"链接为空" code:-1 userInfo:nil];
            [delegate download:url error:error];
        }
    } else {
        NSString *path = [NSString stringWithFormat:@"%@/%@",fileDirectory, [NSString MD5Encrypt:url]];
        path = [path stringByAppendingPathExtension:[url pathExtension]];
        if([[NSFileManager defaultManager] fileExistsAtPath:path]) {
            if(delegate && [delegate respondsToSelector:@selector(download:didFinish:)]) {
                [delegate download:url didFinish:path];
            }
        } else {
            [[PGDownloadManager shareInstance] addTask:url fileDirectory:fileDirectory delegate:delegate];
        }
    }
}

+ (void)cancelTask:(NSString *)url {
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [[PGDownloadManager shareInstance].mTasks objectForKey:downKey];
    if(downTask) {
        [downTask.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
            downTask.resumeData = resumeData;
        }];
    }
}

+ (void)suspendTask:(NSString *)url {
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [[PGDownloadManager shareInstance].mTasks objectForKey:downKey];
    if(downTask) {
        [downTask.task suspend];
    }
}

+ (void)deleteTask:(NSString *)url {
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [[PGDownloadManager shareInstance].mTasks objectForKey:downKey];
    if(downTask) {
        [downTask.task cancel];
        [[PGDownloadManager shareInstance].mTasks removeObjectForKey:downKey];
    }
}

+ (void)deleteDelegate:(id<PGDownloadManagerDelegate>)delegate url:(NSString *)url {
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [[PGDownloadManager shareInstance].mTasks objectForKey:downKey];
    if(downTask) {
        [downTask delDelegate:delegate];
    }
}

#pragma mark -
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{
    NSString *url = downloadTask.currentRequest.URL.absoluteString;
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [self.mTasks objectForKey:downKey];

    NSString *path = [NSString stringWithFormat:@"%@/%@",downTask.fileDirectory, [NSString MD5Encrypt:url]];
    path = [path stringByAppendingPathExtension:[url pathExtension]];
    [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:NULL];

    if(downTask) {
        for(id<PGDownloadManagerDelegate> delegate in downTask.arrayDelegate) {
            if(delegate && [delegate respondsToSelector:@selector(download:didFinish:)]) {
                [delegate download:url didFinish:path];
            }
        }

        [self.mTasks removeObjectForKey:downKey];
    }
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    NSString *url = downloadTask.currentRequest.URL.absoluteString;
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [[PGDownloadManager shareInstance].mTasks objectForKey:downKey];
    if(downTask) {
        downTask.totalBytesWritten = totalBytesWritten;
        downTask.totalBytesExpectedToWrite = totalBytesExpectedToWrite;
    }

    for(id<PGDownloadManagerDelegate> delegate in downTask.arrayDelegate) {
        if(delegate && [delegate respondsToSelector:@selector(download:totalBytesWritten:totalBytesExpectedToWrite:)]) {
            [delegate download:url totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite];
        }
    }
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
 didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes
{
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    // 保存恢复数据
    NSString *url = task.currentRequest.URL.absoluteString;
    NSString *downKey = [NSString MD5Encrypt:url];
    RMDownTask *downTask = [self.mTasks objectForKey:downKey];
    if(downTask && error) {
        [self.lock lock];
        downTask.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
        [self.lock unlock];
    }

    if(error) {
        for(id<PGDownloadManagerDelegate> delegate in downTask.arrayDelegate) {
            if(delegate && [delegate respondsToSelector:@selector(download:error:)]) {
                [delegate download:url error:error];
            }
        }
    }
}

@end


text:
goog.provide('go_map_directive');

goog.require('goog.object');

(function() {
  var module = angular.module('go_map_directive', []);

  module.directive('goMap',
      /**
       * @return {angular.Directive} The directive specs.
       */
      function() {
        return {
          restrict: 'A',
          scope: {
            'm': '=goMapMap'
          },
          link:
              /**
               * @param {angular.Scope} scope Scope.
               * @param {angular.JQLite} element Element.
               * @param {angular.Attributes} attrs Attributes.
               */
              function(scope, element, attrs) {
                /** @type {ol.Map} */
                var map = goog.object.get(scope, 'm');
                map.setTarget(element[0]);
              }
        };
      });
})();