Questions about ArcGIS Runtime SDK 10.2.5 for Qt (C++ API) --Get driving directions--Create a LocalGeoprocessingService

4402
3
03-17-2015 09:46 PM
桂林王
New Contributor

Hi,I followed all the steps of Get driving directions--Create a LocalGeoprocessingService and used the version of Qt(qt-opensource-windows-x86-msvc2013-5.4.0),at last ,when I press the "solve" button ,this .exe fill will be crash,like this:E:\Qtext\RoutingExercise\build-PointToPointRouting_Example-Desktop_Qt_5_4_0_MSVC2013_32bit-Debug\debug\PointToPointRouting_Example.exe crashed. And this  sentence always here--"Route.gpk failed to start" the detail information as follow pictures:QQ截图20150318122808.pngQQ截图20150318122935.pngQQ截图20150318122901.png

0 Kudos
3 Replies
LucasDanzinger
Esri Frequent Contributor

Could you please upload the header/source files, so that I can see if there are any differences in the final code that I have and your final code? Thanks!

-Luke

0 Kudos
桂林王
New Contributor

//PointToPointRouting_Example.h

#ifndef POINTTOPOINTROUTING_EXAMPLE_H

#define POINTTOPOINTROUTING_EXAMPLE_H

namespace EsriRuntimeQt

{

class MapGraphicsView;

class Map;

class ArcGISLocalTiledLayer;

class ArcGISTiledMapServiceLayer;

class ArcGISDynamicMapServiceLayer;

class ArcGISFeatureLayer;

class GraphicsLayer;

class FeatureLayer;

}

//Uncomment if needed

#include "LocalMapService.h"

#include "LocalFeatureService.h"

#include "GraphicsLayer.h"

#include <QPushButton>

#include <QMainWindow>

//for local geoprocessing service

#include "LocalGeoprocessingService.h"

#include "Geoprocessor.h"

class PointToPointRouting_Example : public QMainWindow

{

    Q_OBJECT

public:

    PointToPointRouting_Example (QWidget *parent = 0);

    ~PointToPointRouting_Example ();

public slots:

      void onMapReady();

    //  void onFeatureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo& serviceInfo);

     // void onLocalServiceCreationSuccess(const QString& url, const QString& name);

     // void onLocalServiceCreationFailure(const QString& name);

    //  void onFeatureServiceCreationSuccess(const QString& url, const QString& name);

    //  void onFeatureServiceCreationFailure(const QString& name);

      void onAddStartPoint();

      void onAddEndPoint();

      void onSolve();

      void onServiceCreationSuccess(QString url, QString name);

          void onServiceCreationFailure(QString name);

          void onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*> &result);

          void onGpError(EsriRuntimeQt::ServiceError error);

      void onMousePress(QMouseEvent& event);

      void onMouseRelease(QMouseEvent& event);

private:

    void addStartPoint(EsriRuntimeQt::Point mapPoint);

    void addEndPoint(EsriRuntimeQt::Point mapPoint);

    EsriRuntimeQt::Map* m_map;

    EsriRuntimeQt::MapGraphicsView* m_mapGraphicsView;

    EsriRuntimeQt::ArcGISLocalTiledLayer* m_tiledLayer;

    // UI elements

    QPushButton* m_startPointBtn;

    QPushButton* m_endPointBtn;

    QPushButton* m_solveBtn;

    // Bools to track user input

    bool m_addingStartPoint;

    bool m_addingEndPoint;

     bool m_bRouteActive;

    EsriRuntimeQt::GraphicsLayer* m_graphicsLayer;

    EsriRuntimeQt::Graphic* m_grStartPoint;

    EsriRuntimeQt::Graphic* m_grEndPoint;

    EsriRuntimeQt::Graphic* m_grRouteLine;

    EsriRuntimeQt::LocalGeoprocessingService* m_routingService;

        EsriRuntimeQt::Geoprocessor* m_geoprocessor;

        EsriRuntimeQt::SpatialReference m_srMap;

    QPointF m_lastMouseCoord;

    EsriRuntimeQt::ArcGISTiledMapServiceLayer* m_tiledServiceLayer;

    //  EsriRuntimeQt::ArcGISDynamicMapServiceLayer* m_dynamicServiceLayer;

    //  EsriRuntimeQt::LocalMapService m_localMapService;

    //  EsriRuntimeQt::ArcGISDynamicMapServiceLayer* m_dynamicLocalServiceLayer;

    EsriRuntimeQt::LocalFeatureService m_localFeatureService;

    //  EsriRuntimeQt::ArcGISFeatureLayer* m_localFeatureLayer;

    //  EsriRuntimeQt::GraphicsLayer* m_graphicsLayer;

    //  EsriRuntimeQt::FeatureLayer* m_featureLayer;

          int m_startID;

          int m_endID;

          int m_routeID;

};

