locked
I am trying to use sample code on microsoft documents for Form Recognizer, but it has so many errors when i build it. RRS feed

  • Question

  • by using this document as reference , by using this document as reference ,

    https://docs.microsoft.com/en-us/azure/cognitive-services/form-recognizer/quickstarts/client-library?tabs=windows&pivots=programming-language-csharp#code-examples

    i tried to build the code after copying the code from the document. I have provided neccessary keys and endpoint url.
    but in the end, when i build the code, there are so many errors.
    i google it many errors, but that doesn't work for me.
    Can you help me to fix that errors ?

    i tried to build the code after copying the code from the document. I have provided neccessary keys and endpoint url.
    but in the end, when i build the code, there are so many errors.
    i google it many errors, but that doesn't work for me.

    Can you help me to fix that errors ?
    • Moved by CoolDadTx Monday, July 13, 2020 3:29 PM Azure related
    Monday, July 13, 2020 6:24 AM

All replies

  • Hi Ashraf,

    I'm Mouad and I'll be glad to help you!

    can you add a screenshot of the errors you face, or copy/paste them?

    Monday, July 13, 2020 9:15 AM
  • In addition please share your environment too such as your C# version, .net FW version.

    www.cihanyakar.com

    Monday, July 13, 2020 9:59 AM
  • Hello,

    For Azure related questions use the following forum and note the tags on the right side of the screen which include various sub topics for azure.

    https://docs.microsoft.com/en-us/answers/index.html


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Monday, July 13, 2020 1:43 PM
  • Hi,

    I am using .net core 3.1 on visual studio 2019 and language is C#.
    I copied and paste the code from the document, and provide the essentials. But the errors are look like they have coding issue. The sample code may have things that is not correct. I tried to attach the screenshot but validation doesn't allow me to post any image or link. So i am pasting the error as text.

    Severity Code Description Project File Line Suppression State
    Error CS1503 Argument 1: cannot convert from 'Azure.AI.FormRecognizer.Training.FormTrainingClient' to 'Azure.AI.FormRecognizer.FormRecognizerClient' formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 43 Active
    Error CS1503 Argument 1: cannot convert from 'Azure.AI.FormRecognizer.Training.FormTrainingClient' to 'Azure.AI.FormRecognizer.FormRecognizerClient' formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 49 Active
    Error CS0161 'Program.GetContent(FormRecognizerClient, string)': not all code paths return a value formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 52 Active
    Error CS0246 The type or namespace name 'IReadOnlyList<>' could not be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 54 Active
    Error CS0029 Cannot implicitly convert type 'Azure.Response<Azure.AI.FormRecognizer.Models.FormPageCollection>' to 'Azure.Response<IReadOnlyList<Azure.AI.FormRecognizer.Models.FormPage>>' formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 54 Active
    Error CS0161 'Program.AnalyzeReceipt(FormRecognizerClient, string)': not all code paths return a value formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 83 Active
    Error CS0246 The type or namespace name 'IReadOnlyDictionary<,>' could not be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 123 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'StartTrainingAsync' and no accessible extension method 'StartTrainingAsync' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 167 Active
    Error CS0103 The name 'trainingFileUrl' does not exist in the current context formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 167 Active
    Error CS0029 Cannot implicitly convert type 'string' to 'System.Guid' formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 188 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'StartTrainingAsync' and no accessible extension method 'StartTrainingAsync' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 194 Active
    Error CS0103 The name 'trainingFileUrl' does not exist in the current context formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 194 Active
    Error CS0029 Cannot implicitly convert type 'string' to 'System.Guid' formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 215 Active
    Error CS0246 The type or namespace name 'IReadOnlyList<>' could not be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 221 Active
    Error CS0103 The name 'recognizerClient' does not exist in the current context formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 221 Active
    Error CS0103 The name 'formUri' does not exist in the current context formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 221 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'GetAccountProperties' and no accessible extension method 'GetAccountProperties' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 246 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'GetModelInfos' and no accessible extension method 'GetModelInfos' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 251 Active
    Error CS1061 'Pageable<CustomFormModelInfo>' does not contain a definition for 'Take' and no accessible extension method 'Take' accepting a first argument of type 'Pageable<CustomFormModelInfo>' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 253 Active
    Error CS1061 'CustomFormModelInfo' does not contain a definition for 'CreatedOn' and no accessible extension method 'CreatedOn' accepting a first argument of type 'CustomFormModelInfo' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 258 Active
    Error CS1061 'CustomFormModelInfo' does not contain a definition for 'LastModified' and no accessible extension method 'LastModified' accepting a first argument of type 'CustomFormModelInfo' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 259 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'StartTrainingAsync' and no accessible extension method 'StartTrainingAsync' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 263 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'GetCustomModel' and no accessible extension method 'GetCustomModel' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 266 Active
    Error CS0246 The type or namespace name 'CustomFormSubModel' could not be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 270 Active
    Error CS1061 'CustomFormModel' does not contain a definition for 'Models' and no accessible extension method 'Models' accepting a first argument of type 'CustomFormModel' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 270 Active
    Error CS0128 A local variable or function named 'model' is already defined in this scope formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 285 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'StartTrainingAsync' and no accessible extension method 'StartTrainingAsync' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 285 Active
    Error CS0128 A local variable or function named 'modelCopy' is already defined in this scope formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 288 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'GetCustomModel' and no accessible extension method 'GetCustomModel' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 288 Active
    Error CS0246 The type or namespace name 'CustomFormSubModel' could not be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 292 Active
    Error CS1061 'CustomFormModel' does not contain a definition for 'Models' and no accessible extension method 'Models' accepting a first argument of type 'CustomFormModel' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 292 Active
    Error CS1061 'FormRecognizerClient' does not contain a definition for 'DeleteModel' and no accessible extension method 'DeleteModel' accepting a first argument of type 'FormRecognizerClient' could be found (are you missing a using directive or an assembly reference?) formrecognizer-quickstart C:\Users\Saad\Desktop\formrecognizer-quickstart\Program.cs 306 Active

    Thanks.

    Tuesday, July 14, 2020 5:54 AM
  • Hi,

    I tested the code and found some errors, first thing you should install the nuget package Azure.AI.FormRecognizer ver 1.0.0-preview.4

    in a command prompt, while in the solution folder type:

    dotnet add package Azure.AI.FormRecognizer.Models --version 1.0.0-preview.4

    this should add missing packages, also you should add these using declarations:

    using Azure;
    using Azure.AI.FormRecognizer;
    using Azure.AI.FormRecognizer.Models;
    using Azure.AI.FormRecognizer.Training;
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading.Tasks;

    and here is the rest of code:

        static async Task RunFormRecognizerClient()
        { 
            string endpoint = Environment.GetEnvironmentVariable(
                "FORM_RECOGNIZER_ENDPOINT");
            string apiKey = Environment.GetEnvironmentVariable(
                "FORM_RECOGNIZER_KEY");
            var credential = new AzureKeyCredential(apiKey);
            
            var trainingClient = new FormTrainingClient(new Uri(endpoint), credential);
            var recognizerClient = new FormRecognizerClient(new Uri(endpoint), credential);
                string trainingDataUrl = "<SAS-URL-of-your-form-folder-in-blob-storage>";
            string formUrl = "<SAS-URL-of-a-form-in-blob-storage>";
            string receiptUrl = "https://docs.microsoft.com/azure/cognitive-services/form-recognizer/media"
            + "/contoso-allinone.jpg";
    
            // Call Form Recognizer scenarios:
            Console.WriteLine("Get form content...");
            await GetContent(recognizerClient, formUrl);
    
            Console.WriteLine("Analyze receipt...");
            await AnalyzeReceipt(recognizerClient, receiptUrl);
    
            Console.WriteLine("Train Model with training data...");
            string modelId = await TrainModel(trainingClient, trainingDataUrl);
    
            Console.WriteLine("Analyze PDF form...");
            await AnalyzePdfForm(recognizerClient, modelId, formUrl);
    
            Console.WriteLine("Manage models...");
            await ManageModels(trainingClient, trainingDataUrl) ;
        }

        private static async Task<IReadOnlyList<FormPage>> GetContent(
            FormRecognizerClient recognizerClient, string invoiceUri)
        {
            Response<FormPageCollection> formPages = await recognizerClient
                .StartRecognizeContentFromUri(new Uri(invoiceUri))
                .WaitForCompletionAsync();
                    foreach (FormPage page in formPages.Value)
            {
                Console.WriteLine($"Form Page {page.PageNumber} has {page.Lines.Count}" + 
                    $" lines.");
            
                for (int i = 0; i < page.Lines.Count; i++)
                {
                    FormLine line = page.Lines[i];
                    Console.WriteLine($"    Line {i} has {line.Words.Count}" + 
                        $" word{(line.Words.Count > 1 ? "s" : "")}," +
                        $" and text: '{line.Text}'.");
                }
            
                for (int i = 0; i < page.Tables.Count; i++)
                {
                    FormTable table = page.Tables[i];
                    Console.WriteLine($"Table {i} has {table.RowCount} rows and" +
                        $" {table.ColumnCount} columns.");
                    foreach (FormTableCell cell in table.Cells)
                    {
                        Console.WriteLine($"    Cell ({cell.RowIndex}, {cell.ColumnIndex})" +
                            $" contains text: '{cell.Text}'.");
                    }
                }
            }
            return formPages.Value;
        }

        private static async Task<RecognizedFormCollection> AnalyzeReceipt(
            FormRecognizerClient recognizerClient, string receiptUri)
        {
            Response<RecognizedFormCollection> receipts = await recognizerClient.StartRecognizeReceiptsFromUri(new Uri(receiptUri))
            .WaitForCompletionAsync();
    
            foreach (var receipt in receipts.Value)
            {
                FormField merchantNameField;
                if (receipt.Fields.TryGetValue("MerchantName", out merchantNameField))
                {
                    if (merchantNameField.Value.Type == FieldValueType.String)
                    {
                        string merchantName = merchantNameField.Value.AsString();
    
                        Console.WriteLine($"Merchant Name: '{merchantName}', with confidence {merchantNameField.Confidence}");
                    }
                }
    
                FormField transactionDateField;
                if (receipt.Fields.TryGetValue("TransactionDate", out transactionDateField))
                {
                    if (transactionDateField.Value.Type == FieldValueType.Date)
                    {
                        DateTime transactionDate = transactionDateField.Value.AsDate();
    
                        Console.WriteLine($"Transaction Date: '{transactionDate}', with confidence {transactionDateField.Confidence}");
                    }
                }
                FormField itemsField;
                if (receipt.Fields.TryGetValue("Items", out itemsField))
                {
                    if (itemsField.Value.Type == FieldValueType.List)
                    {
                        foreach (FormField itemField in itemsField.Value.AsList())
                        {
                            Console.WriteLine("Item:");
    
                            if (itemField.Value.Type == FieldValueType.Dictionary)
                            {
                                IReadOnlyDictionary<string, FormField> itemFields = itemField.Value.AsDictionary();
    
                                FormField itemNameField;
                                if (itemFields.TryGetValue("Name", out itemNameField))
                                {
                                    if (itemNameField.Value.Type == FieldValueType.String)
                                    {
                                        string itemName = itemNameField.Value.AsString();
    
                                        Console.WriteLine($"    Name: '{itemName}', with confidence {itemNameField.Confidence}");
                                    }
                                }
    
                                FormField itemTotalPriceField;
                                if (itemFields.TryGetValue("TotalPrice", out itemTotalPriceField))
                                {
                                    if (itemTotalPriceField.Value.Type == FieldValueType.Float)
                                    {
                                        float itemTotalPrice = itemTotalPriceField.Value.AsFloat();
    
                                        Console.WriteLine($"    Total Price: '{itemTotalPrice}', with confidence {itemTotalPriceField.Confidence}");
                                    }
                                }
                            }
                        }
                    }
                }
                FormField totalField;
                if (receipt.Fields.TryGetValue("Total", out totalField))
                {
                    if (totalField.Value.Type == FieldValueType.Float)
                    {
                        float total = totalField.Value.AsFloat();
    
                        Console.WriteLine($"Total: '{total}', with confidence '{totalField.Confidence}'");
                    }
                }
            }
    
            return receipts.Value;
        }

        private static async Task<string> TrainModel(
            FormTrainingClient trainingClient, string trainingFileUrl)
        {
            CustomFormModel model = await trainingClient
                .StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();
            
            Console.WriteLine($"Custom Model Info:");
            Console.WriteLine($"    Model Id: {model.ModelId}");
            Console.WriteLine($"    Model Status: {model.Status}");
            Console.WriteLine($"    Requested on: {model.TrainingStartedOn}");
            Console.WriteLine($"    Completed on: {model.TrainingCompletedOn}");
            foreach (CustomFormSubmodel submodel in model.Submodels)
            {
                Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
                foreach (CustomFormModelField field in submodel.Fields.Values)
                {
                    Console.Write($"    FieldName: {field.Name}");
                    if (field.Label != null)
                    {
                        Console.Write($", FieldLabel: {field.Label}");
                    }
                    Console.WriteLine("");
                }
            }
            return model.ModelId;
        }
    
    

        private static async Task<string> TrainModelWithLabelsAsync(
            FormTrainingClient trainingClient, string trainingFileUrl)
        {
            CustomFormModel model = await trainingClient
            .StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: true).WaitForCompletionAsync();
            
            Console.WriteLine($"Custom Model Info:");
            Console.WriteLine($"    Model Id: {model.ModelId}");
            Console.WriteLine($"    Model Status: {model.Status}");
            Console.WriteLine($"    Requested on: {model.TrainingStartedOn}");
            Console.WriteLine($"    Completed on: {model.TrainingCompletedOn}");        
            foreach (CustomFormSubmodel submodel in model.Submodels)
            {
                Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
                foreach (CustomFormModelField field in submodel.Fields.Values)
                {
                    Console.Write($"    FieldName: {field.Name}");
                    if (field.Accuracy != null)
                    {
                        Console.Write($", Accuracy: {field.Accuracy}");
                    }
                    Console.WriteLine("");
                }
            }
            return model.ModelId;
            
        }

        private static async Task AnalyzePdfForm(
            FormRecognizerClient formClient, string modelId, string pdfFormFile)
        {    
            Response<RecognizedFormCollection> forms = await formClient
                .StartRecognizeCustomFormsFromUri(modelId.ToString(), new Uri(pdfFormFile))
                .WaitForCompletionAsync();
            foreach (RecognizedForm form in forms.Value)
            {
                Console.WriteLine($"Form of type: {form.FormType}");
                foreach (FormField field in form.Fields.Values)
                {
                    Console.WriteLine($"Field '{field.Name}: ");
            
                    if (field.LabelData != null)
                    {
                        Console.WriteLine($"    Label: '{field.LabelData.Text}");
                    }
            
                    Console.WriteLine($"    Value: '{field.ValueData.Text}");
                    Console.WriteLine($"    Confidence: '{field.Confidence}");
                }
            }
        }

        private static async Task ManageModels(
            FormTrainingClient trainingClient, string trainingFileUrl)
        {
            // Check number of models in the FormRecognizer account, 
            // and the maximum number of models that can be stored.
            AccountProperties accountProperties = trainingClient.GetAccountProperties();
            Console.WriteLine($"Account has {accountProperties.CustomModelCount} models.");
            Console.WriteLine($"It can have at most {accountProperties.CustomModelLimit}" +
                $" models.");
            // List the first ten or fewer models currently stored in the account.
            Pageable<CustomFormModelInfo> models = trainingClient.GetCustomModels();
            
            foreach (CustomFormModelInfo modelInfo in models.Take(10))
            {
                Console.WriteLine($"Custom Model Info:");
                Console.WriteLine($"    Model Id: {modelInfo.ModelId}");
                Console.WriteLine($"    Model Status: {modelInfo.Status}");
                Console.WriteLine($"    Created On: {modelInfo.TrainingStartedOn}");
                Console.WriteLine($"    Last Modified: {modelInfo.TrainingCompletedOn}");
            }
    
            // Create a new model to store in the account
            CustomFormModel model = await trainingClient.StartTrainingAsync(
                new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();
            
            // Get the model that was just created
            CustomFormModel modelCopy = trainingClient.GetCustomModel(model.ModelId);
            
            Console.WriteLine($"Custom Model {modelCopy.ModelId} recognizes the following" +
                " form types:");
            
            foreach (CustomFormSubmodel subModel in modelCopy.Submodels)
            {
                Console.WriteLine($"SubModel Form Type: {subModel.FormType}");
                foreach (CustomFormModelField field in subModel.Fields.Values)
                {
                    Console.Write($"    FieldName: {field.Name}");
                    if (field.Label != null)
                    {
                        Console.Write($", FieldLabel: {field.Label}");
                    }
                    Console.WriteLine("");
                }
            }
    
                // Delete the model from the account.
            trainingClient.DeleteModel(model.ModelId);
        }

    now it should compile, but I didn't test it yet, there is a big probability that we'll have runtime errors, I'll try to take a look later!  

    Tuesday, July 14, 2020 8:36 AM
  • Hi Mouad, your overall code doesn't have any error except,

    On your AnalyzeReceipt Method, the first line, i.e.

    Response<RecognizedFormCollection> receipts = await recognizerClient.StartRecognizeReceiptsFromUri(new Uri(receiptUri)).WaitForCompletionAsync();

    through this error 

    Cannot implicitly convert type 'Azure.Response<Azure.AI.FormRecognizer.Models.RecognizedReceiptCollection>' to 'Azure.Response<Azure.AI.FormRecognizer.Models.RecognizedFormCollection>'

    Thursday, July 16, 2020 7:26 AM
  • you are right, but from my part when I look to the method WaitForCompletionAsync of the RecognizeReceiptsOperation the result is of type Response<RecognizeFormCollection>:

        public class RecognizeReceiptsOperation : Operation<RecognizedFormCollection>
        {
            public RecognizeReceiptsOperation(string operationId, FormRecognizerClient client);
    
            public override string Id { get; }
            
            public override RecognizedFormCollection Value { get; }
    
            public override bool HasCompleted { get; }
    
            public override bool HasValue { get; }
    
            public override Response GetRawResponse();
    
            public override Response UpdateStatus(CancellationToken cancellationToken = default);
    
            [AsyncStateMachine(typeof(<UpdateStatusAsync>d__21))]
            public override ValueTask<Response> UpdateStatusAsync(CancellationToken cancellationToken = default);
    
            public override ValueTask<Response<RecognizedFormCollection>> WaitForCompletionAsync(CancellationToken cancellationToken = default);
    
            public override ValueTask<Response<RecognizedFormCollection>> WaitForCompletionAsync(TimeSpan pollingInterval, CancellationToken cancellationToken = default);
        }

    it depend on the version of the Azure.AI.FormRecognizer library, when I sent a feedback on the project repos, they suggest that for the tutorial code to work as it is you should install the version 1.0.0-preview.3 of the library, in my case I'm using the version 1.0.0-preview.4 one.

    here is the repos where my code is: 

    https://github.com/mouadcherkaoui/AzureAIFormRecognizer

    and here is the feedback:

    https://github.com/MicrosoftDocs/azure-docs/issues/58959

    best regards.

    Thursday, July 16, 2020 12:40 PM
  • Thursday, July 16, 2020 12:45 PM