Saturday, 17 August 2013

Drawing location polyline using Google Directions in Google Map Android API V2,

activity_main.xml


<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" ></FrameLayout>

</RelativeLayout>


MainActivity:





import java.util.ArrayList;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

public class MainActivity extends FragmentActivity {



GoogleMap googleMap;
ArrayList<LatLng> points;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

points = new ArrayList<LatLng>();


// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

// Getting GoogleMap object from the fragment
googleMap = fm.getMap();

// Enabling MyLocation Layer of Google Map
googleMap.setMyLocationEnabled(true);


// Setting OnClick event listener for the Google Map
googleMap.setOnMapClickListener(new OnMapClickListener() {

@Override
public void onMapClick(LatLng point) {

// Instantiating the class MarkerOptions to plot marker on the map
MarkerOptions markerOptions = new MarkerOptions();

// Setting latitude and longitude of the marker position
markerOptions.position(point);

// Setting titile of the infowindow of the marker
markerOptions.title("Position");

// Setting the content of the infowindow of the marker
markerOptions.snippet("Latitude:"+point.latitude+","+"Longitude:"+point.longitude);



// Instantiating the class PolylineOptions to plot polyline in the map
PolylineOptions polylineOptions = new PolylineOptions();

// Setting the color of the polyline
polylineOptions.color(Color.RED);

// Setting the width of the polyline
polylineOptions.width(3);

// Adding the taped point to the ArrayList
points.add(point);

// Setting points of polyline
polylineOptions.addAll(points);

// Adding the polyline to the map
googleMap.addPolyline(polylineOptions);

// Adding the marker to the map
googleMap.addMarker(markerOptions);

}
});

googleMap.setOnMapLongClickListener(new OnMapLongClickListener() {

@Override
public void onMapLongClick(LatLng point) {
// Clearing the markers and polylines in the google map
googleMap.clear();

// Empty the array list
points.clear();
}
});

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

}


manifest.xml



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.wptrafficanalyzer.locationpolyline"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
   
    <permission
          android:name="in.wptrafficanalyzer.locationpolyline.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
   
    <uses-permission android:name="in.wptrafficanalyzer.locationpolyline.permission.MAPS_RECEIVE"/>
   
    <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<uses-feature
  android:glEsVersion="0x00020000"
  android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="in.wptrafficanalyzer.locationpolyline.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       
        <meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyDNdFhV5-CKWMiUH7gH1xX8fkQjrZdRdBA"/>
       
       
     
    </application>

</manifest>



Drawing driving route directions between two locations using Google Directions in Google Map Android API V2,

Layout...

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_row_contatiner"/>

<RelativeLayout
   android:id="@+id/bottom_row_contatiner"
   android:layout_height="wrap_content"
   android:layout_width="match_parent"
   android:background="@android:color/background_dark"
   android:layout_alignParentBottom="true"
   >
 
<Button android:id="@+id/calculate_button"
style="@style/wrap_all"
android:text="@string/calculate"
android:background="@drawable/sendbutton"
android:layout_alignParentLeft="true"/>

<LinearLayout android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_centerVertical="true"
   android:layout_toRightOf="@+id/calculate_button"
   android:orientation="horizontal"
   android:gravity="center"
   >
<TextView
   android:id="@+id/cost_textview"
style="@style/textview_center"
android:layout_weight="1"
android:visibility="invisible"
/>

<TextView android:id="@+id/distance_textview"
   style="@style/textview_center"
android:layout_weight="1"
   />
<TextView android:id="@+id/time_textview"
   style="@style/textview_center"
   android:layout_weight="1"
   />

</LinearLayout>
</RelativeLayout>

</RelativeLayout >




MainActivity: 


package com.tulip.maphometest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.app.ProgressDialog;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.widget.SearchView;
import com.actionbarsherlock.widget.SearchView.OnQueryTextListener;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.tulip.maphometest.API.BaseLoaderCallbacks;
import com.tulip.maphometest.API.DirectionsSerializer;
import com.tulip.maphometest.API.LegSerializer;
import com.tulip.maphometest.API.RoutesSerializer;
import com.tulip.maphometest.API.StepSerializer;
import com.tulip.maphometest.Utils.Constant;
import com.tulip.maphometest.Utils.Logger;
import com.tulip.maphometest.Utils.Util;
import com.tulip.taxiguestimator.R;