#endif // POINTTOPOINTROUTING_EXAMPLE_H




//PointToPointRouting_Example.cpp

#include "PointToPointRouting_Example.h"

#include "MapGraphicsView.h"

#include "Map.h"

#include "ArcGISRuntime.h"

#include "Polyline.h"

#include <QMessageBox>

// Uncomment if needed

#include "ArcGISLocalTiledLayer.h"

#include "ArcGISTiledMapServiceLayer.h"

#include "ArcGISDynamicMapServiceLayer.h"

#include "ArcGISFeatureLayer.h"

#include "GraphicsLayer.h"

#include "Graphic.h"

#include "SimpleMarkerSymbol.h"

#include "Point.h"

#include "ServiceInfoTask.h"

#include "GeodatabaseFeatureServiceTable.h"

#include "FeatureLayer.h"

#include "GeometryEngine.h"

#include "SimpleLineSymbol.h"

#include "QVBoxLayout"

#include "QGraphicsProxyWidget"

PointToPointRouting_Example::PointToPointRouting_Example(QWidget *parent)

    : QMainWindow(parent),

    m_addingStartPoint(false),

    m_addingEndPoint(false),

    m_startID(-1),

    m_endID(-1),

    m_routeID(-1)

{

    m_map = new EsriRuntimeQt::Map(this);

    //// connect to signal that is emitted when the map is ready

    //// the mapReady signal is emitted when the Map has obtained a

    //// spatial reference from an added layer

     connect(m_map, SIGNAL(mapReady()), this, SLOT(onMapReady()));

     m_mapGraphicsView = EsriRuntimeQt::MapGraphicsView::create(m_map, this);

     setCentralWidget(m_mapGraphicsView);

     m_map->setWrapAroundEnabled(false);

     QString path = EsriRuntimeQt::ArcGISRuntime::installDirectory();

     path.append("/sdk/samples/data");

     QDir dataDir(path); // using QDir to convert to correct file separator

     QString pathSampleData = dataDir.path() + QDir::separator();

     //geoprocessing package route

     m_routingService = new EsriRuntimeQt::LocalGeoprocessingService(

               pathSampleData + "gpks" + QDir::separator() +

               "Routing" + QDir::separator() + "Route.gpk" );

         m_routingService->setServiceType(EsriRuntimeQt::GPServiceType::Execute);

     //// ArcGIS Online Tiled Basemap Layer

     //m_tiledServiceLayer = new EsriRuntimeQt::ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer", this);

     //m_map->addLayer(m_tiledServiceLayer);

     //// Local Tiled Basemap Layer using: sdk/samples/data/tpks/SanFrancisco.tpk

     QString tiledBaseMapLayer = pathSampleData + "tpks" + QDir::separator() + "SanFrancisco.tpk";

     m_tiledLayer = new EsriRuntimeQt::ArcGISLocalTiledLayer(tiledBaseMapLayer, this);

     m_map->addLayer(m_tiledLayer);

     // create UI elements

         QWidget* widget = new QWidget();

         m_startPointBtn = new QPushButton("Start Point");

         m_startPointBtn->setObjectName("m_startPointBtn");

         m_startPointBtn->setStyleSheet("QPushButton#m_startPointBtn { background-color: white; color: #000; } QPushButton#m_startPointBtn:pressed {background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #dadbde, stop: 1 #f6f7fa);}");

         connect(m_startPointBtn, SIGNAL(clicked()), this, SLOT(onAddStartPoint()));

         m_endPointBtn = new QPushButton("End Point");

         m_endPointBtn->setObjectName("m_endPointBtn");

         m_endPointBtn->setStyleSheet("QPushButton#m_endPointBtn { background-color: white; color: #000; } QPushButton#m_endPointBtn:pressed {background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #dadbde, stop: 1 #f6f7fa);}");

         connect(m_endPointBtn, SIGNAL(clicked()), this, SLOT(onAddEndPoint()));

         m_solveBtn = new QPushButton("Solve");

         m_solveBtn->setObjectName("m_solveBtn");

         m_solveBtn->setStyleSheet("QPushButton#m_solveBtn { background-color: white; color: #000; }");

         connect(m_solveBtn, SIGNAL(clicked()), this, SLOT(onSolve()));

         m_startPointBtn->setEnabled(true);

         m_endPointBtn->setEnabled(true);

         m_solveBtn->setEnabled(false);

         connect(m_routingService, SIGNAL(serviceCreationSuccess(QString,QString)), this, SLOT(onServiceCreationSuccess(QString,QString)));

         connect(m_routingService, SIGNAL(serviceCreationFailure(QString)), this, SLOT(onServiceCreationFailure(QString)));

                 m_routingService->start();

         QVBoxLayout* layout = new QVBoxLayout();

             layout->addWidget(m_startPointBtn);

             layout->addWidget(m_endPointBtn);

             layout->addWidget(m_solveBtn);

             widget->setFixedSize(100,150);

             widget->setLayout(layout);

             widget->setPalette(QPalette(QPalette::Base));

         QGraphicsProxyWidget *proxy = m_mapGraphicsView->scene()->addWidget(widget);

             proxy->setPos(7, 7);

             proxy->setAcceptedMouseButtons(Qt::LeftButton);

             proxy->setFlag(QGraphicsItem::ItemIsSelectable, false);

             proxy->setOpacity(0.75);

    //// ArcGIS Online Dynamic Map Service Layer

    //m_dynamicServiceLayer = new EsriRuntimeQt::ArcGISDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapSe...", this);

    //m_map->addLayer(m_dynamicServiceLayer);

    //Local Dynamic Layer using: sdk/samples/data/mpks/USCitiesStates.mpk

    /*

  QString dataPath = pathSampleData + "mpks" + QDir::separator() + "USCitiesStates.mpk";

  m_localMapService = EsriRuntimeQt::LocalMapService(dataPath);

  // connect to signal that is emitted when the service is created successfully

  connect(&m_localMapService, SIGNAL(serviceCreationSuccess(const QString&, const QString&)), this, SLOT(onLocalServiceCreationSuccess(const QString&, const QString&)));

  // connect to signal that is emitted when the service failed

  connect(&m_localMapService, SIGNAL(serviceCreationFailure(const QString&)), this, SLOT(onLocalServiceCreationFailure(const QString&)));

  // start the service and the Local Server

  m_localMapService.start();

  */

    // Feature service using: sdk/samples/data/mpks/USCitiesStates.mpk

    /*

  QString localFeatureService = pathSampleData + "mpks" + QDir::separator() + "USCitiesStates.mpk";

  m_localFeatureService = EsriRuntimeQt::LocalFeatureService(localFeatureService);

  m_localFeatureService.setMaximumRecords(3000);

  // connect to signal that is emitted when the service is created successfully

  connect(&m_localFeatureService, SIGNAL(serviceCreationSuccess(const QString&, const QString&)), this, SLOT(onFeatureServiceCreationSuccess(const QString&, const QString&)));

  // connect to signal that is emitted when the service failed

  connect(&m_localFeatureService, SIGNAL(serviceCreationFailure(const QString&)), this, SLOT(onFeatureServiceCreationFailure(const QString&)));

  // start the service and the Local Server

  m_localFeatureService.start();

  */

    // Graphics Layer

  //EsriRuntimeQt::Point point1(0, 0, m_map->spatialReference());

  //EsriRuntimeQt::SimpleMarkerSymbol redCircle(Qt::red, 10, EsriRuntimeQt::SimpleMarkerSymbolStyle::Circle);

  //EsriRuntimeQt::Graphic* graphic1 = new EsriRuntimeQt::Graphic(point1, redCircle);

  m_graphicsLayer = new EsriRuntimeQt::GraphicsLayer(this);

  //m_graphicsLayer->addGraphic(graphic1);

  m_map->addLayer(m_graphicsLayer);

     // connect mouse press signals

     connect(m_map, SIGNAL(mousePress(QMouseEvent&)), this, SLOT(onMousePress(QMouseEvent&)));

     connect(m_map, SIGNAL(mouseRelease(QMouseEvent&)), this, SLOT(onMouseRelease(QMouseEvent&)));

}

