Task * CAP3Worker::runCap3() { // Modify output file name, if required QString fileName = getValue<QString>(OUTPUT_FILE); const QString ext = ".ace"; if (datasetNumber > 0) { bool appendExtToResult = false; if (fileName.endsWith(ext)) { int location = fileName.size() - ext.size(); fileName.truncate(location); appendExtToResult = true; } fileName += "_" + QString::number(datasetNumber); if (appendExtToResult) { fileName += ext; } settings.outputFilePath = fileName; } // Run the task CAP3SupportTask *capTask = new CAP3SupportTask(settings); capTask->addListeners(createLogListeners()); connect(capTask, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); datasetNumber++; settings.inputFiles.clear(); return capTask; }
Task * CufflinksWorker::tick() { if (false == settingsAreCorrect) { return NULL; } if (input->hasMessage()) { Message inputMessage = getMessageAndSetupScriptValues(input); SAFE_POINT(!inputMessage.isEmpty(), "Internal error: message can't be NULL!", NULL); QVariantMap data = inputMessage.getData().toMap(); if (settings.fromFile) { settings.url = data[BaseSlots::URL_SLOT().getId()].toString(); } else { settings.assemblyId = data[BaseSlots::ASSEMBLY_SLOT().getId()].value<SharedDbiDataHandler>(); } // Create the task CufflinksSupportTask* cufflinksSupportTask = new CufflinksSupportTask(settings); cufflinksSupportTask->addListeners(createLogListeners()); connect(cufflinksSupportTask, SIGNAL(si_stateChanged()), SLOT(sl_cufflinksTaskFinished())); return cufflinksSupportTask; } else if (input->isEnded()) { setDone(); output->setEnded(); } return NULL; }
void SharedConnectionsDialog::sl_connectClicked() { QListWidgetItem *selectedItem = ui->lwConnections->currentItem(); SAFE_POINT(NULL != selectedItem, "Invalid list item detected", ); const QString connectionName = selectedItem->data(Qt::DisplayRole).toString(); QString fullDbiUrl = getCurrentFullDbiUrl(); countConnectionsToPublicDatabase(fullDbiUrl); if (!AppContext::getPasswordStorage()->contains(fullDbiUrl) && !askCredentials(fullDbiUrl)) { return; } // TODO: don't forget to change this when new DB providers will be introduced const U2DbiRef dbiRef(MYSQL_DBI_ID, fullDbiUrl); bool initializeDb = false; bool isInitialized = checkDatabaseAvailability(dbiRef, initializeDb); if (!isInitialized && !initializeDb) { return; } Task *dbLoadTask = new AddDocumentTask(new ConnectSharedDatabaseTask(dbiRef, connectionName, initializeDb)); connect(dbLoadTask, SIGNAL(si_stateChanged()), SLOT(sl_connectionComplete())); connectionTasks.insert(ui->lwConnections->currentItem(), dbLoadTask); AppContext::getTaskScheduler()->registerTopLevelTask(dbLoadTask); accept(); }
Task* PFMatrixBuildWorker::tick() { if (input->hasMessage()) { Message inputMessage = getMessageAndSetupScriptValues(input); if (inputMessage.isEmpty()) { output->transit(); return NULL; } mtype = PFMatrixWorkerFactory::FREQUENCY_MATRIX_MODEL_TYPE(); QVariantMap data = inputMessage.getData().toMap(); cfg.type = actor->getParameter(TYPE_ATTR)->getAttributeValue<bool>(context) ? PM_DINUCLEOTIDE : PM_MONONUCLEOTIDE; QVariantMap qm = inputMessage.getData().toMap(); SharedDbiDataHandler msaId = qm.value(BaseSlots::MULTIPLE_ALIGNMENT_SLOT().getId()).value<SharedDbiDataHandler>(); QScopedPointer<MAlignmentObject> msaObj(StorageUtils::getMsaObject(context->getDataStorage(), msaId)); SAFE_POINT(!msaObj.isNull(), "NULL MSA Object!", NULL); const MAlignment &msa = msaObj->getMAlignment(); Task* t = new PFMatrixBuildTask(cfg, msa); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; } else if (input->isEnded()) { setDone(); output->setEnded(); } return NULL; }
void SnpEffSupport::sl_validationStatusChanged(bool isValid) { if (isValid) { SnpEffDatabaseListTask* task = new SnpEffDatabaseListTask(); connect(task, SIGNAL(si_stateChanged()), SLOT(sl_databaseListIsReady())); AppContext::getTaskScheduler()->registerTopLevelTask(task); } }
Task::ReportResult FormatDBSupportTask::report() { // remove tmp files if (!fastaTmpFiles.isEmpty()) { QDir dir(QFileInfo(fastaTmpFiles.first()).absoluteDir()); if (!dir.removeRecursively()) { stateInfo.addWarning(tr("Can not remove folder for temporary files.")); emit si_stateChanged(); } } return ReportResult_Finished; }
Task * CuffmergeWorker::tick() { while (input->hasMessage()) { takeAnnotations(); } if (input->isEnded()) { Task *t = createCuffmergeTask(); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; } return NULL; }
void RemoteMachineMonitorDialogImpl::sl_getPublicMachinesButtonClicked() { if( NULL != getPublicMachinesTask ) { rsLog.details(tr("Public machines request is already sent" ) ); return; } getPublicMachinesTask = new RetrievePublicMachinesTask(); connect( getPublicMachinesTask, SIGNAL( si_stateChanged() ), SLOT( sl_getPublicMachinesTaskStateChanged() ) ); AppContext::getTaskScheduler()->registerTopLevelTask( getPublicMachinesTask ); getPublicMachinesButton->setEnabled(false); }
Task* SiteconReader::tick() { if (urls.isEmpty() && tasks.isEmpty()) { setDone(); output->setEnded(); } else { Task* t = new SiteconReadTask(urls.takeFirst()); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); tasks.append(t); return t; } return NULL; }
Task* CollocationWorker::tick() { if (input->hasMessage()) { Message inputMessage = getMessageAndSetupScriptValues(input); if (inputMessage.isEmpty()) { output->transit(); return NULL; } cfg.distance = actor->getParameter(LEN_ATTR)->getAttributeValue<int>(context); cfg.st = actor->getParameter(FIT_ATTR)->getAttributeValue<bool>(context) ? CollocationsAlgorithm::NormalSearch : CollocationsAlgorithm::PartialSearch; cfg.resultAnnotationsName = actor->getParameter(NAME_ATTR)->getAttributeValue<QString>(context); QString annotations = actor->getParameter(ANN_ATTR)->getAttributeValue<QString>(context); QSet<QString> names = QSet<QString>::fromList(annotations.split(QRegExp("\\W+"), QString::SkipEmptyParts)); QVariantMap qm = inputMessage.getData().toMap(); QString resultType = actor->getParameter(TYPE_ATTR)->getAttributeValue<QString>(context); cfg.includeBoundaries = actor->getParameter(INC_BOUNDARY_ATTR)->getAttributeValue<bool>(context); SharedDbiDataHandler seqId = qm.value(BaseSlots::DNA_SEQUENCE_SLOT().getId()).value<SharedDbiDataHandler>(); QScopedPointer<U2SequenceObject> seqObj(StorageUtils::getSequenceObject(context->getDataStorage(), seqId)); CHECK(NULL != seqObj.data(), NULL); const QList<SharedAnnotationData> atl = StorageUtils::getAnnotationTable(context->getDataStorage(), qm.value(FEATURE_TABLE_SLOT)); qint64 seqLength = seqObj->getSequenceLength(); if ((0 != seqLength) && !atl.isEmpty()) { cfg.searchRegion.length = seqLength; bool keepSourceAnns = (COPY_TYPE_ATTR == resultType); Task* t = new CollocationSearchTask(atl, names, cfg, keepSourceAnns); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; } else { // void tick output->put(Message(BaseTypes::ANNOTATION_TABLE_TYPE(), QVariant())); if (input->isEnded()) { output->setEnded(); } return NULL; } } else if (input->isEnded()) { setDone(); output->setEnded(); } return NULL; }
Task* ClustalOWorker::tick() { if (input->hasMessage()) { Message inputMessage = getMessageAndSetupScriptValues(input); if (inputMessage.isEmpty()) { output->transit(); return NULL; } cfg.numIterations=actor->getParameter(NUM_ITERATIONS)->getAttributeValue<int>(context); cfg.maxGuidetreeIterations=actor->getParameter(MAX_GT_ITERATIONS)->getAttributeValue<int>(context); cfg.maxHMMIterations=actor->getParameter(MAX_HMM_ITERATIONS)->getAttributeValue<int>(context); cfg.setAutoOptions=actor->getParameter(SET_AUTO)->getAttributeValue<bool>(context); cfg.numberOfProcessors=AppContext::getAppSettings()->getAppResourcePool()->getIdealThreadCount(); QString path=actor->getParameter(EXT_TOOL_PATH)->getAttributeValue<QString>(context); if(QString::compare(path, "default", Qt::CaseInsensitive) != 0){ AppContext::getExternalToolRegistry()->getByName(ET_CLUSTALO)->setPath(path); } path=actor->getParameter(TMP_DIR_PATH)->getAttributeValue<QString>(context); if(QString::compare(path, "default", Qt::CaseInsensitive) != 0){ AppContext::getAppSettings()->getUserAppsSettings()->setUserTemporaryDirPath(path); } QVariantMap qm = inputMessage.getData().toMap(); SharedDbiDataHandler msaId = qm.value(BaseSlots::MULTIPLE_ALIGNMENT_SLOT().getId()).value<SharedDbiDataHandler>(); QScopedPointer<MultipleSequenceAlignmentObject> msaObj(StorageUtils::getMsaObject(context->getDataStorage(), msaId)); SAFE_POINT(!msaObj.isNull(), "NULL MSA Object!", NULL); const MultipleSequenceAlignment msa = msaObj->getMultipleAlignment(); if (msa->isEmpty()) { algoLog.error(tr("An empty MSA '%1' has been supplied to ClustalO.").arg(msa->getName())); return NULL; } ClustalOSupportTask* supportTask = new ClustalOSupportTask(msa, GObjectReference(), cfg); supportTask->addListeners(createLogListeners()); Task *t = new NoFailTaskWrapper(supportTask); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; } else if (input->isEnded()) { setDone(); output->setEnded(); } return NULL; }
void RemoteMachineMonitorDialogImpl::pingMachine( const RemoteMachineSettingsPtr& settings, QTreeWidgetItem * item ) { assert( NULL != settings && NULL != item ); if (!checkCredentials(settings)) { return; } if( pingingItems.values().contains( item ) ) { rsLog.info(tr("Ping task is already active for machine: %1" ).arg(item->text(0))); return; } pingingItems.insert( settings, item ); item->setIcon(2, PING_WAIT_FOR_RESPONSE); item->setIcon(3, PING_WAIT_FOR_RESPONSE); RetrieveRemoteMachineInfoTask * retrieveInfoTask = new RetrieveRemoteMachineInfoTask( settings ); connect( retrieveInfoTask, SIGNAL( si_stateChanged() ), SLOT( sl_retrieveInfoTaskStateChanged() ) ); AppContext::getTaskScheduler()->registerTopLevelTask( retrieveInfoTask ); }
Task* CallVariantsWorker::tick() { U2OpStatus2Log os; //put variant tracks while (!cache.isEmpty()) { output->put(cache.takeFirst()); } checkState(os); CHECK_OP_EXT(os, setDone(), NULL); //take assemblies from one dataset if (assemblyPort->hasMessage() && settings.assemblyUrls.isEmpty()) { takeAssembly(os); CHECK_OP_EXT(os, processError(os), NULL); } else if (settings.assemblyUrls.isEmpty() && !assemblyUrls.isEmpty()) { settings.assemblyUrls = assemblyUrls; assemblyUrls.clear(); } //take reference sequence if (refSeqPort->hasMessage() && settings.refSeqUrl.isEmpty()) { takeReference(os); CHECK_OP_EXT(os, processError(os), NULL); } //do if (cache.isEmpty() && !settings.refSeqUrl.isEmpty() && !settings.assemblyUrls.isEmpty()) { settings.variationsUrl = GUrlUtils::rollFileName(getValue<QString>(OUT_URL), "_", QSet<QString>()); CallVariantsTask* t = new CallVariantsTask(settings, context->getDataStorage()); t->addListeners(createLogListeners(3)); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); settings.assemblyUrls.clear(); settings.refSeqUrl.clear(); return t; } return NULL; }
void SearchQualifierDialog::search( bool searchAll /* = false*/ ){ QString name = AVQualifierItem::simplifyText(ui->nameEdit->text()); QString val = AVQualifierItem::simplifyText(ui->valueEdit->text()); if (!(name.length() < 20 && TextUtils::fits(TextUtils::QUALIFIER_NAME_CHARS, name.toLatin1().data(), name.length()))) { QMessageBox::critical(this, tr("Error!"), tr("Illegal qualifier name")); return; } if (!Annotation::isValidQualifierValue(val)) { QMessageBox::critical(this, tr("Error!"), tr("Illegal qualifier value")); return; } if(searchAll){ clearPrevResults(); } FindQualifierTaskSettings settings(groupToSearchIn, name, val, ui->exactButton->isChecked(), searchAll, parentAnnotationofPrevResult, indexOfPrevResult); FindQualifierTask* findTask = new FindQualifierTask(treeView, settings); connect(findTask, SIGNAL( si_stateChanged() ), SLOT( sl_searchTaskStateChanged() )); TaskScheduler* s = AppContext::getTaskScheduler(); s->registerTopLevelTask(findTask); }
Task *ConservationPlotWorker::tick() { U2OpStatus2Log os; while (inChannel->hasMessage()) { Message m = getMessageAndSetupScriptValues(inChannel); QVariantMap data = m.getData().toMap(); if (!data.contains(ANNOT_SLOT_ID)) { os.setError("Annotations slot is empty"); return new FailTask(os.getError()); } plotData = StorageUtils::getAnnotationTableHandlers(data[ANNOT_SLOT_ID]); } if (!inChannel->isEnded()) { return NULL; } ConservationPlotSettings settings = createConservationPlotSettings(os); if (os.hasError()) { return new FailTask(os.getError()); } ConservationPlotTask* t = new ConservationPlotTask(settings, context->getDataStorage(), plotData); t->addListeners(createLogListeners()); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; if (inChannel->isEnded()) { setDone(); } return NULL; }
Task* ClustalWWorker::tick() { if (input->hasMessage()) { Message inputMessage = getMessageAndSetupScriptValues(input); if (inputMessage.isEmpty()) { output->transit(); return NULL; } cfg.gapOpenPenalty=actor->getParameter(GAP_OPEN_PENALTY)->getAttributeValue<float>(context); cfg.gapExtenstionPenalty=actor->getParameter(GAP_EXT_PENALTY)->getAttributeValue<float>(context); cfg.gapDist=actor->getParameter(GAP_DIST)->getAttributeValue<float>(context); cfg.endGaps=actor->getParameter(END_GAPS)->getAttributeValue<bool>(context); cfg.noHGaps=actor->getParameter(NO_HGAPS)->getAttributeValue<bool>(context); cfg.noPGaps=actor->getParameter(NO_PGAPS)->getAttributeValue<bool>(context); if(actor->getParameter(ITERATION)->getAttributeValue<int>(context) != 0){ if(actor->getParameter(ITERATION)->getAttributeValue<int>(context) == 1){ cfg.iterationType="TREE"; }else if(actor->getParameter(ITERATION)->getAttributeValue<int>(context) == 2){ cfg.iterationType="ALIGNMENT"; } if(actor->getParameter(NUM_ITERATIONS)->getAttributeValue<int>(context) != 3){ cfg.numIterations=actor->getParameter(NUM_ITERATIONS)->getAttributeValue<int>(context); } } if(actor->getParameter(MATRIX)->getAttributeValue<int>(context) == -1){ if(actor->getParameter(MATRIX)->getAttributeValue<int>(context) == 0){ cfg.matrix="IUB"; }else if(actor->getParameter(MATRIX)->getAttributeValue<int>(context) == 1){ cfg.matrix="CLUSTALW"; }else if(actor->getParameter(MATRIX)->getAttributeValue<int>(context) == 2){ cfg.matrix="BLOSUM"; }else if(actor->getParameter(MATRIX)->getAttributeValue<int>(context) == 3){ cfg.matrix="PAM"; }else if(actor->getParameter(MATRIX)->getAttributeValue<int>(context) == 4){ cfg.matrix="GONNET"; }else if(actor->getParameter(MATRIX)->getAttributeValue<int>(context) == 5){ cfg.matrix="ID"; } } QString path=actor->getParameter(EXT_TOOL_PATH)->getAttributeValue<QString>(context); if(QString::compare(path, "default", Qt::CaseInsensitive) != 0){ AppContext::getExternalToolRegistry()->getByName(ET_CLUSTAL)->setPath(path); } path=actor->getParameter(TMP_DIR_PATH)->getAttributeValue<QString>(context); if(QString::compare(path, "default", Qt::CaseInsensitive) != 0){ AppContext::getAppSettings()->getUserAppsSettings()->setUserTemporaryDirPath(path); } QVariantMap qm = inputMessage.getData().toMap(); SharedDbiDataHandler msaId = qm.value(BaseSlots::MULTIPLE_ALIGNMENT_SLOT().getId()).value<SharedDbiDataHandler>(); QScopedPointer<MultipleSequenceAlignmentObject> msaObj(StorageUtils::getMsaObject(context->getDataStorage(), msaId)); SAFE_POINT(!msaObj.isNull(), "NULL MSA Object!", NULL); const MultipleSequenceAlignment msa = msaObj->getMultipleAlignment(); if (msa->isEmpty()) { algoLog.error(tr("An empty MSA '%1' has been supplied to ClustalW.").arg(msa->getName())); return NULL; } ClustalWSupportTask* supportTask = new ClustalWSupportTask(msa, GObjectReference(), cfg); supportTask->addListeners(createLogListeners()); Task *t = new NoFailTaskWrapper(supportTask); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; } else if (input->isEnded()) { setDone(); output->setEnded(); } return NULL; }
Task* RepeatWorker::tick() { if (input->hasMessage()) { Message inputMessage = getMessageAndSetupScriptValues(input); if (inputMessage.isEmpty()) { output->transit(); return NULL; } cfg.algo = RFAlgorithm(actor->getParameter(ALGO_ATTR)->getAttributeValue<int>(context)); cfg.minLen = actor->getParameter(LEN_ATTR)->getAttributeValue<int>(context); if(actor->getParameter(USE_MIN_DISTANCE_ATTR)->getAttributeValue<bool>(context)){ cfg.minDist = actor->getParameter(MIN_DIST_ATTR)->getAttributeValue<int>(context); }else{ cfg.minDist = 0; } if(actor->getParameter(USE_MAX_DISTANCE_ATTR)->getAttributeValue<bool>(context)){ cfg.maxDist = actor->getParameter(MAX_DIST_ATTR)->getAttributeValue<int>(context); }else{ cfg.maxDist = INT_MAX; } int identity = actor->getParameter(IDENTITY_ATTR)->getAttributeValue<int>(context); cfg.setIdentity(identity); cfg.nThreads = actor->getParameter(THREADS_ATTR)->getAttributeValue<int>(context); cfg.inverted = actor->getParameter(INVERT_ATTR)->getAttributeValue<bool>(context); cfg.filter = RepeatsFilterAlgorithm(actor->getParameter(NESTED_ATTR)->getAttributeValue<int>(context)); cfg.excludeTandems = actor->getParameter(TANMEDS_ATTR)->getAttributeValue<bool>(context); resultName = actor->getParameter(NAME_ATTR)->getAttributeValue<QString>(context); if(resultName.isEmpty()){ resultName = "repeat_unit"; algoLog.error(tr("result name is empty, default name used")); } if(identity > 100 || identity < 0){ algoLog.error(tr("Incorrect value: identity value must be between 0 and 100")); return new FailTask(tr("Incorrect value: identity value must be between 0 and 100")); } QVariantMap map = inputMessage.getData().toMap(); SharedDbiDataHandler seqId = map.value(BaseSlots::DNA_SEQUENCE_SLOT().getId()).value<SharedDbiDataHandler>(); QScopedPointer<U2SequenceObject> seqObj(StorageUtils::getSequenceObject(context->getDataStorage(), seqId)); if (seqObj.isNull()) { return NULL; } U2OpStatusImpl os; DNASequence seq = seqObj->getWholeSequence(os); CHECK_OP(os, new FailTask(os.getError())); if(cfg.minDist < 0){ algoLog.error(tr("Incorrect value: minimal distance must be greater then zero")); return new FailTask(tr("Incorrect value: minimal distance must be greater then zero")); } if (!seq.alphabet->isNucleic()) { QString err = tr("Sequence alphabet is not nucleic!"); return new FailTask(err); } Task* t = new FindRepeatsToAnnotationsTask(cfg, seq, resultName, QString(), "", GObjectReference()); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; } else if (input->isEnded()) { setDone(); output->setEnded(); } return NULL; }
Task* ORFWorker::tick() { if (input->hasMessage()) { Message inputMessage = getMessageAndSetupScriptValues(input); if (inputMessage.isEmpty()) { output->put(Message::getEmptyMapMessage()); } cfg.strand = getStrand(actor->getParameter(BaseAttributes::STRAND_ATTRIBUTE().getId())->getAttributeValue<QString>(context)); cfg.minLen = actor->getParameter(LEN_ATTR)->getAttributeValue<int>(context); cfg.mustFit = actor->getParameter(FIT_ATTR)->getAttributeValue<bool>(context); cfg.mustInit = actor->getParameter(INIT_ATTR)->getAttributeValue<bool>(context); cfg.allowAltStart = actor->getParameter(ALT_ATTR)->getAttributeValue<bool>(context); cfg.includeStopCodon = actor->getParameter(ISC_ATTR)->getAttributeValue<bool>(context); cfg.maxResult2Search = actor->getParameter(RES_ATTR)->getAttributeValue<int>(context); resultName = actor->getParameter(NAME_ATTR)->getAttributeValue<QString>(context); if(resultName.isEmpty()) { algoLog.error(tr("ORF: result name is empty, default name used")); resultName = "misc_feature"; } transId = actor->getParameter(ID_ATTR)->getAttributeValue<QString>(context); if (cfg.minLen < 0) { algoLog.error(tr("ORF: Incorrect value: min-length must be greater then zero")); return new FailTask(tr("Incorrect value: min-length must be greater then zero")); } SharedDbiDataHandler seqId = inputMessage.getData().toMap().value(BaseSlots::DNA_SEQUENCE_SLOT().getId()).value<SharedDbiDataHandler>(); QScopedPointer<U2SequenceObject> seqObj(StorageUtils::getSequenceObject(context->getDataStorage(), seqId)); if (seqObj.isNull()) { return NULL; } const DNAAlphabet* alphabet = seqObj->getAlphabet(); if (alphabet && alphabet->getType() == DNAAlphabet_NUCL) { ORFAlgorithmSettings config(cfg); config.searchRegion.length = seqObj->getSequenceLength(); if (config.strand != ORFAlgorithmStrand_Direct) { DNATranslation* compTT = AppContext::getDNATranslationRegistry()-> lookupComplementTranslation(alphabet); if (compTT != NULL) { config.complementTT = compTT; } else { config.strand = ORFAlgorithmStrand_Direct; } } config.proteinTT = AppContext::getDNATranslationRegistry()-> lookupTranslation(alphabet, DNATranslationType_NUCL_2_AMINO, transId); if (config.proteinTT) { Task* t = new ORFFindTask(config,seqObj->getEntityRef()); connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished())); return t; } } QString err = tr("Bad sequence supplied to ORFWorker: %1").arg(seqObj->getSequenceName()); return new FailTask(err); } else if (input->isEnded()) { output->setEnded(); setDone(); } return NULL; }
TaskSignalMapper::TaskSignalMapper(Task *t) : QObject(t), task(t) { connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskStateChanged()), Qt::DirectConnection); }