org.jboss.shrinkwrap.api.GenericArchive Java Examples

The following examples show how to use org.jboss.shrinkwrap.api.GenericArchive. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TestVDBPublisher.java    From syndesis with Apache License 2.0 6 votes vote down vote up
@Test
public void testGenerateDataSource() throws IOException {
    TeiidOpenShiftClient generator = testDataSetup();

    generator.normalizeDataSourceNames(vdb);

    for (Model model: vdb.getModels()) {
        if (!model.isSource()) {
            continue;
        }
        GenericArchive archive = ShrinkWrap.create(GenericArchive.class, "contents.tar");
        generator.buildDataSourceBuilders(model, archive);
        InputStream dsIs = archive.get("/src/main/java/io/integration/DataSourcesaccountsxyz.java").getAsset().openStream();
        String ds = ObjectConverterUtil.convertToString(dsIs);
        assertEquals(ObjectConverterUtil.convertFileToString(new File("src/test/resources/generated-ds.txt")), ds);
    }
}
 
Example #2
Source File: Deployments.java    From javaee7-petclinic with GNU General Public License v2.0 6 votes vote down vote up
public static WebArchive createVetDeployment() {
    File[] deps = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeDependencies().resolve().withTransitivity().asFile();
    return ShrinkWrap.create(WebArchive.class, "vet.war")
            .addClasses(
                    SpecialtyController.class, VetController.class, LanguageBean.class,
                    SpecialtyConverter.class,
                    SpecialtyDao.class, SpecialtyDaoImpl.class,
                    VetDao.class, VetDaoImpl.class,
                    Owner.class, Pet.class, PetType.class,
                    Specialty.class, Vet.class, Visit.class,
                    VetSortingBean.class)
            .merge(ShrinkWrap.create(GenericArchive.class).as(ExplodedImporter.class)
                    .importDirectory(WEBAPP_SRC).as(GenericArchive.class),
                    "/", Filters.include(".*\\.xhtml$|.*\\.html$"))
            .addAsResource("META-INF/persistence.xml")
            .addAsResource("messages_de.properties")
            .addAsResource("messages_en.properties")
            .addAsLibraries(deps)
            .addAsWebInfResource(
                    new StringAsset("<faces-config version=\"2.2\"/>"),
                    "faces-config.xml");
}
 
Example #3
Source File: Deployments.java    From javaee7-petclinic with GNU General Public License v2.0 6 votes vote down vote up
public static WebArchive createPetTypeDeployment() {
    File[] deps = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeDependencies().resolve().withTransitivity().asFile();
    return ShrinkWrap.create(WebArchive.class, "pettypes.war")
            .addClasses(PetTypeController.class, LanguageBean.class,
                    PetTypeDao.class, PetTypeDaoImpl.class,
                    Owner.class, Pet.class, PetType.class,
                    Specialty.class, Vet.class, Visit.class)
            .merge(ShrinkWrap.create(GenericArchive.class).as(ExplodedImporter.class)
                    .importDirectory(WEBAPP_SRC).as(GenericArchive.class),
                    "/", Filters.include(".*\\.xhtml$|.*\\.html$"))
            .addAsResource("META-INF/persistence.xml")
            .addAsResource("messages_de.properties")
            .addAsResource("messages_en.properties")
            .addAsLibraries(deps)
            .addAsWebInfResource(
                    new StringAsset("<faces-config version=\"2.2\"/>"),
                    "faces-config.xml");
}
 
