text:
#ifndef APRINTER_AUX_CONTROL_MODULE_H
#define APRINTER_AUX_CONTROL_MODULE_H

#include <stdint.h>
#include <math.h>

#include <aprinter/meta/FuncUtils.h>
#include <aprinter/meta/ListForEach.h>
#include <aprinter/meta/TypeListUtils.h>
#include <aprinter/meta/PowerOfTwo.h>
#include <aprinter/meta/Union.h>
#include <aprinter/meta/UnionGet.h>
#include <aprinter/meta/WrapFunction.h>
#include <aprinter/meta/ChooseInt.h>
#include <aprinter/meta/MinMax.h>
#include <aprinter/meta/MemberType.h>
#include <aprinter/meta/BasicMetaUtils.h>
#include <aprinter/meta/StructIf.h>
#include <aprinter/meta/ServiceUtils.h>
#include <aprinter/base/Object.h>
#include <aprinter/base/Callback.h>
#include <aprinter/base/ProgramMemory.h>
#include <aprinter/base/Lock.h>
#include <aprinter/base/Assert.h>
#include <aprinter/base/Hints.h>
#include <aprinter/system/InterruptLock.h>
#include <aprinter/printer/Configuration.h>
#include <aprinter/printer/planning/MotionPlanner.h>
#include <aprinter/misc/ClockUtils.h>
#include <aprinter/printer/utils/JsonBuilder.h>
#include <aprinter/printer/utils/ModuleUtils.h>

#include <aprinter/BeginNamespace.h>

template <typename ModuleArg>
class AuxControlModule {
    APRINTER_UNPACK_MODULE_ARG(ModuleArg)

public:
    struct Object;

public:
    using ReservedHeaterFanNames = MakeTypeList<WrapInt<'F'>, WrapInt<'S'>>;

private:
    using Clock = typename Context::Clock;
    using TimeType = typename Clock::TimeType;
    using TheClockUtils = ClockUtils<Context>;
    using Config = typename ThePrinterMain::Config;
    using TheOutputStream = typename ThePrinterMain::TheOutputStream;
    using TheCommand = typename ThePrinterMain::TheCommand;
    using FpType = typename ThePrinterMain::FpType;
    using TimeConversion = typename ThePrinterMain::TimeConversion;
    using PhysVirtAxisMaskType = typename ThePrinterMain::PhysVirtAxisMaskType;

    using ParamsHeatersList = typename Params::HeatersList;
    using ParamsFansList = typename Params::FansList;
    static int const NumHeaters = TypeListLength<ParamsHeatersList>::Value;
    static int const NumFans = TypeListLength<ParamsFansList>::Value;

    using CWaitTimeoutTicks = decltype(ExprCast<TimeType>(Config::e(Params::WaitTimeout::i()) * TimeConversion()));
    using CWaitReportPeriodTicks = decltype(ExprCast<TimeType>(Config::e(Params::WaitReportPeriod::i()) * TimeConversion()));

    static int const SetHeaterCommand = 104;
    static int const SetFanCommand = 106;
    static int const OffFanCommand = 107;

    AMBRO_DECLARE_GET_MEMBER_TYPE_FUNC(GetMemberType_ChannelPayload, ChannelPayload)

public:
    static void init (Context c)
    {
        auto *o = Object::self(c);
        o->waiting_heaters = 0;
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::init(c)));
        ListFor<FansList>([&] APRINTER_TL(fan, fan::init(c)));
    }

    static void deinit (Context c)
    {
        ListForReverse<FansList>([&] APRINTER_TL(fan, fan::deinit(c)));
        ListForReverse<HeatersList>([&] APRINTER_TL(heater, heater::deinit(c)));
    }

    static bool check_command (Context c, TheCommand *cmd)
    {
        if (cmd->getCmdNumber(c) == SetHeaterCommand) {
            handle_set_heater_command(c, cmd);
            return false;
        }
        if (cmd->getCmdNumber(c) == 105) {
            handle_print_heaters_command(c, cmd);
            return false;
        }
        if (cmd->getCmdNumber(c) == SetFanCommand || cmd->getCmdNumber(c) == OffFanCommand) {
            handle_set_fan_command(c, cmd, cmd->getCmdNumber(c) == OffFanCommand);
            return false;
        }
        if (cmd->getCmdNumber(c) == 116) {
            handle_wait_heaters_command(c, cmd);
            return false;
        }
        if (cmd->getCmdNumber(c) == 921) {
            handle_print_adc_command(c, cmd);
            return false;
        }
        if (cmd->getCmdNumber(c) == 922) {
            handle_clear_error_command(c, cmd);
            return false;
        }
        if (cmd->getCmdNumber(c) == 302) {
            handle_cold_extrude_command(c, cmd);
            return false;
        }
        return ListForBreak<HeatersList>([&] APRINTER_TL(heater, return heater::check_command(c, cmd))) &&
               ListForBreak<FansList>([&] APRINTER_TL(fan, return fan::check_command(c, cmd)));
    }

    static void emergency ()
    {
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::emergency()));
        ListFor<FansList>([&] APRINTER_TL(fan, fan::emergency()));
    }

    static void check_safety (Context c)
    {
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::check_safety(c)));
    }

    static bool check_move_interlocks (Context c, TheOutputStream *err_output, PhysVirtAxisMaskType move_axes)
    {
        return ListForBreak<HeatersList>([&] APRINTER_TL(heater, return heater::check_move_interlocks(c, err_output, move_axes)));
    }

    template <typename TheJsonBuilder>
    static void get_json_status (Context c, TheJsonBuilder *json)
    {
        if (NumHeaters > 0) {
            json->addKeyObject(JsonSafeString{"heaters"});
            ListFor<HeatersList>([&] APRINTER_TL(heater, heater::get_json_status(c, json)));
            json->endObject();
        }

        if (NumFans > 0) {
            json->addKeyObject(JsonSafeString{"fans"});
            ListFor<FansList>([&] APRINTER_TL(fan, fan::get_json_status(c, json)));
            json->endObject();
        }
    }

