text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

// allows autotuning Ignition map (Ign_map_0!)
// we need a locking map (which cells are locked)
// we need a change counter map (which cells are changed and by how much, maybe combine with locking map)

namespace Trionic5Tools
{
    public enum IgnitionMapType : int
    {
        FeedbackIgnitionMap
    }

    public class IgnitionMaps
    {
        public delegate void IgnitionmapCellChanged(object sender, IgnitionmapChangedEventArgs e);
        public event IgnitionMaps.IgnitionmapCellChanged onIgnitionmapCellChanged;

        public delegate void CellLocked(object sender, IgnitionmapChangedEventArgs e);
        public event IgnitionMaps.CellLocked onCellLocked;

        public class IgnitionmapChangedEventArgs : System.EventArgs
        {
            private int _mapindex;

            public int Mapindex
            {
                get { return _mapindex; }
                set { _mapindex = value; }
            }

            private int _cellvalue;

            public int Cellvalue
            {
                get { return _cellvalue; }
                set { _cellvalue = value; }
            }

            public IgnitionmapChangedEventArgs(int mapindex, int cellvalue)
            {
                this._mapindex = mapindex;
                this._cellvalue = cellvalue;
            }
        }

        private IECUFile m_TrionicFile;

        private int[] ignitionmap;
        private int[] originalignitionmap;
        private int[] ignitioncorrectioncountermap;
        private int[] ignitionlockedmap;
        private float[] IgnitionMapInMemory;
        private int[] IgnitionMapCounterInMemory;

        private int[] knockPressTab;

        private int _CellStableTime_ms;

        private double m_IgnitionAdvancePerCycle = 0.1;

        public double IgnitionAdvancePerCycle
        {
            get { return m_IgnitionAdvancePerCycle; }
            set { m_IgnitionAdvancePerCycle = value; }
        }
        private double m_IgnitionRetardFirstKnock = 1.0;

        public double IgnitionRetardFirstKnock
        {
            get { return m_IgnitionRetardFirstKnock; }
            set { m_IgnitionRetardFirstKnock = value; }
        }
        private double m_IgnitionRetardFurtherKnocks = 0.5;

        public double IgnitionRetardFurtherKnocks
        {
            get { return m_IgnitionRetardFurtherKnocks; }
            set { m_IgnitionRetardFurtherKnocks = value; }
        }
        private double m_GlobalMaximumIgnitionAdvance = 35.0;

        public double GlobalMaximumIgnitionAdvance
        {
            get { return m_GlobalMaximumIgnitionAdvance; }
            set { m_GlobalMaximumIgnitionAdvance = value; }
        }

        private double m_MaxumimIgnitionAdvancePerSession = 2;

        public double MaxumimIgnitionAdvancePerSession
        {
            get { return m_MaxumimIgnitionAdvancePerSession; }
            set { m_MaxumimIgnitionAdvancePerSession = value; }
        }

        private int _MinimumEngineSpeedForIgnitionTuning = 1200;

        public int MinimumEngineSpeedForIgnitionTuning
        {
            get { return _MinimumEngineSpeedForIgnitionTuning; }
            set { _MinimumEngineSpeedForIgnitionTuning = value; }
        }

        public int CellStableTime_ms
        {
            get { return _CellStableTime_ms; }
            set { _CellStableTime_ms = value; }
        }

        private bool _isAutoMappingActive = false;

        public bool IsAutoMappingActive
        {
            get { return _isAutoMappingActive; }
            set
            {
                if (_isAutoMappingActive != value)
                {
                    _isAutoMappingActive = value;
                    if (_isAutoMappingActive)
                    {
                        _currentEngineSpeed = 0;
                        _currentBoostLevel = 0;
                        _currentThrottlePosition = 0;
                        _currentAdvance = 0;
                        _currentKnockCondition = false;
                        _cellDurationMonitor.Stop();
                        _cellDurationMonitor.Reset();
                    }
                }
            }
        }

        private double mapsensorfactor = 1;

        public IECUFile TrionicFile
        {
            get { return m_TrionicFile; }
            set
            {
                m_TrionicFile = value;
                if (m_TrionicFile != null)
                {
                    if (m_TrionicFile.Exists())
                    {
                        mapsensorfactor = CalculateConversionFactor(MapSensorType.MapSensor25, m_TrionicFile.GetMapSensorType(false));
                    }
                }
            }
        }

        private double _currentEngineSpeed = 0;
        private double _currentBoostLevel = 0;
        private double _currentThrottlePosition = 0;
        private double _currentAdvance = 0;
        private bool _currentKnockCondition = false;
        private Stopwatch _cellDurationMonitor = new Stopwatch();
        private int _monitoringCellRPMIndex = -1;
        private int _monitoringCellMAPIndex = -1;
        private IgnitionMeasurementCollection _ignitionMeasurements = new IgnitionMeasurementCollection();

        public void InitAutoTuneVars(bool startAutoTune)
        {
            _monitoringCellRPMIndex = -1;
            _monitoringCellMAPIndex = -1;
            _ignitionMeasurements.Clear();
            _cellDurationMonitor.Stop();
            _cellDurationMonitor.Reset();
            // reset the feedback ignition map!
            if (startAutoTune)
            {
                // means we're entering autotune, in that case clear the feedback map
                InitIgnitionFeedbackMaps();
            }

        }

        private void InitIgnitionFeedbackMaps()
        {
            int columns = 18;
            int rows = 16;

            m_TrionicFile.GetMapMatrixWitdhByName(m_TrionicFile.GetFileInfo().GetIgnitionMap(), out columns, out rows);
            if (columns != 0)
            {
                IgnitionMapInMemory = new float[rows * columns];
                IgnitionMapCounterInMemory = new int[rows * columns];
                SaveIgnitionAndCounterMaps();
            }
        }

        public double GetAverageFromMeasurements()
        {
            double average = 0;
            for (int i = 0; i < _ignitionMeasurements.Count; i++)
            {
                average += _ignitionMeasurements[i].IgnitionValue;
            }
            average /= _ignitionMeasurements.Count;
            return average;
        }

        private void CastCellLockedEvent(int mapindex)
        {
            if (onCellLocked != null)
            {
                onCellLocked(this, new IgnitionmapChangedEventArgs(mapindex, 1));
            }
        }

        private void CastIgnitionmapCellChangedEvent(int mapindex, int cellvalue)
        {
            if (onIgnitionmapCellChanged != null)
            {
                onIgnitionmapCellChanged(this, new IgnitionmapChangedEventArgs(mapindex, cellvalue));
            }
        }

        /// <summary>
        /// clears data that might cause problems when switching from idle to normal ignition map or v.v.
        /// </summary>
        public void AutoTuneSwitchMap()
        {
            _monitoringCellRPMIndex = -1;
            _monitoringCellMAPIndex = -1;
            _ignitionMeasurements.Clear();
        }

        private bool _holdUntilKnockIsGone = false;