Example #4
Source File: Deployments.java    From javaee7-petclinic with GNU General Public License v2.0 6 votes vote down vote up
public static WebArchive createSpecialtiesDeployment() {
    File[] deps = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeDependencies().resolve().withTransitivity().asFile();
    WebArchive war = null;
    try {
        war = ShrinkWrap.create(WebArchive.class, "specialties.war")
            .addClasses(SpecialtyController.class, LanguageBean.class,
                    SpecialtyDao.class, SpecialtyDaoImpl.class,
                    Owner.class, Pet.class, PetType.class,
                    Specialty.class, Vet.class, Visit.class)
            .merge(ShrinkWrap.create(GenericArchive.class).as(ExplodedImporter.class)
                    .importDirectory(WEBAPP_SRC).as(GenericArchive.class),
                    "/", Filters.include(".*\\.xhtml$|.*\\.html$"))
            .addAsResource("META-INF/persistence.xml")
            .addAsResource("messages_de.properties")
            .addAsResource("messages_en.properties")
            .addAsLibraries(deps)
            .addAsWebInfResource(
                    new StringAsset("<faces-config version=\"2.2\"/>"),
                    "faces-config.xml");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return war;
}
 
Example #5
Source File: EurostagScenario.java    From ipst with Mozilla Public License 2.0 6 votes vote down vote up
public GenericArchive writeFaultSeqArchive(Domain domain, List<Contingency> contingencies, Network network, EurostagDictionary dictionary, Function<Integer, String> seqFileNameFct) throws IOException {
    if ((contingencies == null) || (contingencies.isEmpty())) {
        throw new RuntimeException("contingencies list is empty, cannot write .seq scenario files");
    }
    GenericArchive archive = domain.getArchiveFactory().create(GenericArchive.class);
    try (FileSystem fileSystem = ShrinkWrapFileSystems.newFileSystem(archive)) {
        Path rootDir = fileSystem.getPath("/");
        for (int i = 0; i < contingencies.size(); i++) {
            Contingency contingency = contingencies.get(i);
            Path seqFile = rootDir.resolve(seqFileNameFct.apply(i));
            try (BufferedWriter writer = Files.newBufferedWriter(seqFile, StandardCharsets.UTF_8)) {
                writeFaultSeq(writer, contingency, network, dictionary);
            }
        }
    }
    return archive;
}
 
Example #6
Source File: TeiidOpenShiftClient.java    From syndesis with Apache License 2.0 5 votes vote down vote up
protected void buildDataSourceBuilders(Model model, GenericArchive archive) {
    for (String name : model.getSourceNames()) {
        try {
            String str = null;
            String replacement = model.getSourceConnectionJndiName(name);
            String translatorName = model.getSourceTranslatorName(name);
            final String resourceName;
            if ("salesforce".equals(translatorName)) {
                resourceName = "s2i/Salesforce.mustache";
            } else if ("mongodb".equals(translatorName)) {
                resourceName = "s2i/MongoDB.mustache";
            } else {
                resourceName = "s2i/Jdbc.mustache";
            }

            try (InputStream is = this.getClass().getClassLoader().getResourceAsStream(resourceName)) {
                str = inputStreamToString(is);
            }

            str = str.replace("{{packageName}}", "io.integration");
            str = str.replace("{{dsName}}", replacement);

            archive.add(new ByteArrayAsset(ObjectConverterUtil
                    .convertToByteArray(new ByteArrayInputStream(str.getBytes("UTF-8")))),
                    "/src/main/java/io/integration/DataSources" + replacement + ".java");

        } catch (IOException e) {
            throw handleError(e);
        }
    }
}
 
Example #7
Source File: Mvn.java    From tomee with Apache License 2.0 5 votes vote down vote up
private Builder add(final Archive<?> webArchive, final File dir, final String root) {
    if (dir == null || !dir.exists()) {
        return this;
    }

    final KnownResourcesFilter filter = new KnownResourcesFilter(dir, root, this.filter);
    filter.update(
        webArchive.merge(
            ShrinkWrap.create(GenericArchive.class).as(ExplodedImporter.class)
                .importDirectory(dir).as(GenericArchive.class), root, filter));

    return this;
}
 
Example #8
Source File: MoviesArquillianHtmlUnitTest.java    From tomee with Apache License 2.0 5 votes vote down vote up
@Deployment
public static WebArchive createDeployment() {
    WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
            .addClasses(Movie.class, MoviesBean.class, MoviesArquillianHtmlUnitTest.class, ActionServlet.class)
            .addAsResource(new ClassLoaderAsset("META-INF/persistence.xml"), "META-INF/persistence.xml");

    war.merge(ShrinkWrap.create(GenericArchive.class).as(ExplodedImporter.class)
                    .importDirectory(Basedir.basedir(WEBAPP_SRC)).as(GenericArchive.class),
            "/", Filters.includeAll());

    return war;
}
 
Example #9
Source File: Deployments.java    From javaee7-petclinic with GNU General Public License v2.0 5 votes vote down vote up
public static WebArchive createOwnerDeployment() {
    File[] deps = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeDependencies().resolve().withTransitivity().asFile();
    WebArchive war = null;
    try {
            war = ShrinkWrap.create(WebArchive.class, "owner.war")
            .addClasses(OwnerController.class, PetTypeController.class, LanguageBean.class,
                    OwnerService.class, OwnerServiceImpl.class,
                    OwnerDao.class, OwnerDaoImpl.class, PetDao.class, PetDaoImpl.class,
                    VisitDao.class, VisitDaoImpl.class,
                    PetTypeDao.class, PetTypeDaoImpl.class,
                    Owner.class, Pet.class, PetType.class,
                    Specialty.class, Vet.class, Visit.class)
            .merge(ShrinkWrap.create(GenericArchive.class).as(ExplodedImporter.class)
                    .importDirectory(WEBAPP_SRC).as(GenericArchive.class),
                    "/", Filters.include(".*\\.xhtml$"))
            .addAsResource("META-INF/persistence.xml")
            .addAsResource("messages_de.properties")
            .addAsResource("messages_en.properties")
            .addAsLibraries(deps)
            .addAsWebInfResource(
                            new StringAsset("<faces-config version=\"2.2\"/>"),
                            "faces-config.xml");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return war;
}
 
Example #10
Source File: DeploymentArchiveUtils.java    From wildfly-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Create CLI archive for deployment testing
 *
 * @param archiveName Name of archive
 * @param content Content in archive file deploy.scr
 * @return Return created {@link File} instance
 */
public static File createCliArchive(String archiveName, String content) {

    final GenericArchive cliArchive = ShrinkWrap.create(GenericArchive.class, archiveName);
    cliArchive.add(new StringAsset(content), "deploy.scr");

    final String tempDir = TestSuiteEnvironment.getTmpDir();
    final File file = new File(tempDir, cliArchive.getName());
    cliArchive.as(ZipExporter.class).exportTo(file, true);
    return file;
}
 
Example #11
Source File: DistributionController.java    From arquillian-container-chameleon with Apache License 2.0 5 votes vote down vote up
private File fetchFromMavenRepository(ExecutorService executor) {
    final MavenCoordinate distributableCoordinate = toMavenCoordinate(targetAdapter.distribution());

    if (distributableCoordinate != null) {
        final File targetDirectory = new File(new File(distributionDownloadFolder, "server"),
            distributableCoordinate.getArtifactId() + "_" + distributableCoordinate.getVersion());

        if (serverAlreadyDownloaded(targetDirectory)) {
            return getDistributionHome(targetDirectory);
        }

        System.out.println(
            "Arquillian Chameleon: downloading distribution " + distributableCoordinate.toCanonicalForm());
        Future<File> uncompressDirectory = executor.submit(new Callable<File>() {
            @Override
            public File call() throws Exception {
                return Maven.resolver().resolve(distributableCoordinate.toCanonicalForm())
                    .withoutTransitivity()
                    .asSingle(GenericArchive.class)
                    .as(ExplodedExporter.class)
                    .exportExploded(targetDirectory, ".");
            }
        });

        try {
            while (!uncompressDirectory.isDone()) {
                System.out.print(PROGRESS_INDICATOR);
                Thread.sleep(HALF_A_SECOND);
            }
            System.out.println();
            return getDistributionHome(uncompressDirectory.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    return null;
}
 
Example #12
Source File: EurostagImpactAnalysis.java    From ipst with Mozilla Public License 2.0 5 votes vote down vote up
private void writeWp43Configs(Domain domain, List<Contingency> contingencies, OutputStream os) throws IOException, ConfigurationException {
    // copy wp43 configuration files
    GenericArchive archive = domain.getArchiveFactory().create(GenericArchive.class);
    try (FileSystem fileSystem = ShrinkWrapFileSystems.newFileSystem(archive)) {
        Path rootDir = fileSystem.getPath("/");
        writeWp43Configs(contingencies, rootDir);
    }
    archive.as(ZipExporter.class).exportTo(os);
}
 
Example #13
Source File: EurostagStabilization.java    From ipst with Mozilla Public License 2.0 5 votes vote down vote up
private void writeDtaAndControls(Domain domain, OutputStream ddbOs, OutputStream dictGensOs) throws IOException {
    GenericArchive archive = domain.getArchiveFactory().create(GenericArchive.class);
    try (FileSystem fileSystem = ShrinkWrapFileSystems.newFileSystem(archive)) {
        Path rootDir = fileSystem.getPath("/");
        ddbClient.dumpDtaFile(rootDir, DTA_FILE_NAME, network, parallelIndexes.toMap(), EurostagUtil.VERSION, dictionary.toMap(), parameters);
    }
    archive.as(ZipExporter.class).exportTo(ddbOs);
    //put just the generators dict csv file (extracted from the ddb files) in the common files set, to be used by wp43 transient stability index
    if (archive.get(DDB_DICT_GENS_CSV) != null) {
        ByteStreams.copy(archive.get(DDB_DICT_GENS_CSV).getAsset().openStream(), dictGensOs);
    } else {
        LOGGER.warn(DDB_DICT_GENS_CSV + " is missing in the dynamic data files set: some security indexers (e.g. transient stability) need this file");
    }
}
 
Example #14
Source File: EdgeResourceIT.java    From javaee8-jaxrs-sample with GNU General Public License v3.0 5 votes vote down vote up
@Deployment(testable = false)
    public static WebArchive createDeployment() {

        File[] extraJars = Maven.resolver().loadPomFromFile("pom.xml")
            .resolve(
                "org.projectlombok:lombok:1.16.8",
                // "org.modelmapper:modelmapper:0.7.5",
                // "org.apache.commons:commons-lang3:3.4",
                // "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.3",
                "io.jsonwebtoken:jjwt:0.8.0"
            )
            .withTransitivity()
            .asFile();

        final WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
            .addAsLibraries(extraJars)
            .addPackages(true, Bootstrap.class.getPackage())
            // .addAsResource("test-log4j.properties", "log4j.properties")
            //Add JPA persistence configration.
            //WARN: In a war package, persistence.xml should be put into /WEB-INF/classes/META-INF/, not /META-INF
            //.addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml")
            .addAsResource("META-INF/persistence.xml")
            .addAsResource("META-INF/orm.xml");

//            .addAsWebInfResource("test-web.xml", "web.xml")
//            // Enable CDI
//            .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
        //  .addAsWebInfResource("test-jboss-deployment-structure.xml", "jboss-deployment-structure.xml");
        war.merge(
            ShrinkWrap.create(GenericArchive.class)
                .as(ExplodedImporter.class)
                .importDirectory("src/main/webapp")
                .as(GenericArchive.class),
            "/"
        );
        LOG.log(Level.INFO, "war to string @{0}", war.toString(true));
        return war;
    }
 
Example #15
Source File: Server.java    From ARCHIVE-wildfly-swarm with Apache License 2.0 4 votes vote down vote up
/**
 * @return the deployedArchives
 */
protected final ConcurrentMap<String, GenericArchive> getDeployedArchives() {
    return deployedArchives;
}
 
Example #16
Source File: Server.java    From thorntail with Apache License 2.0 4 votes vote down vote up
/**
 * @return the deployedArchives
 */
protected final ConcurrentMap<String, GenericArchive> getDeployedArchives() {
    return deployedArchives;
}
 
Example #17
Source File: EurostagScenario.java    From ipst with Mozilla Public License 2.0 4 votes vote down vote up
public GenericArchive writeFaultSeqArchive(List<Contingency> contingencies, Network network, EurostagDictionary dictionary, Function<Integer, String> seqFileNameFct) throws IOException {
    return writeFaultSeqArchive(ShrinkWrap.createDomain(), contingencies, network, dictionary, seqFileNameFct);
}
 
Example #18
Source File: EurostagImpactAnalysis.java    From ipst with Mozilla Public License 2.0 4 votes vote down vote up
private void writeScenarios(Domain domain, List<Contingency> contingencies, OutputStream os) throws IOException {
    GenericArchive archive = new EurostagScenario(parameters, config).writeFaultSeqArchive(domain, contingencies, network, dictionary,
        faultNum -> FAULT_SEQ_FILE_NAME.replace(CommandConstants.EXECUTION_NUMBER_PATTERN, Integer.toString(faultNum)));
    archive.as(ZipExporter.class).exportTo(os);
}
 
Example #19
Source File: EurostagImpactAnalysis.java    From ipst with Mozilla Public License 2.0 4 votes vote down vote up
protected static void writeLimits(Network network, EurostagDictionary dictionary, Domain domain, OutputStream os, EurostagEchExportConfig exportConfig) throws IOException {
    GenericArchive archive = domain.getArchiveFactory().create(GenericArchive.class);
    try (FileSystem fileSystem = ShrinkWrapFileSystems.newFileSystem(archive)) {
        Path rootDir = fileSystem.getPath("/");
        // dump first current limits for each of the branches
        try (BufferedWriter writer = Files.newBufferedWriter(rootDir.resolve(CURRENT_LIMITS_CSV), StandardCharsets.UTF_8)) {
            for (Line l : network.getLines()) {
                if (exportConfig.isExportMainCCOnly() && !EchUtil.isInMainCc(l, exportConfig.isNoSwitch())) {
                    continue;
                }
                dumpLimits(dictionary, writer, l);
            }
            for (TwoWindingsTransformer twt : network.getTwoWindingsTransformers()) {
                if (exportConfig.isExportMainCCOnly() && !EchUtil.isInMainCc(twt, exportConfig.isNoSwitch())) {
                    continue;
                }
                dumpLimits(dictionary, writer, twt);
            }
            for (DanglingLine dl : network.getDanglingLines()) {
                if (exportConfig.isExportMainCCOnly() && !EchUtil.isInMainCc(dl, exportConfig.isNoSwitch())) {
                    continue;
                }
                dumpLimits(dictionary, writer, dl.getId(),
                        dl.getCurrentLimits(),
                        null,
                        dl.getTerminal().getVoltageLevel().getNominalV(),
                        dl.getTerminal().getVoltageLevel().getNominalV());
            }
        }
        try (BufferedWriter writer = Files.newBufferedWriter(rootDir.resolve(VOLTAGE_LIMITS_CSV), StandardCharsets.UTF_8)) {
            for (Bus b : EchUtil.getBuses(network, dictionary.getConfig())) {
                if (exportConfig.isExportMainCCOnly() && !(EchUtil.isInMainCc(b))) {
                    continue;
                }
                VoltageLevel vl = b.getVoltageLevel();
                if (!Double.isNaN(vl.getLowVoltageLimit()) && !Double.isNaN(vl.getHighVoltageLimit())) {
                    writer.write(dictionary.getEsgId(b.getId()));
                    writer.write(";");
                    writer.write(Double.toString(vl.getLowVoltageLimit()));
                    writer.write(";");
                    writer.write(Double.toString(vl.getHighVoltageLimit()));
                    writer.write(";");
                    writer.write(Double.toString(vl.getNominalV()));
                    writer.newLine();
                }
            }
        }

        //dump lines dictionary, for WP43 integration
        dumpLinesDictionary(network, dictionary, rootDir, exportConfig);
        //dump buses dictionary, for WP43 integration
        dumpBusesDictionary(network, dictionary, rootDir, exportConfig);
    }

    archive.as(ZipExporter.class).exportTo(os);
}
 
Example #20
Source File: TeiidOpenShiftClient.java    From syndesis with Apache License 2.0 4 votes vote down vote up
protected void configureBuild(BuildStatus work) {
    work.setStatus(Status.CONFIGURING);
    configureService.execute(new Runnable() {
        @Override
        @SuppressFBWarnings("REC_CATCH_EXCEPTION")
        public void run() {
            info(work.getOpenShiftName(), "Publishing  - Configuring ...");

            String namespace = work.getNamespace();
            PublishConfiguration publishConfig = work.getPublishConfiguration();
            VDBMetaData vdb = publishConfig.getVDB();

            String openShiftName = work.getOpenShiftName();
            try {
                OpenShiftClient client = openshiftClient();
                info(openShiftName, "Publishing - Checking for base image");

                // create build contents as tar file
                info(openShiftName, "Publishing - Creating zip archive");
                GenericArchive archive = ShrinkWrap.create(GenericArchive.class, "contents.tar");
                String pomFile = generatePomXml(vdb, publishConfig.isEnableOData(), publishConfig.isSecurityEnabled());

                debug(openShiftName, "Publishing - Generated pom file: " + StringConstants.NEW_LINE + pomFile);
                archive.add(new StringAsset(pomFile), "pom.xml");

                normalizeDataSourceNames(vdb);

                AccessibleByteArrayOutputStream vdbContents = DefaultMetadataInstance.toBytes(vdb);
                archive.add(new ByteArrayAsset(new ByteArrayInputStream(vdbContents.getBuffer(), 0, vdbContents.getCount())), "/src/main/resources/" + vdb.getName() + "-vdb.xml");

                InputStream configIs = this.getClass().getClassLoader().getResourceAsStream("s2i/application.properties");
                archive.add(new ByteArrayAsset(ObjectConverterUtil.convertToByteArray(configIs)),
                            "/src/main/resources/application.properties");

                for (Model model : vdb.getModels()) {
                    if (model.isSource()) {
                        buildDataSourceBuilders(model, archive);
                    }
                }

                InputStream appIs = this.getClass().getClassLoader().getResourceAsStream("s2i/Application.java");
                archive.add(new ByteArrayAsset(ObjectConverterUtil.convertToByteArray(appIs)),
                            "/src/main/java/io/integration/Application.java");

                info(openShiftName, "Publishing - Converting archive to TarExport");
                InputStream buildContents = archive.as(TarExporter.class).exportAsInputStream();
                info(openShiftName, "Publishing - Completed creating build contents construction");

                info(openShiftName, "Publishing - Creating image stream");
                // use the contents to invoke a binary build
                ImageStream is = createImageStream(client, namespace, openShiftName);

                info(openShiftName, "Publishing - Creating build config");
                BuildConfig buildConfig = createBuildConfig(client, namespace, openShiftName, is, publishConfig);

                info(openShiftName, "Publishing - Creating build");
                Build build = createBuild(client, namespace, buildConfig, buildContents);

                String buildName = build.getMetadata().getName();
                info(openShiftName, "Publishing - Build created: " + buildName);

                PodOperationsImpl publishPod = (PodOperationsImpl)client.pods().withName(buildName + "-build");

                info(openShiftName, "Publishing - Awaiting pod readiness ...");
                waitUntilPodIsReady(openShiftName, client, buildName + "-build", 20);

                info(openShiftName, "Publishing - Fetching environment variables for vdb data sources");

                if (publishConfig.isSecurityEnabled()) {
                    SSOConfigurationProperties configurationProperties = publishConfig.getSsoConfigurationProperties();
                    publishConfig.addEnvironmentVariables(getEnvironmentVariablesForSecurity(configurationProperties));
                }

                publishConfig.addEnvironmentVariables(
                        getEnvironmentVariablesForVDBDataSources(vdb, publishConfig, openShiftName));

                publishConfig.addSecretVariables(getSecretVariablesForVDBDataSources(vdb, publishConfig));

                work.setName(buildName);
                work.setStatusMessage("Build Running");
                work.setPublishPodName(publishPod.getName());
                work.setLastUpdated();
                work.setStatus(Status.BUILDING);

                info(openShiftName, "Publishing  - Configuration completed. Building ... Pod Name: " + work.getPublishPodName());

            } catch (Exception ex) {
                work.setStatus(Status.FAILED);
                work.setStatusMessage(ex.getLocalizedMessage());
                error(work.getOpenShiftName(), "Publishing - Build failed", ex);
            } finally {
                //
                // Building is a long running operation so close the log file
                //
                closeLog(openShiftName);
            }
        }
    });
}