PointToPointRouting_Example::~PointToPointRouting_Example()

{

    // stop the Local Map Service

    /*

  if(m_localMapService.status() == EsriRuntimeQt::LocalServiceStatus::Running)

     m_localMapService.stopAndWait();

  */

    // stop the Local Feature Service

    /*

  if(m_localFeatureService.status() == EsriRuntimeQt::LocalServiceStatus::Running)

    m_localFeatureService.stopAndWait();

  */

    // stop the Local Server Instance for local service

    /*

  if (EsriRuntimeQt::LocalServer::instance().isRunning())

    EsriRuntimeQt::LocalServer::instance().shutdownAndWait();

  */

}

void PointToPointRouting_Example::onMapReady()

{

  // set the map extent

  m_map->setExtent(EsriRuntimeQt::Envelope(-122.520, 37.8365, -122.3023 , 37.6985, m_map->spatialReference()));

  //// Feature Layer

  //// Initialize the FeatureLayer with a GeodatabaseFeatureServiceTable after the Map has

  //// obtained a spatial reference so its features can be projected correctly

  //// specify the URL to create a Service Info Task to get a specific layer by name or id

  //EsriRuntimeQt::ServiceInfoTask* serviceTaskInfo = new EsriRuntimeQt::ServiceInfoTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer", this);

  //connect(serviceTaskInfo, SIGNAL(featureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo&)), this, SLOT(onFeatureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo&)));

  //serviceTaskInfo->featureServiceInfo();

}