public class MainActivity<start, route> extends SherlockFragmentActivity {
   
protected static final String TAG = MainActivity.class.getSimpleName();

private SearchView searchView;

private BaseLoaderCallbacks<DirectionsSerializer> mLoaderCallbacks;
private Button calculate;
private TextView cost;
private TextView distance;
private TextView time;
private ProgressDialog myDialog;
GoogleMap googleMap;
private String mRegion= "AU";

protected String mState;

@SuppressWarnings("rawtypes")
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        calculate = (Button) findViewById(R.id.calculate_button);
        cost = (TextView) findViewById(R.id.cost_textview);
        distance = (TextView) findViewById(R.id.distance_textview);
        time = (TextView) findViewById(R.id.time_textview);
       
        calculate.setOnClickListener(new CalculateButtonListener());
       
        mLoaderCallbacks = new GoogleMapsLoaderCallbacks(this);
       

       
       
        // Initialize the location fields
   if (getSupportLoaderManager().getLoader(Constant.GOOGLE_MAPS_LOADER_ID)!=null)
        {
        Bundle args = new Bundle();
        args.putString(Constant.URL_KEY, "");
        Util.connectToLoader(getSupportLoaderManager(), Constant.GOOGLE_MAPS_LOADER_ID, args, mLoaderCallbacks);
        }
       
 
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.map, new TaxiMapFragment(), Constant.TAXI_FRAGMENT_ID);
        ft.commit();

    }




    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        //Create the search view
        searchView = new SearchView(getSupportActionBar().getThemedContext());
        searchView.setQueryHint("Where to?");

        searchView.setOnQueryTextListener(new OnQueryTextListener() {

@Override
public boolean onQueryTextSubmit(String query)
{
LatLng startLocation = getTaxiMapFragment().getStartLocation();

if (mState == null)
{
try
{
Geocoder geo = new Geocoder(MainActivity.this, Locale.getDefault());
Address addy = geo.getFromLocation(startLocation.latitude,
startLocation.longitude, 1).get(0);
mState = addy.getAdminArea();
mRegion = addy.getCountryCode();

query = query.concat(", "  + mState);

} catch (IOException e) {
e.printStackTrace();
}
}
else
{
query = query.concat(", "  + mState);
}

Logger.e(TAG, query);

showProgressDialog();

String url = Util.buildMapsAPIUrl(
startLocation.latitude+","+startLocation.longitude,
query, mRegion);

Bundle args = new Bundle();
       args.putString(Constant.URL_KEY, url);
     
       Util.restartLoader(
        getSupportLoaderManager(),
        Constant.GOOGLE_MAPS_LOADER_ID,
        args,
        mLoaderCallbacks
        );
     
return true;
}

@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
       
        menu.add("Search")
            .setIcon(R.drawable.abs__ic_search)
            .setActionView(searchView)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
       
        return true;
    }

   
   
   
@Override
public void onDestroy() {
mLoaderCallbacks.onDestroy();
super.onDestroy();
}

private class GoogleMapsLoaderCallbacks extends BaseLoaderCallbacks<DirectionsSerializer>
    {
    public GoogleMapsLoaderCallbacks(Context context) {
super(context);
}

@SuppressWarnings("unchecked")
@Override
protected void LoaderFinishedSuccessfully(DirectionsSerializer response)
{
if (myDialog != null) myDialog.dismiss();

final RoutesSerializer route = response.routes.get(0);
final LegSerializer leg = route.legs.get(0);
//process the data
double tripCost;
if (leg.distance.value>Constant.BASE_FARE_M){
tripCost = Constant.BASE_FARE +
(Constant.COST_PER_M) * (leg.distance.value-Constant.BASE_FARE_M);

//+
//Constant.COST_PER_SECOND * leg.duration.value;

tripCost = Util.round(tripCost, 2);
}
else{
  tripCost = Constant.BASE_FARE;

//+
//Constant.COST_PER_SECOND * leg.duration.value;

tripCost = Util.round(tripCost, 2);

}

List<LatLng> routePolyline = new ArrayList<LatLng>();
for (StepSerializer s : leg.steps)
{
routePolyline.addAll(Util.decodePoints(s.polyline.points));
}

LatLng northeast = new LatLng(route.bounds.northeast.lat, route.bounds.northeast.lng);
LatLng southwest = new LatLng(route.bounds.southwest.lat, route.bounds.southwest.lng);

LatLng endlocation = new LatLng(leg.end_location.lat, leg.end_location.lng);

//update the UI
cost.setText("Rs".concat(String.valueOf(tripCost)));
distance.setText(leg.distance.text);
time.setText(leg.duration.text);

getTaxiMapFragment().drawPolyline(routePolyline);
getTaxiMapFragment().setEndLocation(endlocation);
getTaxiMapFragment().setMapBounds(northeast, southwest);

((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchView.getWindowToken(), 0);

}

@Override
protected void LoaderFailed(DirectionsSerializer response) {
if (myDialog != null) myDialog.dismiss();

Toast.makeText(MainActivity.this, "Error loading data: " + response.status, Toast.LENGTH_SHORT).show();

       cost.requestFocus();

}
    }
   
    private class CalculateButtonListener implements OnClickListener
    {
@Override
public void onClick(View v)
{
LatLng endLocation = getTaxiMapFragment().getEndLocation();
LatLng startLocation = getTaxiMapFragment().getStartLocation();

if (endLocation != null && startLocation != null)
{
String url = Util.buildMapsAPIUrl(
startLocation.latitude+","+startLocation.longitude,
endLocation.latitude+","+endLocation.longitude,
mRegion);

Bundle args = new Bundle();
       args.putString(Constant.URL_KEY, url);
     
       Util.restartLoader(
        getSupportLoaderManager(),
        Constant.GOOGLE_MAPS_LOADER_ID,
        args,
        mLoaderCallbacks
        );

       showProgressDialog();
}
else
{
Toast.makeText(MainActivity.this, "You must have selected a destination to calculate the distance", Toast.LENGTH_SHORT).show();
}
}
    }
   
   
   
   
    private void showProgressDialog ()
    {
    if (myDialog == null)
        {
        myDialog = new ProgressDialog(MainActivity.this);
        myDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
       myDialog.setMessage("Please wait as we retieve the details of your route");
        }
       
        myDialog.show();
    }
   
    @SuppressWarnings("rawtypes")
private TaxiMapFragment getTaxiMapFragment() {
return (TaxiMapFragment) getSupportFragmentManager().findFragmentByTag(Constant.TAXI_FRAGMENT_ID);
}
   
   

   
}



TaxiMapFragment:



package com.tulip.maphometest;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
 

public class TaxiMapFragment<var> extends SupportMapFragment implements LocationListener
{
@SuppressWarnings("unused")
private static final String TAG = TaxiMapFragment.class.getSimpleName();
protected static final LatLng HAMBURG = null;
protected static final LatLng KIEL = null;
private LocationManager locationManager;
private Marker me_marker;
private Marker end_marker;
public LatLng startLocation;
public LatLng endLocation;
private Polyline mCurrentRoute;
private boolean locationFound = false;
GoogleMap googleMap;
ArrayList<LatLng> points;
public LatLng getStartLocation() { return startLocation; }
public LatLng getEndLocation() { return endLocation; }
public void setEndLocation(LatLng endLocation) {
this.endLocation = endLocation;
if (end_marker == null) end_marker = getMap().addMarker(new MarkerOptions().position(endLocation));
else end_marker.setPosition(endLocation);
}
public TaxiMapFragment() {}
@Override
public void onActivityCreated(Bundle savedInstanceState) 
{
super.onActivityCreated(savedInstanceState);
points = new ArrayList<LatLng>();
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 60, this);
Location location = null;
if (savedInstanceState != null) 
{
locationFound = savedInstanceState.getBoolean("locationFound");
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null && locationFound == true) onLocationChanged(location);
}
   getMap().setOnMapLongClickListener(new OnMapLongClickListener() 
   {
@Override
public void onMapLongClick(LatLng touch) 
{
endLocation = touch;
if (end_marker == null) end_marker = getMap().addMarker(new MarkerOptions().position(touch));
else end_marker.setPosition(touch);
end_marker.setTitle("Position");
// Setting the content of the infowindow of the marker
end_marker.setSnippet("Latitude:"+touch.latitude+","+"Longitude:"+touch.longitude);
//
// Marker hamburg =   getMap().addMarker(new MarkerOptions().position(HAMBURG)
//          .title("Hamburg"));
//      Marker kiel =   getMap().addMarker(new MarkerOptions()
//          .position(KIEL)
//          .title("Kiel")
//          .snippet("Kiel is cool")
//          .icon(BitmapDescriptorFactory
//              .fromResource(R.id.icon2 )));
}
});
   getMap().setMyLocationEnabled(true);
// Setting OnClick event listener for the Google Map
/* getMap().setOnMapClickListener(new OnMapClickListener() {
@Override
public void onMapClick(LatLng point) {
// Instantiating the class MarkerOptions to plot marker on the map
MarkerOptions markerOptions = new MarkerOptions();
// Setting latitude and longitude of the marker position
markerOptions.position(point);
// Setting titile of the infowindow of the marker
markerOptions.title("Position");
// Setting the content of the infowindow of the marker
markerOptions.snippet("Latitude:"+point.latitude+","+"Longitude:"+point.longitude);
// Instantiating the class PolylineOptions to plot polyline in the map
PolylineOptions polylineOptions = new PolylineOptions();
// Setting the color of the polyline
polylineOptions.color(Color.BLACK);
// Setting the width of the polyline
polylineOptions.width(3);
// Adding the taped point to the ArrayList 
points.add(point);
// Setting points of polyline
polylineOptions.addAll(points);
// Adding the polyline to the map
getMap().addPolyline(polylineOptions);
// Adding the marker to the map
getMap().addMarker(markerOptions);
}
});*/
/* getMap().setOnMapLongClickListener(new OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng point) {
// Clearing the markers and polylines in the google map
getMap().clear();
// Empty the array list
points.clear();
}
});*/  
   

   
@Override
public void onSaveInstanceState(Bundle outState) 
{
outState.putBoolean("locationFound", false);
super.onSaveInstanceState(outState);
}
@Override
public void onPause()
{
   super.onPause();
   locationManager.removeUpdates(this);
}
@Override
public void onLocationChanged(final Location location) 
{
if (getMap() != null)
{
double lat = location.getLatitude();
double lng = location.getLongitude();
startLocation = new LatLng(lat, lng);
getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15));
if (me_marker == null) me_marker = getMap().addMarker(new MarkerOptions().position(startLocation));
else me_marker.setPosition(startLocation);
locationFound  = true;
locationManager.removeUpdates(this);
}
}