private:
    template <typename Name>
    static void print_name (Context c, TheOutputStream *cmd)
    {
        cmd->reply_append_ch(c, Name::Letter);
        if (Name::Number != 0) {
            cmd->reply_append_uint32(c, Name::Number);
        }
    }

    template <typename Name, typename TheJsonBuilder>
    static void print_json_name (Context c, TheJsonBuilder *json)
    {
        if (Name::Number == 0) {
            json->add(JsonSafeChar{Name::Letter});
        } else {
            char str[3] = {Name::Letter, '0' + Name::Number, '\0'};
            json->add(JsonSafeString{str});
        }
    }

    template <typename Name>
    static bool match_name (Context c, TheCommand *cmd)
    {
        typename TheCommand::PartRef part;
        return cmd->find_command_param(c, Name::Letter, &part) && cmd->getPartUint32Value(c, part) == Name::Number;
    }

    struct HeaterState {
        FpType current;
        FpType target;
        bool error;
    };

    template <int HeaterIndex>
    struct Heater {
        struct Object;
        struct ObserverGetValueCallback;
        struct ObserverHandler;

        using HeaterSpec = TypeListGet<ParamsHeatersList, HeaterIndex>;
        static_assert(NameCharIsValid<HeaterSpec::Name::Letter, ReservedHeaterFanNames>::Value, "Heater name not allowed");

        using ControlInterval = decltype(Config::e(HeaterSpec::ControlInterval::i()));
        APRINTER_MAKE_INSTANCE(TheControl, (HeaterSpec::ControlService::template Control<Context, Object, Config, ControlInterval, FpType>))
        APRINTER_MAKE_INSTANCE(ThePwm, (HeaterSpec::PwmService::template Pwm<Context, Object>))
        APRINTER_MAKE_INSTANCE(TheObserver, (HeaterSpec::ObserverService::template Observer<Context, Object, Config, FpType, ObserverGetValueCallback, ObserverHandler>))
        using PwmDutyCycleData = typename ThePwm::DutyCycleData;
        APRINTER_MAKE_INSTANCE(TheFormula, (HeaterSpec::Formula::template Formula<Context, Object, Config, FpType>))
        APRINTER_MAKE_INSTANCE(TheAnalogInput, (HeaterSpec::AnalogInput::template AnalogInput<Context, Object>))
        using AdcFixedType = typename TheAnalogInput::FixedType;
        using AdcIntType = typename AdcFixedType::IntType;
        using MinSafeTemp = decltype(Config::e(HeaterSpec::MinSafeTemp::i()));
        using MaxSafeTemp = decltype(Config::e(HeaterSpec::MaxSafeTemp::i()));

        // compute the ADC readings corresponding to MinSafeTemp and MaxSafeTemp
        using AdcRange = APRINTER_FP_CONST_EXPR((PowerOfTwo<double, AdcFixedType::num_bits>::Value));
        template <typename Temp>
        static auto TempToAdcAbs (Temp) -> decltype(TheFormula::TempToAdc(Temp()) * AdcRange());
        using AdcFpLowLimit = APRINTER_FP_CONST_EXPR(1.0 + 0.1);
        using AdcFpHighLimit = APRINTER_FP_CONST_EXPR((PowerOfTwoMinusOne<AdcIntType, AdcFixedType::num_bits>::Value - 0.1));
        using InfAdcSafeTemp = If<TheFormula::NegativeSlope, decltype(MaxSafeTemp()), decltype(MinSafeTemp())>;
        using SupAdcSafeTemp = If<TheFormula::NegativeSlope, decltype(MinSafeTemp()), decltype(MaxSafeTemp())>;
        using InfAdcValueFp = decltype(ExprFmax(AdcFpLowLimit(), TempToAdcAbs(InfAdcSafeTemp())));
        using SupAdcValueFp = decltype(ExprFmin(AdcFpHighLimit(), TempToAdcAbs(SupAdcSafeTemp())));

        using CMinSafeTemp = decltype(ExprCast<FpType>(MinSafeTemp()));
        using CMaxSafeTemp = decltype(ExprCast<FpType>(MaxSafeTemp()));
        using CInfAdcValue = decltype(ExprCast<AdcIntType>(InfAdcValueFp()));
        using CSupAdcValue = decltype(ExprCast<AdcIntType>(SupAdcValueFp()));
        using CControlIntervalTicks = decltype(ExprCast<TimeType>(ControlInterval() * TimeConversion()));

        struct ChannelPayload {
            FpType target;
        };

        template <typename This=AuxControlModule>
        static constexpr typename This::HeatersMaskType HeaterMask () { return (HeatersMaskType)1 << HeaterIndex; }

        static void init (Context c)
        {
            auto *o = Object::self(c);
            o->m_enabled = false;
            o->m_was_not_unset = false;
            o->m_report_thermal_runaway = false;
            o->m_target = NAN;
            TimeType time = Clock::getTime(c) + (TimeType)(0.05 * TimeConversion::value());
            o->m_control_event.init(c, APRINTER_CB_STATFUNC_T(&Heater::control_event_handler));
            o->m_control_event.appendAt(c, time + (APRINTER_CFG(Config, CControlIntervalTicks, c) / 2));
            ThePwm::init(c, time);
            TheObserver::init(c);
            TheAnalogInput::init(c);
            ColdExtrusionFeature::init(c);
        }

        static void deinit (Context c)
        {
            auto *o = Object::self(c);
            TheAnalogInput::deinit(c);
            TheObserver::deinit(c);
            ThePwm::deinit(c);
            o->m_control_event.deinit(c);
        }

        static FpType adc_to_temp (Context c, AdcFixedType adc_value)
        {
            if (TheAnalogInput::isValueInvalid(adc_value)) {
                return NAN;
            }
            FpType adc_fp = adc_value.template fpValue<FpType>();
            if (!TheAnalogInput::IsRounded) {
                adc_fp += (FpType)(0.5 / PowerOfTwo<double, AdcFixedType::num_bits>::Value);
            }
            return TheFormula::adcToTemp(c, adc_fp);
        }

        static AdcFixedType get_adc (Context c)
        {
            return TheAnalogInput::getValue(c);
        }

        static bool adc_is_unsafe (Context c, AdcFixedType adc_value)
        {
            return
                TheAnalogInput::isValueInvalid(adc_value) ||
                adc_value.bitsValue() <= APRINTER_CFG(Config, CInfAdcValue, c) ||
                adc_value.bitsValue() >= APRINTER_CFG(Config, CSupAdcValue, c);
        }

        static FpType get_temp (Context c)
        {
            AdcFixedType adc_raw = get_adc(c);
            return adc_to_temp(c, adc_raw);
        }
        struct ObserverGetValueCallback : public AMBRO_WFUNC_TD(&Heater::get_temp) {};

        static HeaterState get_state (Context c)
        {
            auto *o = Object::self(c);

            HeaterState st;
            st.current = get_temp(c);
            bool enabled;
            AMBRO_LOCK_T(InterruptTempLock(), c, lock_c) {
                st.target = o->m_target;
                enabled = o->m_enabled;
            }
            st.error = (!FloatIsNan(st.target) && !enabled);
            return st;
        }

        static void append_value (Context c, TheOutputStream *cmd)
        {
            HeaterState st = get_state(c);

            cmd->reply_append_ch(c, ' ');
            print_name<typename HeaterSpec::Name>(c, cmd);
            cmd->reply_append_ch(c, ':');
            cmd->reply_append_fp(c, st.current);
            cmd->reply_append_pstr(c, AMBRO_PSTR(" /"));
            cmd->reply_append_fp(c, st.target);
            if (st.error) {
                cmd->reply_append_pstr(c, AMBRO_PSTR(",err"));
            }
        }

        static void append_adc_value (Context c, TheCommand *cmd)
        {
            AdcFixedType adc_value = get_adc(c);
            cmd->reply_append_ch(c, ' ');
            print_name<typename HeaterSpec::Name>(c, cmd);
            cmd->reply_append_pstr(c, AMBRO_PSTR("A:"));
            cmd->reply_append_fp(c, adc_value.template fpValue<FpType>());
        }

        static void clear_error (Context c, TheCommand *cmd)
        {
            auto *o = Object::self(c);

            FpType target;
            bool enabled;
            AMBRO_LOCK_T(InterruptTempLock(), c, lock_c) {
                target = o->m_target;
                enabled = o->m_enabled;
            }

            if (!FloatIsNan(target) && !enabled) {
                set(c, target);
            }
        }

        template <typename ThisContext>
        static void set (ThisContext c, FpType target)
        {
            auto *o = Object::self(c);
            AMBRO_ASSERT(!FloatIsNan(target))

            AMBRO_LOCK_T(InterruptTempLock(), c, lock_c) {
                o->m_target = target;
                o->m_enabled = true;
            }
        }

        template <typename ThisContext>
        static void unset (ThisContext c, bool orderly)
        {
            auto *o = Object::self(c);
            AMBRO_LOCK_T(InterruptTempLock(), c, lock_c) {
                if (orderly) {
                    o->m_target = NAN;
                } else if (o->m_enabled) {
                    o->m_report_thermal_runaway = true;
                }
                o->m_enabled = false;
                o->m_was_not_unset = false;
                PwmDutyCycleData duty;
                ThePwm::computeZeroDutyCycle(&duty);
                ThePwm::setDutyCycle(lock_c, duty);
            }
        }

        template <typename ThisContext>
        static void set_or_unset (ThisContext c, FpType target)
        {
            if (AMBRO_LIKELY(!FloatIsNan(target))) {
                set(c, target);
            } else {
                unset(c, true);
            }
        }

        static bool check_set_command (Context c, TheCommand *cmd, bool force, bool use_default)
        {
            if (!use_default ? match_name<typename HeaterSpec::Name>(c, cmd) : (HeaterSpec::SetMCommand != 0 && SetHeaterCommand == HeaterSpec::SetMCommand)) {
                handle_set_command(c, cmd, force);
                return false;
            }
            return true;
        }

        static bool check_command (Context c, TheCommand *cmd)
        {
            if (HeaterSpec::SetMCommand != 0 && HeaterSpec::SetMCommand != SetHeaterCommand && cmd->getCmdNumber(c) == HeaterSpec::SetMCommand) {
                bool force = cmd->find_command_param(c, 'F', nullptr);
                if (force || cmd->tryPlannedCommand(c)) {
                    handle_set_command(c, cmd, force);
                }
                return false;
            }
            return true;
        }

        static void handle_set_command (Context c, TheCommand *cmd, bool force)
        {
            FpType target = cmd->get_command_param_fp(c, 'S', 0.0f);
            if (!(target >= APRINTER_CFG(Config, CMinSafeTemp, c) && target <= APRINTER_CFG(Config, CMaxSafeTemp, c))) {
                target = NAN;
            }

            cmd->finishCommand(c);

            if (force) {
                set_or_unset(c, target);
            } else {
                auto *planner_cmd = ThePlanner<>::getBuffer(c);
                PlannerChannelPayload *payload = UnionGetElem<PlannerChannelIndex<>::Value>(&planner_cmd->channel_payload);
                payload->type = HeaterIndex;
                UnionGetElem<HeaterIndex>(&payload->heaters)->target = target;
                ThePlanner<>::channelCommandDone(c, PlannerChannelIndex<>::Value + 1);
                ThePrinterMain::submitted_planner_command(c);
            }
        }

        static void check_safety (Context c)
        {
            TheAnalogInput::check_safety(c);

            AdcFixedType adc_value = get_adc(c);
            if (adc_is_unsafe(c, adc_value)) {
                unset(c, false);
            }
        }

        static void observer_handler (Context c, bool state)
        {
            auto *o = Object::self(c);
            auto *mo = AuxControlModule::Object::self(c);
            AMBRO_ASSERT(TheObserver::isObserving(c))
            AMBRO_ASSERT(mo->waiting_heaters & HeaterMask())

            if (state) {
                mo->inrange_heaters |= HeaterMask();
            } else {
                mo->inrange_heaters &= ~HeaterMask();
            }
            check_wait_completion(c);
        }
        struct ObserverHandler : public AMBRO_WFUNC_TD(&Heater::observer_handler) {};

        static void emergency ()
        {
            ThePwm::emergency();
        }

        template <typename ThisContext, typename TheChannelPayloadUnion>
        static void channel_callback (ThisContext c, TheChannelPayloadUnion *payload_union)
        {
            ChannelPayload *payload = UnionGetElem<HeaterIndex>(payload_union);
            set_or_unset(c, payload->target);
        }

        static void control_event_handler (Context c)
        {
            auto *o = Object::self(c);

            o->m_control_event.appendAfterPrevious(c, APRINTER_CFG(Config, CControlIntervalTicks, c));

            AdcFixedType adc_value = get_adc(c);
            if (adc_is_unsafe(c, adc_value)) {
                unset(c, false);
            }

            bool enabled;
            FpType target;
            bool was_not_unset;
            bool report_thermal_runaway;
            AMBRO_LOCK_T(InterruptTempLock(), c, lock_c) {
                enabled = o->m_enabled;
                target = o->m_target;
                was_not_unset = o->m_was_not_unset;
                o->m_was_not_unset = enabled;
                report_thermal_runaway = o->m_report_thermal_runaway;
                o->m_report_thermal_runaway = false;
            }
            if (AMBRO_LIKELY(enabled)) {
                if (!was_not_unset) {
                    TheControl::init(c);
                }
                FpType sensor_value = adc_to_temp(c, adc_value);
                if (!FloatIsNan(sensor_value)) {
                    FpType output = TheControl::addMeasurement(c, sensor_value, target);
                    PwmDutyCycleData duty;
                    ThePwm::computeDutyCycle(output, &duty);
                    AMBRO_LOCK_T(InterruptTempLock(), c, lock_c) {
                        if (o->m_was_not_unset) {
                            ThePwm::setDutyCycle(lock_c, duty);
                        }
                    }
                }
            }

            if (report_thermal_runaway) {
                auto *output = ThePrinterMain::get_msg_output(c);
                output->reply_append_pstr(c, AMBRO_PSTR("//"));
                print_heater_error(c, output, AMBRO_PSTR("HeaterThermalRunaway"));
                output->reply_poke(c);
            }

            if (TheObserver::isObserving(c) && !enabled) {
                TheCommand *cmd = ThePrinterMain::get_locked(c);
                print_heater_error(c, cmd, AMBRO_PSTR("HeaterThermalRunaway"));
                complete_wait(c, true, nullptr);
            }

            maybe_report(c);
        }

        template <typename TheHeatersMaskType>
        static void update_wait_mask (Context c, TheCommand *cmd, TheHeatersMaskType *mask)
        {
            if (match_name<typename HeaterSpec::Name>(c, cmd)) {
                *mask |= HeaterMask();
            }
        }

        template <typename TheHeatersMaskType>
        static bool start_wait (Context c, TheCommand *cmd, TheHeatersMaskType mask)
        {
            auto *o = Object::self(c);
            auto *mo = AuxControlModule::Object::self(c);

            if ((mask & HeaterMask()) || mask == 0) {
                FpType target;
                bool enabled;
                AMBRO_LOCK_T(InterruptTempLock(), c, lock_c) {
                    target = o->m_target;
                    enabled = o->m_enabled;
                }

                if (!FloatIsNan(target)) {
                    if (!enabled) {
                        print_heater_error(c, cmd, AMBRO_PSTR("HeaterThermalRunaway"));
                        return false;
                    }
                    mo->waiting_heaters |= HeaterMask();
                    TheObserver::startObserving(c, target);
                }
                else if ((mask & HeaterMask())) {
                    print_heater_error(c, cmd, AMBRO_PSTR("HeaterNotEnabled"));
                    return false;
                }
            }

            return true;
        }

        static void print_heater_error (Context c, TheOutputStream *cmd, AMBRO_PGM_P errstr)
        {
            cmd->reply_append_pstr(c, AMBRO_PSTR("Error:"));
            cmd->reply_append_pstr(c, errstr);
            cmd->reply_append_ch(c, ':');
            print_name<typename HeaterSpec::Name>(c, cmd);
            cmd->reply_append_ch(c, '\n');
        }

        static void stop_wait (Context c)
        {
            auto *mo = AuxControlModule::Object::self(c);

            if ((mo->waiting_heaters & HeaterMask())) {
                TheObserver::stopObserving(c);
            }
        }

        static bool check_move_interlocks (Context c, TheOutputStream *err_output, PhysVirtAxisMaskType move_axes)
        {
            return ColdExtrusionFeature::check_move_interlocks(c, err_output, move_axes);
        }

        template <typename TheJsonBuilder>
        static void get_json_status (Context c, TheJsonBuilder *json)
        {
            HeaterState st = get_state(c);

            print_json_name<typename HeaterSpec::Name>(c, json);
            json->entryValue();
            json->startObject();
            json->addSafeKeyVal("current", JsonDouble{st.current});
            json->addSafeKeyVal("target", JsonDouble{st.target});
            json->addSafeKeyVal("error", JsonBool{st.error});
            json->endObject();
        }

        static void print_cold_extrude (Context c, TheOutputStream *output)
        {
            ColdExtrusionFeature::print_cold_extrude(c, output);
        }

        template <typename TheHeatersMaskType>
        static void set_cold_extrude (Context c, bool allow, TheHeatersMaskType heaters_mask)
        {
            ColdExtrusionFeature::set_cold_extrude(c, allow, heaters_mask);
        }

        AMBRO_STRUCT_IF(ColdExtrusionFeature, HeaterSpec::ColdExtrusion::Enabled) {
            template <typename AxisName, typename AccumMask>
            using ExtrudersMaskFoldFunc = WrapValue<PhysVirtAxisMaskType, (AccumMask::Value | ThePrinterMain::template GetPhysVirtAxisByName<AxisName::Value>::AxisMask)>;
            using ExtrudersMask = TypeListFold<typename HeaterSpec::ColdExtrusion::ExtruderAxes, WrapValue<PhysVirtAxisMaskType, 0>, ExtrudersMaskFoldFunc>;

            using CMinExtrusionTemp = decltype(ExprCast<FpType>(Config::e(HeaterSpec::ColdExtrusion::MinExtrusionTemp::i())));
            using ConfigExprs = MakeTypeList<CMinExtrusionTemp>;

            static void init (Context c)
            {
                auto *o = Object::self(c);
                o->cold_extrusion_allowed = false;
            }

            static bool check_move_interlocks (Context c, TheOutputStream *err_output, PhysVirtAxisMaskType move_axes)
            {
                auto *o = Object::self(c);
                if (!o->cold_extrusion_allowed && (move_axes & ExtrudersMask::Value)) {
                    FpType temp = get_temp(c);
                    if (!(temp >= APRINTER_CFG(Config, CMinExtrusionTemp, c)) || isinf(temp)) {
                        err_output->reply_append_pstr(c, AMBRO_PSTR("Error:"));
                        err_output->reply_append_pstr(c, AMBRO_PSTR("ColdExtrusionPrevented:"));
                        print_name<typename HeaterSpec::Name>(c, err_output);
                        err_output->reply_append_ch(c, '\n');
                        return false;
                    }
                }
                return true;
            }

            static void print_cold_extrude (Context c, TheOutputStream *output)
            {
                auto *o = Object::self(c);
                output->reply_append_ch(c, ' ');
                print_name<typename HeaterSpec::Name>(c, output);
                output->reply_append_ch(c, '=');
                output->reply_append_ch(c, o->cold_extrusion_allowed ? '1' : '0');
            }

            template <typename TheHeatersMaskType>
            static void set_cold_extrude (Context c, bool allow, TheHeatersMaskType heaters_mask)
            {
                auto *o = Object::self(c);
                if ((heaters_mask & HeaterMask())) {
                    o->cold_extrusion_allowed = allow;
                }
            }

            struct Object : public ObjBase<ColdExtrusionFeature, typename Heater::Object, EmptyTypeList> {
                bool cold_extrusion_allowed;
            };
        }
        AMBRO_STRUCT_ELSE(ColdExtrusionFeature) {
            static void init (Context c) {}
            static bool check_move_interlocks (Context c, TheOutputStream *err_output, PhysVirtAxisMaskType move_axes) { return true; }
            static void print_cold_extrude (Context c, TheOutputStream *output) {}
            template <typename TheHeatersMaskType>
            static void set_cold_extrude (Context c, bool allow, TheHeatersMaskType heaters_mask) {}
            struct Object {};
        };

        struct Object : public ObjBase<Heater, typename AuxControlModule::Object, MakeTypeList<
            TheControl,
            ThePwm,
            TheObserver,
            TheFormula,
            TheAnalogInput,
            ColdExtrusionFeature
        >> {
            uint8_t m_enabled : 1;
            uint8_t m_was_not_unset : 1;
            uint8_t m_report_thermal_runaway : 1;
            FpType m_target;
            typename Context::EventLoop::TimedEvent m_control_event;
        };

        using ConfigExprs = MakeTypeList<CMinSafeTemp, CMaxSafeTemp, CInfAdcValue, CSupAdcValue, CControlIntervalTicks>;
    };

    template <int FanIndex>
    struct Fan {
        struct Object;

        using FanSpec = TypeListGet<ParamsFansList, FanIndex>;
        static_assert(NameCharIsValid<FanSpec::Name::Letter, ReservedHeaterFanNames>::Value, "Fan name not allowed");

        APRINTER_MAKE_INSTANCE(ThePwm, (FanSpec::PwmService::template Pwm<Context, Object>))
        using PwmDutyCycleData = typename ThePwm::DutyCycleData;

        struct ChannelPayload {
            PwmDutyCycleData duty;
        };

        static void init (Context c)
        {
            TimeType time = Clock::getTime(c) + (TimeType)(0.05 * TimeConversion::value());
            ThePwm::init(c, time);
        }

        static void deinit (Context c)
        {
            ThePwm::deinit(c);
        }

        static bool check_set_command (Context c, TheCommand *cmd, bool force, bool is_turn_off, bool use_default)
        {
            if (!use_default ? match_name<typename FanSpec::Name>(c, cmd) : (
                !is_turn_off ?
                (FanSpec::SetMCommand != 0 && SetFanCommand == FanSpec::SetMCommand) :
                (FanSpec::OffMCommand != 0 && OffFanCommand == FanSpec::OffMCommand)
            )) {
                handle_set_command(c, cmd, force, is_turn_off);
                return false;
            }
            return true;
        }

        static bool check_command (Context c, TheCommand *cmd)
        {
            if ((FanSpec::SetMCommand != 0 && FanSpec::SetMCommand != SetFanCommand && cmd->getCmdNumber(c) == FanSpec::SetMCommand) ||
                (FanSpec::OffMCommand != 0 && FanSpec::OffMCommand != OffFanCommand && cmd->getCmdNumber(c) == FanSpec::OffMCommand)
            ) {
                bool force = cmd->find_command_param(c, 'F', nullptr);
                if (force || cmd->tryPlannedCommand(c)) {
                    bool is_turn_off = (cmd->getCmdNumber(c) == FanSpec::OffMCommand);
                    handle_set_command(c, cmd, force, is_turn_off);
                }
                return false;
            }
            return true;
        }

        static void handle_set_command (Context c, TheCommand *cmd, bool force, bool is_turn_off)
        {
            FpType target = 0.0f;
            if (!is_turn_off) {
                target = 1.0f;
                if (cmd->find_command_param_fp(c, 'S', &target)) {
                    target *= (FpType)FanSpec::SpeedMultiply::value();
                }
            }

            cmd->finishCommand(c);

            PwmDutyCycleData duty;
            ThePwm::computeDutyCycle(target, &duty);

            if (force) {
                ThePwm::setDutyCycle(c, duty);
            } else {
                auto *planner_cmd = ThePlanner<>::getBuffer(c);
                PlannerChannelPayload *payload = UnionGetElem<PlannerChannelIndex<>::Value>(&planner_cmd->channel_payload);
                payload->type = NumHeaters + FanIndex;
                UnionGetElem<FanIndex>(&payload->fans)->duty = duty;
                ThePlanner<>::channelCommandDone(c, PlannerChannelIndex<>::Value + 1);
                ThePrinterMain::submitted_planner_command(c);
            }
        }

        template <typename TheJsonBuilder>
        static void get_json_status (Context c, TheJsonBuilder *json)
        {
            FpType target = ThePwm::template getCurrentDutyFp<FpType>(c);

            print_json_name<typename FanSpec::Name>(c, json);
            json->entryValue();
            json->startObject();
            json->addSafeKeyVal("target", JsonDouble{target});
            json->endObject();
        }

        static void emergency ()
        {
            ThePwm::emergency();
        }

        template <typename ThisContext, typename TheChannelPayloadUnion>
        static void channel_callback (ThisContext c, TheChannelPayloadUnion *payload_union)
        {
            ChannelPayload *payload = UnionGetElem<FanIndex>(payload_union);
            ThePwm::setDutyCycle(c, payload->duty);
        }

        struct Object : public ObjBase<Fan, typename AuxControlModule::Object, MakeTypeList<
            ThePwm
        >> {};
    };

    using HeatersList = IndexElemList<ParamsHeatersList, Heater>;
    using FansList = IndexElemList<ParamsFansList, Fan>;

    using HeatersChannelPayloadUnion = Union<MapTypeList<HeatersList, GetMemberType_ChannelPayload>>;
    using FansChannelPayloadUnion = Union<MapTypeList<FansList, GetMemberType_ChannelPayload>>;

    using HeatersMaskType = ChooseInt<MaxValue(1, NumHeaters), false>;
    static HeatersMaskType const AllHeatersMask = PowerOfTwoMinusOne<HeatersMaskType, NumHeaters>::Value;

    struct PlannerChannelPayload {
        uint8_t type;
        union {
            HeatersChannelPayloadUnion heaters;
            FansChannelPayloadUnion fans;
        };
    };

    template <typename This=AuxControlModule> struct PlannerChannelCallback;
    struct PlannerChannelSpec : public MotionPlannerChannelSpec<PlannerChannelPayload, PlannerChannelCallback<AuxControlModule>, Params::EventChannelBufferSize, typename Params::EventChannelTimerService> {};

    template <typename This=AuxControlModule>
    using ThePlanner = typename This::ThePrinterMain::ThePlanner;

    template <typename This=AuxControlModule>
    using PlannerChannelIndex = typename This::ThePrinterMain::template GetPlannerChannelIndex<PlannerChannelSpec>;

    static void handle_set_heater_command (Context c, TheCommand *cmd)
    {
        bool force = cmd->find_command_param(c, 'F', nullptr);
        if (!force && !cmd->tryPlannedCommand(c)) {
            return;
        }
        if (ListForBreak<HeatersList>([&] APRINTER_TL(heater, return heater::check_set_command(c, cmd, force, false))) &&
            ListForBreak<HeatersList>([&] APRINTER_TL(heater, return heater::check_set_command(c, cmd, force, true)))
        ) {
            if (NumHeaters > 0) {
                cmd->reportError(c, AMBRO_PSTR("UnknownHeater"));
            }
            cmd->finishCommand(c);
        }
    }

    static void handle_print_heaters_command (Context c, TheCommand *cmd)
    {
        cmd->reply_append_pstr(c, AMBRO_PSTR("ok"));
        print_heaters(c, cmd);
        cmd->finishCommand(c, true);
    }

    static void print_heaters (Context c, TheOutputStream *cmd)
    {
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::append_value(c, cmd)));
        cmd->reply_append_ch(c, '\n');
    }

    static void handle_set_fan_command (Context c, TheCommand *cmd, bool is_turn_off)
    {
        bool force = cmd->find_command_param(c, 'F', nullptr);
        if (!force && !cmd->tryPlannedCommand(c)) {
            return;
        }
        if (ListForBreak<FansList>([&] APRINTER_TL(fan, return fan::check_set_command(c, cmd, force, is_turn_off, false))) &&
            ListForBreak<FansList>([&] APRINTER_TL(fan, return fan::check_set_command(c, cmd, force, is_turn_off, true)))
        ) {
            if (NumFans > 0) {
                cmd->reportError(c, AMBRO_PSTR("UnknownFan"));
            }
            cmd->finishCommand(c);
        }
    }

    static void handle_wait_heaters_command (Context c, TheCommand *cmd)
    {
        auto *o = Object::self(c);
        if (!cmd->tryUnplannedCommand(c)) {
            return;
        }
        AMBRO_ASSERT(o->waiting_heaters == 0)
        HeatersMaskType heaters_mask = 0;
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::update_wait_mask(c, cmd, &heaters_mask)));
        o->waiting_heaters = 0;
        o->inrange_heaters = 0;
        o->wait_started_time = Clock::getTime(c);
        if (!ListForBreak<HeatersList>([&] APRINTER_TL(heater, return heater::start_wait(c, cmd, heaters_mask)))) {
            cmd->reportError(c, nullptr);
            cmd->finishCommand(c);
            ListFor<HeatersList>([&] APRINTER_TL(heater, heater::stop_wait(c)));
            o->waiting_heaters = 0;
            return;
        }
        if (o->waiting_heaters) {
            o->report_poll_timer.setTo(o->wait_started_time);
            ThePrinterMain::now_active(c);
        } else {
            cmd->finishCommand(c);
        }
    }

    static void handle_print_adc_command (Context c, TheCommand *cmd)
    {
        cmd->reply_append_pstr(c, AMBRO_PSTR("ok"));
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::append_adc_value(c, cmd)));
        cmd->reply_append_ch(c, '\n');
        cmd->finishCommand(c, true);
    }

    static void handle_clear_error_command (Context c, TheCommand *cmd)
    {
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::clear_error(c, cmd)));
        cmd->finishCommand(c);
    }

    static void handle_cold_extrude_command (Context c, TheCommand *cmd)
    {
        if (!cmd->find_command_param(c, 'P', nullptr)) {
            cmd->reply_append_pstr(c, AMBRO_PSTR("ColdExtrude:"));
            ListFor<HeatersList>([&] APRINTER_TL(heater, heater::print_cold_extrude(c, cmd)));
            cmd->reply_append_ch(c, '\n');
        } else {
            bool allow = (cmd->get_command_param_uint32(c, 'P', 0) > 0);
            HeatersMaskType heaters_mask = 0;
            ListFor<HeatersList>([&] APRINTER_TL(heater, heater::update_wait_mask(c, cmd, &heaters_mask)));
            if (heaters_mask == 0) {
                heaters_mask = AllHeatersMask;
            }
            ListFor<HeatersList>([&] APRINTER_TL(heater, heater::set_cold_extrude(c, allow, heaters_mask)));
        }
        cmd->finishCommand(c);
    }

    static void complete_wait (Context c, bool error, AMBRO_PGM_P errstr)
    {
        auto *o = Object::self(c);
        AMBRO_ASSERT(o->waiting_heaters)

        TheCommand *cmd = ThePrinterMain::get_locked(c);
        if (error) {
            cmd->reportError(c, errstr);
        }
        cmd->finishCommand(c);
        ListFor<HeatersList>([&] APRINTER_TL(heater, heater::stop_wait(c)));
        o->waiting_heaters = 0;
        ThePrinterMain::now_inactive(c);
    }

    static void check_wait_completion (Context c)
    {
        auto *o = Object::self(c);
        AMBRO_ASSERT(o->waiting_heaters)

        bool reached = o->inrange_heaters == o->waiting_heaters;
        bool timed_out = (TimeType)(Clock::getTime(c) - o->wait_started_time) >= APRINTER_CFG(Config, CWaitTimeoutTicks, c);

        if (reached || timed_out) {
            complete_wait(c, timed_out, AMBRO_PSTR("WaitTimedOut"));
        }
    }

    static void maybe_report (Context c)
    {
        auto *o = Object::self(c);
        if (o->waiting_heaters && o->report_poll_timer.isExpired(c)) {
            o->report_poll_timer.addTime(APRINTER_CFG(Config, CWaitReportPeriodTicks, c));
            auto *output = ThePrinterMain::get_msg_output(c);
            output->reply_append_pstr(c, AMBRO_PSTR("//HeatProgress"));
            print_heaters(c, output);
            output->reply_poke(c);
        }
    }

    template <typename This>
    static void planner_channel_callback (typename ThePlanner<This>::template Channel<PlannerChannelIndex<This>::Value>::CallbackContext c, PlannerChannelPayload *payload)
    {
        auto *ob = Object::self(c);

        ListForOneBool<HeatersList, 0>(payload->type, [&] APRINTER_TL(heater, heater::channel_callback(c, &payload->heaters))) ||
        ListForOneBool<FansList, NumHeaters>(payload->type, [&] APRINTER_TL(fan, fan::channel_callback(c, &payload->fans)));
    }
    template <typename This> struct PlannerChannelCallback : public AMBRO_WFUNC_TD(&AuxControlModule::template planner_channel_callback<This>) {};

