Example #1
0
        public void TagElevation_MultiplicityOperatorWhenNoMultiplicity()
        {
            // Arrange
            var ds = new DicomDataset
            {
                //root->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "Root"),

                //root->PseudoColorPaletteInstanceReferenceSequence
                new DicomSequence(DicomTag.PseudoColorPaletteInstanceReferenceSequence,
                                  new DicomDataset()
                {
                    // No multiplicity!
                    //root->PseudoColorPaletteInstanceReferenceSequence->TextString
                    new DicomShortString(DicomTag.TextString, "abcd"),
                })
            };

            var elevator = new TagElevator("PseudoColorPaletteInstanceReferenceSequence->TextString", "[]", "a");

            ShowContentSequence(ds, DicomTag.PseudoColorPaletteInstanceReferenceSequence);

            //should pass when you do
            Assert.AreEqual("abcd", elevator.GetValue(ds));

            elevator = new TagElevator("PseudoColorPaletteInstanceReferenceSequence->TextString", "[]", "happy fun times");
            Assert.IsNull(elevator.GetValue(ds));
        }
Example #2
0
        public void TagElevation_MultipleLeavesAndMultiplicity_FindValues()
        {
            // Arrange
            var ds = new DicomDataset
            {
                //root->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "Root"),

                //root->PseudoColorPaletteInstanceReferenceSequence
                new DicomSequence(DicomTag.PseudoColorPaletteInstanceReferenceSequence,
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->TextString
                    new DicomShortString(DicomTag.TextString, "abcd", "efgh"),
                },
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->TextString
                    new DicomShortString(DicomTag.TextString, "hij", "klm"),
                })
            };

            const string searchString = "PseudoColorPaletteInstanceReferenceSequence->TextString&+";

            var elevator = new TagElevator(searchString, null, null);

            ShowContentSequence(ds, DicomTag.PseudoColorPaletteInstanceReferenceSequence);

            //should pass when you do
            Assert.AreEqual($"abcd\\efgh{Environment.NewLine}hij\\klm", elevator.GetValue(ds));
        }
Example #3
0
        public void TagElevation_Multiplicity_Conditional(string toFind, string expectedResults)
        {
            if (!string.IsNullOrWhiteSpace(expectedResults))
            {
                expectedResults = expectedResults.Replace("\r\n", Environment.NewLine);
            }

            // Arrange
            var ds = new DicomDataset
            {
                //root->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "Root"),

                //root->PseudoColorPaletteInstanceReferenceSequence
                new DicomSequence(DicomTag.PseudoColorPaletteInstanceReferenceSequence,
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->TextString
                    new DicomShortString(DicomTag.TextString, "abcd", "efgh"),
                },
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->TextString
                    new DicomShortString(DicomTag.TextString, "hij", "klm"),
                })
            };

            ShowContentSequence(ds, DicomTag.PseudoColorPaletteInstanceReferenceSequence);

            var elevator = new TagElevator("PseudoColorPaletteInstanceReferenceSequence->TextString&+", "[]", toFind);

            Assert.AreEqual(expectedResults, elevator.GetValue(ds));
        }
Example #4
0
        [TestCase(".->CodingSchemeDesignator", "99_OFFIS_DCMTK", false, true)] //throws because all ContentSequence->ConceptNameCodeSequence->CodeMeaning are designated by the same value Offis...
        public void TagElevation_ConditionalCurrentNode_OtherTags(string conditional, string conditionalMatch, bool expectedToFind, bool expectMultipleMatchesException)
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.report01);

            var file = DicomFile.Open(_srDcmPath);

            var elevator = new TagElevator("ContentSequence->ConceptNameCodeSequence->CodeMeaning", conditional, conditionalMatch);

            ShowContentSequence(file.Dataset);

            if (expectMultipleMatchesException)
            {
                Assert.Throws <TagNavigationException>(() => elevator.GetValue(file.Dataset));
            }
            else
            {
                object value = elevator.GetValue(file.Dataset);

                if (expectedToFind)
                {
                    Assert.AreEqual("Treatment", value);
                }
                else
                {
                    Assert.IsNull(value);
                }
            }
        }
