internal static Expression GetExpressionInternal(this QueryParameters qParams, string parameterKey, object value, Type typeExpression) { if (qParams == null) { return(Expression.Constant(value, typeExpression)); } if (!qParams.SupportParameterExpression || qParams.ParametersValues.Count >= 20) { RegisterParameterName(qParams, parameterKey, value); return(Expression.Constant(value, typeExpression)); } var ending = LinqFilterGenerator.IsNullableType(typeExpression) ? typeExpression.GetGenericArguments()[0].Name + "N" : typeExpression.Name; if (TypeDescriptor.GetProperties(typeof(StructQueryParameters.Item)).Find(ending, false) == null) { RegisterParameterName(qParams, parameterKey, value); return(Expression.Constant(value, typeExpression)); } qParams.ParametersNames.Add(parameterKey); qParams.ParametersValues.Add(value); var index = qParams.ParametersValues.Count - 1; var valueExp = Expression.Property(qParams.ParameterExpression, "Parameter" + index); return(Expression.Property(valueExp, ending)); }
internal static IDictionary <string, IList> GetForPublicationStrings(Dictionary <string, List <FilterItem> > filterValues, IEnumerable <FilterHtmlGenerator.Filter> allFilters) { var filters = new Dictionary <string, IList>(); foreach (var filter in allFilters) { if (string.IsNullOrEmpty(filter.FilterName)) { continue; } var filterName = LinqFilterGenerator.GetFilterName(filter.FilterName); var filterItemValues = filterValues.ContainsKey(filter.FilterName) ? filterValues[filter.FilterName] : (filterValues.ContainsKey(filterName) ? filterValues[filterName] : null); if (filterItemValues == null) { continue; } foreach (var filterItem in filterItemValues) { if ("Non".Equals(filterItem.FilterType)) { continue; } var values = filter.GetListValuesString(filterItem).Cast <object>().ToList(); if (values.Count > 0) { if (!filters.ContainsKey(filterName)) { filters[filterName] = values; } else { var list = filters[filterName] as List <List <object> >; if (list != null) { list.Add(values); } else { var previousList = (List <object>)filters[filterName]; list = new List <List <object> > { previousList, values }; filters[filterName] = list; } } } } } return(filters); }
public virtual List <FilterItem> GetFilterValuesByName(string filterName) { var filterValues = GetFilterValues(); if (filterValues.ContainsKey(filterName) && filterValues[filterName].Count > 0) { return(filterValues[filterName]); } var originalFilterName = LinqFilterGenerator.GetFilterName(filterName); if (filterValues.ContainsKey(originalFilterName) && filterValues[originalFilterName].Count > 0) { return(filterValues[originalFilterName]); } return(null); }
public static List <string> GetFilterStrings(Dictionary <string, List <FilterItem> > filterValues, IEnumerable <FilterHtmlGenerator.Filter> allFilters) { var filters = new List <string>(); foreach (var filter in allFilters) { if (string.IsNullOrEmpty(filter.FilterName) || !filter.Visible) { continue; } var filterName = LinqFilterGenerator.GetFilterName(filter.FilterName); var filterItemValues = filterValues.ContainsKey(filter.FilterName) ? filterValues[filter.FilterName] : (filterValues.ContainsKey(filterName) ? filterValues[filterName] : null); if (filterItemValues == null) { continue; } foreach (var filterItem in filterItemValues) { if ("Non".Equals(filterItem.FilterType)) { continue; } var values = filter.GetValuesString(filterItem).ToList(); if (values.Count == 2) { filters.Add(filter.Header + " " + values[0] + " " + values[1]); } else if (values.Count > 0) { filters.Add(filter.Header + " " + values[0]); if (values.Count > 1) { filters.AddRange(values.Skip(1).Select(r => " " + r)); } } } } return(filters); }
/// <summary> /// Сортировка данных на стороне SQL сервера. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="data"></param> /// <param name="columns"></param> /// <param name="sort"></param> /// <returns></returns> public static IQueryable <T> SortBy <T>(this IQueryable <T> data, BaseGridColumns columns, ICollection <DataSorter> sort) where T : class { var dictionary = columns.Columns.OfType <GridColumn>().ToDictionary(r => r.ColumnNameIndex); var sortExpression = string.Join( ",", sort .Where(r => dictionary.ContainsKey(r.Property) && !string.IsNullOrEmpty(dictionary[r.Property].Sort)) .Select(r => dictionary[r.Property].Sort + (r.Direction == SortDirection.DESC ? " desc" : string.Empty))); if (string.IsNullOrEmpty(sortExpression)) { return(data); } return(LinqFilterGenerator.OrderBy(data, sortExpression)); }
public static IDictionary <string, List <string> > GetDictionaryFilterStrings(Dictionary <string, List <FilterItem> > filterValues, IEnumerable <FilterHtmlGenerator.Filter> allFilters) { var filters = new Dictionary <string, List <string> >(); foreach (var filter in allFilters) { if (string.IsNullOrEmpty(filter.FilterName)) { continue; } var filterName = LinqFilterGenerator.GetFilterName(filter.FilterName); var filterItemValues = filterValues.ContainsKey(filter.FilterName) ? filterValues[filter.FilterName] : (filterValues.ContainsKey(filterName) ? filterValues[filterName] : null); if (filterItemValues == null) { continue; } foreach (var filterItem in filterItemValues) { if ("Non".Equals(filterItem.FilterType)) { continue; } var values = filter.GetValuesString(filterItem).ToList(); if (values.Count > 0) { if (!filters.ContainsKey(filterName)) { filters[filterName] = new List <string>(); } filters[filterName].AddRange(values); } } } return(filters); }
protected override void FilterInitialize() { if (_filterInitialized) { return; } _filterInitialized = true; _filters = (IList <Filter>)HttpContext.Current.Items["DIC_MySecondDictionary.FiltersCache"]; if (Page == null && _filters != null) { _filterHandlers = _filters. Union(_filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); return; } BrowseFilterParameters parameters; IList <Filter> filters = new List <Filter>(); var stack = new Stack <IList <Filter> >(); _filters = filters; Filter current; BaseFilterParameter currentBF = null; //колонка 'Name' current = currentBF = new BaseFilterParameterString <DIC_MySecondDictionary>(r => r.Name) { FilterName = "Name", Header = DIC_MySecondDictionaryResources.Name__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Text, MaxLength = 255, Width = "98%", }; currentBF.AddFilter(filters); //filters.Add(current); parameters = new BrowseFilterParameters(); GetBrowseFilterParameters_refFirstDictionary(parameters); //колонка 'First Dictionary Value' current = currentBF = new BaseFilterParameter <DIC_MySecondDictionary, Int64>(r => r.refFirstDictionary, r => r.DIC_MyFirstDictionary_refFirstDictionary.Name, r => r.DIC_MyFirstDictionary_refFirstDictionary.Name) { FilterName = "refFirstDictionary", Header = DIC_MySecondDictionaryResources.refFirstDictionary__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Reference, ProjectName = "SampleDictionaries", TableName = "DIC_MyFirstDictionary", Lookup = true, MinimumPrefixLength = 1, Width = "98%", SelectMode = "none", IsMultipleSelect = true, BrowseFilterParameters = parameters, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Decimal Value' current = currentBF = new BaseFilterParameter <DIC_MySecondDictionary, Decimal>(r => r.DecimalValue) { FilterName = "DecimalValue", Header = DIC_MySecondDictionaryResources.DecimalValue__Header, IsJournalFilter = true, Mandatory = false, Type = FilterHtmlGenerator.FilterType.Numeric, DecimalPrecision = 2, MaxLength = 11, Columns = 11, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Boolean Value' current = currentBF = new BaseFilterParameter <DIC_MySecondDictionary, Boolean>(r => r.BoolValue) { FilterName = "BoolValue", Header = DIC_MySecondDictionaryResources.BoolValue__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Boolean, TrueBooleanText = DIC_MySecondDictionaryResources.BoolValue__TrueText, FalseBooleanText = DIC_MySecondDictionaryResources.BoolValue__FalseText, }; currentBF.AddFilter(filters); //filters.Add(current); if (Url.IsMultipleSelect) { current = new Filter { FilterName = MultipleSelectedValues, Header = TableResources.MultipleSelectedFilterHeader, Type = FilterHtmlGenerator.FilterType.Boolean, TrueBooleanText = TableResources.MultipleSelectedFilterSelected, FalseBooleanText = TableResources.MultipleSelectedFilterNotSelected, Mandatory = true, FilterHandler = delegate(IQueryable enumerable, Enum type, string value1, string value2) { throw new Exception("Is not actual delegate"); }, }; filters.Add(current); } AddSearchFilter(filters); SetDefaultFilterType(filters); FilterInitialize(filters); if (CustomFilter != null && !_customFiltersInitialized) { _customFiltersInitialized = true; InitializeCustomFilters(filters); } _filterHandlers = filters. Union(filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); HttpContext.Current.Items["DIC_MySecondDictionary.FiltersCache"] = filters; }
public override IQueryable SetFilters(IQueryable query) { FilterInitialize(); foreach (var provider in filterProviders) { provider.IsSelect = true; provider.Url = Url; provider.ProjectName = "SampleDictionaries"; provider.Init(typeof(DIC_MySecondDictionary)); provider.SetFilters(ref query); } var filter = (IQueryable <DIC_MySecondDictionary>)query; //SetFilters(ref filter); query = filter; var enumerable = FilterByCustomExpressions((IQueryable <DIC_MySecondDictionary>)query); enumerable = FilterData(enumerable); if (ParentControl != null) { var param = Expression.Parameter(typeof(DIC_MySecondDictionary), "r"); var filterExp = ParentControl.GetExpression(FilterByParentControl, param); if (filterExp != null) { Expression pred = Expression.Lambda(filterExp, param); Expression expr = Expression.Call(typeof(Queryable), "Where", new[] { typeof(DIC_MySecondDictionary) }, enumerable.Expression, pred); enumerable = (IQueryable <DIC_MySecondDictionary>)enumerable.Provider.CreateQuery(expr); } else { string filterValue; filterValue = ParentControl.SelectedValue == null ? "0" : ParentControl.SelectedValueLong.ToString(); enumerable = (IQueryable <DIC_MySecondDictionary>) LinqFilterGenerator.GenerateFilter(enumerable, typeof(DIC_MySecondDictionary), "Equal", FilterByParentControl, filterValue, null); } } IQueryable queryable = enumerable; if (ParentControl == null) { if (NavigatorControl == null) { NavigatorControl = new DIC_MySecondDictionaryNavigatorControl { Url = Url } } ; queryable = NavigatorControl.FilterData(queryable); if (Url.UserControl != null && Url.UserControl.StartsWith("DIC_MySecondDictionary")) { foreach (var queryParameter in Url.QueryParameters) { if (queryParameter.Key.Contains(".") && !string.IsNullOrEmpty(queryParameter.Value) && !queryParameter.Key.EndsWith(".id")) { queryable = LinqFilterGenerator.GenerateFilter(queryable, typeof(DIC_MySecondDictionary), "Equal", queryParameter.Key, queryParameter.Value, null); } } } } return((IQueryable <DIC_MySecondDictionary>)queryable); }
public static void SetGridFilters <TKey, TTable, TDataContext, TRow>( this GridFilters gridFilter, string gridFilterStr, BaseFilterControl <TKey, TTable, TDataContext> filter, BaseGridColumns columns) where TKey : struct where TTable : class where TDataContext : DataContext, new() where TRow : BaseRow, new() { var conditions = GetFilterValues(gridFilterStr); if (conditions == null) { return; } filter.Filter += (sender, filterArgs) => { var filterColumns = columns.Columns.OfType <GridColumn>().ToDictionary(r => r.ColumnNameIndex); foreach (var condition in conditions.Conditions) { var filterColumn = filterColumns[condition.Field]; if (filterColumn.SetGridFilterHandler != null) { filterColumn.SetGridFilterHandler(filterArgs, condition); continue; } var property = filterColumn.FilterColumnMapping ?? condition.Field; var param = Expression.Parameter(typeof(TTable), "filterExtNet"); Type fieldType; var getValueExp = LinqFilterGenerator.GetProperty( typeof(TTable), property, param, out fieldType); var values = GetValue(condition, fieldType); DateTime?dateEnd = null; if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?)) { if (condition.Comparison == Comparison.Eq) { values[0] = ((DateTime)values[0]).Date; dateEnd = ((DateTime)values[0]).AddDays(1).AddSeconds(-1); } else { dateEnd = ((DateTime)values[0]).Date; values[0] = ((DateTime)values[0]).Date.AddDays(1).AddSeconds(-1); } } if (filterColumn.IsForeignKey && filterColumn.DataSource != null && !filterColumn.IsLookup && (fieldType == typeof(long) || fieldType == typeof(long?)) && condition.Type == FilterType.List) { IEnumerable data = null; var strValues = values.Cast <string>().ToDictionary(r => r.ToLower()); filterColumn.DataSource.GetView("").Select(new DataSourceSelectArguments(), c => data = c); values = data.Cast <IDataRow>() .Where(r => strValues.ContainsKey(r.Name.ToLower())) .Select(r => Convert.ChangeType(r.Value, fieldType)) .ToArray(); } Expression expression = null; foreach (var value in values) { var exp3 = dateEnd != null ? filterArgs.QueryParameters.GetExpression( dateEnd.ToString(), dateEnd, fieldType) : null; var tempExp = GetExpression( getValueExp, filterArgs.QueryParameters.GetExpression(value.ToString(), value, fieldType), exp3, condition); expression = expression == null ? tempExp : Expression.Or(expression, tempExp); } if (expression != null) { var lambda = Expression.Lambda <Func <TTable, bool> >(expression, param); filterArgs.AddFilter(lambda); } } }; }
protected override void FilterInitialize() { if (_filterInitialized) { return; } _filterInitialized = true; _filters = (IList <Filter>)HttpContext.Current.Items["MyProductActions.FiltersCache"]; if (Page == null && _filters != null) { _filterHandlers = _filters. Union(_filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); return; } BrowseFilterParameters parameters; IList <Filter> filters = new List <Filter>(); var stack = new Stack <IList <Filter> >(); _filters = filters; Filter current; BaseFilterParameter currentBF = null; parameters = new BrowseFilterParameters(); GetBrowseFilterParameters_refProduct(parameters); //колонка 'Мой товар' current = currentBF = new BaseFilterParameter <MyProductAction, Int64>(r => r.refProduct, r => r.MyProduct_refProduct.Name, r => r.MyProduct_refProduct.Name) { FilterName = "refProduct", Header = MyProductActionsResources.refProduct__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Reference, ProjectName = "SampleDictionaries", TableName = "MyProducts", Lookup = true, MinimumPrefixLength = 1, Width = "98%", SelectMode = "none", IsMultipleSelect = true, BrowseFilterParameters = parameters, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Дата/время действия' current = currentBF = new BaseFilterParameter <MyProductAction, DateTime>(r => r.DateTimeAction) { FilterName = "DateTimeAction", Header = MyProductActionsResources.DateTimeAction__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Numeric, IsDateTime = true, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Изменение кол-ва' current = currentBF = new BaseFilterParameter <MyProductAction, Decimal>(r => r.AmountChange) { FilterName = "AmountChange", Header = MyProductActionsResources.AmountChange__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Numeric, DecimalPrecision = 2, MaxLength = 8, Columns = 8, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Примечание' current = currentBF = new BaseFilterParameterString <MyProductAction>(r => r.Note) { FilterName = "Note", Header = MyProductActionsResources.Note__Header, IsJournalFilter = true, Mandatory = false, Type = FilterHtmlGenerator.FilterType.Text, MaxLength = 500, Width = "98%", }; currentBF.AddFilter(filters); //filters.Add(current); if (Url.IsMultipleSelect) { current = new Filter { FilterName = MultipleSelectedValues, Header = TableResources.MultipleSelectedFilterHeader, Type = FilterHtmlGenerator.FilterType.Boolean, TrueBooleanText = TableResources.MultipleSelectedFilterSelected, FalseBooleanText = TableResources.MultipleSelectedFilterNotSelected, Mandatory = true, FilterHandler = delegate(IQueryable enumerable, Enum type, string value1, string value2) { throw new Exception("Is not actual delegate"); }, }; filters.Add(current); } AddSearchFilter(filters); SetDefaultFilterType(filters); FilterInitialize(filters); if (CustomFilter != null && !_customFiltersInitialized) { _customFiltersInitialized = true; InitializeCustomFilters(filters); } _filterHandlers = filters. Union(filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); HttpContext.Current.Items["MyProductActions.FiltersCache"] = filters; }
protected override void FilterInitialize() { if (_filterInitialized) { return; } _filterInitialized = true; _filters = (IList <Filter>)HttpContext.Current.Items["DIC_MyFirstDictionary.FiltersCache"]; if (Page == null && _filters != null) { _filterHandlers = _filters. Union(_filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); return; } BrowseFilterParameters parameters; IList <Filter> filters = new List <Filter>(); var stack = new Stack <IList <Filter> >(); _filters = filters; Filter current; BaseFilterParameter currentBF = null; //колонка 'System code' current = currentBF = new BaseFilterParameterString <DIC_MyFirstDictionary>(r => r.Code) { FilterName = "Code", Header = DIC_MyFirstDictionaryResources.Code__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Text, MaxLength = 4, Columns = 4, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Name' current = currentBF = new BaseFilterParameterString <DIC_MyFirstDictionary>(r => r.Name) { FilterName = "Name", Header = DIC_MyFirstDictionaryResources.Name__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Text, MaxLength = 255, Width = "98%", }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Date time Start' current = currentBF = new BaseFilterParameter <DIC_MyFirstDictionary, DateTime>(r => r.DateStart) { FilterName = "DateStart", Header = DIC_MyFirstDictionaryResources.DateStart__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Numeric, IsDateTime = true, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Date time End' current = currentBF = new BaseFilterParameter <DIC_MyFirstDictionary, DateTime>(r => r.DateEnd) { FilterName = "DateEnd", Header = DIC_MyFirstDictionaryResources.DateEnd__Header, IsJournalFilter = true, Mandatory = false, Type = FilterHtmlGenerator.FilterType.Numeric, IsDateTime = true, }; currentBF.AddFilter(filters); //filters.Add(current); if (Url.IsMultipleSelect) { current = new Filter { FilterName = MultipleSelectedValues, Header = TableResources.MultipleSelectedFilterHeader, Type = FilterHtmlGenerator.FilterType.Boolean, TrueBooleanText = TableResources.MultipleSelectedFilterSelected, FalseBooleanText = TableResources.MultipleSelectedFilterNotSelected, Mandatory = true, FilterHandler = delegate(IQueryable enumerable, Enum type, string value1, string value2) { throw new Exception("Is not actual delegate"); }, }; filters.Add(current); } AddSearchFilter(filters); SetDefaultFilterType(filters); FilterInitialize(filters); if (CustomFilter != null && !_customFiltersInitialized) { _customFiltersInitialized = true; InitializeCustomFilters(filters); } _filterHandlers = filters. Union(filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); HttpContext.Current.Items["DIC_MyFirstDictionary.FiltersCache"] = filters; }
protected override void FilterInitialize() { if (_filterInitialized) { return; } _filterInitialized = true; _filters = (IList <Filter>)HttpContext.Current.Items["MyProducts.FiltersCache"]; if (Page == null && _filters != null) { _filterHandlers = _filters. Union(_filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); return; } BrowseFilterParameters parameters; IList <Filter> filters = new List <Filter>(); var stack = new Stack <IList <Filter> >(); _filters = filters; Filter current; BaseFilterParameter currentBF = null; //колонка 'Наименование' current = currentBF = new BaseFilterParameterString <MyProduct>(r => r.Name) { FilterName = "Name", Header = MyProductsResources.Name__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Text, MaxLength = 200, Width = "98%", }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Дата создания' current = currentBF = new BaseFilterParameter <MyProduct, DateTime>(r => r.CreationDate) { FilterName = "CreationDate", Header = MyProductsResources.CreationDate__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Numeric, IsDateTime = true, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Цена' current = currentBF = new BaseFilterParameter <MyProduct, Decimal>(r => r.Price) { FilterName = "Price", Header = MyProductsResources.Price__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Numeric, DecimalPrecision = 2, MaxLength = 8, Columns = 8, }; currentBF.AddFilter(filters); //filters.Add(current); //колонка 'Доступно' current = currentBF = new BaseFilterParameter <MyProduct, Decimal>(r => r.Amount) { FilterName = "Amount", Header = MyProductsResources.Amount__Header, IsJournalFilter = true, Mandatory = true, Type = FilterHtmlGenerator.FilterType.Numeric, DecimalPrecision = 2, MaxLength = 8, Columns = 8, }; currentBF.AddFilter(filters); //filters.Add(current); if (Url.IsMultipleSelect) { current = new Filter { FilterName = MultipleSelectedValues, Header = TableResources.MultipleSelectedFilterHeader, Type = FilterHtmlGenerator.FilterType.Boolean, TrueBooleanText = TableResources.MultipleSelectedFilterSelected, FalseBooleanText = TableResources.MultipleSelectedFilterNotSelected, Mandatory = true, FilterHandler = delegate(IQueryable enumerable, Enum type, string value1, string value2) { throw new Exception("Is not actual delegate"); }, }; filters.Add(current); } AddSearchFilter(filters); SetDefaultFilterType(filters); FilterInitialize(filters); if (CustomFilter != null && !_customFiltersInitialized) { _customFiltersInitialized = true; InitializeCustomFilters(filters); } _filterHandlers = filters. Union(filters.SelectMany(r => r.AllChildren)). Where(p => p.FilterHandler != null). ToDictionary(p => LinqFilterGenerator.GetFilterName(p.FilterName)); HttpContext.Current.Items["MyProducts.FiltersCache"] = filters; }