public:
    template <typename This=AuxControlModule>
    using GetEventChannelTimer = typename ThePlanner<This>::template GetChannelTimer<PlannerChannelIndex<This>::Value>;

    template <int HeaterIndex>
    using GetHeaterPwm = typename Heater<HeaterIndex>::ThePwm;

    template <int HeaterIndex>
    using GetHeaterAnalogInput = typename Heater<HeaterIndex>::TheAnalogInput;

    template <int FanIndex>
    using GetFanPwm = typename Fan<FanIndex>::ThePwm;

    using MotionPlannerChannels = MakeTypeList<PlannerChannelSpec>;

    using ConfigExprs = MakeTypeList<CWaitTimeoutTicks, CWaitReportPeriodTicks>;

public:
    struct Object : public ObjBase<AuxControlModule, ParentObject, JoinTypeLists<
        HeatersList,
        FansList
    >> {
        HeatersMaskType waiting_heaters;
        HeatersMaskType inrange_heaters;
        TimeType wait_started_time;
        typename TheClockUtils::PollTimer report_poll_timer;
    };
};

APRINTER_ALIAS_STRUCT(AuxControlName, (
    APRINTER_AS_VALUE(char, Letter),
    APRINTER_AS_VALUE(uint8_t, Number)
))

struct AuxControlNoColdExtrusionParams {
    static bool const Enabled = false;
};