Example #5
0
        public void TagElevation_TwoDeep_FindValue()
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.image11);

            var file = DicomFile.Open(_imDcmPath);

            var elevator = new TagElevator("ModalityLUTSequence->LUTExplanation");

            object value = elevator.GetValue(file.Dataset);

            Assert.IsNotNull(file);
            Assert.AreEqual(value, "KESPR LUT");
        }
Example #6
0
        public void TagElevation_TagNotFound_ReturnsNull(string path)
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.image11);

            var file = DicomFile.Open(_imDcmPath);

            var elevator = new TagElevator(path);

            object value = elevator.GetValue(file.Dataset);

            Assert.IsNotNull(file);
            Assert.IsNull(value);
        }
Example #7
0
        [TestCase("..->[..]->TextValue", "The plan of treatment is as follows")] //actually results in matching all elements of ContentSequence (not just [4]) so will match everyone
        public void TagElevation_DoubleDotConditional_ThenArrayElementBuddies_FindValue(string conditional, string conditionalMatch)
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.report01);

            var file = DicomFile.Open(_srDcmPath);

            var elevator = new TagElevator("ContentSequence->ConceptNameCodeSequence->CodeMeaning+", conditional, conditionalMatch);

            ShowContentSequence(file.Dataset);

            object value = elevator.GetValue(file.Dataset);

            Assert.AreEqual($"Observer Name{Environment.NewLine}Observer Organization Name{Environment.NewLine}Description{Environment.NewLine}Diagnosis{Environment.NewLine}Treatment", value);
        }
Example #8
0
        public void TagElevation_TextValueConditionals_FindValue(string conditional, string conditionalMatch)
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.report01);

            var file = DicomFile.Open(_srDcmPath);

            var elevator = new TagElevator("ContentSequence->TextValue", conditional, conditionalMatch);

            ShowContentSequence(file.Dataset);

            object value = elevator.GetValue(file.Dataset);

            Assert.AreEqual("Redlands Clinic", value);
        }
Example #9
0
        public void TagElevation_DoubleDotConditionalSpam_NeverMatch(string conditional, string conditionalMatch)
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.report01);

            var file = DicomFile.Open(_srDcmPath);

            var elevator = new TagElevator("ContentSequence->ConceptNameCodeSequence->CodeMeaning&", conditional, conditionalMatch);

            ShowContentSequence(file.Dataset);

            object value = elevator.GetValue(file.Dataset);

            Assert.IsNull(value);
        }
Example #10
0
        public void TagElevation_TwoDeepWithConditional_FindValue()
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.report01);

            var file = DicomFile.Open(_srDcmPath);

            var elevator = new TagElevator("ContentSequence->TextValue", ".->ConceptNameCodeSequence->CodeMeaning", "Observer Organization Name");

            ShowContentSequence(file.Dataset);

            object value = elevator.GetValue(file.Dataset);

            Assert.IsNotNull(file);
            Assert.AreEqual("Redlands Clinic", value);
        }
Example #11
0
        public void TagElevation_ThreeDeep_FindValue()
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.report01);

            var file = DicomFile.Open(_srDcmPath);

            //for debugging purposes
            ShowContentSequence(file.Dataset);

            var elevator = new TagElevator("ContentSequence->ConceptNameCodeSequence->CodeMeaning+");

            object value = elevator.GetValue(file.Dataset);

            string expected =
                $"Observer Name{Environment.NewLine}Observer Organization Name{Environment.NewLine}Description{Environment.NewLine}Diagnosis{Environment.NewLine}Treatment";

            Assert.AreEqual(expected, value);
        }