void PointToPointRouting_Example::onAddStartPoint()

{

    m_addingStartPoint = true;

    m_addingEndPoint = false;

}

void PointToPointRouting_Example::onAddEndPoint()

{

    m_addingStartPoint = false;

    m_addingEndPoint = true;

}

void PointToPointRouting_Example::onSolve()

{

    // We will define this slot later...

    if ((m_endID == -1)|| (m_startID == -1))

      {

        QMessageBox::warning(this, "Warning", "You need to add at least one start point and one end point to solve a route.", QMessageBox::Ok);

        return;

      }

      // Reset the drawing bools

      m_addingStartPoint = false;

      m_addingEndPoint = false;

      if (m_routeID != -1)

      {

        m_graphicsLayer->removeGraphic(m_routeID);

      }

      QList<EsriRuntimeQt::GPParameter*> parameters;

      EsriRuntimeQt::GPFeatureRecordSetLayer* param = new EsriRuntimeQt::GPFeatureRecordSetLayer("Input_Locations", this);

      param->setGeometryType(EsriRuntimeQt::GeometryType::Point);

      param->setSpatialReference(m_srMap);

      param->addGraphic(m_grStartPoint);

      param->addGraphic(m_grEndPoint);

      parameters.append(param);

      m_geoprocessor->execute(parameters);

}

void PointToPointRouting_Example::onServiceCreationSuccess(QString url, QString name)

