Ejemplo n.º 1
0
        public PanelAdmin(List <StatisticCommon.TEC> tec, FormChangeMode.MANAGER type)
        {
            preInitialize(type);

            //Для установки типов соединения (оптимизация кол-ва соединений с БД)
            HMark markQueries = new HMark();

            markQueries.Marked((int)CONN_SETT_TYPE.ADMIN);
            markQueries.Marked((int)CONN_SETT_TYPE.PBR);

            try { m_admin.InitTEC(tec, markQueries); }
            catch (Exception e)
            {
                Logging.Logg().Exception(e, Logging.INDEX_MESSAGE.NOT_SET, "PanelAdmin::Initialize () - m_admin.InitTEC ()...");
            }

            if (!(m_admin.m_list_tec.Count > 0))
            {
                Logging.Logg().Error(@"PanelAdmin::PanelAdmin () - список ТЭЦ пуст...", Logging.INDEX_MESSAGE.NOT_SET);
            }
            else
            {
                ;
            }

            initialize();
        }
Ejemplo n.º 2
0
        public void InitTEC(List <StatisticCommon.TEC> listTEC)
        {
            m_listTecView = new List <TecView> ();

            HMark markQueries = new HMark();

            markQueries.Marked((int)CONN_SETT_TYPE.ADMIN);
            markQueries.Marked((int)CONN_SETT_TYPE.PBR);
            markQueries.Marked((int)CONN_SETT_TYPE.DATA_AISKUE);
            markQueries.Marked((int)CONN_SETT_TYPE.DATA_SOTIASSO);
            //markQueries.Marked((int)CONN_SETT_TYPE.DATA_SOTIASSO_3_MIN);
            //markQueries.Marked((int)CONN_SETT_TYPE.DATA_SOTIASSO_1_MIN);

            //Отладка ???!!!
            int DEBUG_ID_TEC = -1;

            foreach (StatisticCommon.TEC t in listTEC)
            {
                if ((DEBUG_ID_TEC == -1) || (DEBUG_ID_TEC == t.m_id))
                {
                    m_listTecView.Add(new TecView(TecView.TYPE_PANEL.ADMIN_ALARM, -1, -1));
                    m_listTecView [m_listTecView.Count - 1].InitTEC(new List <StatisticCommon.TEC> {
                        t
                    }, markQueries);
                    m_listTecView[m_listTecView.Count - 1].updateGUI_Fact = new IntDelegateIntIntFunc(m_listTecView[m_listTecView.Count - 1].SuccessThreadRDGValues);
                    m_listTecView[m_listTecView.Count - 1].EventReg      += new TecView.DelegateOnEventReg(OnAdminAlarm_EventReg);

                    m_listTecView[m_listTecView.Count - 1].m_arTypeSourceData[(int)TG.ID_TIME.MINUTES] = CONN_SETT_TYPE.DATA_SOTIASSO;
                    m_listTecView[m_listTecView.Count - 1].m_arTypeSourceData[(int)TG.ID_TIME.HOURS]   = CONN_SETT_TYPE.DATA_SOTIASSO;

                    m_listTecView[m_listTecView.Count - 1].m_bLastValue_TM_Gen = true;

                    EventConfirm += m_listTecView[m_listTecView.Count - 1].OnEventConfirm;
                }
                else
                {
                    ;
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Перегруженный метод, принимающий индекс источника информации
        /// </summary>
        /// <param name="indx">Индекс-таг-идентификатор типа источника данных для отображения</param>
        private void rbtnSourceData_Click(CONN_SETT_TYPE indx)
        {
            if (m_arRbtnSourceData [(int)indx].Checked == false)
            {
                m_markSourceData.UnMarked();
                m_markSourceData.Marked((int)indx);

                rbtnSourceData_Click();
            }
            else
            {
                ;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Открытый пользовательский конструктор FormGraphicsSettings инициализирует поля m_formMain, delegateUpdateActiveGui, delegateHideGraphicsSettings
        /// </summary>
        /// <param name="form">Родительская форма - главное окно приложения</param>
        /// <param name="fUpdate">Метод для применения изменений</param>
        /// <param name="fHide">Метод снятия с отображения диалогового окна</param>
        /// <param name="bAllowedChangeShema">Признак(настраиваемый из БД) разрешения изменять цветовую схему</param>
        public FormGraphicsSettings(DelegateIntFunc fUpdate, DelegateFunc fHide, bool bAllowedChangeShema)
        {
            // инициализация полей заданными пользователем значениями
            delegateUpdateActiveGui      = fUpdate;
            delegateHideGraphicsSettings = fHide;
            _allowedChangeShema          = bAllowedChangeShema;
            //масштабирование выключено по умолчанию
            scale = false;
            // полю m_markSourceData присваиваем ссылку на экземпляр класса HMark, вызываем конструктор HMark с одним параметром, передаем 0
            m_markSourceData = new HMark(0);

            InitializeComponent();

            bool           bGroupBoxSourceData   = false;                                               //переменной bGroupBoxSourceData присваиваем false
            CONN_SETT_TYPE cstGroupBoxSourceData = CONN_SETT_TYPE.AISKUE_3_MIN;                         //переменной cstGroupBoxSourceData присваиваем константу=1 (AISKUE_3_MIN)

            //Проверка условия прав доступа к возможности смены источника данных
            if (HStatisticUsers.IsAllowed((int)HStatisticUsers.ID_ALLOWED.SOURCEDATA_CHANGED) == true)
            //if (m_formMain.m_users.IsAllowed(HStatisticUsers.ID_ALLOWED.SOURCEDATA_CHANGED) == true)
            //if ((HStatisticUsers.RoleIsAdmin == true) || (HStatisticUsers.RoleIsKomDisp == true))
            {
                bGroupBoxSourceData   = true;                      //переменной bGroupBoxSourceData присваиваем true (групповой источник данных)
                cstGroupBoxSourceData = CONN_SETT_TYPE.COSTUMIZE;  //переменной cstGroupBoxSourceData присваиваем константу=4 (по умолчанию установлен COSTUMIZE)

                //кнопки АИСКУЭ+СОТИАССО и СОТИАССО(3 мин) становятся активными (да вроде все активные..?)
                m_arRbtnSourceData [(int)CONN_SETT_TYPE.AISKUE_PLUS_SOTIASSO].Enabled = HStatisticUsers.IsAllowed((int)HStatisticUsers.ID_ALLOWED.SOURCEDATA_ASKUE_PLUS_SOTIASSO);
                m_arRbtnSourceData [(int)CONN_SETT_TYPE.SOTIASSO_3_MIN].Enabled       = HStatisticUsers.IsAllowed((int)HStatisticUsers.ID_ALLOWED.SOURCEDATA_SOTIASSO_3_MIN);
            }
            else
            {
                ;
            }

            this.gbxSourceData.Enabled = bGroupBoxSourceData;       //??
            m_markSourceData.Marked((int)cstGroupBoxSourceData);

            checkedSourceData();           // вызов метода проверки источника данных

            m_graphTypes = GraphTypes.Bar; // тип графика-Гистограмма по умолчанию
        }
Ejemplo n.º 5
0
        public FormGraphicsSettings(FormMain fm, DelegateIntFunc delUp, DelegateFunc Hide)
        {
            InitializeComponent();

            delegateUpdateActiveGui      = delUp;
            delegateHideGraphicsSettings = Hide;
            m_formMain = fm;

            scale            = false;
            m_markSourceData = new HMark(0);

            bool           bGroupBoxSourceData   = false;
            CONN_SETT_TYPE cstGroupBoxSourceData = CONN_SETT_TYPE.AISKUE_3_MIN;

            //Проверка условия прав доступа к возможности смены источника данных
            if (HStatisticUsers.IsAllowed((int)HStatisticUsers.ID_ALLOWED.SOURCEDATA_CHANGED) == true)
            //if (m_formMain.m_users.IsAllowed(HStatisticUsers.ID_ALLOWED.SOURCEDATA_CHANGED) == true)
            //if ((HStatisticUsers.RoleIsAdmin == true) || (HStatisticUsers.RoleIsKomDisp == true))
            {
                bGroupBoxSourceData   = true;
                cstGroupBoxSourceData = CONN_SETT_TYPE.COSTUMIZE;

                m_arRadioButtonSourceData[(int)CONN_SETT_TYPE.AISKUE_PLUS_SOTIASSO].Enabled = HStatisticUsers.IsAllowed((int)HStatisticUsers.ID_ALLOWED.SOURCEDATA_ASKUE_PLUS_SOTIASSO);
                m_arRadioButtonSourceData[(int)CONN_SETT_TYPE.SOTIASSO_3_MIN].Enabled       = HStatisticUsers.IsAllowed((int)HStatisticUsers.ID_ALLOWED.SOURCEDATA_SOTIASSO_3_MIN);
            }
            else
            {
                ;
            }

            this.groupBoxSourceData.Enabled = bGroupBoxSourceData;
            m_markSourceData.Marked((int)cstGroupBoxSourceData);

            checkedSourceData();

            m_graphTypes = GraphTypes.Bar; //Гистограмма
        }
Ejemplo n.º 6
0
        protected override void Start()
        {
            int i = -1;

            CreateFormConnectionSettings("connsett_tg.ini", true);

            int    iConfigDB       = -1;
            string keyTypeConfigDB = @"ТипБДКфгНазначение";

            //FileINI fileINI = new FileINI(@"setup.ini");
            //string sec = "Main (" + ProgramBase.AppName + ")";
            iConfigDB = Int32.Parse(m_sFileINI.GetMainValueOfKey(keyTypeConfigDB));

            TYPE_DATABASE_CFG iTypeConfigDB = TYPE_DATABASE_CFG.UNKNOWN;

            for (TYPE_DATABASE_CFG t = TYPE_DATABASE_CFG.CFG_190; t < TYPE_DATABASE_CFG.UNKNOWN; t++)
            {
                if (t.ToString().Contains(iConfigDB.ToString()) == true)
                {
                    iTypeConfigDB = t;
                    break;
                }
                else
                {
                    ;
                }
            }

            bool bIgnoreTECInUse = false;

            HMark markQueries = new HMark();

            markQueries.Marked((int)StatisticCommon.CONN_SETT_TYPE.ADMIN);
            markQueries.Marked((int)StatisticCommon.CONN_SETT_TYPE.PBR);

            int idListener = DbSources.Sources().Register(s_listFormConnectionSettings[(int)StatisticCommon.CONN_SETT_TYPE.CONFIG_DB].getConnSett(), false, @"CONFIG_DB");

            for (i = 0; i < (Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE; i++)
            {
                if (i == (Int16)CONN_SETT_TYPE.SOURCE)
                {
                    m_arAdmin[i] = new AdminTransTG(new bool [] { false, false });
                }
                else
                if (i == (Int16)CONN_SETT_TYPE.DEST)
                {
                    m_arAdmin[i] = new AdminTransTG(new bool[] { false, true });
                }
                else
                {
                    ;
                }

                try {
                    ((AdminTS)m_arAdmin[i]).InitTEC(idListener, FormChangeMode.MODE_TECCOMPONENT.UNKNOWN, iTypeConfigDB, markQueries, bIgnoreTECInUse);
                    RemoveTEC(m_arAdmin[i]);
                }
                catch (Exception e)
                {
                    Logging.Logg().Exception(e, Logging.INDEX_MESSAGE.NOT_SET, "FormMainTransTG::FormMainTransTG ()");
                    //ErrorReport("Ошибка соединения. Перехож в ожидание.");
                    //setUIControlConnectionSettings(i);
                    break;
                }
                //((AdminTS)m_arAdmin[i]).connSettConfigDB = m_formConnectionSettings.getConnSett();
                ((AdminTS)m_arAdmin[i]).m_typeFields = AdminTS.TYPE_FIELDS.DYNAMIC;
                if (i == (Int16)CONN_SETT_TYPE.SOURCE)
                {
                    m_arAdmin[i].m_ignore_date = false;
                }
                else
                if (i == (Int16)CONN_SETT_TYPE.DEST)
                {
                    m_arAdmin[i].m_ignore_date = true;
                }
                else
                {
                    ;
                }

                //m_arAdmin[i].m_ignore_connsett_data = true; //-> в конструктор
            }

            DbSources.Sources().UnRegister(idListener);

            if (!(i < (Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE))
            {
                setUIControlConnectionSettings((Int16)CONN_SETT_TYPE.DEST);

                for (i = 0; i < (Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE; i++)
                {
                    m_arAdmin[i].SetDelegateWait(delegateStartWait, delegateStopWait, delegateEvent);
                    //m_arAdmin[i].SetDelegateWait(new DelegateFunc(StartWait), new DelegateFunc(StopWait), delegateEvent);
                    m_arAdmin[i].SetDelegateReport(ErrorReport, WarningReport, ActionReport, ReportClear);

                    m_arAdmin[i].SetDelegateData(setDataGridViewAdmin, errorDataGridViewAdmin);
                    m_arAdmin[i].SetDelegateSaveComplete(saveDataGridViewAdminComplete);

                    m_arAdmin[i].SetDelegateDatetime(setDatetimePicker);

                    //m_arAdmin [i].mode (FormChangeMode.MODE_TECCOMPONENT.GTP);

                    m_arAdmin[i].Start();
                }

                /*
                 * // This needs to be declared in a place where it will not go out of scope.
                 * // For example, it would be a class variable in a form class.
                 * System.IO.FileSystemWatcher watcher = new System.IO.FileSystemWatcher();
                 * // This code would go in one of the initialization methods of the class.
                 * watcher.Path = "c:\\";
                 * // Watch only for changes to *.txt files.
                 * watcher.Filter = "*.txt";
                 * watcher.IncludeSubdirectories = false;
                 * // Enable the component to begin watching for changes.
                 * watcher.EnableRaisingEvents = true;
                 * // Filter for Last Write changes.
                 * watcher.NotifyFilter = System.IO.NotifyFilters.LastWrite;
                 * // Example of watching more than one type of change.
                 * watcher.NotifyFilter = System.IO.NotifyFilters.LastWrite | System.IO.NotifyFilters.Size;
                 *
                 * //Асинхронно
                 * watcher.Changed += new System.IO.FileSystemEventHandler(this.watcher_Changed);
                 *
                 * //Сихронно
                 * watcher.WaitForChanged(System.IO.WatcherChangeTypes.All);
                 */

                //panelMain.Visible = false;

                start();
            }
            else
            {
                ;
            }
        }
Ejemplo n.º 7
0
        //SortedList<DateTime, OneField> HourlyFieldValues;

        /// <summary>
        /// Конструктор открывает коннект к базе. Закрывает деструктор.
        /// </summary>
        public MySQLtechsite(bool bCalculatedHalfHourValues)
        {
            int iRes = -1;

            m_bCalculatedHalfHourValues = bCalculatedHalfHourValues;

            int iConfigDB = -1;
            ConnectionSettings connSett = Program.ReadConnSettFromFileINI(out iConfigDB);

            connSett.id = ConnectionSettings.UN_ENUMERABLE_ID;

            Console.WriteLine("DB parametrs: IP=" + connSett.server + ", port=" + connSett.port + ", DBName=" + connSett.dbName + ", UID=" + connSett.userName + Environment.NewLine);

            //Соединение дл я БД конфигурации
            m_idListener = DbSources.Sources().Register(connSett, false, @"CONFIG_DB");
            m_connection = DbSources.Sources().GetConnection(m_idListener, out iRes);

            TYPE_DATABASE_CFG typeConfigDB = TYPE_DATABASE_CFG.UNKNOWN;

            for (TYPE_DATABASE_CFG t = TYPE_DATABASE_CFG.CFG_190; t < TYPE_DATABASE_CFG.UNKNOWN; t++)
            {
                if (t.ToString().Contains(iConfigDB.ToString()) == true)
                {
                    typeConfigDB = t;
                    break;
                }
                else
                {
                    ;
                }
            }

            if (iRes == 0)
            {
                m_admin = new AdminTS(new bool [] { false, true });

                HMark markQueries = new HMark();
                markQueries.Marked((int)StatisticCommon.CONN_SETT_TYPE.ADMIN);
                markQueries.Marked((int)StatisticCommon.CONN_SETT_TYPE.PBR);

                m_admin.InitTEC(m_idListener, FormChangeMode.MODE_TECCOMPONENT.GTP, typeConfigDB, markQueries, true);
                m_listIndexTECComponent = m_admin.GetListIndexTECComponent(FormChangeMode.MODE_TECCOMPONENT.GTP);

                m_listIdMCTECComponent = new List <int>();

                int i = -1, j = -1;
                for (i = 0; i < m_listIndexTECComponent.Count; i++)
                {
                    for (j = 0; j < m_admin.allTECComponents[m_listIndexTECComponent[i]].m_listMCentreId.Count; j++)
                    {
                        m_listIdMCTECComponent.Add(m_admin.allTECComponents[m_listIndexTECComponent[i]].m_listMCentreId[j]);
                    }
                }

                //Пересоединение для таблиц ПБР
                if ((DbTSQLInterface.IsConnected(ref m_connection) == true) && (m_listIdMCTECComponent.Count > 0))
                {
                    DbSources.Sources().UnRegister(m_idListener);

                    m_idListener       = DbSources.Sources().Register(m_admin.allTECComponents[m_listIndexTECComponent[0]].tec.connSetts[(int)StatisticCommon.CONN_SETT_TYPE.PBR], false, @"PBR");
                    m_connection       = DbSources.Sources().GetConnection(m_idListener, out iRes);
                    m_strTableNamePPBR = m_admin.allTECComponents[m_listIndexTECComponent[0]].tec.m_arNameTableUsedPPBRvsPBR[(int)AdminTS.TYPE_FIELDS.STATIC];
                }
                else
                {
                }
            }
            else
            {
                ;
            }

            {
                //itssAUX.PrintErrorMessage("Ошибка! MySQLtechsite::MySQLtechsite () - чтение файла с шифрованными параметрами соединения (" + m_strFileNameConnSett + ")...");
                itssAUX.PrintErrorMessage("Проверте параметры соединения (" + Program.m_fileINI.m_NameFileINI + "). Затем запустите программу с аргументом /setmysqlpassword..." + Environment.NewLine);
            }
        }
Ejemplo n.º 8
0
        protected override void Start()
        {
            int i = -1;

            CreateFormConnectionSettings("connsett_mt.ini", true);

            m_sFileINI.AddMainPar(@"ТипБДКфгИсточник", @"200");
            m_sFileINI.AddMainPar(@"ИгнорДатаВремя-ModesTerminale", false.ToString());

            int[]    arConfigDB        = new int[(Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE];
            string[] arKeyTypeConfigDB = new string[(Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE] {
                @"ТипБДКфгИсточник", @"ТипБДКфгНазначение"
            };

            TYPE_DATABASE_CFG[] arTypeConfigDB = new TYPE_DATABASE_CFG[(Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE] {
                TYPE_DATABASE_CFG.UNKNOWN, TYPE_DATABASE_CFG.UNKNOWN
            };
            for (i = 0; i < (Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE; i++)
            {
                arConfigDB[i] = Int32.Parse(m_sFileINI.GetMainValueOfKey(arKeyTypeConfigDB[i]));
                for (TYPE_DATABASE_CFG t = TYPE_DATABASE_CFG.CFG_190; t < TYPE_DATABASE_CFG.UNKNOWN; t++)
                {
                    if (t.ToString().Contains(arConfigDB[i].ToString()) == true)
                    {
                        arTypeConfigDB[i] = t;
                        break;
                    }
                    else
                    {
                        ;
                    }
                }
            }

            bool   bIgnoreTECInUse = false;
            string strTypeField    = m_sFileINI.GetMainValueOfKey(@"РДГФорматТаблицаНазначение");
            int    idListener      = -1;

            HMark markQueries = new HMark();

            markQueries.Marked((int)StatisticCommon.CONN_SETT_TYPE.ADMIN);
            markQueries.Marked((int)StatisticCommon.CONN_SETT_TYPE.PBR);
            markQueries.Marked((int)StatisticCommon.CONN_SETT_TYPE.MTERM);

            for (i = 0; i < (Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE; i++)
            {
                idListener = DbMCSources.Sources().Register(s_listFormConnectionSettings[(int)StatisticCommon.CONN_SETT_TYPE.CONFIG_DB].getConnSett(i), false, @"CONFIG_DB");

                if (!(idListener < 0))
                {
                    switch (i)
                    {
                    case (Int16)CONN_SETT_TYPE.SOURCE:
                        m_arAdmin[i] = new AdminMT();
                        break;

                    case (Int16)CONN_SETT_TYPE.DEST:
                        m_arAdmin[i] = new AdminTS_Modes(new bool[] { false, true });
                        break;

                    default:
                        break;
                    }
                    try
                    {
                        m_arAdmin[i].InitTEC(idListener, m_modeTECComponent, arTypeConfigDB [i], markQueries, bIgnoreTECInUse);
                        RemoveTEC(m_arAdmin[i]);
                    }
                    catch (Exception e)
                    {
                        Logging.Logg().Exception(e, Logging.INDEX_MESSAGE.NOT_SET, "FormMainTransMT::FormMainTransMT ()");
                        //ErrorReport("Ошибка соединения. Переход в ожидание.");
                        //setUIControlConnectionSettings(i);
                        break;
                    }
                    switch (i)
                    {
                    case (Int16)CONN_SETT_TYPE.SOURCE:
                        m_arAdmin[i].m_ignore_date = bool.Parse(m_sFileINI.GetMainValueOfKey(@"ИгнорДатаВремя-ModesTerminale"));
                        break;

                    case (Int16)CONN_SETT_TYPE.DEST:
                        if (strTypeField.Equals(AdminTS.TYPE_FIELDS.DYNAMIC.ToString()) == true)
                        {
                            ((AdminTS)m_arAdmin[i]).m_typeFields = AdminTS.TYPE_FIELDS.DYNAMIC;
                        }
                        else if (strTypeField.Equals(AdminTS.TYPE_FIELDS.STATIC.ToString()) == true)
                        {
                            ((AdminTS)m_arAdmin[i]).m_typeFields = AdminTS.TYPE_FIELDS.STATIC;
                        }
                        else
                        {
                            ;
                        }
                        m_arAdmin[i].m_ignore_date = bool.Parse(m_sFileINI.GetMainValueOfKey(@"ИгнорДатаВремя-techsite"));
                        break;

                    default:
                        break;
                    }

                    //m_arAdmin[i].m_ignore_connsett_data = true; //-> в конструктор

                    DbMCSources.Sources().UnRegister(idListener);
                }
                else
                {
                    ;
                }
            }

            if (!(i < (Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE))
            {
                setUIControlConnectionSettings((Int16)CONN_SETT_TYPE.DEST);

                for (i = 0; i < (Int16)CONN_SETT_TYPE.COUNT_CONN_SETT_TYPE; i++)
                {
                    //setUIControlConnectionSettings(i); //??? Перенос ДО цикла

                    m_arAdmin[i].SetDelegateWait(delegateStartWait, delegateStopWait, delegateEvent);
                    //m_arAdmin[i].SetDelegateWait(new DelegateFunc(StartWait), new DelegateFunc(StopWait), delegateEvent);
                    m_arAdmin[i].SetDelegateReport(ErrorReport, WarningReport, ActionReport, ReportClear);

                    m_arAdmin[i].SetDelegateData(setDataGridViewAdmin, errorDataGridViewAdmin);
                    m_arAdmin[i].SetDelegateSaveComplete(saveDataGridViewAdminComplete);

                    m_arAdmin[i].SetDelegateDatetime(setDatetimePicker);

                    //m_arAdmin [i].mode (FormChangeMode.MODE_TECCOMPONENT.GTP);

                    //??? Перенос ПОСЛЕ цикла
                    //if (i == (int)(Int16)CONN_SETT_TYPE.DEST)
                    //    (Int16)CONN_SETT_TYPE.DEST
                    m_arAdmin[i].Start();
                    //else
                    //    ;
                }

                //Перенес обратно...
                //((AdminTS)m_arAdmin[(Int16)CONN_SETT_TYPE.DEST]).StartDbInterface();

                //panelMain.Visible = false;

                base.Start();
            }
            else
            {
                ;
            }
        }