Example #12
0
        public void TagElevation_TwoDeepReport_FindValue()
        {
            //File.WriteAllBytes(srDcmPath, TestStructuredReports.report01);

            var file = DicomFile.Open(_srDcmPath);

            var elevator = new TagElevator("ContentSequence->TextValue+");

            ShowContentSequence(file.Dataset);

            object value = elevator.GetValue(file.Dataset);

            Assert.IsNotNull(file);
            Assert.IsTrue(value.ToString().Contains("Redlands Clinic"));
            Assert.IsTrue(value.ToString().Contains("This 78-year-old gentleman referred by Dr"));
            Assert.IsTrue(value.ToString().Contains(" involving the skin of the left external ear, "));

            Assert.IsTrue(value.ToString().Contains("possibility of complication was discussed with this patient at some length, and he accepted therapy as outlined."));
        }
Example #13
0
        public void TagElevation_Multiplicity(bool specifyConcatenateMultiplicity)
        {
            // Arrange
            var ds = new DicomDataset
            {
                //root->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "Root"),

                //root->PseudoColorPaletteInstanceReferenceSequence
                new DicomSequence(DicomTag.PseudoColorPaletteInstanceReferenceSequence,
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->TextString
                    new DicomShortString(DicomTag.TextString, "abcd", "efgh"),
                })
            };

            var searchString = "PseudoColorPaletteInstanceReferenceSequence->TextString";

            if (specifyConcatenateMultiplicity)
            {
                searchString += "&";
            }

            var elevator = new TagElevator(searchString, null, null);

            ShowContentSequence(ds, DicomTag.PseudoColorPaletteInstanceReferenceSequence);

            if (specifyConcatenateMultiplicity)
            {
                //should pass when you do
                Assert.AreEqual("abcd\\efgh", elevator.GetValue(ds));
            }
            else
            {
                //should fail when you don't specify multiplicity concatenation
                var ex = Assert.Throws <TagNavigationException>(() => elevator.GetValue(ds));
                Assert.IsTrue(ex.Message.Contains("Multiplicity"));
            }
        }
Example #14
0
        /// <summary>
        /// Creates a new instance by deserializing the given xml
        /// </summary>
        /// <param name="element"></param>
        public TagElevationRequest(XmlElement element)
        {
            if (element.Name != "TagElevationRequest")
            {
                throw new MalformedTagElevationRequestCollectionXmlException("Expected xml element name to be TagElevationRequest");
            }

            ColumnName       = element["ColumnName"].InnerText;
            ElevationPathway = element["ElevationPathway"].InnerText;


            var conditional = element["Conditional"];

            if (conditional != null)
            {
                ConditionalPathway = conditional["ConditionalPathway"].InnerText;
                ConditionalRegex   = conditional["ConditionalRegex"].InnerText;
            }

            Elevator = new TagElevator(this);
        }
Example #15
0
        public void TagElevation_MultipleLeavesAndMultiplicity_WithArraySiblingConditional_FindValues()
        {
            // Arrange
            var ds = new DicomDataset
            {
                //root->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "Root"),

                //root->PseudoColorPaletteInstanceReferenceSequence
                new DicomSequence(DicomTag.PseudoColorPaletteInstanceReferenceSequence,
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->CodeValue
                    new DicomShortString(DicomTag.CodeValue, "CODE_01"),
                },
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->CodeMeaning
                    new DicomShortString(DicomTag.CodeMeaning, "Description"),
                })
            };

            ShowContentSequence(ds, DicomTag.PseudoColorPaletteInstanceReferenceSequence);

            //this won't match because CodeValue is an array sibling of the Sequence PseudoColorPaletteInstanceReferenceSequence
            var elevator = new TagElevator("PseudoColorPaletteInstanceReferenceSequence->CodeMeaning", ".->CodeValue", "^CODE"); //match starting with code

            //should pass when you do
            Assert.IsNull(elevator.GetValue(ds));

            //use the Array sibling starter instead of the sequence sibling starter (i.e. [..] instead of .)
            elevator = new TagElevator("PseudoColorPaletteInstanceReferenceSequence->CodeMeaning", "[..]->CodeValue", "^CODE"); //match starting with code

            //should pass when you do
            Assert.AreEqual("Description", elevator.GetValue(ds));
        }