APRINTER_ALIAS_STRUCT_EXT(AuxControlColdExtrusionParams, (
    APRINTER_AS_TYPE(MinExtrusionTemp),
    APRINTER_AS_TYPE(ExtruderAxes)
), (
    static bool const Enabled = true;
))

APRINTER_ALIAS_STRUCT(AuxControlModuleHeaterParams, (
    APRINTER_AS_TYPE(Name),
    APRINTER_AS_VALUE(int, SetMCommand),
    APRINTER_AS_TYPE(AnalogInput),
    APRINTER_AS_TYPE(Formula),
    APRINTER_AS_TYPE(MinSafeTemp),
    APRINTER_AS_TYPE(MaxSafeTemp),
    APRINTER_AS_TYPE(ControlInterval),
    APRINTER_AS_TYPE(ControlService),
    APRINTER_AS_TYPE(ObserverService),
    APRINTER_AS_TYPE(PwmService),
    APRINTER_AS_TYPE(ColdExtrusion)
))

APRINTER_ALIAS_STRUCT(AuxControlModuleFanParams, (
    APRINTER_AS_TYPE(Name),
    APRINTER_AS_VALUE(int, SetMCommand),
    APRINTER_AS_VALUE(int, OffMCommand),
    APRINTER_AS_TYPE(SpeedMultiply),
    APRINTER_AS_TYPE(PwmService)
))

APRINTER_ALIAS_STRUCT_EXT(AuxControlModuleService, (
    APRINTER_AS_VALUE(int, EventChannelBufferSize),
    APRINTER_AS_TYPE(EventChannelTimerService),
    APRINTER_AS_TYPE(WaitTimeout),
    APRINTER_AS_TYPE(WaitReportPeriod),
    APRINTER_AS_TYPE(HeatersList),
    APRINTER_AS_TYPE(FansList)
), (
    APRINTER_MODULE_TEMPLATE(AuxControlModuleService, AuxControlModule)
))

#include <aprinter/EndNamespace.h>

#endif


