下面列出了怎么用org.eclipse.emf.ecore.resource.ResourceSet的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* @generated NOT
*/
@Override
public Profile getProfile ()
{
if ( this.profile == null )
{
final ResourceSet rs = new ResourceSetImpl ();
final Resource r = rs.createResource ( URI.createURI ( DEFAULT_URI ), "org.eclipse.scada.configuration.world.osgi.profile" );
try
{
r.load ( null );
}
catch ( final IOException e )
{
throw new RuntimeException ( e );
}
this.profile = (Profile)EcoreUtil.getObjectByType ( r.getContents (), ProfilePackage.Literals.PROFILE );
if ( this.profile == null )
{
throw new IllegalStateException ( String.format ( "Resource loaded from %s does not contain an object of type %s", DEFAULT_URI, Profile.class.getName () ) );
}
}
return this.profile;
}
protected List<EPackageInfo> createEPackageInfosFromGenModel(URI genModelURI) {
ResourceSet resourceSet = createResourceSet(genModelURI);
Resource resource = resourceSet.getResource(genModelURI, true);
List<EPackageInfo> ePackageInfos = Lists.newArrayList();
for (TreeIterator<EObject> i = resource.getAllContents(); i.hasNext();) {
EObject next = i.next();
if (next instanceof GenPackage) {
GenPackage genPackage = (GenPackage) next;
EPackage ePackage = genPackage.getEcorePackage();
URI importURI;
if(ePackage.eResource() == null) {
importURI = URI.createURI(ePackage.getNsURI());
} else {
importURI = ePackage.eResource().getURI();
}
EPackageInfo ePackageInfo = new EPackageInfo(ePackage, importURI, genModelURI, genPackage
.getQualifiedPackageInterfaceName(), genPackage.getGenModel().getModelPluginID());
ePackageInfos.add(ePackageInfo);
} else if (!(next instanceof GenModel)) {
i.prune();
}
}
return ePackageInfos;
}
protected List<URI> collectResources(Iterable<String> roots, ResourceSet resourceSet) {
String extensions = Joiner.on("|").join(languages.keySet());
NameBasedFilter nameBasedFilter = new NameBasedFilter();
// TODO test with whitespaced file extensions
nameBasedFilter.setRegularExpression(".*\\.(?:(" + extensions + "))$");
List<URI> resources = new ArrayList<>();
Multimap<String, URI> modelsFound = new PathTraverser().resolvePathes(IterableExtensions.toList(roots),
(URI input) -> {
boolean matches = nameBasedFilter.matches(input);
if (matches) {
forceDebugLog("Adding file \'" + input + "\'");
resources.add(input);
}
return matches;
});
modelsFound.asMap().forEach((String uri, Collection<URI> resource) -> {
File file = new File(uri);
if (resource != null && !file.isDirectory() && file.getName().endsWith(".jar")) {
registerBundle(file);
}
});
return resources;
}
private ResourceSet getResourceSet() {
// TODO Auto-generated method stub
ResourceSet resourceSet = new ResourceSetImpl();
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/BPMN/20100524/MODEL", Bpmn2Package.eINSTANCE);
(EPackage.Registry.INSTANCE).put("http://www.founderfix.com/fixflow", FixFlowPackage.eINSTANCE);
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/DD/20100524/DI", DiPackage.eINSTANCE);
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/DD/20100524/DC", DcPackage.eINSTANCE);
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/BPMN/20100524/DI", BpmnDiPackage.eINSTANCE);
FixFlowPackage.eINSTANCE.eClass();
FixFlowPackage xxxPackage = FixFlowPackage.eINSTANCE;
EPackage.Registry.INSTANCE.put(xxxPackage.getNsURI(), xxxPackage);
Bpmn2ResourceFactoryImpl ddd = new Bpmn2ResourceFactoryImpl();
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("fixflow", ddd);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("bpmn", ddd);
resourceSet.getPackageRegistry().put(xxxPackage.getNsURI(), xxxPackage);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("bpmn", ddd);
return resourceSet;
}
protected ResourceSet getResourceSetForModel(final List<Exception> exceptions) {
final ResourceSet rs = new ResourceSetImpl();
final XMIResourceFactoryImpl xmiResourceFactory = new XMIResourceFactoryImpl();
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore", xmiResourceFactory);
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", xmiResourceFactory);
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put(GenconfUtils.GENCONF_EXTENSION_FILE,
xmiResourceFactory);
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("uml", xmiResourceFactory);
final ResourceSet res = M2DocUtils.createResourceSetForModels(exceptions, generation, rs,
GenconfUtils.getOptions(generation));
res.getURIConverter().getURIHandlers().add(0, uriHandler);
return res;
}
@Override
public void findReferences(final TargetURIs targetURIs, IResourceDescription resourceDescription,
IResourceAccess resourceAccess, final Acceptor acceptor, final IProgressMonitor monitor) {
final URI resourceURI = resourceDescription.getURI();
if (resourceAccess != null && targetURIs.containsResource(resourceURI)) {
IUnitOfWork.Void<ResourceSet> finder = new IUnitOfWork.Void<ResourceSet>() {
@Override
public void process(final ResourceSet state) throws Exception {
Resource resource = state.getResource(resourceURI, true);
findReferences(targetURIs, resource, acceptor, monitor);
}
};
resourceAccess.readOnly(resourceURI, finder);
} else {
findReferencesInDescription(targetURIs, resourceDescription, resourceAccess, acceptor, monitor);
}
}
@Test
public void testEmptyProject() {
try {
final IProject project = IResourcesSetupUtil.createProject("MyProject");
IResourcesSetupUtil.addNature(project, XtextProjectHelper.NATURE_ID);
final ResourceSet rs = this.liveScopeResourceSetProvider.get(project);
StringConcatenation _builder = new StringConcatenation();
_builder.append("container MyProject isEmpty=true {");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final String expected = _builder.toString();
Assert.assertEquals(expected, this.formatContainers(rs));
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
public <Result> Result useTemporaryResource(
ResourceSet resourceSet, Grammar language,
AbstractRule rootRule, String content, IUnitOfWork<Result, XtextResource> runnable) {
XtextResource resource = languageRegistry.createTemporaryResourceIn(language, resourceSet);
if (rootRule != null)
PartialParser.assignRootRule(resource, (ParserRule) rootRule);
try {
resource.load(new StringInputStream(content, resource.getEncoding()), null);
return runnable.exec(resource);
} catch(Exception e) {
throw new RuntimeException(e);
} finally {
if (resource != null) {
if (resource.isLoaded())
resource.unload();
resourceSet.getResources().remove(resource);
}
}
}
/**
* Serializes the given {@link JSONDocument} using the Xtext serialization facilities provided by the JSON language.
*/
public static String serializeJSON(JSONDocument document) {
ISerializer jsonSerializer = N4LanguageUtils.getServiceForContext(FILE_EXTENSION, ISerializer.class).get();
ResourceSet resourceSet = N4LanguageUtils.getServiceForContext(FILE_EXTENSION, ResourceSet.class).get();
// Use temporary Resource as AbstractFormatter2 implementations can only format
// semantic elements that are contained in a Resource.
Resource temporaryResource = resourceSet.createResource(URIUtils.toFileUri("__synthetic." + FILE_EXTENSION));
temporaryResource.getContents().add(document);
// create string writer as serialization output
StringWriter writer = new StringWriter();
// enable formatting as serialization option
SaveOptions serializerOptions = SaveOptions.newBuilder().format().getOptions();
try {
jsonSerializer.serialize(document, writer, serializerOptions);
return writer.toString();
} catch (IOException e) {
throw new RuntimeException("Failed to serialize JSONDocument " + document, e);
}
}
/**
* Tries to find {@link Constant} that my be defined in the same formatter or in any formatter that is extended by the current formatter.
* An appropriate constant should be matched by comparing its name with the desired one.
*
* @param resourceSet
* to be used for loading
* @param node
* parse subtree for the reference
* @return A singleton list containing the desired constant, or an empty list if not found.
*/
private List<EObject> getConstant(final ResourceSet resourceSet, final INode node) {
String constantFullyQualifiedName = NodeModelUtils.getTokenText(node);
String formatName = URI.createURI(constantFullyQualifiedName).trimFileExtension().toString();
if (formatName != null) {
FormatConfiguration result = loadExtendedFormatConfiguration(formatName, resourceSet);
if (result != null) {
EList<Constant> constants = result.getConstants();
for (Constant constant : constants) {
if (constantFullyQualifiedName.equals(formatName + "." + constant.getName())) {
return Collections.<EObject> singletonList(constant);
}
}
}
}
return Collections.emptyList();
}
/** Copy a model based on a number of {@link URI}s. */
public static List<URI> copy(List<URI> sourceURIs, Metamodel metamodel,
URIMapper mapper) throws IOException {
final List<URI> targetURIs = new ArrayList<URI>();
final ResourceSet model = ResourceUtils.loadResourceSet(sourceURIs, metamodel
.getEPackages());
for (final Resource resource : model.getResources()) {
if (resource.getURI() == null
|| resource.getURI().isPlatformPlugin()) {
continue;
}
final URI targetURI = mapper.map(resource.getURI());
if (targetURI != null) {
resource.setURI(targetURI);
targetURIs.add(targetURI);
}
}
ResourceUtils.saveResourceSet(model, null);
return targetURIs;
}
/**
* Deletes all entries in the Xtext index that start with one of the given project URIs will be cleaned from the
* index.
*
* @param toBeWiped
* URIs of project roots
*/
public void wipeURIsFromIndex(IProgressMonitor monitor, Collection<FileURI> toBeWiped) {
Set<String> toBeWipedStrings = new HashSet<>();
for (FileURI toWipe : toBeWiped) {
toBeWipedStrings.add(toWipe.toString());
N4JSProjectName projectName = toWipe.getProjectName();
validatorExtension.clearAllMarkersOfExternalProject(projectName);
}
ResourceSet resourceSet = core.createResourceSet(Optional.absent());
IResourceDescriptions index = core.getXtextIndex(resourceSet);
Set<URI> toBeRemoved = new HashSet<>();
for (IResourceDescription res : index.getAllResourceDescriptions()) {
URI resUri = res.getURI();
String resUriString = resUri.toString();
for (String toWipeProject : toBeWipedStrings) {
if (resUriString.startsWith(toWipeProject)) {
toBeRemoved.add(resUri);
break;
}
}
}
builderState.clean(toBeRemoved, monitor);
}
protected ResourceSet createResourceSet(@Extension final AbstractHierarchyBuilderTest.HierarchyBuilderTestConfiguration configuration) {
try {
final XtextResourceSet resourceSet = this.resourceSetProvider.get();
for (final Pair<String, String> model : configuration.models) {
{
final Resource resource = resourceSet.createResource(URI.createURI(model.getKey()));
String _value = model.getValue();
LazyStringInputStream _lazyStringInputStream = new LazyStringInputStream(_value, "UTF-8");
resource.load(_lazyStringInputStream, null);
this._validationTestHelper.assertNoIssues(resource);
}
}
return resourceSet;
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
private void createUMLFile(URI uri, String modelname){
Model model = UMLFactory.eINSTANCE.createModel();
model.setName(modelname);
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(
UMLResource.FILE_EXTENSION,
UMLResource.Factory.INSTANCE
);
Resource modelResource = resourceSet.createResource(uri);
modelResource.getContents().add(model);
try {
modelResource.save(null);
} catch (IOException e) {
e.printStackTrace();
}
}
public T load ( final URI uri, final String contentTypeId ) throws IOException
{
final ResourceSet rs = new ResourceSetImpl ();
final Resource r = rs.createResource ( uri, contentTypeId );
r.load ( null );
for ( final Object o : r.getContents () )
{
if ( this.clazz.isAssignableFrom ( o.getClass () ) )
{
return this.clazz.cast ( o );
}
}
throw new IllegalStateException ( String.format ( "Model %s does not contain an object of type %s", uri, this.clazz ) );
}
@Override
public Set<IService> getServices(IReadOnlyQueryEnvironment queryEnvironment, ResourceSet resourceSetForModels,
Map<String, String> options) {
final Set<IService> res = new LinkedHashSet<>();
final String sessionURIStr = options.get(M2DocSiriusUtils.SIRIUS_SESSION_OPTION);
if (sessionURIStr != null) {
URI sessionURI = URI.createURI(sessionURIStr, false);
final String genconfURIStr = options.get(GenconfUtils.GENCONF_URI_OPTION);
if (genconfURIStr != null) {
sessionURI = sessionURI.resolve(URI.createURI(genconfURIStr));
}
if (URIConverter.INSTANCE.exists(sessionURI, Collections.emptyMap())) {
final Session session = SessionManager.INSTANCE.getSession(sessionURI, new NullProgressMonitor());
final boolean forceRefresh = Boolean.valueOf(options.get(M2DocSiriusUtils.SIRIUS_FORCE_REFRESH));
final M2DocSiriusServices serviceInstance = new M2DocSiriusServices(session, forceRefresh);
res.addAll(ServiceUtils.getServices(queryEnvironment, serviceInstance));
services.put(queryEnvironment, serviceInstance);
}
}
return res;
}
protected File createStubs(ResourceSet resourceSet) {
File outputDirectory = createTempDir("stubs");
JavaIoFileSystemAccess fileSystemAccess = javaIoFileSystemAccessProvider.get();
fileSystemAccess.setOutputPath(outputDirectory.toString());
List<Resource> resources = Lists.newArrayList(resourceSet.getResources());
for (Resource resource : resources) {
IResourceDescription description = resourceDescriptionManager.getResourceDescription(resource);
stubGenerator.doGenerateStubs(fileSystemAccess, description);
}
return outputDirectory;
}
@Test public void testUriFormat() throws Exception {
URI uri = EcoreUtil.getURI(SubsubpackagePackage.Literals.ANOTHER_TYPE);
assertTrue(AsubpackagePackage.eNS_URI.equals(uri.trimFragment().toString()));
ResourceSet set = new ResourceSetImpl();
EObject eObject = set.getEObject(uri, true);
assertSame(SubsubpackagePackage.Literals.ANOTHER_TYPE, eObject);
}
/**
* This can be used to update the resource set's package registry with all needed EPackages.
*
* @param resourceSet
* The resource set which registry has to be updated.
* @generated
*/
@Override
public void registerPackages(ResourceSet resourceSet) {
super.registerPackages(resourceSet);
if (!isInWorkspace(org.eclipse.uml2.uml.UMLPackage.class)) {
resourceSet.getPackageRegistry().put(org.eclipse.uml2.uml.UMLPackage.eINSTANCE.getNsURI(), org.eclipse.uml2.uml.UMLPackage.eINSTANCE);
}
/*
* If you want to change the content of this method, do NOT forget to change the "@generated"
* tag in the Javadoc of this method to "@generated NOT". Without this new tag, any compilation
* of the Acceleo module with the main template that has caused the creation of this class will
* revert your modifications.
*/
/*
* If you need additional package registrations, you can register them here. The following line
* (in comment) is an example of the package registration for UML.
*
* You can use the method "isInWorkspace(Class c)" to check if the package that you are about to
* register is in the workspace.
*
* To register a package properly, please follow the following conventions:
*
* If the package is located in another plug-in, already installed in Eclipse. The following content should
* have been generated at the beginning of this method. Do not register the package using this mechanism if
* the metamodel is located in the workspace.
*
* if (!isInWorkspace(UMLPackage.class)) {
* // The normal package registration if your metamodel is in a plugin.
* resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
* }
*
* If the package is located in another project in your workspace, the plugin containing the package has not
* been register by EMF and Acceleo should register it automatically. If you want to use the generator in
* stand alone, the regular registration (seen a couple lines before) is needed.
*
* To learn more about Package Registration, have a look at the Acceleo documentation (Help -> Help Contents).
*/
}
/**
* This can be used to update the resource set's package registry with all needed EPackages.
*
* @param resourceSet
* The resource set which registry has to be updated.
* @generated
*/
@Override
public void registerPackages(ResourceSet resourceSet) {
super.registerPackages(resourceSet);
if (!isInWorkspace(org.eclipse.uml2.uml.UMLPackage.class)) {
resourceSet.getPackageRegistry().put(org.eclipse.uml2.uml.UMLPackage.eINSTANCE.getNsURI(), org.eclipse.uml2.uml.UMLPackage.eINSTANCE);
}
/*
* If you want to change the content of this method, do NOT forget to change the "@generated"
* tag in the Javadoc of this method to "@generated NOT". Without this new tag, any compilation
* of the Acceleo module with the main template that has caused the creation of this class will
* revert your modifications.
*/
/*
* If you need additional package registrations, you can register them here. The following line
* (in comment) is an example of the package registration for UML.
*
* You can use the method "isInWorkspace(Class c)" to check if the package that you are about to
* register is in the workspace.
*
* To register a package properly, please follow the following conventions:
*
* If the package is located in another plug-in, already installed in Eclipse. The following content should
* have been generated at the beginning of this method. Do not register the package using this mechanism if
* the metamodel is located in the workspace.
*
* if (!isInWorkspace(UMLPackage.class)) {
* // The normal package registration if your metamodel is in a plugin.
* resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
* }
*
* If the package is located in another project in your workspace, the plugin containing the package has not
* been register by EMF and Acceleo should register it automatically. If you want to use the generator in
* stand alone, the regular registration (seen a couple lines before) is needed.
*
* To learn more about Package Registration, have a look at the Acceleo documentation (Help -> Help Contents).
*/
}
/**
* Gets the Generation from the given {@link URI}.
*
* @param uri
* the {@link URI}
* @return the Generation from the given {@link URI}
*/
public static Generation getGeneration(URI uri) {
ResourceSet rs = new ResourceSetImpl();
Resource modelResource = rs.getResource(uri, true);
if (modelResource != null && !modelResource.getContents().isEmpty()) {
EObject root = modelResource.getContents().get(0);
if (root instanceof Generation) {
return (Generation) root;
}
}
return null;
}
/** Create the appender for a Sarl SarlBehaviorUnit.
* @param name the name of the SarlBehaviorUnit
* @param resourceSet the set of the resources that must be used for
* containing the generated resource, and resolving types from names.
* @return the appender.
*/
@Pure
public SarlBehaviorUnitSourceAppender buildSarlBehaviorUnit(String name, ResourceSet resourceSet) {
SarlBehaviorUnitSourceAppender a = new SarlBehaviorUnitSourceAppender(createSarlBehaviorUnit(name, resourceSet));
getInjector().injectMembers(a);
return a;
}
UserDataAwareScope(IScope outer, ISelectable selectable, Predicate<IEObjectDescription> filter, EClass type,
boolean ignoreCase, ResourceSet resourceSet, CanLoadFromDescriptionHelper canLoadFromDescriptionHelper,
IContainer container) {
super(outer, selectable, filter, type, ignoreCase);
this.resourceSet = resourceSet;
this.canLoadFromDescriptionHelper = canLoadFromDescriptionHelper;
this.container = container;
this.type = type;
}
public Declarators.DeclaratorsData getDeclaratorData(final TargetURIs targetURIs, final IReferenceFinder.IResourceAccess resourceAccess) {
Declarators.DeclaratorsData result = targetURIs.<Declarators.DeclaratorsData>getUserData(Declarators.KEY);
if ((result != null)) {
return result;
}
final HashSet<QualifiedName> declaratorNames = CollectionLiterals.<QualifiedName>newHashSet();
final Consumer<URI> _function = (URI uri) -> {
final IUnitOfWork<Object, ResourceSet> _function_1 = (ResourceSet it) -> {
Object _xblockexpression = null;
{
final Consumer<URI> _function_2 = (URI objectURI) -> {
final EObject object = it.getEObject(objectURI, true);
if ((object != null)) {
final JvmType type = EcoreUtil2.<JvmType>getContainerOfType(object, JvmType.class);
if ((type != null)) {
QualifiedName _lowerCase = this.nameConverter.toQualifiedName(type.getIdentifier()).toLowerCase();
declaratorNames.add(_lowerCase);
QualifiedName _lowerCase_1 = this.nameConverter.toQualifiedName(type.getQualifiedName('.')).toLowerCase();
declaratorNames.add(_lowerCase_1);
}
}
};
targetURIs.getEObjectURIs(uri).forEach(_function_2);
_xblockexpression = null;
}
return _xblockexpression;
};
resourceAccess.<Object>readOnly(uri, _function_1);
};
targetURIs.getTargetResourceURIs().forEach(_function);
Declarators.DeclaratorsData _declaratorsData = new Declarators.DeclaratorsData(declaratorNames);
result = _declaratorsData;
targetURIs.<Declarators.DeclaratorsData>putUserData(Declarators.KEY, result);
return result;
}
private void createAllResourcesWorkspace(ResourceSet resourceSet) {
final Set<URI> uris = newHashSet();
for (IN4JSProject project : findAllProjects()) {
project.getSourceContainers().forEach(sc -> {
for (URI sourceFile : sc) {
if (isN4File(sourceFile) && uris.add(sourceFile)) {
resourceSet.createResource(sourceFile);
}
}
});
}
}
protected URI computeUnusedUri(ResourceSet resourceSet) {
String name = "__synthetic";
for (int i = 0; i < Integer.MAX_VALUE; i++) {
URI syntheticUri = URI.createURI(name + i + "." + parser.fileExtension);
syntheticUri = resourceSet.getURIConverter().normalize(syntheticUri);
if (resourceSet.getResource(syntheticUri, false) == null)
return syntheticUri;
}
throw new IllegalStateException();
}
/**
* @throws InterruptedException
* thrown when user cancels the operation
* @see N4JSDReader#readN4JSDs(Collection, Function, SubMonitorMsg)
*/
public Collection<SpecInfo> readN4JSDs(Collection<IN4JSProject> projects,
Function<IN4JSProject, ResourceSet> resSetProvider, SubMonitorMsg monitor) throws InterruptedException {
SubMonitorMsg sub = monitor.convert(100 * (projects.size() + 2));
n4jsdReader.issueAcceptor = this.issueAcceptor;
return n4jsdReader.readN4JSDs(projects, resSetProvider, sub);
}
@Override
protected List<JvmType> doVisitParameterizedTypeReference(ParameterizedTypeReference reference, ResourceSet resourceSet) {
JvmType type = reference.getType();
if (!type.eIsProxy()) {
if (type instanceof JvmTypeParameter) {
return getRawTypesFromConstraints(reference.getOwner(), (JvmTypeParameter) type, resourceSet);
}
return Collections.singletonList(type);
}
return Collections.emptyList();
}
protected void enhanceCompoundReference(List<LightweightTypeReference> references,
CompoundTypeReference result, ResourceSet resourceSet) {
if (references.isEmpty()) {
throw new IllegalStateException("References may not be empty");
}
for(LightweightTypeReference component: references) {
result.addComponent(component.accept(this, resourceSet));
}
}
@Override
public XtextResource createResource() {
ResourceSet resourceSet = resourceSetProvider.get(null);
Resource grammarResource = resourceSet.createResource(
URI.createURI(SYNTHETIC_SCHEME + ":/" + grammarAccess.getGrammar().getName() + ".xtext"));
grammarResource.getContents().add(EcoreUtil.copy(grammarAccess.getGrammar()));
XtextResource result = (XtextResource) resourceSet.createResource(
URI.createURI(SYNTHETIC_SCHEME + ":/" + grammarAccess.getGrammar().getName() + ".___singlecodetemplate"));
resourceSet.getResources().add(result);
return result;
}