Example #16
0
        public void ComplexTagNestingTests(string pathway, string conditional, string conditionalMatch, object expectedResults)
        {
            if (!string.IsNullOrWhiteSpace((string)expectedResults))
            {
                expectedResults = ((string)expectedResults).Replace("\r\n", Environment.NewLine);
            }

            // Arrange
            var ds = new DicomDataset
            {
                //root->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "Root"),

                //root->PseudoColorPaletteInstanceReferenceSequence
                new DicomSequence(DicomTag.PseudoColorPaletteInstanceReferenceSequence,
                                  new DicomDataset()
                {
                    // Text multiplicity
                    //root->PseudoColorPaletteInstanceReferenceSequence->TextString
                    new DicomShortString(DicomTag.TextString, "abcd", "efgh"),

                    //root->PseudoColorPaletteInstanceReferenceSequence->SpecimenShortDescription
                    new DicomShortText(DicomTag.SpecimenShortDescription, "1.1"),

                    //root->PseudoColorPaletteInstanceReferenceSequence->ProbeDriveEquipmentSequence
                    new DicomSequence(DicomTag.ProbeDriveEquipmentSequence,
                                      new DicomDataset
                    {
                        //root->PseudoColorPaletteInstanceReferenceSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                        new DicomShortText(DicomTag.SpecimenShortDescription, "2.1"),

                        //root->PseudoColorPaletteInstanceReferenceSequence->ProbeDriveEquipmentSequence->PatientID
                        new DicomShortString(DicomTag.PatientID, "2.2")
                    },

                                      //root->PseudoColorPaletteInstanceReferenceSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                                      new DicomDataset
                    {
                        new DicomShortText(DicomTag.SpecimenShortDescription, "2.1")
                    }),

                    //root->PseudoColorPaletteInstanceReferenceSequence->AbstractPriorCodeSequence
                    new DicomSequence(DicomTag.AbstractPriorCodeSequence,
                                      new DicomDataset
                    {
                        //root->PseudoColorPaletteInstanceReferenceSequence->AbstractPriorCodeSequence->ProbeDriveEquipmentSequence
                        new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                        {
                            //root->PseudoColorPaletteInstanceReferenceSequence->AbstractPriorCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                            new DicomShortText(DicomTag.SpecimenShortDescription, "3.1"),

                            //root->PseudoColorPaletteInstanceReferenceSequence->AbstractPriorCodeSequence->ProbeDriveEquipmentSequence->PatientID
                            new DicomShortString(DicomTag.PatientID, "3.2")
                        }),

                        //root->PseudoColorPaletteInstanceReferenceSequence->AbstractPriorCodeSequence
                        new DicomSequence(DicomTag.AbstractPriorCodeSequence,
                                          new DicomDataset()
                        {
                        }),

                        //root->PseudoColorPaletteInstanceReferenceSequence->AbstractPriorCodeSequence->SpecimenShortDescription
                        new DicomShortText(DicomTag.SpecimenShortDescription, "2.1")
                    }),


                    //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence
                    new DicomSequence(DicomTag.PatientGantryRelationshipCodeSequence,
                                      new DicomDataset
                    {
                        //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->ProbeDriveEquipmentSequence
                        new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                        {
                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                            new DicomShortText(DicomTag.SpecimenShortDescription, "3.1"),

                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->ProbeDriveEquipmentSequence->PatientID
                            new DicomShortString(DicomTag.PatientID, "3.2")
                        }),

                        //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->SpecimenShortDescription
                        new DicomShortText(DicomTag.SpecimenShortDescription, "2.1")
                    }),


                    //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence [array of 3 sequences]
                    new DicomSequence(DicomTag.PatientInsurancePlanCodeSequence,
                                      new DicomDataset[]
                    {
                        new DicomDataset
                        {
                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence
                            new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                            {
                                //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                                new DicomShortText(DicomTag.SpecimenShortDescription, "3_0_.1"),

                                //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->PatientID
                                new DicomShortString(DicomTag.PatientID, "3_0_.2")
                            }),

                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->SpecimenShortDescription
                            new DicomShortText(DicomTag.SpecimenShortDescription, "2_0_.1")
                        },

                        new DicomDataset
                        {
                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence
                            new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                            {
                                //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                                new DicomShortText(DicomTag.SpecimenShortDescription, "3_1_.1"),

                                //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->PatientID
                                new DicomShortString(DicomTag.PatientID, "3_1_.2")
                            }),

                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientInsurancePlanCodeSequence->SpecimenShortDescription
                            new DicomShortText(DicomTag.SpecimenShortDescription, "2_1_.1")
                        },


                        new DicomDataset
                        {
                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->ProbeDriveEquipmentSequence
                            new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                            {
                                //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                                new DicomShortText(DicomTag.SpecimenShortDescription, "3_2_.1"),

                                //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->ProbeDriveEquipmentSequence->PatientID
                                new DicomShortString(DicomTag.PatientID, "3_2_.2")
                            }),

                            //root->PseudoColorPaletteInstanceReferenceSequence->PatientGantryRelationshipCodeSequence->SpecimenShortDescription
                            new DicomShortText(DicomTag.SpecimenShortDescription, "2_2.1")
                        }
                    }),

                    //root->PseudoColorPaletteInstanceReferenceSequence->PatientID
                    new DicomDataset {
                        new DicomShortText(DicomTag.PatientID, "1.2")
                    }
                }),
            };

            var elevator = new TagElevator(pathway, conditional, conditionalMatch);

            ShowContentSequence(ds, DicomTag.PseudoColorPaletteInstanceReferenceSequence);

            object value = elevator.GetValue(ds);

            Assert.AreEqual(expectedResults, value);
        }