text:
<!--
  Copyright 2014 sonaive.com. All rights reserved.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  -->

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:v2ex="http://schemas.android.com/apk/res-auto"
    v2ex:theme="@style/ActionBarThemeOverlay"
    v2ex:popupTheme="@style/ActionBarPopupThemeOverlay"
    android:id="@+id/toolbar_actionbar"
    android:background="@null"
    v2ex:titleTextAppearance="@style/ActionBar.TitleText"
    v2ex:contentInsetStart="?actionBarInsetStart"
    android:layout_width="match_parent"
    android:layout_height="?actionBarSize" >

    <com.sonaive.v2ex.ui.widgets.SimpleSearchView
        android:id="@+id/search_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.v7.widget.Toolbar>

redpajama_set_name: RedPajamaGithub


text:
layout: contribute
title: Contribute
---

Want to Contribute?

Contributors are needed to keep the project moving forward!

What you can do

File a bug or task

Read the Contributor Guidelines

Join the Dev mailing list and send a brief introduction of yourself to it

Join the discussion on Slack

Sign the Individual Contributor License Agreement (ICLA) and submit it

                <input id="jira-search-box" type="text" class="form-control" placeholder="Search current issue list...">

                    <button id="jira-search-button" class="btn btn-default" type="button"></button>

                    View All Issues

                    See all Committers / Contributors

    {% for projectType in site.data.contribute-repo-links %}
    {% assign firstProjectType = forloop.first %}

{{ projectType.title }}

            {% for project in projectType.projects %}

            {% if firstProjectType and forloop.first %}
                {% assign itemClass = "first" %}
            {% else %}
                {% assign itemClass = "" %}
            {% endif %}

                        {{ project.project }}

            {% endfor %}

    {% endfor %}


text:
function H=Ry(pitch)
% Rotation around Y (pitch).
%
% Homogeneous matrix for a rotation about Y axis.

H = [ypr2R(0,pitch,0) zeros(3,1); 0 0 0 1];


text:
FILE *LOG_FILE = NULL;

Server *SRV = NULL;

char *test_Connection_create_destroy()
{
    const char remote[IPADDR_SIZE];

    Connection *conn = Connection_create(NULL, 0, 0, remote, NULL);
    Connection_destroy(conn);

    return NULL;
}

char *test_Connection_deliver()
{
    bstring t1;
    const char remote[IPADDR_SIZE];
    Connection *conn = Connection_create(NULL, 1, 0, remote, NULL);

    int rc = Connection_deliver(conn, t1 = bfromcstr("TEST"));
    // depending on the platform this will fail or not if send is allowed on files
    mu_assert(rc == -1, "Should NOT be able to write.");

    Connection_destroy(conn);
    bdestroy(t1);

    return NULL;
}

int test_task_with_sample(const char *sample_file)
{
    check(SRV, "Server isn't configured.");

    Connection *conn = Connection_create(SRV, 12, 1400, "127.0.0.1", NULL);
    check(conn, "Failed to create the conn.");

    sentinel("REWRITE NEEDED");

    Connection_task(conn);

    return 1;
error:
    return 0;
}

char *test_Connection_task()
{
    // TODO: bring these back with a different mechanism
    // debug(">>>>> XML <<<<<");
    // mu_assert(test_task_with_sample("tests/sample.xml"), "xml failed.");
    // debug(">>>>> JSON <<<<<");
    // mu_assert(test_task_with_sample("tests/sample.json"), "json failed.");
    // debug(">>>>> GARBAGE <<<<<");
    // mu_assert(test_task_with_sample("tests/sample.garbage"), "garbage failed");
    // debug(">>>>>> HTTP <<<<<<");
    // mu_assert(test_task_with_sample("tests/sample.http"), "http failed");

    return NULL;
}

char * all_tests() {
    mu_suite_start();

    Server_init();
    Server *SRV = Server_create("uuid", "localhost", "0.0.0.0",
            "1999", "chroot", "access_log", "error_log", "pid_file");
    Host *zedshaw_com = Host_create("zedshaw.com");

    Host_add_backend(zedshaw_com, "@chat", strlen("@chat"), BACKEND_HANDLER, NULL);

    Dir *tests = Dir_create("tests/", "index.html", "text/plain");

    Host_add_backend(zedshaw_com, "/tests", strlen("/tests"), BACKEND_DIR, tests);

    Server_set_default_host(SRV, zedshaw_com);

    mu_run_test(test_Connection_create_destroy);
    mu_run_test(test_Connection_deliver);
    mu_run_test(test_Connection_task);

    Server_destroy(SRV);
    // TODO: the above will eventually do this
    Host_destroy(zedshaw_com);
    zmq_term(ZMQ_CTX);
    return NULL;
}

RUN_TESTS(all_tests);


text:
class CreatePluginLearnerStates < ActiveRecord::Migration
  def change
    create_table :plugin_learner_states do |t|
      t.integer :plugin_id
      t.integer :user_id
      t.integer :run_id
      t.string  :shared_learner_state_key
      t.timestamps
    end

    add_index :plugin_learner_states, [:plugin_id, :run_id], name: 'plugin_run__states'
    add_index :plugin_learner_states, [:shared_learner_state_key, :run_id], name: 'shared_run_plugin_states'
    add_index :plugin_learner_states, [:shared_learner_state_key, :user_id], name: 'shared_user_plugin_states'
  end

end


text:
- An integer value can be defined as one or more consecutive digits.

## 1. Define the expected oven time in minutes

- You need to define a [method][methods] without any arguments.
- You need to return an integer value (see [built-in types]).

## 2. Calculate the remaining oven time in minutes

- You need to define a [method][methods] with a single parameter.
- The method's parameter is an integer.
- You need to return an integer value (see [built-in types]).
- You can use the `-` operator to subtract values.

## 3. Calculate the preparation time in minutes

- You need to define a [method][methods] with a single parameter.
- The method's parameter is an integer.
- You need to return an integer value (see [built-in types]).
- You can use the `*` operator to multiply values.

## 4. Calculate the elapsed time in minutes

- You need to define a [method][methods] with two parameters.
- The method's parameters are of type integer.
- You need to return an integer value (see [built-in types]).
- You can [invoke][invocation] one of the other methods you've defined previously.
- You can use the `+` operator to add values.

[methods]: https://docs.scala-lang.org/overviews/scala-book/methods-first-look.html
[built-in types]: https://docs.scala-lang.org/overviews/scala-book/built-in-types.html
[invocation]: https://docs.scala-lang.org/style/method-invocation.html