{

    Q_UNUSED(url);

    Q_UNUSED(name);

    // create a Geoprocessor that points to the geoprocessing service URL

    QString urlService(m_routingService->urlGeoprocessingService());

    m_geoprocessor = new EsriRuntimeQt::Geoprocessor( urlService + "/Route");

    m_geoprocessor->setProcessSR(m_srMap);

    m_geoprocessor->setOutSR(m_srMap);

    disconnect(m_geoprocessor, SIGNAL(gpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)), this, SLOT(onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*>&)));

    disconnect(m_geoprocessor, SIGNAL(gpError(EsriRuntimeQt::ServiceError)), this, SLOT(onGpError(EsriRuntimeQt::ServiceError)));

    connect(m_geoprocessor, SIGNAL(gpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)), this, SLOT(onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*>&)));

    connect(m_geoprocessor, SIGNAL(gpError(EsriRuntimeQt::ServiceError)), this, SLOT(onGpError(EsriRuntimeQt::ServiceError)));

    m_bRouteActive = true;

}

void PointToPointRouting_Example::onServiceCreationFailure(QString name)

{

    m_bRouteActive = false;

    qWarning() << name + " failed to start";

    qWarning() << m_routingService->error().what();

}

void PointToPointRouting_Example::onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*> &result)

{

    foreach (EsriRuntimeQt::GPParameter* outputParameter, result)

    {

        EsriRuntimeQt::GPFeatureRecordSetLayer* gpLayer = qobject_cast<EsriRuntimeQt::GPFeatureRecordSetLayer*>(outputParameter);

        if (!gpLayer)

            continue;

        // get all the graphics and add them to the graphics layer.

        foreach (EsriRuntimeQt::Graphic* resultGraphic, gpLayer->graphics())

        {

            EsriRuntimeQt::Graphic* grRouteLine = new EsriRuntimeQt::Graphic(resultGraphic->geometry(), EsriRuntimeQt::SimpleLineSymbol(QColor("black"), 2.0, EsriRuntimeQt::SimpleLineSymbolStyle::Dash));

            // add to the graphics layer

            m_routeID = m_graphicsLayer->addGraphic(grRouteLine);

            m_graphicsLayer->sendToBack(m_routeID);

        }

    }

}

void PointToPointRouting_Example::onGpError(EsriRuntimeQt::ServiceError error)

{

    qWarning() << QString("Service Error, code: %1, message: %2, details: %3").arg(QString::number(error.code()), error.message(), error.details());

}

void PointToPointRouting_Example::onMousePress(QMouseEvent& event)

{

    // store the location of the mouse click

        if (event.button() == Qt::LeftButton)

            m_lastMouseCoord = QPointF(event.pos().x(), event.pos().y());

}

void PointToPointRouting_Example::onMouseRelease(QMouseEvent& event)

{

    if (event.button() != Qt::LeftButton)

            return;

    QPointF scenePosition = event.pos();

    // make sure the mouse didn't move - if so it was a pan so do nothing

    if (m_lastMouseCoord.x() != scenePosition.x() || m_lastMouseCoord.y() != scenePosition.y())

       return;

    // Clicked in item box

    if (m_mapGraphicsView->scene()->itemAt(scenePosition, QTransform()))

       return;

    EsriRuntimeQt::Point pt = m_map->toMapPoint(scenePosition.x(), scenePosition.y());

        if (m_addingStartPoint)

        {

            addStartPoint(pt);

        }

        else if (m_addingEndPoint)

        {

            addEndPoint(pt);

        }

        if (m_startID != -1 && m_endID != -1)

            m_solveBtn->setEnabled(true);

}

void PointToPointRouting_Example::addStartPoint(EsriRuntimeQt::Point mapPoint)

{

    if (EsriRuntimeQt::GeometryEngine::within(mapPoint, m_map->extent()))

    {

        EsriRuntimeQt::SimpleMarkerSymbol purpleDiamond(QColor(102, 0, 187), 15, EsriRuntimeQt::SimpleMarkerSymbolStyle::Diamond);

        purpleDiamond.setOutline(EsriRuntimeQt::SimpleLineSymbol(QColor("black"), 1.0, EsriRuntimeQt::SimpleLineSymbolStyle::Solid));

        if (m_startID != -1)

        {

            m_graphicsLayer->removeGraphic(m_startID);

        }

        m_grStartPoint = new EsriRuntimeQt::Graphic(mapPoint, purpleDiamond);

        m_startID = m_graphicsLayer->addGraphic(static_cast<EsriRuntimeQt::Graphic*>(m_grStartPoint->clone()));

    }

}