Example #17
0
        public void TagElevation_SiblingConditionals(string conditional, string conditionalMatch, string expectedResults)
        {
            expectedResults = expectedResults.Replace("\r\n", Environment.NewLine);

            var ds = new DicomDataset
                     (
                //root->PatientInsurancePlanCodeSequence [array of 3 sibling sequences]
                new DicomSequence
                    (DicomTag.PatientInsurancePlanCodeSequence,
                    new DicomDataset
            {
                //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence
                new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                {
                    //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                    new DicomShortText(DicomTag.SpecimenShortDescription, "3_0.1"),

                    //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->PatientID
                    new DicomShortString(DicomTag.PatientID, "3_0.2")
                }),

                //root->PatientInsurancePlanCodeSequence->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "2_0.1")
            },

                    new DicomDataset
            {
                //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence
                new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                {
                    //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                    new DicomShortText(DicomTag.SpecimenShortDescription, "3_1.1"),

                    //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->PatientID
                    new DicomShortString(DicomTag.PatientID, "3_1.2")
                }),

                //root->PatientInsurancePlanCodeSequence->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "2_1.1")
            },


                    new DicomDataset
            {
                //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence
                new DicomSequence(DicomTag.ProbeDriveEquipmentSequence, new DicomDataset()
                {
                    //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->SpecimenShortDescription
                    new DicomShortText(DicomTag.SpecimenShortDescription, "3_2.1"),

                    //root->PatientInsurancePlanCodeSequence->ProbeDriveEquipmentSequence->PatientID
                    new DicomShortString(DicomTag.PatientID, "3_2.2")
                }),

                //root->PatientInsurancePlanCodeSequence->SpecimenShortDescription
                new DicomShortText(DicomTag.SpecimenShortDescription, "2_2.1")
            }
                    )
                     );

            var elevator = new TagElevator("PatientInsurancePlanCodeSequence->SpecimenShortDescription+", conditional, conditionalMatch);

            ShowContentSequence(ds, DicomTag.PatientInsurancePlanCodeSequence);

            object value = elevator.GetValue(ds);

            Assert.AreEqual(expectedResults, value);
        }