text:
![Logo of the project](https://raw.githubusercontent.com/LibusoftCicom/lc-datepicker/master/src/assets/logo.png)

# LC DatePicker

> Pure Angular date and time picker component.

[![npm version](https://badge.fury.io/js/%40libusoftcicom%2Flc-datepicker.svg)](https://www.npmjs.com/package/@libusoftcicom/lc-datepicker)

[![Build Status](https://travis-ci.org/LibusoftCicom/lc-datepicker.svg?branch=master)](https://travis-ci.org/LibusoftCicom/lc-datepicker)

# Demo

[Click here for preview](https://libusoftcicom.github.io/lc-datepicker/)

# Description

- LC DatePicker is an Angular component that generates a datepicker calendar on your input element
- Compatible with Angular 2+ up to Angular v8.0.0
- Only dependencies are RxJS, MomentJS and Font Awesome
- Customizable date format and language
- Can be configured as time, date-time, date, month or year picker

# Tested with

- Firefox (latest)
- Chrome (latest)
- Chromium (latest)
- Edge
- IE11

## Installing / Getting started

```shell
npm install @libusoftcicom/lc-datepicker
```

skip this if SystemJS is not used as module loader:

```shell
System.config({
  paths: {
    'npm:': 'node_modules/'
  },
  map: {
    '@libusoftcicom/lc-datepicker' : 'npm:@libusoftcicom/lc-datepicker/bundles/lc-datepicker.umd'
  }
})
```

Use the following snippet inside your app module:

```shell
import {LcDatePickerModule} from '@libusoftcicom/lc-datepicker';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
    ,LcDatePickerModule
  ],
  providers: [
    ...
  ],
  bootstrap: [...]
})
export class AppModule {}
```

Use the following snippet inside your component:

```shell
import {DatePickerConfig, ECalendarType} from '@libusoftcicom/lc-datepicker';

@Component({
  ...
})
export class AppComponent {

  private dateValue: string = null;
  public config = new DatePickerConfig();
  public CalendarOpened: boolean = false;

  constructor() {

    // configuration is optional
    this.config.CalendarType = ECalendarType.Date;
    this.config.Localization = 'en';
    ...
  }

  public get Date() {
    return this.dateValue;
  }

  public set Date(value: string) {
    this.dateValue = value;
  }

}
```

Use the following snippet inside your template for date-picker:

```shell
<lc-datepicker [(opened)]="CalendarOpened" [config]="config" [(date)]="Date"></lc-datepicker>
```

Use the following snippet inside your template for date-range-picker:

```shell
<lc-date-range-picker [(opened)]="CalendarOpened" [config]="config" [(date)]="Date"></lc-date-range-picker>
```

## DatePicker config parameters

- CalendarType: ECalendarType
- Localization: String
- MaxYear: Number
- MinYear: Number
- MaxMonth: Number
- MinMonth: Number
- MaxDay: Number
- MinDay: Number
- ConfirmLabel: String
- PrimaryColor: String
- FontColor: String
- Format: Moment.MomentInput
- setDisabledDates( Array<Moment.MomentInput> )
- addDisabledTimeRange( start<Moment.MomentInput>, stop<Moment.MomentInput> )</li>

## Developing

### Built With:

- Angular
- MomentJS
- Font Awesome

### Setting up Dev

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.1.3.

[Angular CLI](https://github.com/angular/angular-cli) must be installed before building LC DatePicker component.

```shell
npm install -g @angular/cli
```

```shell
git clone https://github.com/LibusoftCicom/lc-datepicker.git
cd lc-datepicker/
npm install
npm run start
```

Open "http://localhost:4200" in browser

### Building

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.1.3.

[Angular CLI](https://github.com/angular/angular-cli) must be installed before building LC DatePicker component.

```shell
npm install -g @angular/cli
```

```shell
git clone https://github.com/LibusoftCicom/lc-datepicker.git
cd lc-datepicker/
npm install
npm run build
```

## Versioning

We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [link to tags on this repository](https://github.com/LibusoftCicom/lc-datepicker/tags).

## Tests

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.1.3.

[Angular CLI](https://github.com/angular/angular-cli) must be installed before building LC DatePicker component.

```shell
npm install -g @angular/cli
```

```shell
git clone https://github.com/LibusoftCicom/lc-datepicker.git
cd lc-datepicker/
npm install
npm run test
```

## Contributing

### Want to help?

Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our [contributing guide](https://github.com/LibusoftCicom/lc-datepicker/blob/master/CONTRIBUTING.md) and [code of conduct](https://github.com/LibusoftCicom/lc-datepicker/blob/master/CODE_OF_CONDUCT.md) and then check out one of our [issues](https://github.com/LibusoftCicom/lc-datepicker/issues).

## Licensing

LC DatePicker is freely distributable under the terms of the [MIT license](https://github.com/LibusoftCicom/lc-datepicker/blob/master/LICENSE).


text:
function(newDoc, currDoc, user) {
  if(currDoc) {
    throw({ forbidden: "Documents in this database are immutable." });
  }
}


text:
using System;

#if NET472
using System.Data.Linq.SqlClient;
#else
using System.Data;
#endif

using System.Linq;

using LinqToDB;
using LinqToDB.Mapping;

using NUnit.Framework;

namespace Tests.Linq
{
	using Model;

	[TestFixture]
	public class StringFunctionTests : TestBase
	{
		[Test]
		public void Length([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Length == "John".Length && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsConstant([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Contains("oh") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsConstant2([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where !p.FirstName.Contains("o%h") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsConstant3([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var arr = new[] { "oh", "oh'", "oh\\" };

				var q = from p in db.Person where  arr.Contains(p.FirstName) select p;
				Assert.AreEqual(0, q.Count());
			}
		}

		[Test]
		public void ContainsConstant4([DataSources(TestProvName.AllFirebird)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var s = "123[456";

				var q = from p in db.Person where p.ID == 1 && s.Contains("[") select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsConstant5([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.ID == 1 && "123[456".Contains("[") select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsConstant41([DataSources(TestProvName.AllInformix)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var s  = "123[456";
				var ps = "[";

				var q = from p in db.Person where p.ID == 1 && s.Contains(ps) select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsConstant51([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var ps = "[";

				var q = from p in db.Person where p.ID == 1 && "123[456".Contains(ps) select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsParameter1([DataSources] string context)
		{
			var str = "oh";

			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Contains(str) && p.ID == 1 select new { p, str };
				var r = q.ToList().First();
				Assert.AreEqual(1,   r.p.ID);
				Assert.AreEqual(str, r.str);
			}
		}

		[Test]
		public void ContainsParameter2([DataSources] string context)
		{
			var str = "o%h";

			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where !p.FirstName.Contains(str) && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsParameter3()
		{
			var str = "o";

			using (var db = new TestDataConnection())
			{
				var q =
					from d in db.Doctor
					join p in db.Person.Where(p => p.FirstName.Contains(str))
					on d.PersonID equals p.ID
					select p;

				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ContainsParameter4([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				AreEqual(
					from p in Person
					select new
					{
						p,
						Field1 = p.FirstName.Contains("Jo")
					} into p
					where p.Field1
					orderby p.Field1
					select p,
					from p in db.Person
					select new
					{
						p,
						Field1 = p.FirstName.Contains("Jo")
					} into p
					where p.Field1
					orderby p.Field1
					select p);
			}
		}

		[Test]
		public void ContainsNull([DataSources(ProviderName.Access, TestProvName.AllInformix)] string context)
		{
			using (var db = GetDataContext(context))
			{
				string? firstName = null;
				int?    id        = null;

				var _ =
				(
					from p in db.Person
					where
						(int?)p.ID == id &&
						(string.IsNullOrEmpty(firstName) || p.FirstName.Contains(firstName))
					select p
				).ToList();
			}
		}

		[Test]
		public void StartsWith1([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.StartsWith("Jo") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[ActiveIssue(2005, Configuration = TestProvName.AllFirebird)]
		[Test]
		public void StartsWithSQL([DataSources(false)] string context)
		{
			using (var db = new TestDataConnection(context))
			{
				(from p in db.Person where p.FirstName.StartsWith("Jo") && !p.LastName.StartsWith("Je") select p).ToList();

				// https://github.com/linq2db/linq2db/issues/2005
				if (context.Contains("Firebird"))
				{
					Assert.True(db.LastQuery!.Contains(" STARTING WITH 'Jo'"));
					Assert.True(db.LastQuery.Contains(" NOT STARTING WITH 'Je'"));
				}
				else if (context.Contains("SqlServer") || context.Contains("SqlAzure"))
				{
					Assert.True(db.LastQuery!.Contains(" LIKE N'Jo%'"));
					Assert.True(db.LastQuery.Contains("NOT LIKE N'Je%'"));
				}
				else if (context.Contains("Informix"))
				{
					Assert.True(db.LastQuery!.Contains(" LIKE 'Jo%'"));
					Assert.True(db.LastQuery.Contains("NOT p.LastName LIKE 'Je%'"));
				}
				else
				{
					Assert.True(db.LastQuery!.Contains(" LIKE 'Jo%'"));
					Assert.True(db.LastQuery.Contains("NOT LIKE 'Je%'"));
				}
			}
		}

		[Test]
		public void StartsWith2([DataSources(ProviderName.DB2, TestProvName.AllAccess)] string context)
		{
			using (var db = GetDataContext(context))
				AreEqual(
					from p in    Person where "John123".StartsWith(p.FirstName) select p,
					from p in db.Person where "John123".StartsWith(p.FirstName) select p);
		}

		[Test]
		public void StartsWith3([DataSources(ProviderName.DB2, TestProvName.AllAccess)] string context)
		{
			var str = "John123";

			using (var db = GetDataContext(context))
				AreEqual(
					from p in    Person where str.StartsWith(p.FirstName) select p,
					from p in db.Person where str.StartsWith(p.FirstName) select p);
		}

		[Test]
		public void StartsWith4([DataSources(ProviderName.DB2, TestProvName.AllAccess)] string context)
		{
			using (var db = GetDataContext(context))
				AreEqual(
					from p1 in    Person
					from p2 in    Person
					where p1.ID == p2.ID && p1.FirstName.StartsWith(p2.FirstName)
					select p1,
					from p1 in db.Person
					from p2 in db.Person
					where p1.ID == p2.ID &&
						Sql.Like(p1.FirstName, p2.FirstName.Replace("%", "~%"), '~')
					select p1);
		}

		[Test]
		public void StartsWith5([DataSources(ProviderName.DB2, TestProvName.AllAccess)] string context)
		{
			using (var db = GetDataContext(context))
				AreEqual(
					from p1 in    Person
					from p2 in    Person
					where p1.ID == p2.ID && p1.FirstName.Replace("J", "%").StartsWith(p2.FirstName.Replace("J", "%"))
					select p1,
					from p1 in db.Person
					from p2 in db.Person
					where p1.ID == p2.ID && p1.FirstName.Replace("J", "%").StartsWith(p2.FirstName.Replace("J", "%"))
					select p1);
		}

		[Test]
		public void EndsWith([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.EndsWith("hn") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

#if NET472
		[Test]
		public void Like11([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where SqlMethods.Like(p.FirstName, "%hn%") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Like12([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where !SqlMethods.Like(p.FirstName, @"%h~%n%", '~') && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}
#endif

		[Test]
		public void Like21([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.Like(p.FirstName, "%hn%") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Like22([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where !Sql.Like(p.FirstName, @"%h~%n%", '~') && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void IndexOf11([DataSources(TestProvName.AllInformix, ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.IndexOf("oh") == 1 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void IndexOf12([DataSources(TestProvName.AllInformix, ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.IndexOf("") == 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void IndexOf2([DataSources(TestProvName.AllInformix, ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.LastName.IndexOf("e", 2) == 4 && p.ID == 2 select p;
				Assert.AreEqual(2, q.ToList().First().ID);
			}
		}

		[ActiveIssue(Details = "Sql.CharIndex(string, string, int) have incorrect SQL logic for all providers (except HANA)")]
		[Test]
		public void IndexOf3([DataSources(
			ProviderName.DB2, TestProvName.AllFirebird,
			ProviderName.SqlCe, TestProvName.AllAccess, ProviderName.SQLiteMS)]
			string context)
		{
			var s = "e";
			var n1 = 2;
			var n2 = 5;

			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.LastName.IndexOf(s, n1, n2) == 4 && p.ID == 2 select p;
				Assert.AreEqual(2, q.ToList().First().ID);
			}
		}

		[Test]
		public void LastIndexOf1([DataSources(
			ProviderName.DB2, TestProvName.AllInformix,
			ProviderName.SqlCe, TestProvName.AllAccess, TestProvName.AllSapHana, ProviderName.SQLiteMS)]
			string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.LastName.LastIndexOf("p") == 2 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void LastIndexOf2([DataSources(
			ProviderName.DB2, TestProvName.AllInformix, ProviderName.SqlCe,
			TestProvName.AllAccess, TestProvName.AllSapHana, ProviderName.SQLiteMS)]
			string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.ID == 1 select new { p.ID, FirstName = "123" + p.FirstName + "012345" };
				q = q.Where(p => p.FirstName.LastIndexOf("123", 5) == 8);
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void LastIndexOf3([DataSources(
			ProviderName.DB2, TestProvName.AllInformix, ProviderName.SqlCe,
			TestProvName.AllAccess, TestProvName.AllSapHana, ProviderName.SQLiteMS)]
			string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.ID == 1 select new { p.ID, FirstName = "123" + p.FirstName + "0123451234" };
				q = q.Where(p => p.FirstName.LastIndexOf("123", 5, 6) == 8);
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CharIndex1([DataSources(TestProvName.AllInformix, ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.CharIndex("oh", p.FirstName) == 2 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CharIndex2([DataSources(TestProvName.AllInformix, ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.CharIndex("p", p.LastName, 2) == 3 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Left([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.Left(p.FirstName, 2) == "Jo" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Right([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.Right(p.FirstName, 3) == "ohn" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void RightInSelect([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.ID == 1 select Sql.Right(p.FirstName, 3);
				Assert.AreEqual("ohn", q.ToList().First());
			}
		}

		[Test]
		public void Substring1([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Substring(1) == "ohn" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Substring2([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Substring(1, 2) == "oh" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Reverse([DataSources(
			ProviderName.DB2, TestProvName.AllInformix, ProviderName.SqlCe,
			TestProvName.AllAccess, TestProvName.AllSapHana, ProviderName.SQLiteMS)]
			string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.Reverse(p.FirstName) == "nhoJ" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Stuff1([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.Stuff(p.FirstName, 3, 1, "123") == "Jo123n" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		class Category
		{
			[PrimaryKey, Identity] public int     Id;
			[Column, NotNull]      public string? Name;
		}

		class Task
		{
			[PrimaryKey, Identity] public int     Id;
			[Column, NotNull]      public string? Name;
		}

		class TaskCategory
		{
			[Column, NotNull] public int Id;
			[Column, NotNull] public int TaskId;
			[Column, NotNull] public int CategoryId;
		}

		[Test]
		public void Stuff2([IncludeDataSources(TestProvName.AllSqlServer2008Plus)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q =
					from t in db.GetTable<Task>()
					join tc in db.GetTable<TaskCategory>() on t.Id equals tc.TaskId into g
					from tc in g.DefaultIfEmpty()
					select new
					{
						t.Id,
						t.Name,
						Categories = Sql.Stuff(
							from c in db.GetTable<Category>()
							where c.Id == tc.CategoryId
							select "," + c.Name, 1, 1, "")
					};

				q.ToString();
			}
		}

		[Test]
		public void Insert([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Insert(2, "123") == "Jo123hn" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Remove1([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Remove(2) == "Jo" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Remove2([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Remove(1, 2) == "Jn" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Space([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName + Sql.Space(p.ID + 1) + "123" == "John  123" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void PadRight([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where Sql.PadRight(p.FirstName, 6, ' ') + "123" == "John  123" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void PadRight1([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.PadRight(6) + "123" == "John  123" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void PadRight2([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.PadRight(6, '*') + "123" == "John**123" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void PadLeft([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where "123" + Sql.PadLeft(p.FirstName, 6, ' ') == "123  John" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void PadLeft1([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where "123" + p.FirstName.PadLeft(6) == "123  John" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void PadLeft2([DataSources(ProviderName.SQLiteMS)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where "123" + p.FirstName.PadLeft(6, '*') == "123**John" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Replace([DataSources(TestProvName.AllAccess)] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.Replace("hn", "lie") == "Jolie" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Trim([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q =
					from p in db.Person where p.ID == 1 select new { p.ID, Name = "  " + p.FirstName + " " } into pp
					where pp.Name.Trim() == "John" select pp;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void TrimLeft([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q =
					from p in db.Person where p.ID == 1 select new { p.ID, Name = "  " + p.FirstName + " " } into pp
					where pp.Name.TrimStart() == "John " select pp;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void TrimRight([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q =
					from p in db.Person where p.ID == 1 select new { p.ID, Name = "  " + p.FirstName + " " } into pp
					where pp.Name.TrimEnd() == "  John" select pp;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ToLower([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.ToLower() == "john" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ToLowerParameter([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var param = "JOHN";
				var q = from p in db.Person where p.FirstName.ToLower() == param.ToLower() && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ToUpper([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.ToUpper() == "JOHN" && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void ToUpperParam([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var param = "john";
				var q = from p in db.Person where p.FirstName.ToUpper() == param.ToUpper() && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.CompareTo("John") == 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareToNotEqual1([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.CompareTo("Jo") != 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareToNotEqual2([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where 0 != p.FirstName.CompareTo("Jo") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo1([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.CompareTo("Joh") > 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo2([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.CompareTo("Johnn") < 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo21([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.CompareTo("Johnn") <= 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo22([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where 0 >= p.FirstName.CompareTo("Johnn") && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo3([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.CompareTo(55) > 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo31([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.FirstName.CompareTo(55) >= 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareTo32([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where 0 <= p.FirstName.CompareTo(55) && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareOrdinal1([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where string.CompareOrdinal(p.FirstName, "Joh") > 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void CompareOrdinal2([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where string.CompareOrdinal(p.FirstName, 1, "Joh", 1, 2) == 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Compare1([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where string.Compare(p.FirstName, "Joh") > 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Compare2([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where string.Compare(p.FirstName, "joh", true) > 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Compare3([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where string.Compare(p.FirstName, 1, "Joh", 1, 2) == 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void Compare4([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where string.Compare(p.FirstName, 1, "Joh", 1, 2, true) == 0 && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void IsNullOrEmpty1([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where !string.IsNullOrEmpty(p.FirstName) && p.ID == 1 select p;
				Assert.AreEqual(1, q.ToList().First().ID);
			}
		}

		[Test]
		public void IsNullOrEmpty2([DataSources] string context)
		{
			using (var db = GetDataContext(context))
			{
				var q = from p in db.Person where p.ID == 1 select string.IsNullOrEmpty(p.FirstName);
				Assert.AreEqual(false, q.ToList().First());
			}
		}
	}
}


text:
"""Sequence Interfaces
"""

from __future__ import absolute_import

__docformat__ = 'restructuredtext'
from .. import Interface

class IMinimalSequence(Interface):
    """Most basic sequence interface.

    All sequences are iterable.  This requires at least one of the
    following:

    - a `__getitem__()` method that takes a single argument; interger
      values starting at 0 must be supported, and `IndexError` should
      be raised for the first index for which there is no value, or

    - an `__iter__()` method that returns an iterator as defined in
      the Python documentation (http://docs.python.org/lib/typeiter.html).

    """

    def __getitem__(index):
        """`x.__getitem__(index)` <==> `x[index]`

        Declaring this interface does not specify whether `__getitem__`
        supports slice objects."""

class IFiniteSequence(IMinimalSequence):

    def __len__():
        """`x.__len__()` <==> `len(x)`"""

class IReadSequence(IFiniteSequence):
    """read interface shared by tuple and list"""

    def __contains__(item):
        """`x.__contains__(item)` <==> `item in x`"""

    def __lt__(other):
        """`x.__lt__(other)` <==> `x < other`"""

    def __le__(other):
        """`x.__le__(other)` <==> `x <= other`"""

    def __eq__(other):
        """`x.__eq__(other)` <==> `x == other`"""

    def __ne__(other):
        """`x.__ne__(other)` <==> `x != other`"""

    def __gt__(other):
        """`x.__gt__(other)` <==> `x > other`"""

    def __ge__(other):
        """`x.__ge__(other)` <==> `x >= other`"""

    def __add__(other):
        """`x.__add__(other)` <==> `x + other`"""

    def __mul__(n):
        """`x.__mul__(n)` <==> `x * n`"""

    def __rmul__(n):
        """`x.__rmul__(n)` <==> `n * x`"""

    def __getslice__(i, j):
        """`x.__getslice__(i, j)` <==> `x[i:j]`

        Use of negative indices is not supported.

        Deprecated since Python 2.0 but still a part of `UserList`.
        """

class IExtendedReadSequence(IReadSequence):
    """Full read interface for lists"""

    def count(item):
        """Return number of occurrences of value"""

    def index(item, *args):
        """Return first index of value

        `L.index(value, [start, [stop]])` -> integer"""

class IUniqueMemberWriteSequence(Interface):
    """The write contract for a sequence that may enforce unique members"""

    def __setitem__(index, item):
        """`x.__setitem__(index, item)` <==> `x[index] = item`

        Declaring this interface does not specify whether `__setitem__`
        supports slice objects.
        """

    def __delitem__(index):
        """`x.__delitem__(index)` <==> `del x[index]`

        Declaring this interface does not specify whether `__delitem__`
        supports slice objects.
        """

    def __setslice__(i, j, other):
        """`x.__setslice__(i, j, other)` <==> `x[i:j]=other`

        Use of negative indices is not supported.

        Deprecated since Python 2.0 but still a part of `UserList`.
        """

    def __delslice__(i, j):
        """`x.__delslice__(i, j)` <==> `del x[i:j]`

        Use of negative indices is not supported.

        Deprecated since Python 2.0 but still a part of `UserList`.
        """
    def __iadd__(y):
        """`x.__iadd__(y)` <==> `x += y`"""

    def append(item):
        """Append item to end"""

    def insert(index, item):
        """Insert item before index"""

    def pop(index=-1):
        """Remove and return item at index (default last)"""

    def remove(item):
        """Remove first occurrence of value"""

    def reverse():
        """Reverse *IN PLACE*"""

    def sort(cmpfunc=None):
        """Stable sort *IN PLACE*; `cmpfunc(x, y)` -> -1, 0, 1"""

    def extend(iterable):
        """Extend list by appending elements from the iterable"""

class IWriteSequence(IUniqueMemberWriteSequence):
    """Full write contract for sequences"""

    def __imul__(n):
        """`x.__imul__(n)` <==> `x *= n`"""

class ISequence(IReadSequence, IWriteSequence):
    """Full sequence contract"""


text:
from ldtools import __version__, url, author_email

import datetime
import logging
import mimetypes
import os
import shutil
import socket
import rdflib

from ldtools.utils import urllib2

# set socket timeout. URLError will occur if time passed
socket.setdefaulttimeout(5)

__useragent__ = 'ldtools-{version} ({url}, {author_email})'.format(
    version=__version__, url=url, author_email=author_email
)

# add mimetypes python does not know yet
mimetypes.add_type("text/n3", ".n3")
mimetypes.add_type("text/rdf+n3", ".n3")
mimetypes.add_type("text/turtle", ".n3")

class FiletypeMappingError(Exception):
    pass

class ContentNegotiationError(Exception):
    pass

logger = logging.getLogger("ldtools")

def get_file_extension(filename):
    extension = filename.split(".")[1:][-1:]
    return str(extension[0]) if extension else ""

def assure_parser_plugin_exists(format):
    try:
        rdflib.graph.plugin.get(name=format, kind=rdflib.parser.Parser)
    except rdflib.plugin.PluginException:
        msg = "No parser plugin found for %s" % format
        logger.error(msg)
        raise ContentNegotiationError(msg)

def guess_format_from_filename(file_name):
    file_extension = file_name.split(".")[-1]
    if file_name != file_extension:
        return file_extension

class AbstractBackend(object):
    """Abstract Backend. Overwrite in subclasses"""
    pass

class RestBackend(AbstractBackend):
    GET_headers = {
        'User-agent': __useragent__,
        'Accept': (
            'text/n3,'
            'text/rdf+n3,'
            'application/rdf+xml;q=0.8'
            "text/turtle;q=0.7,"
            # 'application/xhtml+xml;q=0.5'
            # '*/*;q=0.1'
            # XHTML+RDFa
        )
    }

    PUT_headers = {"User-Agent": __useragent__}

    def GET(
        self,
        uri,
        extra_headers=None,
        httphandler=None,
    ):
        """Lookup URI and follow redirects. Return data"""

        if not hasattr(self, "uri"):
            self.uri = uri
        else:
            if not self.uri == uri:
                raise Exception("You cannot pass different uris to the same "
                                "backend")

        if httphandler:
            if isinstance(httphandler, list):
                opener = urllib2.build_opener(*httphandler)
            else:
                opener = urllib2.build_opener(httphandler)
        else:
            opener = urllib2.build_opener()

        if extra_headers:
            self.GET_headers.update(extra_headers)

        reference_time = datetime.datetime.now()

        request = urllib2.Request(url=uri, headers=self.GET_headers)

        try:
            resultF = opener.open(request)
        except (UnicodeEncodeError, socket.timeout):
            return None

        now = datetime.datetime.now()
        self.lookup_time = now - reference_time

        if resultF.geturl() != uri:
            logger.info(
                "%s was redirected. Content url: %r" % (
                    uri, resultF.geturl()))

        if "Content-Length" in resultF.headers:
            logger.info(
                "Content-Length: %s" % resultF.headers["Content-Length"])

        if "Content-Type" not in resultF.headers:
            raise FiletypeMappingError("No Content-Type specified in response")
        self.content_type = resultF.headers['Content-Type'].split(";")[0]

        # Many servers don't do content negotiation: if one of the following
        # content_types are returned by server, assume the mapped type
        overwrite_content_type_map = {
            "text/plain": "application/rdf+xml",
        }

        if self.content_type in overwrite_content_type_map:
            self.content_type = overwrite_content_type_map[self.content_type]

        try:
            file_extension = mimetypes.guess_extension(self.content_type)
            assert file_extension
        except AssertionError:
            logger.error(
                "{} not supported by ldtools".format(
                    resultF.headers['Content-Type']))
            raise FiletypeMappingError(
                "No mimetype found for %s" % self.content_type)

        format = file_extension.strip(".")

        # assure format is correct
        if format in ["rdf", "ksh"]:
            format = "xml"
        # check if rdflib parser exists for format
        assure_parser_plugin_exists(format)

        self.format = format
        return resultF.read()

    def PUT(self, data):
        assert self.uri, "GET has to be called before PUT possible"

        self.PUT_headers.update({
            "Content-Type": self.content_type,
            "Content-Length": str(len(data)),
        })

        opener = urllib2.build_opener(urllib2.HTTPHandler)
        request = urllib2.Request(self.uri,
                                  data=data,
                                  headers=self.PUT_headers)
        request.get_method = lambda: 'PUT'
        response = opener.open(request)
        return response

class FileBackend(AbstractBackend):
    """Manages one xml file as a data basis"""

    def __init__(self, filename,
                 format=None,
                 store_old_versions=True):
        assert os.path.exists(filename)

        format = format if format else guess_format_from_filename(filename)
        assure_parser_plugin_exists(format)

        self.format = format
        self.filename = filename
        self.store_old_versions = store_old_versions

    def GET(self,
            uri,
            extra_headers=None,
            httphandler=None,
            ):
        assert not extra_headers, "Not Implemented"
        assert not httphandler, "Not Implemented"
        if not hasattr(self, "uri"):
            self.uri = uri
        else:
            if not self.uri == uri:
                raise Exception("You cannot pass different uris to the same "
                                "backend")

        with open(self.filename, "r") as f:
            data = f.read()
        return data

    def PUT(self, data):
        assert self.uri, "GET has to be called before PUT"

        if os.path.exists(self.filename) and self.store_old_versions:
            # File already exists. Make backup copy
            now = datetime.datetime.strftime(datetime.datetime.utcnow(),
                                             '%Y%m%d-%H%M%S')
            file_extension = get_file_extension(self.filename)
            if file_extension:
                old_version = u"%s.%s.%s" % (
                    self.filename.strip(file_extension),
                    now, file_extension)
            else:
                old_version = u"%s_%s" % (self.filename, now)
            self.old_version = old_version
            shutil.copy(self.filename, old_version)

        with open(self.filename, "w") as f:
            f.write(data)

    def revert_to_old_version(self):
        assert self.store_old_versions, (
            "This FileBackend is not configured to store old versions")
        if hasattr(self, "old_version"):
            logger.info("Reverting to version before last saved version")
            shutil.copy(self.old_version, self.filename)
            os.remove(self.old_version)
            delattr(self, "old_version")

class MemoryBackend(AbstractBackend):
    def __init__(self, data=None, format="xml"):
        self.data = data if data else ""
        assure_parser_plugin_exists(format)
        self.format = format

    def GET(self,
            uri,
            extra_headers=None,
            httphandler=None,
            ):
        assert not extra_headers, "Not Implemented"
        assert not httphandler, "Not Implemented"
        return self.data

    def PUT(self, data):
        self.data = data


text:
<!DOCTYPE html>
<!DOCTYPE html>

  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
  <title>Booking - BlushUp</title>

  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  <link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
  <link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>

      Logo

BOOKING

BOOKING

      menu

Parallax Template

A modern responsive front-end framework based on Material Design

          Get Started

              Kitty Chong

As a Makeup Artist (MUA), I hold that ideal imaging of a female is
                achieved by exuding her innate beauty and external style in the best light.
                Service area within Malaysia.

              Write Review
              Book Artist

                Kitty Chongmore_vert

                  Write Review
                  Book Artist

                Kitty Chongclose

As a Makeup Artist (MUA), I hold that ideal imaging of a female is achieved
                  by exuding her innate beauty and external style in the best light.
                  I focus on delicate makeup enhancing a woman's feature and refining feminity.
                  Service area within Malaysia.
                  Price Range: RM 150-300

              Kitty Chong

As a Makeup Artist (MUA), I hold that ideal imaging of a female is
                achieved by exuding her innate beauty and external style in the best light.
                Service area within Malaysia.

              Write Review
              Book Artist

A modern responsive front-end framework based on Material Design

Contact Us

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque id nunc nec volutpat. Etiam pellentesque tristique arcu, non consequat magna fermentum ac. Cras ut ultricies eros. Maecenas eros justo, ullamcorper a sapien id, viverra ultrices eros. Morbi sem neque, posuere et pretium eget, bibendum sollicitudin lacus. Aliquam eleifend sollicitudin diam, eu mattis nisl maximus sed. Nulla imperdiet semper molestie. Morbi massa odio, condimentum sed ipsum ac, gravida ultrices erat. Nullam eget dignissim mauris, non tristique erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

A modern responsive front-end framework based on Material Design

Company Bio

We are a team of college students working on this project like it's our full time job. Any amount would help support and continue development on this project and is greatly appreciated.

Settings

Link 1

Link 2

Link 3

Link 4

Connect

Link 1

Link 2

Link 3

Link 4

      Made by Materialize


text:
'use strict';

var constants = {
    amigoLayersData: [
        {
            name: 'AmigoStreet',
            url: 'https://www.amigocloud.com/api/v1/base_layers/2',
            tiles: 'https://cdnamigocloud.global.ssl.fastly.net/api/v1/base_layers/2/tiles'
        },
        {
            name: 'AmigoGray',
            url: 'https://www.amigocloud.com/api/v1/base_layers/392',
            tiles: 'https://cdnamigocloud.global.ssl.fastly.net/api/v1/base_layers/392/tiles'
        },
        {
            name: 'AmigoSatellite',
            url: 'https://www.amigocloud.com/api/v1/base_layers/3',
            tiles: 'https://cdnamigocloud.global.ssl.fastly.net/api/v1/base_layers/3/tiles'
        }
    ],
    baseUrl: 'https://www.amigocloud.com',
    socketServerUrl: 'https://www.amigocloud.com/amigosocket',
    amigoLogoUrl: 'https://cdnamigocloud.global.ssl.fastly.net/static/homepage/img/press-kit/amigocloud.png',
    apiUrl: '/api/v1'
};


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _01.Day_of_Week
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] days = {"Monday", "Tuesday", "Wednesday",
            "Thursday","Friday","Saturday","Sunday"};

            var day = int.Parse(Console.ReadLine());

            if (day>=1&&day<=7)
            {
                Console.WriteLine(days[day-1]);
            }
            else
            {
                Console.WriteLine("Invalid Day");
            }

        }
    }
}


text:
using System;
using System.Linq;
using System.Threading.Tasks;

#nullable enable

namespace Avalonia.Controls.Platform
{
    /// <summary>
    /// Defines a platform-specific system dialog implementation.
    /// </summary>
    [Obsolete]
    internal class SystemDialogImpl : ISystemDialogImpl
    {
        public async Task<string[]?> ShowFileDialogAsync(FileDialog dialog, Window parent)
        {
            if (dialog is OpenFileDialog openDialog)
            {
                var filePicker = parent.StorageProvider;
                if (!filePicker.CanOpen)
                {
                    return null;
                }

                var options = openDialog.ToFilePickerOpenOptions();

                var files = await filePicker.OpenFilePickerAsync(options);
                return files
                    .Select(file => file.TryGetUri(out var fullPath)
                        ? fullPath.LocalPath
                        : file.Name)
                    .ToArray();
            }
            else if (dialog is SaveFileDialog saveDialog)
            {
                var filePicker = parent.StorageProvider;
                if (!filePicker.CanSave)
                {
                    return null;
                }

                var options = saveDialog.ToFilePickerSaveOptions();

                var file = await filePicker.SaveFilePickerAsync(options);
                if (file is null)
                {
                    return null;
                }

                var filePath = file.TryGetUri(out var fullPath)
                    ? fullPath.LocalPath
                    : file.Name;
                return new[] { filePath };
            }
            return null;
        }

        public async Task<string?> ShowFolderDialogAsync(OpenFolderDialog dialog, Window parent)
        {
            var filePicker = parent.StorageProvider;
            if (!filePicker.CanPickFolder)
            {
                return null;
            }

            var options = dialog.ToFolderPickerOpenOptions();

            var folders = await filePicker.OpenFolderPickerAsync(options);
            return folders
                .Select(f => f.TryGetUri(out var uri) ? uri.LocalPath : null)
                .FirstOrDefault(u => u is not null);
        }
    }
}


text:
<?php
use concurso\Repositorio\JuradosRepositorio;

class juradosControlador extends Controlador
{
    protected $juradoRepo;

    public function __construct()
    {
        parent::__construct();
    }

    //metodo para llamar al controller index
    public function index()
    {
        $this->juradoRepo = new JuradosRepositorio();
        return print_r(json_encode($this->juradoRepo->save()));
    }

    public function nuevo()
    {
        $datos = $_POST;
        $this->juradoRepo = new JuradosRepositorio();
        return $this->juradoRepo->nuevo($datos);
    }
}


text:
<?php
session_start();
if ($_SESSION['manager']==""){
	echo "<script type='text/javascript'>alert('ILLEGAL!');location.href='index.php';</script>";
		exit();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<link rel="stylesheet" type="text/css" href="../style/admin.css"/>

<title>无标题文档</title>
</head>

<body>
后台主页

</body>
</html>


text:
Handmade notebooks from trash

Upcycling community's refuse with community's records, ideas, memories...

Notebooks have been used for different purposes such as drawing, writing and recording results of experiments, ideas or memoranda by many artists, scientists, and thinkers through the ages. Here there are different types of notebooks regarding their color, shape, size and combination. They are simple, imperfect and different than usual industrial notebooks, but more importantly they are from trash. Every one of them has a unique serial and with that serial the (hi)story of it can be viewed.

      {% for notebook in site.notebooks %}

        {% if notebook.type == "modal" %}

        {% else %}

        {% endif %}

{{ notebook.title }}

{{ notebook.subtitle }}

      {% endfor %}