        public void HandleRealtimeData(double rpm, double tps, double boost, double ignitionadvance, bool isKnocking)
        {
            if (_isAutoMappingActive && !_holdUntilKnockIsGone)  // _holdUuntilKnockIsGone indicates we should ignore measurements until knock is over
            {
                if (rpm > _MinimumEngineSpeedForIgnitionTuning)
                {
                    // only handle this stuff if automapping is active
                    // first off, get the index in the ignition map for the given engine speed and load
                    double currentLoad = boost;
                    currentLoad += 1;
                    currentLoad /= 0.01;
                    int rpmindex = LookUpIndexAxisRPMMap(rpm, "Ign_map_0_y_axis!", 1);
                    int mapindex = LookUpIndexAxisMap(currentLoad, "Ign_map_0_x_axis!");

                    // we need to be higher in boost than what knock_press_tab tells us, because below these pressure, knock will not
                    // be detected
                    int boostLimit = knockPressTab[rpmindex];
                    double dLimit = (double)boostLimit;
                    dLimit *= mapsensorfactor;

                    //EDIT: We made a slight mistake here... we need to start altering one column HIGHER in boost because
                    // if we change the column directly when boost > knockPressTab[..] we will still influence ignition advance
                    // because of T5 table interpolation. So, we need to skip ONE extra column
                    // how can we do this? ... get the index for boostLimit as well
                    int mapMinimumIndex = LookUpIndexAxisMap(boostLimit, "Ign_map_0_x_axis!");

                    if (dLimit > currentLoad) return;
                    if (mapindex <= mapMinimumIndex + 1) return; // we're not allowed to alter this column because it will cause interpolation issues

                    //so we now know in what cell we are
                    // if the cell changed, we need to restart the stopwatch
                    // if the cell is unchanged we need to check the stopwatchduration against the settings
                    if (rpmindex != _monitoringCellRPMIndex || mapindex != _monitoringCellMAPIndex)
                    {
                        // set both values
                        _ignitionMeasurements.Clear(); // clear average collection
                        _monitoringCellRPMIndex = rpmindex;
                        _monitoringCellMAPIndex = mapindex;
                        // reset stopwatch
                        _cellDurationMonitor.Stop();
                        _cellDurationMonitor.Reset();
                        _cellDurationMonitor.Start();
                    }
                    else
                    {
                        // appearantly we are in the same cell
                        if (_monitoringCellMAPIndex >= 0 && _monitoringCellRPMIndex >= 0)
                        {
                            IgnitionMeasurement _measurement = new IgnitionMeasurement();
                            _measurement.IgnitionValue = ignitionadvance;
                            _ignitionMeasurements.Add(_measurement);
                            long elapsed_ms = _cellDurationMonitor.ElapsedMilliseconds;

                            if (elapsed_ms > _CellStableTime_ms)
                            {
                                //Console.WriteLine("Stable in cell: " + rpmindex.ToString() + " " + mapindex.ToString());
                                float average_ignition_in_cell = (float)GetAverageFromMeasurements();
                                int ignitionAdvanceValueFromMap = ignitionmap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex];

                                // TODO: if knocking, retard ignition by 1 full degree and lock the cell.
                                // TODO: if NOT knocking, advance ignition by m_IgnitionAdvancePerCycle (0.1 by default) degrees but ONLY if the boost is higher than the knock detection limit AND knock detection is turned on
                                // If we make a change we need to reset the monitor time and the measurements
                                if (isKnocking)
                                {
                                    _holdUntilKnockIsGone = true;
                                    if (IsCellLocked(_monitoringCellMAPIndex, _monitoringCellRPMIndex))
                                    {
                                        ignitionAdvanceValueFromMap -= Convert.ToInt32(m_IgnitionRetardFurtherKnocks * 10); // might be knocking based on previous cell.. now what
                                        // only update stuff AFTER knock has disappeared again
                                        AddLogEntry("Decreasing by " + m_IgnitionRetardFurtherKnocks.ToString() + " degrees because locked cell still knocked rpm: " + rpm.ToString() + " boost: " + boost.ToString() + " adjusted to " + ignitionAdvanceValueFromMap.ToString());
                                        if (ignitionAdvanceValueFromMap <= 0) ignitionAdvanceValueFromMap = 0;
                                        ignitionmap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex] = ignitionAdvanceValueFromMap;
                                        ignitioncorrectioncountermap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex]++;
                                        CastIgnitionmapCellChangedEvent((rpmindex * 18) + mapindex, ignitionAdvanceValueFromMap);
                                    }
                                    else
                                    {
                                        ignitionAdvanceValueFromMap -= Convert.ToInt32(m_IgnitionRetardFirstKnock * 10);
                                        if (ignitionAdvanceValueFromMap <= 0) ignitionAdvanceValueFromMap = 0;
                                        AddLogEntry("Decreasing by " + m_IgnitionRetardFirstKnock.ToString() + " degrees because non-locked cell knocked rpm: " + rpm.ToString() + " boost: " + boost.ToString() + " adjusted to " + ignitionAdvanceValueFromMap.ToString());
                                        ignitionmap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex] = ignitionAdvanceValueFromMap;
                                        ignitioncorrectioncountermap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex]++;
                                        CastIgnitionmapCellChangedEvent((rpmindex * 18) + mapindex, ignitionAdvanceValueFromMap);
                                        LockCell(_monitoringCellMAPIndex, _monitoringCellRPMIndex);
                                    }
                                    _ignitionMeasurements.Clear(); // clear average collection
                                    _cellDurationMonitor.Stop();
                                    _cellDurationMonitor.Reset();
                                    _cellDurationMonitor.Start();

                                }
                                else
                                {
                                    _holdUntilKnockIsGone = false;
                                    if (!IsCellLocked(_monitoringCellMAPIndex, _monitoringCellRPMIndex))
                                    {
                                        //increase ignition by m_IgnitionAdvancePerCycle (0.1 by default) degrees IF the cell is not locked, otherwise leave it be
                                        //Cast event to increase ignition

                                        // check against m_MaxumimIgnitionAdvancePerSession
                                        int originalAdvance = originalignitionmap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex];
                                        double advanceThisSession = Convert.ToDouble(ignitionAdvanceValueFromMap - originalAdvance);
                                        advanceThisSession /= 10;
                                        if (advanceThisSession >= m_MaxumimIgnitionAdvancePerSession)
                                        {
                                            AddLogEntry("Maximum advance increase reached for rpm: " + rpm.ToString() + " boost: " + boost.ToString() + " adjusted to " + ignitionAdvanceValueFromMap.ToString());
                                            if (ignitionAdvanceValueFromMap > Convert.ToInt32(m_GlobalMaximumIgnitionAdvance * 10))
                                            {
                                                ignitionmap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex] = Convert.ToInt32(m_GlobalMaximumIgnitionAdvance * 10); // cap
                                                CastIgnitionmapCellChangedEvent((rpmindex * 18) + mapindex, Convert.ToInt32(m_GlobalMaximumIgnitionAdvance * 10));
                                            }
                                        }
                                        else
                                        {
                                            ignitionAdvanceValueFromMap += Convert.ToInt32(m_IgnitionAdvancePerCycle * 10);
                                            if (ignitionAdvanceValueFromMap >= Convert.ToInt32(m_GlobalMaximumIgnitionAdvance * 10)) ignitionAdvanceValueFromMap = Convert.ToInt32(m_GlobalMaximumIgnitionAdvance * 10); // max @ 40 degrees advance
                                            AddLogEntry("Increasing by " + m_IgnitionAdvancePerCycle.ToString() + " degrees because non-locked cell did not knock rpm: " + rpm.ToString() + " boost: " + boost.ToString() + " adjusted to " + ignitionAdvanceValueFromMap.ToString());
                                            ignitionmap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex] = ignitionAdvanceValueFromMap;
                                            ignitioncorrectioncountermap[_monitoringCellRPMIndex * 18 + _monitoringCellMAPIndex]++;
                                            CastIgnitionmapCellChangedEvent((rpmindex * 18) + mapindex, ignitionAdvanceValueFromMap);
                                        }
                                    }
                                    _ignitionMeasurements.Clear(); // clear average collection
                                    _cellDurationMonitor.Stop();
                                    _cellDurationMonitor.Reset();
                                    _cellDurationMonitor.Start();
                                }

                            }
                        }
                        else
                        {
                            // nothing, invalid index from map
                            _ignitionMeasurements.Clear(); // clear average collection
                            _cellDurationMonitor.Stop();
                            _cellDurationMonitor.Reset();
                            _cellDurationMonitor.Start();
                        }
                    }
                }
            }
            else if (!isKnocking)
            {
                _holdUntilKnockIsGone = false;
            }
        }

        public void LockCell(int _monitoringCellMAPIndex, int _monitoringCellRPMIndex)
        {
            ignitionlockedmap.SetValue(1, (_monitoringCellRPMIndex * 18) + _monitoringCellMAPIndex);
            SaveIgnitionAndCounterMaps();
        }

        public void UnlockCell(int _monitoringCellMAPIndex, int _monitoringCellRPMIndex)
        {
            ignitionlockedmap.SetValue(0, (_monitoringCellRPMIndex * 18) + _monitoringCellMAPIndex);
            SaveIgnitionAndCounterMaps();
        }

        /// <summary>
        /// Checks if the current cell is locked (previously detected knock
        /// </summary>
        /// <param name="_monitoringCellMAPIndex"></param>
        /// <param name="_monitoringCellRPMIndex"></param>
        /// <returns></returns>
        private bool IsCellLocked(int _monitoringCellMAPIndex, int _monitoringCellRPMIndex)
        {
            //TODO: Implement this, should check whether a CELL is locked
            // This LOCK table should only be cleared by the USER not automatically by software when starting autotune or something
            if ((int)ignitionlockedmap.GetValue((_monitoringCellRPMIndex * 18) + _monitoringCellMAPIndex) > 0)
            {
                return true;
            }
            return false;
        }

        public int[] GetCurrentlyMutatedIgnitionMap()
        {
            return ignitionmap;
        }

        public void ClearIgnitionLockedMap()
        {
            for (int i = 0; i < ignitionlockedmap.Length; i++) ignitionlockedmap.SetValue(0, i);
            SaveIgnitionAndCounterMaps();
        }

        public int[] GetIgnitionLockedMap()
        {
            return ignitionlockedmap;
        }

        public int[] GetCurrentlyMutatedIgnitionMapCounter()
        {
            return ignitioncorrectioncountermap;
        }

        public int[] GetOriginalIgnitionmap()
        {
            return originalignitionmap;
        }

        public void SetOriginalIgnitionMap(int[] ignitionmapdata)
        {

            originalignitionmap = new int[ignitionmapdata.Length];
            for (int t = 0; t < ignitionmapdata.Length; t++)
            {
                originalignitionmap[t] = ignitionmapdata[t];
            }

        }

        public void SetKnockPressTab(int[] knockpressuremap)
        {
            knockPressTab = new int[knockpressuremap.Length];
            for (int t = 0; t < knockpressuremap.Length; t++)
            {
                knockPressTab[t] = knockpressuremap[t];
            }
        }

        public void SetCurrentIgnitionMap(int[] ignitionmapdata)
        {

            // copy the data
            ignitionmap = new int[ignitionmapdata.Length];
            for (int t = 0; t < ignitionmapdata.Length; t++)
            {
                ignitionmap[t] = ignitionmapdata[t];
            }
            // and create a correction counter map with all 0's
            ignitioncorrectioncountermap = new int[ignitionmapdata.Length];
            for (int i = 0; i < ignitioncorrectioncountermap.Length; i++)
            {
                ignitioncorrectioncountermap[i] = 0; // initialize
            }
        }

        public void InitializeMaps()
        {
            // first get the data length we should use (default is 18x16 Ign_map_0)
            string injection_map_name = m_TrionicFile.GetFileInfo().GetIgnitionMap();
            int map_length = m_TrionicFile.GetFileInfo().GetSymbolLength(injection_map_name);
            if (map_length == 0) map_length = 18 * 16; // fail safe for bins without a correct symbol table, e.g. maptun/nordic files etc
            try
            {
                string foldername = Path.Combine(Path.GetDirectoryName(m_TrionicFile.GetFileInfo().Filename), "IgnitionMaps");
                if (!Directory.Exists(foldername))
                {
                    Directory.CreateDirectory(foldername);
                }

                if (File.Exists(Path.Combine(foldername, Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionFeedbackmap.ign")))
                {
                    IgnitionMapInMemory = LoadTargetIgnitionMap(Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionFeedbackmap.ign");
                }
                else
                {
                    int columns = 18;
                    int rows = 16;

                    //m_TrionicFile.GetMapMatrixWitdhByName(m_TrionicFile.GetFileInfo().GetIgnitionMap(), out columns, out rows);
                    if (columns != 0)
                    {
                        IgnitionMapInMemory = new float[rows * columns];
                        IgnitionMapCounterInMemory = new int[rows * columns];
                        ignitionlockedmap = new int[rows * columns];
                        SaveIgnitionAndCounterMaps();
                    }
                }
                if (File.Exists(Path.Combine(foldername, Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionFeedbackCountermap.ign")))
                {
                    IgnitionMapCounterInMemory = LoadCounterMap(Path.Combine(foldername, Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionFeedbackCountermap.ign"));
                }
                if (File.Exists(Path.Combine(foldername, Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionLockedmap.ign")))
                {
                    ignitionlockedmap = LoadCounterMap(Path.Combine(foldername, Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionLockedmap.ign"));
                }

            }
            catch (Exception tafrE)
            {
                Console.WriteLine(tafrE.Message);
            }

        }

        private int LookUpIndexAxisRPMMap(double value, string symbolname, int multiplywith)
        {
            int return_index = -1;
            double min_difference = 10000000;
            byte[] axisvalues = m_TrionicFile.ReadData((uint)m_TrionicFile.GetFileInfo().GetSymbolAddressFlash(symbolname), (uint)m_TrionicFile.GetFileInfo().GetSymbolLength(symbolname));
            if (m_TrionicFile.GetFileInfo().isSixteenBitTable(symbolname))
            {
                for (int t = 0; t < axisvalues.Length; t += 2)
                {
                    int b = (int)(byte)axisvalues.GetValue(t) * 256;
                    b += (int)(byte)axisvalues.GetValue(t + 1);
                    b *= multiplywith;
                    double diff = Math.Abs((double)b - value);
                    if (min_difference > diff)
                    {
                        min_difference = diff;
                        // this is our index
                        return_index = t / 2;
                        // Console.WriteLine("Difference was: " + diff.ToString() + " at index " + return_index.ToString());

                    }
                }
            }
            else
            {
                for (int t = 0; t < axisvalues.Length; t++)
                {
                    int b = (int)(byte)axisvalues.GetValue(t);
                    b *= multiplywith;
                    double diff = Math.Abs((double)b - value);
                    if (min_difference > diff)
                    {
                        min_difference = diff;
                        // this is our index
                        return_index = t;
                    }
                }
            }
            return return_index;
        }

        private double CalculateConversionFactor(MapSensorType fromSensorType, MapSensorType toSensorType)
        {
            double factor = 1.2;
            switch (fromSensorType)
            {
                case MapSensorType.MapSensor25:
                    switch (toSensorType)
                    {
                        case MapSensorType.MapSensor25:
                            factor = 1.0;           // from 2.5 to 2.5 mapsensor
                            break;
                        case MapSensorType.MapSensor30:
                            factor = 1.2;           // from 2.5 to 3.0 mapsensor
                            break;
                        case MapSensorType.MapSensor35:
                            factor = 1.4;           // from 2.5 to 3.5 mapsensor
                            break;
                        case MapSensorType.MapSensor40:
                            factor = 1.6;           // from 2.5 to 4.0 mapsensor
                            break;
                        case MapSensorType.MapSensor50:
                            factor = 2.0;           // from 2.5 to 5.0 mapsensor
                            break;
                    }
                    break;
                case MapSensorType.MapSensor30:
                    switch (toSensorType)
                    {
                        case MapSensorType.MapSensor25:
                            factor = 0.8333;           // from 3.0 to 2.5 mapsensor
                            break;
                        case MapSensorType.MapSensor30:
                            factor = 1.0;           // from 3.0 to 3.0 mapsensor
                            break;
                        case MapSensorType.MapSensor35:
                            factor = 1.1666;           // from 3.0 to 3.5 mapsensor
                            break;
                        case MapSensorType.MapSensor40:
                            factor = 1.3333;           // from 3.0 to 4.0 mapsensor
                            break;
                        case MapSensorType.MapSensor50:
                            factor = 1.6667;           // from 3.0 to 5.0 mapsensor
                            break;
                    }
                    break;
                case MapSensorType.MapSensor35:
                    switch (toSensorType)
                    {
                        case MapSensorType.MapSensor25:
                            factor = 0.7143;           // from 3.5 to 2.5 mapsensor
                            break;
                        case MapSensorType.MapSensor30:
                            factor = 0.8571;           // from 3.5 to 3.0 mapsensor
                            break;
                        case MapSensorType.MapSensor35:
                            factor = 1.0;           // from 3.5 to 3.5 mapsensor
                            break;
                        case MapSensorType.MapSensor40:
                            factor = 1.1429;           // from 3.5 to 4.0 mapsensor
                            break;
                        case MapSensorType.MapSensor50:
                            factor = 1.4285;           // from 3.5 to 5.0 mapsensor
                            break;
                    }
                    break;
                case MapSensorType.MapSensor40:
                    switch (toSensorType)
                    {
                        case MapSensorType.MapSensor25:
                            factor = 0.6250;           // from 4.0 to 2.5 mapsensor
                            break;
                        case MapSensorType.MapSensor30:
                            factor = 0.75;           // from 4.0 to 3.0 mapsensor
                            break;
                        case MapSensorType.MapSensor35:
                            factor = 0.875;           // from 4.0 to 3.5 mapsensor
                            break;
                        case MapSensorType.MapSensor40:
                            factor = 1.0;           // from 4.0 to 4.0 mapsensor
                            break;
                        case MapSensorType.MapSensor50:
                            factor = 1.25;           // from 4.0 to 5.0 mapsensor
                            break;
                    }
                    break;
                case MapSensorType.MapSensor50:
                    switch (toSensorType)
                    {
                        case MapSensorType.MapSensor25:
                            factor = 0.5;           // from 5.0 to 2.5 mapsensor
                            break;
                        case MapSensorType.MapSensor30:
                            factor = 0.6;           // from 5.0 to 3.0 mapsensor
                            break;
                        case MapSensorType.MapSensor35:
                            factor = 0.7;           // from 5.0 to 3.5 mapsensor
                            break;
                        case MapSensorType.MapSensor40:
                            factor = 0.8;           // from 5.0 to 4.0 mapsensor
                            break;
                        case MapSensorType.MapSensor50:
                            factor = 1.0;           // from 5.0 to 5.0 mapsensor
                            break;
                    }
                    break;
            }
            return factor;
        }

        private int LookUpIndexAxisMap(double value, string symbolname)
        {
            int return_index = -1;
            double min_difference = 10000000;

            double factor = mapsensorfactor;//CalculateConversionFactor(MapSensorType.MapSensor25, m_TrionicFile.GetMapSensorType(false));

            byte[] axisvalues = m_TrionicFile.ReadData((uint)m_TrionicFile.GetFileInfo().GetSymbolAddressFlash(symbolname), (uint)m_TrionicFile.GetFileInfo().GetSymbolLength(symbolname));

            if (m_TrionicFile.GetFileInfo().isSixteenBitTable(symbolname))
            {
                for (int t = 0; t < axisvalues.Length; t += 2)
                {
                    int b = (int)(byte)axisvalues.GetValue(t) * 256;
                    b += (int)(byte)axisvalues.GetValue(t + 1);

                    /*if (threebarsensor)*/
                    b = (int)((double)b * /*1.2*/ factor);
                    double diff = Math.Abs((double)b - value);

                    if (min_difference > diff)
                    {
                        min_difference = diff;
                        // this is our index
                        return_index = t / 2;
                        // Console.WriteLine("Difference was: " + diff.ToString() + " at index " + return_index.ToString());

                    }
                }
            }
            else
            {

                for (int t = 0; t < axisvalues.Length; t++)
                {
                    int b = (int)(byte)axisvalues.GetValue(t);

                    /*if (threebarsensor)*/
                    b = (int)((double)b * /*1.2*/ factor);

                    double diff = Math.Abs((double)b - value);
                    if (min_difference > diff)
                    {
                        min_difference = diff;
                        // this is our index
                        return_index = t;
                    }
                }
            }
            //Console.WriteLine("Index found = " + return_index.ToString());
            return return_index;
        }

        public int[] GetIgnitionCountermap()
        {
            return IgnitionMapCounterInMemory;
        }

        public float[] GetFeedbackIgnitionMap()
        {
            return IgnitionMapInMemory;
        }

        public int[] GetFeedbackIgnitionMapinIntegers()
        {
            return LoadTargetIgnitionMapInIntegers(IgnitionMapInMemory);
        }

        public int[] GetFeedBackmapInIntegers()
        {
            return LoadTargetIgnitionMapInIntegers(IgnitionMapInMemory);
        }

        private void UpdateFeedbackMaps()
        {
            // cast an event to the main application to refresh the Ignition maps if visible
        }

        public void SaveMaps()
        {
            SaveIgnitionAndCounterMaps();
        }

        public string GetFeedbackIgnitionMapname()
        {
            string foldername = Path.Combine(Path.GetDirectoryName(m_TrionicFile.GetFileInfo().Filename), "IgnitionMaps");
            if (!Directory.Exists(foldername))
            {
                Directory.CreateDirectory(foldername);
            }

            return Path.Combine(foldername, Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-feedbackignitiontab.ign");
        }

        private void SaveIgnitionAndCounterMaps()
        {
            try
            {
                if (IgnitionMapInMemory != null)
                {
                    // save it to the correct filename
                    SaveTargetIgnitionMap(Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionFeedbackmap.ign", IgnitionMapInMemory);
                }
                if (IgnitionMapCounterInMemory != null)
                {
                    // save it
                    SaveTargetIgnitionCounterMap(Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionFeedbackCountermap.ign", IgnitionMapCounterInMemory);
                }
                if (ignitionlockedmap != null)
                {
                    SaveTargetIgnitionCounterMap(Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-IgnitionLockedmap.ign", ignitionlockedmap);
                }
            }
            catch (Exception stargetE)
            {
                Console.WriteLine(stargetE.Message);
            }
        }

        byte[] open_loop=null;
        private bool IsCellClosedLoop(int mapvalue, int rpmindex)
        {
            if (open_loop == null)
            {
                open_loop = m_TrionicFile.ReadData((uint)m_TrionicFile.GetFileInfo().GetSymbolAddressFlash("Open_loop!"), (uint)m_TrionicFile.GetFileInfo().GetSymbolLength("Open_loop!"));
            }
            // look up the value in open_loop! map
            if (open_loop.Length > 1)
            {
                int closed_loop_limit = Convert.ToInt32(open_loop.GetValue(rpmindex));
                if (closed_loop_limit < mapvalue) return false;
            }
            return true;
        }

        private void SaveTargetIgnitionMap(string filename, float[] map)
        {
            int columns = 18;
            int rows = 16;

            if (m_TrionicFile.Exists())
            {
                string foldername = Path.Combine(Path.GetDirectoryName(m_TrionicFile.GetFileInfo().Filename), "IgnitionMaps");
                if (!Directory.Exists(foldername))
                {
                    Directory.CreateDirectory(foldername);
                }
                filename = Path.Combine(foldername, filename);
                //m_TrionicFile.GetMapMatrixWitdhByName(m_TrionicFile.GetFileInfo().GetIgnitionMap(), out columns, out rows);
                if (map.Length == columns * rows)
                {
                    using (StreamWriter sw = new StreamWriter(filename, false))
                    {
                        for (int rt = 0; rt < rows; rt++)
                        {
                            for (int ct = 0; ct < columns; ct++)
                            {
                                float value = (float)map.GetValue((rt * columns) + ct);
                                sw.Write(value.ToString("F2") + ";");
                            }
                            sw.Write(Environment.NewLine);
                        }
                    }
                }
                else
                {
                    //  MessageBox.Show("Target IGN map has different length than main VE map");
                }
            }
        }

        private void AddLogEntry(string entry)
        {
            if (m_TrionicFile.Exists())
            {
                string foldername = Path.Combine(Path.GetDirectoryName(m_TrionicFile.GetFileInfo().Filename), "IgnitionMaps");
                if (!Directory.Exists(foldername))
                {
                    Directory.CreateDirectory(foldername);
                }

                string filename = Path.Combine(foldername, DateTime.Now.Date.ToString("yyyyMMdd") + "-IgnitionTuning.log");
                using (StreamWriter sw = new StreamWriter(filename, true))
                {
                    sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + entry);
                }
            }
        }

        private void SaveTargetIgnitionCounterMap(string filename, int[] map)
        {
            int columns = 18;
            int rows = 16;
            if (m_TrionicFile.Exists())
            {
                string foldername = Path.Combine(Path.GetDirectoryName(m_TrionicFile.GetFileInfo().Filename), "IgnitionMaps");
                if (!Directory.Exists(foldername))
                {
                    Directory.CreateDirectory(foldername);
                }
                filename = Path.Combine(foldername, filename);

                //m_TrionicFile.GetMapMatrixWitdhByName(m_TrionicFile.GetFileInfo().GetIgnitionMap(), out columns, out rows);
                if (map.Length == columns * rows)
                {
                    using (StreamWriter sw = new StreamWriter(filename, false))
                    {
                        for (int rt = 0; rt < rows; rt++)
                        {
                            for (int ct = 0; ct < columns; ct++)
                            {
                                int value = (int)map.GetValue((rt * columns) + ct);
                                sw.Write(value.ToString() + ";");
                            }
                            sw.Write(Environment.NewLine);
                        }
                    }
                }
                else
                {
                    //   MessageBox.Show("Target IGN counter map has different length than main VE map");
                }
            }

        }

        private double ConvertToDouble(string v)
        {
            double d = 0;
            if (v == "") return d;
            string vs = "";
            vs = v.Replace(System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator, System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
            Double.TryParse(vs, out d);
            return d;
        }

        public int[] LoadTargetIgnitionMapInIntegers()
        {
            string foldername = Path.Combine(Path.GetDirectoryName(m_TrionicFile.GetFileInfo().Filename), "IgnitionMaps");
            if (!Directory.Exists(foldername))
            {
                Directory.CreateDirectory(foldername);
            }

            string filename = Path.Combine(foldername, Path.GetFileNameWithoutExtension(m_TrionicFile.GetFileInfo().Filename) + "-targetignition.ign");
            int[] map = new int[m_TrionicFile.GetFileInfo().GetSymbolLength(m_TrionicFile.GetFileInfo().GetIgnitionMap())/2];
            map.Initialize();
            if (m_TrionicFile.Exists())
            {
                if (File.Exists(filename))
                {
                    try
                    {
                        // read all lines
                        string line = string.Empty;
                        char[] sep = new char[1];
                        sep.SetValue(';', 0);
                        int idx = 0;
                        using (StreamReader sr = new StreamReader(filename))
                        {
                            while ((line = sr.ReadLine()) != null)
                            {
                                string[] values = line.Split(sep);
                                foreach (string value in values)
                                {
                                    if (value.Length > 0)
                                    {
                                        int val = (int)(Math.Ceiling(ConvertToDouble(value) * 10));
                                        byte b1 = (byte)(val / 256);
                                        byte b2 = (byte)(val - (int)b1 * 256);
                                        map.SetValue(b1, idx++);
                                        map.SetValue(b2, idx++);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception E)
                    {
                        //  MessageBox.Show("Failed to load target IGN map: " + E.Message);
                        Console.WriteLine(E.Message);

                    }
                }
            }
            else
            {
                map = new int[0x120];
                map.Initialize();
            }
            return map;

        }

        private int[] LoadTargetIgnitionMapInIntegers(float[] orginalmap)
        {

            int[] map = new int[/*m_TrionicFile.GetFileInfo().GetSymbolLength(m_TrionicFile.GetFileInfo().GetIgnitionMap())*/ orginalmap.Length];
            map.Initialize();
            if (m_TrionicFile.Exists())
            {
                try
                {
                    int idx = 0;
                    foreach (float f in orginalmap)
                    {
                        int val = (int)(Math.Ceiling(f * 10));
                        map.SetValue(val, idx++);
                    }
                }
                catch (Exception E)
                {
                    //   MessageBox.Show("Failed to load target IGN map: " + E.Message);
                    Console.WriteLine(E.Message);
                }
            }
            else
            {
                map = new int[orginalmap.Length];
                map.Initialize();
            }
            return map;
        }

        private float[] LoadTargetIgnitionMap(string filename)
        {
            // load the target IGN map into memory
            float[] map = new float[m_TrionicFile.GetFileInfo().GetSymbolLength(m_TrionicFile.GetFileInfo().GetIgnitionMap())/2];
            map.Initialize();
            if (m_TrionicFile.Exists())
            {
                string foldername = Path.Combine(Path.GetDirectoryName(m_TrionicFile.GetFileInfo().Filename), "IgnitionMaps");
                if (!Directory.Exists(foldername))
                {
                    Directory.CreateDirectory(foldername);
                }
                filename = Path.Combine(foldername, filename);

                if (File.Exists(filename))
                {
                    try
                    {
                        string line = string.Empty;
                        char[] sep = new char[1];
                        sep.SetValue(';', 0);
                        int idx = 0;
                        using (StreamReader sr = new StreamReader(filename))
                        {
                            while ((line = sr.ReadLine()) != null)
                            {
                                string[] values = line.Split(sep);
                                foreach (string value in values)
                                {
                                    if (value.Length > 0)
                                    {
                                        float val = (float)(ConvertToDouble(value));
                                        map.SetValue(val, idx++);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception E)
                    {
                        //      MessageBox.Show("Failed to load target IGN map: " + E.Message);
                        // something went wrong, try to reinitialize the map
                        Console.WriteLine(E.Message);

                    }
                }
            }
            else
            {
                map = new float[0x120];
                map.Initialize();
            }
            return map;
        }

        private int[] LoadCounterMap(string filename)
        {
            // load the target IGN map into memory
            int[] map = new int[m_TrionicFile.GetFileInfo().GetSymbolLength(m_TrionicFile.GetFileInfo().GetIgnitionMap()) / 2 ];
            map.Initialize();
            if (m_TrionicFile.Exists())
            {
                if (File.Exists(filename))
                {
                    try
                    {
                        string line = string.Empty;
                        char[] sep = new char[1];
                        sep.SetValue(';', 0);
                        int idx = 0;
                        using (StreamReader sr = new StreamReader(filename))
                        {
                            while ((line = sr.ReadLine()) != null)
                            {
                                string[] values = line.Split(sep);
                                foreach (string value in values)
                                {
                                    if (value.Length > 0)
                                    {
                                        int val = Convert.ToInt32(value);
                                        map.SetValue(val, idx++);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception E)
                    {
                        //  MessageBox.Show("Failed to load target IGN counter map: " + E.Message);
                        Console.WriteLine(E.Message);
                    }
                }
            }
            else
            {
                map = new int[0x120];
                map.Initialize();

            }
            return map;
        }

        private bool IsAllZero(float[] values)
        {
            for (int t = 0; t < values.Length; t++)
            {
                if (values[t] != 0) return false;
            }
            return true;
        }

        public void ClearIgnitionFeedbackMapCell(int mapindex)
        {
            try
            {
                if (IgnitionMapInMemory != null)
                {
                    IgnitionMapInMemory[mapindex] = 0;
                }
                if (IgnitionMapCounterInMemory != null)
                {
                    IgnitionMapCounterInMemory[mapindex] = 0;
                }
            }
            catch (Exception E)
            {
                Console.WriteLine(E.Message);
            }
        }
    }
}


text:
Build an app that is functionally similar to this: https://codepen.io/FreeCodeCamp/full/wGqEga/.

## Requirements

* User Story: I can search Wikipedia entries in a search box and see the resulting Wikipedia entries.

* User Story: I can click a button to see a random Wikipedia entry.

**Hint #1:** Here's a URL you can use to get a random Wikipedia article: https://en.wikipedia.org/wiki/Special:Random.

**Hint #2:** Here's an entry on using Wikipedia's API: https://www.mediawiki.org/wiki/API:Main_page.

**Hint #3:** Use this link to experiment with Wikipedia's API.

## Notes

redpajama_set_name: RedPajamaGithub


text:
<template name="databaseDumpRestore">
    {{> pageHeading title=getPageHeading }}

    {{#if isConnected}}

Mongodump

                            <form method="get" class="form-horizontal">

                                    {{_ "arguments"}}

                                        <select id="cmbMongodumpArgs"
                                                data-placeholder="{{_ "select_options"}}"
                                                multiple="true"
                                                class="chosen-select form-control"
                                                tabindex="-1">
                                            <option value="-v">verbose</option>
                                            <option value="--quiet">quiet</option>
                                            <option value="--host">host</option>
                                            <option value="--port">port</option>
                                            <option value="--ipv6">ipv6</option>
                                            <option value="--ssl">ssl</option>
                                            <option value="--sslCAFile">sslCAFile</option>
                                            <option value="--sslPEMKeyFile">sslPEMKeyFile</option>
                                            <option value="--sslPEMKeyPassword">sslPEMKeyPassword</option>
                                            <option value="--sslCRLFile">sslCRLFile</option>
                                            <option value="--sslAllowInvalidCertificates">
                                                sslAllowInvalidCertificates
                                            </option>
                                            <option value="--sslAllowInvalidHostnames">
                                                sslAllowInvalidHostnames
                                            </option>
                                            <option value="--sslFIPSMode">sslFIPSMode</option>
                                            <option value="--username">username</option>
                                            <option value="--password">password</option>
                                            <option value="--authenticationDatabase">
                                                authenticationDatabase
                                            </option>
                                            <option value="--authenticationMechanism">
                                                authenticationMechanism
                                            </option>
                                            <option value="--gssapiServiceName">gssapiServiceName</option>
                                            <option value="--gssapiHostName">gssapiHostName</option>
                                            <option value="--db">db</option>
                                            <option value="--collection">collection</option>
                                            <option value="--query">query</option>
                                            <option value="--queryFile">queryFile</option>
                                            <option value="--readPreference">readPreference</option>
                                            <option value="--forceTableScan">forceTableScan</option>
                                            <option value="--gzip">gzip</option>
                                            <option value="--out">out</option>
                                            <option value="--archive">archive</option>
                                            <option value="--repair">repair</option>
                                            <option value="--oplog">oplog</option>
                                            <option value="--dumpDbUsersAndRoles">dumpDbUsersAndRoles
                                            </option>
                                            <option value="--excludeCollection">excludeCollection</option>
                                            <option value="--excludeCollectionsWithPrefix">
                                                excludeCollectionsWithPrefix
                                            </option>
                                            <option value="--numParallelCollections">
                                                numParallelCollections
                                            </option>
                                            <option value="--viewsAsCollections">viewsAsCollections</option>

                                        </select>

                                {{> mongodumpOptions}}

                                        {{_ "logs"}}

                                            <textarea id="txtMongodumpLogs" class="form-control"></textarea>

                            </form>

                                    <button id="btnExecuteMongodump"
                                            class="btn btn-block btn-outline btn-primary ladda-button"
                                            type="button"
                                            data-style="contract">
                                        {{_ "execute"}}</button>

Mongorestore

                            <form method="get" class="form-horizontal">

                                    {{_ "arguments"}}

                                        <select id="cmbMongorestoreArgs"
                                                data-placeholder="{{_ "select_options"}}"
                                                multiple="true"
                                                class="chosen-select form-control"
                                                tabindex="-1">
                                            <option value="-v">verbose</option>
                                            <option value="--quiet">quiet</option>
                                            <option value="--host">host</option>
                                            <option value="--port">port</option>
                                            <option value="--ssl">ssl</option>
                                            <option value="--sslCAFile">sslCAFile</option>
                                            <option value="--sslPEMKeyFile">sslPEMKeyFile</option>
                                            <option value="--sslPEMKeyPassword">sslPEMKeyPassword</option>
                                            <option value="--sslCRLFile">sslCRLFile</option>
                                            <option value="--sslAllowInvalidCertificates">
                                                sslAllowInvalidCertificates
                                            </option>
                                            <option value="--sslAllowInvalidHostnames">
                                                sslAllowInvalidHostnames
                                            </option>
                                            <option value="--sslFIPSMode">sslFIPSMode</option>
                                            <option value="--username">username</option>
                                            <option value="--password">password</option>
                                            <option value="--authenticationDatabase">
                                                authenticationDatabase
                                            </option>
                                            <option value="--authenticationMechanism">
                                                authenticationMechanism
                                            </option>
                                            <option value="--gssapiServiceName">gssapiServiceName</option>
                                            <option value="--gssapiHostName">gssapiHostName</option>
                                            <option value="--db">db</option>
                                            <option value="--collection">collection</option>
                                            <option value="--nsExclude">nsExclude</option>
                                            <option value="--nsInclude">nsInclude</option>
                                            <option value="--nsFrom">nsFrom</option>
                                            <option value="--nsTo">nsTo</option>
                                            <option value="--objcheck">objcheck</option>
                                            <option value="--drop">drop</option>
                                            <option value="--dryRun">dryRun</option>
                                            <option value="--oplogReplay">oplogReplay</option>
                                            <option value="--oplogLimit">oplogLimit</option>
                                            <option value="--oplogFile">oplogFile</option>
                                            <option value="--keepIndexVersion">keepIndexVersion</option>
                                            <option value="--noIndexRestore">noIndexRestore</option>
                                            <option value="--noOptionsRestore">noOptionsRestore</option>
                                            <option value="--restoreDbUsersAndRoles">restoreDbUsersAndRoles</option>
                                            <option value="--writeConcern">writeConcern</option>
                                            <option value="--maintainInsertionOrder">maintainInsertionOrder</option>
                                            <option value="--numParallelCollections">numParallelCollections</option>
                                            <option value="--numInsertionWorkersPerCollection">
                                                numInsertionWorkersPerCollection
                                            </option>
                                            <option value="--stopOnError">stopOnError</option>
                                            <option value="--bypassDocumentValidation">bypassDocumentValidation</option>
                                            <option value="--gzip">gzip</option>
                                            <option value="--archive">archive</option>
                                            <option value="--dir">dir</option>

                                        </select>

                                {{> mongorestoreOptions}}

                                        {{_ "logs"}}

                                            <textarea id="txtMongorestoreLogs" class="form-control"></textarea>

                            </form>

                                    <button id="btnExecuteMongorestore"
                                            class="btn btn-block btn-outline btn-primary ladda-button"
                                            type="button"
                                            data-style="contract">
                                        {{_ "execute"}}</button>

Mongoexport

                            <form method="get" class="form-horizontal">

                                    {{_ "arguments"}}

                                        <select id="cmbMongoexportArgs"
                                                data-placeholder="{{_ "select_options"}}"
                                                multiple="true"
                                                class="chosen-select form-control"
                                                tabindex="-1">
                                            <option value="-v">verbose</option>
                                            <option value="--quiet">quiet</option>
                                            <option value="--host">host</option>
                                            <option value="--port">port</option>
                                            <option value="--ipv6">ipv6</option>
                                            <option value="--ssl">ssl</option>
                                            <option value="--sslCAFile">sslCAFile</option>
                                            <option value="--sslPEMKeyFile">sslPEMKeyFile</option>
                                            <option value="--sslPEMKeyPassword">sslPEMKeyPassword</option>
                                            <option value="--sslCRLFile">sslCRLFile</option>
                                            <option value="--sslAllowInvalidCertificates">
                                                sslAllowInvalidCertificates
                                            </option>
                                            <option value="--sslAllowInvalidHostnames">
                                                sslAllowInvalidHostnames
                                            </option>
                                            <option value="--sslFIPSMode">sslFIPSMode</option>
                                            <option value="--username">username</option>
                                            <option value="--password">password</option>
                                            <option value="--authenticationDatabase">
                                                authenticationDatabase
                                            </option>
                                            <option value="--authenticationMechanism">
                                                authenticationMechanism
                                            </option>
                                            <option value="--gssapiServiceName">gssapiServiceName</option>
                                            <option value="--gssapiHostName">gssapiHostName</option>
                                            <option value="--db">db</option>
                                            <option value="--collection">collection</option>
                                            <option value="--fields">fields</option>
                                            <option value="--fieldFile">fieldFile</option>
                                            <option value="--query">query</option>
                                            <option value="--type">type</option>
                                            <option value="--out">out</option>
                                            <option value="--jsonArray">jsonArray</option>
                                            <option value="--pretty">pretty</option>
                                            <option value="--slaveOk">slaveOk</option>
                                            <option value="--readPreference">readPreference</option>
                                            <option value="--forceTableScan">forceTableScan</option>
                                            <option value="--skip">skip</option>
                                            <option value="--limit">limit</option>
                                            <option value="--sort">sort</option>
                                        </select>

                                {{> mongoexportOptions}}

                                        {{_ "logs"}}

                                            <textarea id="txtMongoexportLogs" class="form-control"></textarea>

                            </form>

                                    <button id="btnExecuteMongoexport"
                                            class="btn btn-block btn-outline btn-primary ladda-button"
                                            type="button"
                                            data-style="contract">
                                        {{_ "execute"}}</button>

Mongoimport

                            <form method="get" class="form-horizontal">

                                    {{_ "arguments"}}

                                        <select id="cmbMongoimportArgs"
                                                data-placeholder="{{_ "select_options"}}"
                                                multiple="true"
                                                class="chosen-select form-control"
                                                tabindex="-1">
                                            <option value="-v">verbose</option>
                                            <option value="--quiet">quiet</option>
                                            <option value="--host">host</option>
                                            <option value="--port">port</option>
                                            <option value="--ipv6">ipv6</option>
                                            <option value="--ssl">ssl</option>
                                            <option value="--sslCAFile">sslCAFile</option>
                                            <option value="--sslPEMKeyFile">sslPEMKeyFile</option>
                                            <option value="--sslPEMKeyPassword">sslPEMKeyPassword</option>
                                            <option value="--sslCRLFile">sslCRLFile</option>
                                            <option value="--sslAllowInvalidCertificates">
                                                sslAllowInvalidCertificates
                                            </option>
                                            <option value="--sslAllowInvalidHostnames">
                                                sslAllowInvalidHostnames
                                            </option>
                                            <option value="--sslFIPSMode">sslFIPSMode</option>
                                            <option value="--username">username</option>
                                            <option value="--password">password</option>
                                            <option value="--authenticationDatabase">
                                                authenticationDatabase
                                            </option>
                                            <option value="--authenticationMechanism">
                                                authenticationMechanism
                                            </option>
                                            <option value="--gssapiServiceName">gssapiServiceName</option>
                                            <option value="--gssapiHostName">gssapiHostName</option>
                                            <option value="--db">db</option>
                                            <option value="--collection">collection</option>
                                            <option value="--fields">fields</option>
                                            <option value="--fieldFile">fieldFile</option>
                                            <option value="--ignoreBlanks">ignoreBlanks</option>
                                            <option value="--type">type</option>
                                            <option value="--file">file</option>
                                            <option value="--drop">drop</option>
                                            <option value="--headerline">headerline</option>
                                            <option value="--mode">mode</option>
                                            <option value="--upsertFields">upsertFields</option>
                                            <option value="--stopOnError">stopOnError</option>
                                            <option value="--jsonArray">jsonArray</option>
                                            <option value="--maintainInsertionOrder">maintainInsertionOrder</option>
                                            <option value="--numInsertionWorkers">numInsertionWorkers</option>
                                            <option value="--writeConcern">writeConcern</option>
                                            <option value="--bypassDocumentValidation">bypassDocumentValidation</option>
                                            <option value="--columnsHaveTypes">columnsHaveTypes</option>
                                            <option value="--parseGrace">parseGrace</option>
                                        </select>

                                {{> mongoimportOptions}}

                                        {{_ "logs"}}

                                            <textarea id="txtMongoimportLogs" class="form-control"></textarea>

                            </form>

                                    <button id="btnExecuteMongoimport"
                                            class="btn btn-block btn-outline btn-primary ladda-button"
                                            type="button"
                                            data-style="contract">
                                        {{_ "execute"}}</button>

    {{/if}}
</template>


text:
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import {Position} from 'codemirror'

// Components
import FluxEditor from 'src/shared/components/FluxEditor'
import Threesizer from 'src/shared/components/threesizer/Threesizer'
import FluxFunctionsToolbar from 'src/timeMachine/components/fluxFunctionsToolbar/FluxFunctionsToolbar'
import VariableToolbar from 'src/timeMachine/components/variableToolbar/VariableToolbar'
import ToolbarTab from 'src/timeMachine/components/ToolbarTab'

// Actions
import {setActiveQueryText} from 'src/timeMachine/actions'
import {saveAndExecuteQueries} from 'src/timeMachine/actions/queries'

// Utils
import {getActiveQuery} from 'src/timeMachine/selectors'
import {insertFluxFunction} from 'src/timeMachine/utils/insertFunction'
import {insertVariable} from 'src/timeMachine/utils/insertVariable'

// Constants
import {HANDLE_VERTICAL, HANDLE_NONE} from 'src/shared/constants'

// Types
import {AppState, FluxToolbarFunction} from 'src/types'

interface StateProps {
  activeQueryText: string
}

interface DispatchProps {
  onSetActiveQueryText: typeof setActiveQueryText
  onSubmitQueries: typeof saveAndExecuteQueries
}

interface State {
  displayFluxFunctions: boolean
}

type Props = StateProps & DispatchProps

class TimeMachineFluxEditor extends PureComponent<Props, State> {
  private cursorPosition: Position = {line: 0, ch: 0}

  public state: State = {
    displayFluxFunctions: true,
  }

  public render() {
    const {activeQueryText, onSubmitQueries, onSetActiveQueryText} = this.props

    const divisions = [
      {
        size: 0.75,
        handleDisplay: HANDLE_NONE,
        render: () => (
          <FluxEditor
            script={activeQueryText}
            status={{type: '', text: ''}}
            onChangeScript={onSetActiveQueryText}
            onSubmitScript={onSubmitQueries}
            suggestions={[]}
            onCursorChange={this.handleCursorPosition}
          />
        ),
      },
      {
        render: () => {
          return (
            <>

                <ToolbarTab
                  onSetActive={this.hideFluxFunctions}
                  name="Variables"
                  active={!this.state.displayFluxFunctions}
                />
                <ToolbarTab
                  onSetActive={this.showFluxFunctions}
                  name="Functions"
                  active={this.state.displayFluxFunctions}
                  testID="functions-toolbar-tab"
                />

              {this.rightDivision}
            </>
          )
        },
        handlePixels: 6,
        size: 0.25,
      },
    ]

    return (

        <Threesizer orientation={HANDLE_VERTICAL} divisions={divisions} />

    )
  }

  private get rightDivision(): JSX.Element {
    const {displayFluxFunctions} = this.state

    if (displayFluxFunctions) {
      return (
        <FluxFunctionsToolbar
          onInsertFluxFunction={this.handleInsertFluxFunction}
        />
      )
    }

    return <VariableToolbar onClickVariable={this.handleInsertVariable} />
  }

  private handleCursorPosition = (position: Position): void => {
    this.cursorPosition = position
  }

  private handleInsertVariable = async (
    variableName: string
  ): Promise<void> => {
    const {activeQueryText} = this.props
    const {line, ch} = this.cursorPosition

    const {updatedScript, cursorPosition} = insertVariable(
      line,
      ch,
      activeQueryText,
      variableName
    )

    await this.props.onSetActiveQueryText(updatedScript)

    this.handleCursorPosition(cursorPosition)
  }

  private handleInsertFluxFunction = async (
    func: FluxToolbarFunction
  ): Promise<void> => {
    const {activeQueryText} = this.props
    const {line} = this.cursorPosition

    const {updatedScript, cursorPosition} = insertFluxFunction(
      line,
      activeQueryText,
      func
    )
    await this.props.onSetActiveQueryText(updatedScript)

    this.handleCursorPosition(cursorPosition)
  }

  private showFluxFunctions = () => {
    this.setState({displayFluxFunctions: true})
  }

  private hideFluxFunctions = () => {
    this.setState({displayFluxFunctions: false})
  }
}

const mstp = (state: AppState) => {
  const activeQueryText = getActiveQuery(state).text

  return {activeQueryText}
}

const mdtp = {
  onSetActiveQueryText: setActiveQueryText,
  onSubmitQueries: saveAndExecuteQueries,
}

export default connect<StateProps, DispatchProps, {}>(
  mstp,
  mdtp
)(TimeMachineFluxEditor)


text:
package fi.csc.microarray.auth;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Random;

import org.junit.Assert;
import org.junit.Test;

import fi.csc.microarray.config.ConfigurationLoader.IllegalConfigurationException;
import fi.csc.microarray.config.DirectoryLayout;

public class LoginTest {

	@Test
	public void expirationTest() throws IOException, IllegalConfigurationException {

		DirectoryLayout.uninitialise();
		DirectoryLayout.initialiseUnitTestLayout();

		String validUsername = "valid";
		String expiredUsername = "expired";
		String password = "password";

		// create test passwd file and map
		File testPasswdFile = File.createTempFile("chipster-passwd-test", null);

		GregorianCalendar tomorrow = new GregorianCalendar();
		tomorrow.set(Calendar.DATE, tomorrow.get(Calendar.DATE) + 1);
		GregorianCalendar yesterday = new GregorianCalendar();
		yesterday.set(Calendar.DATE, yesterday.get(Calendar.DATE) - 1);

		PrintWriter pWriter = new PrintWriter(new BufferedWriter(new FileWriter(testPasswdFile)));
		pWriter.println(validUsername + ":password:" + SimpleFileLoginModule.EXPIRATION_DATE_FORMAT.format(tomorrow.getTime()));
		pWriter.println(expiredUsername + ":password:" + SimpleFileLoginModule.EXPIRATION_DATE_FORMAT.format(yesterday.getTime()));
		pWriter.close();

		File testJaasConfigFile = createTestJaasConfig(testPasswdFile);
		AuthenticationProvider authProvider = createAuthProvider(testJaasConfigFile);

		// test
		Assert.assertTrue(authProvider.authenticate(validUsername, password.toCharArray()));
		Assert.assertFalse(authProvider.authenticate(expiredUsername, password.toCharArray()));
	}

	/**
	 * Utility method for testing users file anomalies.
	 */
	public void manualTest(File usersFileToTest, String username, String password) throws IOException, IllegalConfigurationException {

		DirectoryLayout.initialiseSimpleLayout().getConfiguration();

		File testJaasConfigFile = createTestJaasConfig(usersFileToTest);
		AuthenticationProvider authProvider = createAuthProvider(testJaasConfigFile);

		// test
		Assert.assertTrue(authProvider.authenticate(username, password.toCharArray()));
	}

	private AuthenticationProvider createAuthProvider(File testJaasConfigFile) throws IOException, IllegalConfigurationException {
		DirectoryLayout.uninitialise();
		DirectoryLayout.initialiseSimpleLayout().getConfiguration();
		AuthenticationProvider authProvider = new JaasAuthenticationProvider();
		System.setProperty("java.security.auth.login.config", testJaasConfigFile.getPath());
		return authProvider;
	}

	private File createTestJaasConfig(File testPasswdFile) throws IOException {
		File testJaasConfigFile = File.createTempFile("chipster-jaas-config-test", null);
		PrintWriter jWriter = new PrintWriter(new BufferedWriter(new FileWriter(testJaasConfigFile)));
		jWriter.println("Chipster {");
	    jWriter.print("fi.csc.microarray.auth.SimpleFileLoginModule sufficient passwdFile=\"");
	    jWriter.print(testPasswdFile.getPath());
	    jWriter.println("\";");
	    jWriter.println("};");
		jWriter.close();
		return testJaasConfigFile;
	}

	//@Test(groups = {"stress"} )
	// FIXME JAAS seems not to understand that we try to set up different login configs in expirationTest and stressTest
	// (SimpleFileLoginModule gets wrong users file)
	public void stressLoginTest() throws IOException, IllegalConfigurationException {

		int usernameMaxLength = 5;
		int passwordMaxLength = 5;

		int userCount = 200;
		int bruteCount = 100000;

		// create test passwd file and map
		HashMap<String, String> users = new HashMap<String, String>();
		File testPasswdFile = File.createTempFile("chipster-passwd-test", null);
		PrintWriter pWriter = new PrintWriter(new BufferedWriter(new FileWriter(testPasswdFile)));

		String username;
		String password;
		for (int i = 0; i < userCount; i++) {
			username = getShortRandomString(usernameMaxLength);
			if (users.get(username) == null) {
				password = getShortRandomString(passwordMaxLength);
				users.put(username, password);
				pWriter.println(username + ':' + password + getDescriptionColumn());
			}
		}
		pWriter.close();

		File testJaasConfigFile = createTestJaasConfig(testPasswdFile);
		AuthenticationProvider authProvider = createAuthProvider(testJaasConfigFile);

		// brute force
		int successCount = 0;
		int failCount = 0;
		String bruteUsername;
		String brutePassword;
		String realPassword;

		for (int i = 0; i < bruteCount; i++) {
			bruteUsername = getShortRandomString(usernameMaxLength);
			brutePassword = getShortRandomString(passwordMaxLength);

			// auth successful, check that it really is
			if (authProvider.authenticate(bruteUsername, brutePassword.toCharArray())) {
				realPassword = users.get(bruteUsername);
				Assert.assertNotNull(realPassword);
				Assert.assertEquals(realPassword, brutePassword);
				successCount++;
			}

			// auth failed, check that it really should
			else {
				realPassword = users.get(bruteUsername);
				if (realPassword != null) {
					Assert.assertNotSame(realPassword, brutePassword);
				}
				failCount++;
			}
		}

		System.out.println("successful: " + successCount + ", failed: " + failCount);

	}

	@Test
	public void randomTest() {
		for (int i = 0; i < 100; i++) {
			Assert.assertTrue(getShortRandomString(3).length() <= 3);
		}
	}

	private String getShortRandomString(int maxLength) {

		Random r = new Random();
		String longString = "";
		String result = "";
		int length;
		boolean valid = false;

		while (!valid) {
			longString = randomString();
			length = r.nextInt(10000) % maxLength ;
			result = longString.substring(2, length + 1 + 2);
			if (result.indexOf(':') == -1) {
				valid = true;
			}
		}

		return result;
	}

	private String randomString() {
		Random r = new Random();
		String token = Long.toString(Math.abs(r.nextLong()), 36);
		return token;
	}

	private String getDescriptionColumn() {
		String result = "";
		Random r = new Random();

		int choice = r.nextInt(2345) % 3;
		switch (choice) {
		case 0:
			result = "";
			break;
		case 1:
			result = ":";
			break;
		case 2:
			result = ":" + randomString();
			break;
		}

		return result;
	}
}


text:
'use strict'

module.exports = function (input) {
  return input ? 'show-me' : 'hide-me'
}


text:
"""Clear out matching diffs.

Revision ID: 1cf84ddb034c
Revises: 4d7019b218d4
Create Date: 2013-10-28 08:46:17.516023

"""

# revision identifiers, used by Alembic.
revision = '1cf84ddb034c'
down_revision = '4d7019b218d4'

from alembic import context, op
from collections import defaultdict
from sqlalchemy.sql import and_, table, column
import os
import pickle
import sqlalchemy as sa

file_ = table('file',
              column('id', sa.Integer),
              column('sha1', sa.String),
              column('size', sa.Integer))

testcase = table('testcase',
                 column('id', sa.Integer),
                 column('output_type', sa.Enum('diff', 'image', 'text',
                                               name='output_type')))

testcaseresult = table('testcaseresult',
                       column('diff_id', sa.Integer),
                       column('submission_id', sa.Integer),
                       column('test_case_id', sa.Integer))

def no_diff(sha1, directory):
    path = os.path.join(directory, sha1[:2], sha1[2:4], sha1[4:])
    diff = pickle.load(open(path))
    return diff._diff is None

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    directory = context.config.file_config.get('app:main', 'file_directory')

    conn = op.get_bind()

    # test cases whose results store diffs
    diff_tcs = [tc_id for (tc_id, output) in conn.execute(testcase.select())
                if output == 'diff']

    diff_to_tcrs = defaultdict(list)
    for (diff_id, s_id, tc_id) in conn.execute(
        testcaseresult.select().where(testcaseresult.c.test_case_id
                                      .in_(diff_tcs))):
        if diff_id:
            diff_to_tcrs[diff_id].append({'s_id': s_id, 'tc_id': tc_id})

    # Prune diffs that are not significantly unique
    diff_to_tcrs = {x: y for (x, y) in diff_to_tcrs.items() if len(y) > 64}

    # Find test case results with no diff
    empty_tcrs = []
    for (f_id, sha1, size) in conn.execute(file_.select()
                                           .where(file_.c.id
                                                  .in_(diff_to_tcrs.keys()))):
        if size == 0:
            print('Found unexpected zero byte diff on: {}'
                  .format(diff_to_tcrs[f_id]))
            empty_tcrs.extend(diff_to_tcrs[f_id])
        elif no_diff(sha1, directory):
            empty_tcrs.extend(diff_to_tcrs[f_id])

    if not empty_tcrs:  # Exit early
        return

    # Update diff to None for appropriate TestCaseResults
    conn.execute(testcaseresult.update().where(and_(
                testcaseresult.c.submission_id == sa.bindparam('s_id'),
                testcaseresult.c.test_case_id == sa.bindparam('tc_id')))
               .values(diff_id=None), empty_tcrs)
    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    pass
    ### end Alembic commands ###


text:
<?php

/**
 * Get an Apache subprocess_env variable
 *
 * @phpstub
 *
 * @param string $variable
 * @param bool $walk_to_top
 *
 * @return string The value of the Apache environment variable on success, or false on
 *                failure
 */
function apache_getenv($variable, $walk_to_top = false)
{
}


text:
class AddServiceIdToAppointmentServices < ActiveRecord::Migration[5.0]
  def change
    add_reference :appointment_services, :service, index: true, foreign_key: true
  end
end


text:
@class IOSClass;
@class JavaUtilConcurrentTimeUnitEnum;
@protocol JavaUtilConcurrentCallable;

@protocol ComGoogleCommonUtilConcurrentTimeLimiter < NSObject, JavaObject >

- (id)newProxyWithId:(id)target
        withIOSClass:(IOSClass *)interfaceType
            withLong:(jlong)timeoutDuration
withJavaUtilConcurrentTimeUnitEnum:(JavaUtilConcurrentTimeUnitEnum *)timeoutUnit OBJC_METHOD_FAMILY_NONE;

- (id)callWithTimeoutWithJavaUtilConcurrentCallable:(id<JavaUtilConcurrentCallable>)callable
                                           withLong:(jlong)timeoutDuration
                 withJavaUtilConcurrentTimeUnitEnum:(JavaUtilConcurrentTimeUnitEnum *)timeoutUnit
                                        withBoolean:(jboolean)interruptible;

@end

J2OBJC_EMPTY_STATIC_INIT(ComGoogleCommonUtilConcurrentTimeLimiter)

J2OBJC_TYPE_LITERAL_HEADER(ComGoogleCommonUtilConcurrentTimeLimiter)

#endif

#pragma pop_macro("ComGoogleCommonUtilConcurrentTimeLimiter_INCLUDE_ALL")


text:
/* -*-C++-*-
****************************************************************************
*
* File:         ComTdbFirstN.h
* Description:
*
* Created:      5/2/2003
* Language:     C++
*
*
*
*
****************************************************************************
*/

#ifndef COM_FIRSTN_H
#define COM_FIRSTN_H

#include "ComTdb.h"

class ComTdbFirstN : public ComTdb
{
  friend class ExFirstNTcb;

public:

  ComTdbFirstN();

  ComTdbFirstN(
      ComTdb * child_tdb,
      Int64 firstNRows,
      ex_expr * firstNRowsExpr,
      ex_cri_desc *workCriDesc,
      ex_cri_desc * givenCriDesc,
      ex_cri_desc * returnedCriDesc,
      queue_index down,
      queue_index up,
      Lng32 numBuffers,
      ULng32 bufferSize);

  ~ComTdbFirstN();

  Int32 orderedQueueProtocol() const
  {
    return -1;
  };

  ComTdb * getChildTdb(){return tdbChild_;};

  // ---------------------------------------------------------------------
  // Redefine virtual functions required for Versioning.
  //----------------------------------------------------------------------
  virtual unsigned char getClassVersionID()
  {
    return 1;
  }

  virtual void populateImageVersionIDArray()
  {
    setImageVersionID(1,getClassVersionID());
    ComTdb::populateImageVersionIDArray();
  }

  virtual short getClassSize()
  { return (short)sizeof(ComTdbFirstN); }

  virtual Long pack (void *);
  virtual Lng32 unpack(void *, void * reallocator);

  void display() const;

  virtual const ComTdb* getChild(Int32 pos) const
  {
    if (pos == 0)
      return tdbChild_.getPointer();
    else
      return NULL;
  }

  virtual Int32 numChildren() const { return 1; }
  virtual const char *getNodeName() const { return "EX_FIRSTN"; };
  virtual Int32 numExpressions() const { return 1; };
  virtual ex_expr* getExpressionNode(Int32 pos) { return firstNRowsExpr_; };
  virtual const char * getExpressionName(Int32 pos) const { return "firstNRowsExpr"; };

  // ---------------------------------------------------------------------
  // Used by the internal SHOWPLAN command to get attributes of a TDB.
  // ---------------------------------------------------------------------
  virtual void displayContents(Space *space,ULng32 flag);

  Int64 firstNRows() { return firstNRows_; }
protected:

  Int64 firstNRows_;                // 00-07
  ComTdbPtr tdbChild_;              // 08-15
  ExExprPtr firstNRowsExpr_;      // 16-23
  ExCriDescPtr workCriDesc_;       // 24-31
  char filler0ComTdbFirstN_[32];    // 32-63  unused
};

#endif


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

namespace Level14.BoardGameRules.Expressions
{
    class ConstIntExpr: Expression
    {
        int i;

        public ConstIntExpr(int i)
        {
            this.i = i;
        }

        public override object Eval(GameState state, IReadContext c)
        {
            // LIT_INT must not depend on state and context
            return i;
        }

        static ConstIntExpr()
        {
            Expression.RegisterParser("LIT_INT", tree =>
            {
                int i = int.Parse(tree.GetOnlyChild().Text);
                return new ConstIntExpr(i);
            });
        }

        public override string ToString()
        {
            return i.ToString();
        }
    }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<TITLE>Q Light Controller Plus Plus Documentation</TITLE>

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

Audio Input/Output device selection

This page describes how to select an input or output audio device
to be used inside QLC+.

To access the Input/Output Manager, just click on the tab with the  icon
placed on the bottom of the QLC+ main screen.

Select the desired universe on the left hand side of the screen and then click the
Audio tab placed beside the Profile tab on the top right hand side of the screen.

The list of audio devices detected by QLC+ is displayed. Each device has a checkbox
depending on if it supports input capture or audio output capabilities.

The first entry of the list is always "Default device", and it is selected as input
and output by default. In this way QLC+ will work in most of the cases out of the box.

The default device is the one that you currently use to listen
to music or to record audio with a microphone.

If in your system there are additional audio cards (PCI or USB), it is possible
to select them in this panel as the preferred QLC+ input or output device.

Basically an input device is used by Virtual Console Audio Triggers
while an output device is used by audio functions.

The selection of an audio input/output line should take immediate effect in QLC+. If not
you are invited to restart QLC+ to allow a complete initialization of the internal audio engine.