@Override
public void onProviderDisabled(String provider) {}

@Override
public void onProviderEnabled(String provider) {}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void drawPolyline(final List<LatLng> routePolyline)
{
PolylineOptions options = new PolylineOptions();
options.addAll(routePolyline);
options.color(Color.BLACK);
if (mCurrentRoute == null) mCurrentRoute = getMap().addPolyline(options);
else mCurrentRoute.setPoints(routePolyline);
 
}
public void setMapBounds (final LatLng northEast, final LatLng southWest)
{
final ViewTreeObserver vto = getView().getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
   @SuppressWarnings("deprecation")
@Override
   public void onGlobalLayout() {
   
LatLngBounds bounds = new LatLngBounds(southWest, northEast);
getMap().animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
getView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
   }
});
}
}






Thursday, 8 August 2013

HOW TO CHANGE COLOR IN ANDROID TAB ACTIVITY??

HOW TO CHANGE COLOR IN ANDROID TAB ACTIVITY??

MAIN.XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
</LinearLayout>


MAINACTIVITY:

package com.androidpeople.tab;

import android.app.TabActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabSpec;

public class TabBarExample extends TabActivity implements OnTabChangeListener {
TabHost tabHost;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab);
        
        /* TabHost will have Tabs */
        tabHost = (TabHost)findViewById(android.R.id.tabhost);
        tabHost.setOnTabChangedListener(this);
        
        /* TabSpec used to create a new tab. 
         * By using TabSpec only we can able to setContent to the tab.
         * By using TabSpec setIndicator() we can set name to tab. */
        
        /* tid1 is firstTabSpec Id. Its used to access outside. */
        TabSpec firstTabSpec = tabHost.newTabSpec("tid1");
        TabSpec secondTabSpec = tabHost.newTabSpec("tid1");
        
        /* TabSpec setIndicator() is used to set name for the tab. */
        /* TabSpec setContent() is used to set content for a particular tab. */
        firstTabSpec.setIndicator("First Tab Name", getResources().getDrawable(R.drawable.logo));
        secondTabSpec.setIndicator("Second Tab Name", getResources().getDrawable(R.drawable.logo));
        
        firstTabSpec.setContent(new Intent(this,FirstTab.class));
        secondTabSpec.setContent(new Intent(this,SecondTab.class));
        
        /* Add tabSpec to the TabHost to display. */
        tabHost.addTab(firstTabSpec);
        tabHost.addTab(secondTabSpec);
        
        for(int i=0;i<tabHost.getTabWidget().getChildCount();i++)
        {
        tabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#7392B5"));
        }
        
        tabHost.getTabWidget().setCurrentTab(1);
        tabHost.getTabWidget().getChildAt(1).setBackgroundColor(Color.parseColor("#4E4E9C"));
        
    }

    
    
@Override
public void onTabChanged(String tabId) {
// TODO Auto-generated method stub
for(int i=0;i<tabHost.getTabWidget().getChildCount();i++)
        {
        tabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#7392B5"));
        } 
tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab()).setBackgroundColor(Color.parseColor("#4E4E9C"));
}
    
    
    
}