void PointToPointRouting_Example::addEndPoint(EsriRuntimeQt::Point mapPoint)

{

    if (EsriRuntimeQt::GeometryEngine::within(mapPoint, m_map->extent()))

    {

        EsriRuntimeQt::SimpleMarkerSymbol purpleDiamond(QColor(0, 102, 187), 15, EsriRuntimeQt::SimpleMarkerSymbolStyle::Diamond);

        purpleDiamond.setOutline(EsriRuntimeQt::SimpleLineSymbol(QColor("black"), 1.0, EsriRuntimeQt::SimpleLineSymbolStyle::Solid));

        if (m_endID != -1)

        {

            m_graphicsLayer->removeGraphic(m_endID);

        }

        m_grEndPoint = new EsriRuntimeQt::Graphic(mapPoint, purpleDiamond);

        m_endID = m_graphicsLayer->addGraphic(static_cast<EsriRuntimeQt::Graphic*>(m_grEndPoint->clone()));

    }

}

/*

void PointToPointRouting_Example::onFeatureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo& serviceInfo)

{

  QList<EsriRuntimeQt::FeatureLayerInfo*> layerInfoList = serviceInfo.layers("states");

  if(!layerInfoList.isEmpty() && !layerInfoList.at(0)->url().isEmpty())

  {

    // give the feature service table the URL to the feature service layer

    EsriRuntimeQt::GeodatabaseFeatureServiceTable* featureServiceTable = new EsriRuntimeQt::GeodatabaseFeatureServiceTable(layerInfoList.at(0)->url(), this);

    // initialize the feature layer with the feature service table as its feature source

    m_featureLayer = new EsriRuntimeQt::FeatureLayer(featureServiceTable, this);

    m_map->addLayer(m_featureLayer);

  }

}

*/

/*

void PointToPointRouting_Example::onLocalServiceCreationSuccess(const QString& url, const QString& name)

{

  Q_UNUSED(url);

  Q_UNUSED(name);

   // create the ArcGISDynamicMapServiceLayer using the LocalMapService's url

   m_dynamicLocalServiceLayer = new EsriRuntimeQt::ArcGISDynamicMapServiceLayer(m_localMapService.urlMapService(), this);

   m_map->addLayer(m_dynamicLocalServiceLayer);

}

*/

/*

void PointToPointRouting_Example::onLocalServiceCreationFailure(const QString& name)

{

  qWarning() << name + " failed to start";

  qWarning() << m_localMapService.error().what();

}

*/

/*

void PointToPointRouting_Example::onFeatureServiceCreationSuccess(const QString& url, const QString& name)

{

  Q_UNUSED(url);

  Q_UNUSED(name);

  QString serviceUrl;

  EsriRuntimeQt::FeatureServiceInfo featureServiceInfo = m_localFeatureService.featureServiceInfo();

  QList<EsriRuntimeQt::FeatureLayerInfo*> layerInfoList= featureServiceInfo.layers("Cities");

  if(!layerInfoList.isEmpty())

    serviceUrl = layerInfoList.at(0)->url();

  if (serviceUrl.isEmpty())

  {

    qWarning() << "The required layer does not exist";

    return;

  }

  m_localFeatureLayer = new EsriRuntimeQt::ArcGISFeatureLayer(serviceUrl, this);

  m_map->addLayer(m_localFeatureLayer);

}

*/

/*

void PointToPointRouting_Example::onFeatureServiceCreationFailure(const QString& name)

{

  qWarning() << name + " failed to start";

  qWarning() << m_localFeatureService.error().what();

}

*/

//Thank you !
0 Kudos
JeanneTrieu
Occasional Contributor

Hi,

I was not able to repro your crash but there were a few typos in the code that I have fixed in the attachment.

Can you try the attached code and see if this resolves your crash? The online documentation will be fixed soon to reflect the changes in the attachment.

Regards,

Jen Trieu | Product Eng.

0 Kudos