public async Task CreateInMemoryImport() { if (_unloadCancellationToken.IsCancellationRequested) { return; } using (var access = await _projectLockService.WriteLockAsync(_unloadCancellationToken)) { // A bit odd but we have to "check it out" prior to creating it to avoid some of the validations in chk CPS await access.CheckoutAsync(_inMemoryImportFullPath); // Now either open or create the in-memory file. Normally Create will happen, but in // a scenario where your project had previously failed to load for some reason, need to TryOpen // to avoid a new reason for a project load failure _inMemoryImport = ProjectRootElement.TryOpen(_inMemoryImportFullPath, access.ProjectCollection); if (_inMemoryImport != null) { // The file already exists. Scrape it out so we don’t add duplicate items. _inMemoryImport.RemoveAllChildren(); } else { // The project didn’t already exist, so create it, and then mark the evaluated project dirty // so that MSBuild will notice. This step isn’t necessary if the project was already in memory. _inMemoryImport = CreateEmptyMsBuildProject(_inMemoryImportFullPath, access.ProjectCollection); // Note that we actually need to mark every project evaluation dirty that is already loaded. await ReevaluateLoadedConfiguredProjects(_unloadCancellationToken, access); } _filesItemGroup = _inMemoryImport.AddItemGroup(); _directoriesItemGroup = _inMemoryImport.AddItemGroup(); _temporaryAddedItemGroup = _inMemoryImport.AddItemGroup(); } }
void CreateBuildProject() { string projectPath = Path.Combine(buildDirectory, "content.contentproj"); string outputPath = Path.Combine(buildDirectory, "bin"); // Create the build project. projectRootElement = ProjectRootElement.Create(projectPath); // Include the standard targets file that defines how to build XNA Framework content. projectRootElement.AddImport(Application.StartupPath + "\\Exporters\\FBX\\XNA\\XNA Game Studio\\" + "v4.0\\Microsoft.Xna.GameStudio.ContentPipeline.targets"); buildProject = new Project(projectRootElement); buildProject.SetProperty("XnaPlatform", "Windows"); buildProject.SetProperty("XnaProfile", "Reach"); buildProject.SetProperty("XnaFrameworkVersion", "v4.0"); buildProject.SetProperty("Configuration", "Release"); buildProject.SetProperty("OutputPath", outputPath); buildProject.SetProperty("ContentRootDirectory", "."); buildProject.SetProperty("ReferencePath", Application.StartupPath); // Register any custom importers or processors. foreach (string pipelineAssembly in pipelineAssemblies) { buildProject.AddItem("Reference", pipelineAssembly); } // Hook up our custom error logger. errorLogger = new ErrorLogger(); buildParameters = new BuildParameters(ProjectCollection.GlobalProjectCollection) {Loggers = new ILogger[] {errorLogger}}; }
public ProjectInstance (ProjectRootElement xml, IDictionary<string, string> globalProperties, string toolsVersion, ProjectCollection projectCollection) { InitializeProperties (); throw new NotImplementedException (); }
public MSBuildProject(FilePath filePath) { FilePath = filePath; _msBuildProject = ProjectRootElement.Open(filePath.FullPath, _globalCollection); foreach (var item in _msBuildProject.Items) { if (item.ItemType == "Reference") References.Add(item.Include); else if (item.ItemType == "Compile" || item.ItemType == "None") { var entry = new ProjectFileEntry(new FilePath(this.ProjectDirectory, item.Include)); foreach (var element in item.Metadata) { if (element.Name == "DependentUpon") { entry.Dependencies.Add(element.Value); } } entry.ParentProject = this; AddFileEventHandlers(entry); ProjectFiles.Add(entry); } } SetupEventHandlers(); HasUnsavedData = false; }
public BuildIntegrationTests(ITestOutputHelper logger) : base(logger) { int seed = (int)DateTime.Now.Ticks; this.random = new Random(seed); this.Logger.WriteLine("Random seed: {0}", seed); this.buildManager = new BuildManager(); this.projectCollection = new ProjectCollection(); this.projectDirectory = Path.Combine(this.RepoPath, "projdir"); Directory.CreateDirectory(this.projectDirectory); this.LoadTargetsIntoProjectCollection(); this.testProject = this.CreateProjectRootElement(this.projectDirectory, "test.proj"); this.testProjectInRoot = this.CreateProjectRootElement(this.RepoPath, "root.proj"); this.globalProperties.Add("NerdbankGitVersioningTasksPath", Environment.CurrentDirectory + "\\"); // Sterilize the test of any environment variables. foreach (System.Collections.DictionaryEntry variable in Environment.GetEnvironmentVariables()) { string name = (string)variable.Key; if (ToxicEnvironmentVariablePrefixes.Any(toxic => name.StartsWith(toxic, StringComparison.OrdinalIgnoreCase))) { this.globalProperties[name] = string.Empty; } } }
internal static async Task<BuildResult> BuildAsync(this BuildManager buildManager, ITestOutputHelper logger, ProjectCollection projectCollection, ProjectRootElement project, string target, IDictionary<string, string> globalProperties = null, LoggerVerbosity logVerbosity = LoggerVerbosity.Detailed, ILogger[] additionalLoggers = null) { Requires.NotNull(buildManager, nameof(buildManager)); Requires.NotNull(projectCollection, nameof(projectCollection)); Requires.NotNull(project, nameof(project)); globalProperties = globalProperties ?? new Dictionary<string, string>(); var projectInstance = new ProjectInstance(project, globalProperties, null, projectCollection); var brd = new BuildRequestData(projectInstance, new[] { target }, null, BuildRequestDataFlags.ProvideProjectStateAfterBuild); var parameters = new BuildParameters(projectCollection); var loggers = new List<ILogger>(); loggers.Add(new ConsoleLogger(logVerbosity, s => logger.WriteLine(s.TrimEnd('\r', '\n')), null, null)); loggers.AddRange(additionalLoggers); parameters.Loggers = loggers.ToArray(); buildManager.BeginBuild(parameters); var result = await buildManager.BuildAsync(brd); buildManager.EndBuild(); return result; }
protected override ProjectUpgradeState UpgradeProjectCheck(ProjectRootElement projectXml, ProjectRootElement userProjectXml, Action<__VSUL_ERRORLEVEL, string> log, ref Guid projectFactory, ref __VSPPROJECTUPGRADEVIAFACTORYFLAGS backupSupport) { var envVarsProp = projectXml.Properties.FirstOrDefault(p => p.Name == NodejsConstants.EnvironmentVariables); if (envVarsProp != null && !string.IsNullOrEmpty(envVarsProp.Value)) { return ProjectUpgradeState.OneWayUpgrade; } return ProjectUpgradeState.NotNeeded; }
internal ProjectUsingTaskElement (string taskName, string assemblyFile, string assemblyName, ProjectRootElement containingProject) { TaskName = taskName; AssemblyFile = assemblyFile; AssemblyName = assemblyName; ContainingProject = containingProject; }
internal ProjectOutputElement (string taskParameter, string itemType, string propertyName, ProjectRootElement containintProject) { TaskParameter = taskParameter; ItemType = itemType; PropertyName = propertyName; ContainingProject = containintProject; }
/// <summary> /// Initializes a new instance of the <see cref="ProjectXmlChangedEventArgs"/> class /// that represents a change to a specific project root element. /// </summary> /// <param name="projectXml">The ProjectRootElement whose content was actually changed.</param> /// <param name="unformattedReason">The unformatted (may contain {0}) reason for the dirty event.</param> /// <param name="formattingParameter">The formatting parameter to use with <paramref name="unformattedReason"/>.</param> internal ProjectXmlChangedEventArgs(ProjectRootElement projectXml, string unformattedReason, string formattingParameter) { ErrorUtilities.VerifyThrowArgumentNull(projectXml, "projectXml"); this.ProjectXml = projectXml; _unformattedReason = unformattedReason; _formattingParameter = formattingParameter; }
private static void AddItems(ProjectRootElement elem, string groupName, params string[] items) { var group = elem.AddItemGroup(); foreach (var item in items) { group.AddItem(groupName, item); } }
public override void Dispose() { base.Dispose(); UnloadCurrentlyOpenProject(); // unload project + userProject: projectFile = null; userProjectFile = null; }
/// <summary> /// Initializes a new instance of the <see cref="ResolvedImport"/> struct. /// </summary> internal ResolvedImport(Project project, ProjectImportElement importingElement, ProjectRootElement importedProject) { ErrorUtilities.VerifyThrowInternalNull(importingElement, "parent"); ErrorUtilities.VerifyThrowInternalNull(importedProject, "child"); _importingElement = importingElement; _importedProject = importedProject; _isImported = !ReferenceEquals(project.Xml, importingElement.ContainingProject); }
protected override void UpgradeProject(ref ProjectRootElement projectXml, ref ProjectRootElement userProjectXml, Action<__VSUL_ERRORLEVEL, string> log) { var envVarsProp = projectXml.Properties.FirstOrDefault(p => p.Name == NodejsConstants.EnvironmentVariables); if (envVarsProp != null) { var globals = projectXml.PropertyGroups.FirstOrDefault() ?? projectXml.AddPropertyGroup(); AddOrSetProperty(globals, NodejsConstants.Environment, envVarsProp.Value.Replace(";", "\r\n")); envVarsProp.Parent.RemoveChild(envVarsProp); log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradedEnvironmentVariables)); } }
internal static ProjectInstance LoadProjectInstance(MSBuild.Evaluation.ProjectCollection projectCollection, ProjectRootElement rootElement, IDictionary<string, string> globalProps) { lock (SolutionProjectCollectionLock) { string toolsVersion = rootElement.ToolsVersion; if (string.IsNullOrEmpty(toolsVersion)) toolsVersion = projectCollection.DefaultToolsVersion; return new ProjectInstance(rootElement, globalProps, toolsVersion, projectCollection); } }
internal ProjectUsingTaskParameterElement (string name, string output, string required, string parameterType, ProjectRootElement containingProject) { Name = name; Output = output; Required = required; ParameterType = parameterType; ContainingProject = containingProject; }
public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties, string toolsVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings) { ProjectCollection = projectCollection; Xml = xml; GlobalProperties = globalProperties; ToolsVersion = toolsVersion; }
/// <summary> /// Creates an unparented ProjectOnErrorElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent. /// </summary> internal static ProjectOnErrorElement CreateDisconnected(string executeTargets, ProjectRootElement containingProject) { XmlElementWithLocation element = containingProject.CreateElement(XMakeElements.onError); ProjectOnErrorElement onError = new ProjectOnErrorElement(element, containingProject); onError.ExecuteTargetsAttribute = executeTargets; return onError; }
/// <summary> /// Constructor called by derived classes, except from ProjectRootElement. /// Parameters may not be null, except parent. /// </summary> internal ProjectElement(XmlElement xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) { ErrorUtilities.VerifyThrowArgumentNull(xmlElement, "xmlElement"); ProjectXmlUtilities.VerifyThrowProjectValidNamespace((XmlElementWithLocation)xmlElement); ErrorUtilities.VerifyThrowArgumentNull(containingProject, "containingProject"); this.XmlElement = (XmlElementWithLocation)xmlElement; _parent = parent; this.ContainingProject = containingProject; }
static ProjectImportElement AddImport( ProjectRootElement projectRoot, string importedProjectFile, ProjectImportLocation importLocation) { if (importLocation == ProjectImportLocation.Top) { return AddImportAtTop(projectRoot, importedProjectFile); } return projectRoot.AddImport(importedProjectFile); }
/// <summary> /// Creates an unparented ProjectImportElement, wrapping an unparented XmlElement. /// Validates the project value. /// Caller should then ensure the element is added to a parent /// </summary> internal static ProjectImportElement CreateDisconnected(string project, ProjectRootElement containingProject) { XmlElementWithLocation element = containingProject.CreateElement(XMakeElements.import); ProjectImportElement import = new ProjectImportElement(element, containingProject); import.Project = project; return import; }
/// <summary> /// Creates an unparented ProjectMetadataElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent. /// </summary> internal static ProjectMetadataElement CreateDisconnected(string name, ProjectRootElement containingProject) { XmlUtilities.VerifyThrowArgumentValidElementName(name); ErrorUtilities.VerifyThrowArgument(!FileUtilities.ItemSpecModifiers.IsItemSpecModifier(name), "ItemSpecModifierCannotBeCustomMetadata", name); ErrorUtilities.VerifyThrowInvalidOperation(XMakeElements.IllegalItemPropertyNames[name] == null, "CannotModifyReservedItemMetadata", name); XmlElementWithLocation element = containingProject.CreateElement(name); return new ProjectMetadataElement(element, containingProject); }
/// <summary> /// Creates an unparented ProjectPropertyElement, wrapping an unparented XmlElement. /// Validates name. /// Caller should then ensure the element is added to the XmlDocument in the appropriate location. /// </summary> internal static ProjectPropertyElement CreateDisconnected(string name, ProjectRootElement containingProject) { XmlUtilities.VerifyThrowArgumentValidElementName(name); ErrorUtilities.VerifyThrowInvalidOperation(XMakeElements.IllegalItemPropertyNames[name] == null && !ReservedPropertyNames.IsReservedProperty(name), "OM_CannotCreateReservedProperty", name); XmlElementWithLocation element = containingProject.CreateElement(name); return new ProjectPropertyElement(element, containingProject); }
private static void AddItemsWithLocation(ProjectRootElement elem, string groupName, params string[] items) { var group = elem.AddItemGroup(); foreach (var item in items) { ProjectItemElement element = group.AddItem(groupName, item); element.AddMetadata("HintPath", @"C:\" + item + ".dll"); } }
void AddPropertyWithCondition(ProjectRootElement projectRoot, string name, string value, string condition) { ProjectPropertyGroupElement groupProperty = projectRoot.CreatePropertyGroupElement(); groupProperty.Condition = condition; projectRoot.AppendChild(groupProperty); ProjectPropertyElement property = projectRoot.CreatePropertyElement(name); groupProperty.AppendChild(property); property.Value = value; property.Condition = condition; }
public ProjectInspector(string filename) { try { xmlProj = Microsoft.Build.Construction.ProjectRootElement.Open(filename); } catch (Microsoft.Build.Exceptions.InvalidProjectFileException) { // leave xmlProj non-initialized, other methods will check its state in prologue } }
protected static void AddOrSetProperty(ProjectRootElement project, string name, string value) { bool anySet = false; foreach (var prop in project.Properties.Where(p => p.Name == name)) { prop.Value = value; anySet = true; } if (!anySet) { project.AddProperty(name, value); } }
/// <summary> /// Creates an unparented ProjectItemDefinitionElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent. /// </summary> internal static ProjectItemDefinitionElement CreateDisconnected(string itemType, ProjectRootElement containingProject) { XmlUtilities.VerifyThrowArgumentValidElementName(itemType); // Orcas inadvertently did not check for reserved item types (like "Choose") in item definitions, // as we do for item types in item groups. So we do not have a check here. // Although we could perhaps add one, as such item definitions couldn't be used // since no items can have the reserved itemType. XmlElementWithLocation element = containingProject.CreateElement(itemType); return new ProjectItemDefinitionElement(element, containingProject); }
public void AddElement(ProjectRootElement root) { var ret = root.AddPropertyGroup (); ret.Condition = Condition; foreach (var p in Properties) { var value = p.Value (); if (string.IsNullOrWhiteSpace (value)) continue; var pe = ret.AddProperty (p.Name, value); pe.Condition = p.Condition; } }
public override void Process( ProjectRootElement project, Dictionary<string, ProjectPropertyGroupElement> groups ) { ProjectPropertyGroupElement imports; if (!groups.TryGetValue("Imports", out imports)) { imports = project.AddPropertyGroup(); } AddOrSetProperty(imports, "PtvsTargetsFile", @"$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets"); project.AddImport("$(PtvsTargetsFile)").Condition = "Exists($(PtvsTargetsFile))"; project.AddImport(@"$(MSBuildToolsPath)\Microsoft.Common.targets").Condition = "!Exists($(PtvsTargetsFile))"; }
public BuildIntegrationTests(ITestOutputHelper logger) : base(logger) { int seed = (int)DateTime.Now.Ticks; this.random = new Random(seed); this.Logger.WriteLine("Random seed: {0}", seed); this.buildManager = new BuildManager(); this.projectCollection = new ProjectCollection(); this.projectDirectory = Path.Combine(this.RepoPath, "projdir"); Directory.CreateDirectory(this.projectDirectory); this.testProject = this.CreateProjectRootElement(); this.globalProperties.Add("NerdbankGitVersioningTasksPath", Environment.CurrentDirectory + "\\"); }
public Project LoadProject(string path) { using FileStream stream = new(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous); using StreamReader readStream = new(stream); using var xmlReader = XmlReader.Create(readStream, s_xmlReaderSettings); var xml = ProjectRootElement.Create(xmlReader); xml.FullPath = path; return(new(xml)); }
/// <summary> /// Initialize an unparented ProjectImportElement /// </summary> internal ProjectImportElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
/// <summary> /// Handle event that is fired when an entry in the project root element cache is removed /// from its strong cache. /// </summary> /// <remarks> /// When an entry is removed from a project root element cache's strong cache, we will remove /// its entries from our string cache. Otherwise the string cache ends up being the only one /// holding references to the Xml documents that have already been dropped. /// </remarks> private void OnStrongCacheEntryRemoved(object sender, ProjectRootElement projectRootElement) { ErrorUtilities.VerifyThrowArgumentNull(projectRootElement, "projectRootElement"); Clear(projectRootElement.XmlDocument); }
/// <summary> /// Initialize a parented ProjectItemElement instance /// </summary> internal ProjectItemElement(XmlElementWithLocation xmlElement, ProjectItemGroupElement parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Initialize an unparented ProjectPropertyGroupElement /// </summary> private ProjectPropertyGroupElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
internal ProjectImportGroupElement(ProjectRootElement containingProject) { ContainingProject = containingProject; }
/// <summary> /// Initialize a parented UsingTaskParameterGroupElement /// </summary> internal UsingTaskParameterGroupElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); VerifyCorrectParent(parent); }
/// <summary> /// Initialize a parented ProjectChooseElement /// </summary> internal ProjectChooseElement(XmlElement xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
internal ProjectExtensionsElement(XmlElement xmlElement, ProjectRootElement parent, ProjectRootElement project) : base(xmlElement, parent, project) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
private ProjectExtensionsElement(XmlElement xmlElement, ProjectRootElement project) : base(xmlElement, null, project) { }
/// <summary> /// Initialize a parented ProjectImportElement /// </summary> internal ProjectImportElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject, SdkReference sdkReference = null) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); ParsedSdkReference = sdkReference; }
/// <summary> /// Called only by the parser to tell the ProjectRootElement its backing XmlElement and its own parent project (itself) /// This can't be done during construction, as it hasn't loaded the document at that point and it doesn't have a 'this' pointer either. /// </summary> internal void SetProjectRootElementFromParser(XmlElementWithLocation xmlElement, ProjectRootElement projectRootElement) { this.XmlElement = xmlElement; this.ContainingProject = projectRootElement; }
/// <summary> /// Initialize an unparented ProjectItemElement instance /// </summary> private ProjectItemElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
/// <inheritdoc /> protected override ProjectElement CreateNewInstance(ProjectRootElement owner) { return(owner.CreateWhenElement(this.Condition)); }
/// <inheritdoc /> protected override ProjectElement CreateNewInstance(ProjectRootElement owner) { return(owner.CreatePropertyGroupElement()); }
/// <summary> /// Initialize a parented ProjectWhenElement /// </summary> internal ProjectWhenElement(XmlElement xmlElement, ProjectChooseElement parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Initialize an unparented ProjectWhenElement /// </summary> private ProjectWhenElement(XmlElement xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
private ProjectImportGroupElement ParseProjectImportGroupElement(XmlElementWithLocation element, ProjectRootElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnlyConditionAndLabel); ProjectImportGroupElement importGroup = new ProjectImportGroupElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectErrorUtilities.VerifyThrowInvalidProject ( childElement.Name == XMakeElements.import, childElement.Location, "UnrecognizedChildElement", childElement.Name, element.Name ); ProjectImportElement item = ParseProjectImportElement(childElement, importGroup); importGroup.AppendParentedChildNoChecks(item); } return(importGroup); }
/// <summary> /// Creates an unparented ProjectPropertyGroupElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent /// </summary> internal static ProjectPropertyGroupElement CreateDisconnected(ProjectRootElement containingProject) { XmlElementWithLocation element = containingProject.CreateElement(XMakeElements.propertyGroup); return(new ProjectPropertyGroupElement(element, containingProject)); }
/// <inheritdoc /> protected override ProjectElement CreateNewInstance(ProjectRootElement owner) { return(new WrapperForProjectRootElement(this.ContainingProject)); }
/// <summary> /// Initialize a parented ProjectUsingTaskElement /// </summary> internal ProjectUsingTaskElement(XmlElementWithLocation xmlElement, ProjectRootElement parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
/// <summary> /// Constructor /// </summary> internal WrapperForProjectRootElement(ProjectRootElement containingProject) { ErrorUtilities.VerifyThrowInternalNull(containingProject, "containingProject"); this.ContainingProject = containingProject; }
/// <inheritdoc /> protected override ProjectElement CreateNewInstance(ProjectRootElement owner) { return(owner.CreateItemElement(this.ItemType, this.Include)); }
/// <summary> /// Returns a new instance of this same type. /// Any properties that cannot be set after creation should be set to copies of values /// as set for this instance. /// </summary> /// <param name="owner">The factory to use for creating the new instance.</param> protected abstract ProjectElement CreateNewInstance(ProjectRootElement owner);
/// <summary> /// Initialize an unparented UsingTaskParameterGroupElement /// </summary> private UsingTaskParameterGroupElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
internal ProjectCommentElement(ProjectRootElement containingProject) { ContainingProject = containingProject; }
internal ProjectItemElement(string itemType, ProjectRootElement containingProject) { ItemType = itemType; ContainingProject = containingProject; }
internal ProjectExtensionsElement(ProjectRootElement containingProject) { ContainingProject = containingProject; }