Thursday, 30 May 2019

What is Kotlin

Q. What is Kotlin  or Overview on Kotlin .

Ans:-
1. It needs Java Virtual Machine (JVM) to execute byte code.
2. Avoid NullPointerException.
3. Values : val : work like constant. as like final in java.
4. Variable : var : normal variable declaration
5. We can pass a function as parameter in another function.
6. We can also return another  function   from a function like returning a variable.
6.


Wednesday, 29 May 2019

Most asking JAVA's Interview Question

1. Palindrome in JAVA in given integer.//ex: 121,323 are Palindrome
public static void findPalindromeInt(int num) {
int temp = num;
int result = 0, rem;
while (num > 0) {
rem = num % 10;
result = result * 10 + rem;
num = num / 10;
}
if(temp==result)
System.out.println("Number is Palindrome");
else
System.out.println("Number is not Palindrome");
}
2.  Palindrome in JAVA in given String.


private void checkPalindromeStr(String input) {
    String temp = input;
    String sum = "";
    for (int i = input.length() - 1; i >= 0; i--) {
        sum = sum + input.charAt(i);
    }
    if (temp.equalsIgnoreCase(sum)) {
        Log.d("LOG", "Palindrome");    } else {
        Log.d("LOG", "Not palindrome");    }

}

3. Count character repetition in a given string using HashMap.//ex:wwkggdrdw =w3k1g2d2r1
private static void charCount(String input) {
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0; i <= input.length() - 1; i++) {
if (map.containsKey(input.charAt(i))) {
map.put(input.charAt(i), map.get(input.charAt(i))+1);
}else {
map.put(input.charAt(i),1);
}
}
for (Map.Entry<Character,Integer> entry:map.entrySet()){
System.out.print(entry.getKey()+""+entry.getValue()+"");
}
}
4.  Reverse a String using inbuilt function.//ex:raja=ajar
private static void revString(String input){
StringBuilder result = new StringBuilder(input);
result.reverse();
System.out.println(result);
}
5. Reverse a String without using inbuilt function.//ex:Supriya =ayirpus
private static void revString(String input) {
String temp = "";
for (int i = input.length() - 1; i >= 0; i--) {
temp = temp + input.charAt(i);
}
System.out.println(temp);
}
6.  Count number of word in given string.////ex:world is world i am world i =world3 is1 i2 am1
private static void countWord(String input) {
HashMap<String, Integer> map = new HashMap<>();
String[] str = input.split(" ");
for (String s : str) {
if (map.containsKey(s)) {
map.put(s, map.get(s) + 1);
} else {
map.put(s, 1);
}
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.print(entry.getKey() + "" + entry.getValue() + " ");
}
}
7. Count number of word in given string Using minimum code.
private void countWord1(String input) {
    Log.d("Word  1  ", "" + new Date().getTime());
    List<String> stringList = new ArrayList<String>(Arrays.asList(input.split(" ")));
    for (String str : new HashSet<>(stringList)) {
        Log.d("Word : ", "" + str + " : Frequency : " + Collections.frequency(stringList, str));
    }
    Log.d("Word 2  ", "" + new Date().getTime());
}

8. Iterate HashMap using while loop.
//iterate HashMap using While and advance for loop.
private void iterateHash() {
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "supriya");
    map.put(3, "saurabh");
    map.put(2, "ankit");
    map.put(4, "navin");
    Iterator iterator = map.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry entry = (Map.Entry) iterator.next();
        Log.d("LOG", "  " + entry.getKey() + "  " + entry.getValue());    }
}

9. Check Prime 
private static void isPrime(int num) {
int count = 0;
for (int i = 2; i < num - 1; i++) {
if (num % i == 0) {
count++;
}
}
if (count == 0) {
System.out.println("Prime Number");
} else {
System.out.println("Not Prime");
}
}
10. Fibonacci series.
private static void printFibonacci(int limit) {
int a, b = 0, c = 1;
for (int i = 0; i < limit; i++) {
a = b;
b = c;
c = a + b;
System.out.println(a + "");
}
}
11. Iterate ArrayList using while loop and for-each loop.
public static void iterateList(){
List<Integer> list =new ArrayList<>();
list.add(132);
list.add(132);
list.add(342);
Iterator iterator= list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next()+"");
}
Iterate ArrayList using for-each loop.
public static void iterateList() {
List<Integer> list = new ArrayList<>();
list.add(132);
list.add(132);
list.add(342);
for(Integer num:list){
System.out.println(num+"");
}
}
12. Find Dublicate Character in a given String./emmaroopa=emao
public static void findDuplicate(String input) {
for (int i = 0; i < input.length() - 1; i++) {
for (int j = i + 1; j < input.length(); j++) {
if (input.charAt(i) == input.charAt(j)) {
System.out.println(input.charAt(i));
}
}
}
13. Check Armstrong Number in java.//Armstrong Number :-153 = 1*1*1 + 5*5*5 + 3*3*3 = 153.
private static void findArmstrong(int num) {
int result = 0, rem, temp = num;
while (num > 0) {
rem = num % 10;
result = result + (rem * rem * rem);
num = num / 10;
}
if (temp == result) {
System.out.println(result + "");
}
}
14. Replace all white space in a given string.
private static void replaceSpace(String input) {
input = input.replaceAll(" ", "");
input = input.replaceAll("\\s", "");
//both can be used
System.out.println(input);
}
15. Factorial in JAVA
private static void findFactorial(int num){
int fact=1;
for(int i=1;i<=num;i++){
fact=fact*i;
}
System.out.println(fact+"");
}
}
Factorial using Recursion :-
private int recusionFactorial(int n) {
    if (n == 0)
        return 1;
    else        return (n * recusionFactorial(n - 1));
}
16. WAP in JAVA to find run length encoding if the input is "wwwaadxxxw" then output should be :- w3a2d1x3w1.
private static void lengthEncoding(String input) {
int count = 1;
String output = "";
for (int i = 0; i < input.length(); i++) {
while (i < (input.length() - 1) && input.charAt(i) == input.charAt(i + 1)) {
count++;
i++;
}
output = output + input.charAt(i) + count;
count = 1;
}
System.out.println(output);
}
17. In  a given alphanumeric string return sum of the digit 0-9 that appears in the string ignoring all other character. Ex: ac2bh3fg12mgf32 output :- 2+3+1+2+3+2 = 13
private void sumOfDigit(String input) {
    int sum = 0;
    for (char s : input.toCharArray()) {
        if (Character.isDigit(s)) {
            sum = sum + Character.getNumericValue(s);
        }
    }
    Log.d("supriya", sum+"");
}
18. Find peak element in an array. A peak element is an element if it is not smaller than its neighbours./ Ex:{10,80,15,2,23,90,67,120,3,134,7} output :- 20,90.120,134.
public static void findPeakElement(int[] element) {
for (int i = 0; i < element.length; i++) {
while (i < element.length - 1 && element[i] < element[i + 1] && element[i + 1] > element[i + 2]) {
System.out.println(element[i + 1]);
i++;
}
}
}
19. WAP leader in an array. An element is leader  if it is greater than its its right side of all element.Ex: {16,17,4,3,5,2} output:- 2,5,17.
public static void findLeader(int[] arr) {
int max = arr[arr.length - 1];
System.out.println(max);
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] > max) {
max = arr[i];
System.out.println(arr[i]);
}
}
}
20. Array of 0's and 1sin random order.Segregate 0s on left side and 1s on right side of the array.Traverse array only once.
input {0,1,1,0,0,1,0,1,0,1,1}
output{0,0,0,0,0,1,1,1,1,1,1}
public static void printZeroOne(int[] arr) {
    int l = 0;
    int r = arr.length - 1;
    while (l < r) {
        while (arr[l] == 0 && l < r) {
            l++;
        }
        while (arr[r] == 1 && l < r) {
            r--;
        }
        if (l < r) {
            int temp;
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;
        }
    }
    for (int i : arr) {
        System.out.print(i + " ");
    }
}

21. Remove adjacent occurrences of 2 same character in a string.Ex:- if the input string is "abbacca" the output will be empty or if the input is aaaebccb then output will be e.

22. Given array {5,2,1,7,2,3} and another Y. Find all the pairs whose sum is Y.
private void findPair(int[] arr, int num) {
    for (int i = 0; i < arr.length; i++) {
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[i] + arr[j] == num) {
                System.out.print(arr[i] + "," + arr[j]);
                Log.d("supriya", "  " + arr[i] + "," + arr[j]);
            }
        }
    }
}
23. Binary Search .
private static int binarySearch(int[] arr, int num) {
int l = 0, r = arr.length - 1, mid;
while (l <= r) {
mid = l + ((r - l) / 2);
if (num == arr[mid]) {
return mid;
} else if (num < arr[mid]) {
r = mid - 1;
} else if (num > arr[mid]) {
l = mid + 1;
}
}
return -1;
}
In Binary search if duplicate item is available than search the item at very first position.
Ex:- {21,100, 100, 100, 100, 100, 401, 453, 588, 789, 890};
than print the position of 100 at very first position.
private boolean binarySearch(int[] arr, int num) {
    int l = 0;
    int r = arr.length - 1;
    int mid;
    while (l <= r) {
        mid = l + (r - l / 2);
        if (arr[mid] == num) {
            if (arr[mid - 1] == num) {
                l = l - 1;
            } else {
                Log.d("supriya:::  ", mid + "");
                return true;
            }
        }
        if (num > arr[mid]) {
            l = mid + 1;
        }
        if (num < arr[mid]) {
            r = mid - 1;
        }
    }
    return false;
}
24. Binary tree Inorder Traverses.
25.  Binary tree Preorder.
26.  Binary tree Postorder.
27.BFS Algorithm.
28. DFS Algorithm
29. Max heap / Min Heap
30. Print 3rd last element in linked list on one traverse.
31. WAP Write a Java program to check if a vowel is present in a string.
private static void fun(String s) {
char[] str = s.toCharArray();
if (s.toLowerCase().matches(".*[aeiou].*")) {
System.out.print("Vowel present");
}else
System.out.print("Not Vowel present");
}
32. WAP to rated the string at there place ex :- {"my","name","is","supriya"}
o/p:- {"ym","eman","si","ayirpus"}
private void revStringAtPlace(String[] strArr) {
    String str = "";
    for (int i = 0; i < strArr.length; i++) {
        for (int j = strArr[i].length() - 1; j >= 0; j--) {
            str = str + strArr[i].charAt(j) + "";
        }
        strArr[i] = str;
    }
    for (String s : strArr) {
        Log.d("supriya", s);
    }
}

32. WAP to  reverse item in a array. int[] arr{1,3,2}; o/p:- 231
public static void arrayRev(int[] arr) {
    int[] temp = new int[arr.length];
    int j = 0;
    for (int i = arr.length - 1; i >= 0; i--) {
        if (j < arr.length) {
            assert temp != null;
            temp[j] = arr[i];
            j++;
        }
    }
    for (int k : temp) {
        Log.d("supriya", k + "");
    }

}
33. WAP to find second Largest from an array.
public static void findSecondHigh(int[] arr) {
    int largest = arr[0];
    int secLargest = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] > largest) {
            secLargest = largest;
            largest = arr[i];
        } else if (arr[i] > secLargest) {
            secLargest = arr[i];
        }
    }
    Log.d("supriya", "Largest ::=" + largest + "   " + "SecondLargest::  " + secLargest);
}
34. WAP to remove all space from a string.
private static void fun(String str){
System.out.println(str);
str = str.replaceAll(" ","");
System.out.println(str);
}
35. WAP to sort an Array.
private static void fun(int[] arr){
Arrays.sort(arr);
for (int i:arr)
System.out.print(i+" ");
}
36. WAP to make pyramid.
   1 
  1 2 
 1 2 3 
1 2 3 4 
private static void fun(int n) {
for (int i = 1; i < n; i++) {
for (int j = n - i; j >1; j--) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print(j+" ");
}
System.out.println();
}
}
37. WAP to illustrate merge sort.

Friday, 24 May 2019

Perform search in RecyclerView android

In MainActivity :- 


stcCityNAme is string array
private void filterData(String filterText) {
    List<String> filteList = new ArrayList<>();
    for (String s:stcCityNAme) {
        if(s.toLowerCase().startsWith(filterText))
        filteList.add(s);
    }
    if(filteList.size() == 0) {
        Toast.makeText(getApplicationContext(),"No Data Found",Toast.LENGTH_SHORT).show();
    }
    adapter.filter(filteList);
}



in Adapter :-
public void filter(List<String> filteList) {
    this.list = filteList;
    notifyDataSetChanged();
}

Xml:-



Message Passing  from one Activity to Another Activity :-

ClassA:-
Intent intent = new Intent(ClassB.this,ClassC.class);
intent.putExtra("messageB","Message form ClassB....:::");
startActivityForResult(intent,123);

@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d("supriya",resultCode+"");
    if(requestCode == 123) {
        messageB.setText(data.getStringExtra("messageC"));
    }
}

ClassB:-
// Get the transferred data from source activity.Intent intent = getIntent();
messageC.setText(intent.getStringExtra("messageB"));

Intent intent = new Intent();
intent.putExtra("messageC", "Message back from C");
setResult(RESULT_OK, intent);
finish();

Thursday, 23 May 2019

How to make Immutable class in java

Immutable Class in Java :-
String, Boolean, Byte, Short are immutable class in java.

Immutable class in java mean once object of class created ,than the state of object cannot be change.

Here are following steps to create the immutable class in java:-

1. create a class as final :- That no one can extends the class.

2. Declare the Variable as private that  direct access not allowed.

3. Declare the variable as final that value can assign only once.

4. No setter method allowed.

5. Only getter method  : Will have perform cloning of object in getter method to return rather than return actual object.

import java.util.HashMap;
import java.util.Map;

public final class ImmutableClass {

private final String name;
private final int id;
private final Map<Integer, Integer> map;

public ImmutableClass(String name, int id, Map<Integer, Integer> map) {
this.name = name;
this.id = id;
Map<Integer, Integer> tempMap = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
tempMap.put(entry.getKey(), entry.getValue());
}
this.map = tempMap;
}

public String getName() {
return name;
}

public int getId() {
return id;
}

public Map<Integer, Integer> getMap() {
Map<Integer, Integer> tempMap = new HashMap<>();
tempMap = map;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
tempMap.put(entry.getKey(), entry.getValue());
}
return tempMap;
}
}

Singleton Class in java


Singleton Design Pattern :-
it Limits no of object creation of that class is only one. Only one instance of the class we can create in the whole application.

1. Make a public class.
2. Declare variable of private and static type that will object of the class.
3. Create a private constructor .
4. Make a public static method which well return instance of the class.

Example are follows:-

public class SingletonClass {

private static SingletonClass singletonClass = null;

private SingletonClass() {
}

public static synchronized SingletonClass getInstance() {
if (singletonClass == null) {
singletonClass = new SingletonClass();
}
return singletonClass;
}
}
Example: To test that object is created only one below we can test
SingletonClass a=SingletonClass.getInstance();
SingletonClass b=SingletonClass.getInstance();
SingletonClass c=SingletonClass.getInstance();

System.out.println(a.hashCode());
System.out.println(b.hashCode());
System.out.println(c.hashCode());
Output:-
1791741888
1791741888
1791741888

Monday, 13 May 2019

DataBinding in MVVVM pattern using LiveData and Retrofit

In Previous example i am replacing thing using ViewBinding like following:-
1. we have to enable dataBinding in app.gradle file like following :-
dataBinding {
    enabled = true}

2. MainActivity:-
public class MainActivity extends AppCompatActivity {
    private MainActivityViewModel viewModel;
    private ActivityMainBinding binding;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);       
 binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        viewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
        getEmpDetailFromViewModel();
    }

    private void initRecyclerView(List<AlbumResponse> responses) {
        AlbumAdapter adapter = new AlbumAdapter(responses);
        RecyclerView.LayoutManager manager = new LinearLayoutManager(this);
        binding.recyclerView.setLayoutManager(manager);
        binding.recyclerView.setAdapter(adapter);
        binding.recyclerView.setHasFixedSize(true);
    }
}

layout xml will change like following :-


2. AlbumAdapter:-
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.MyViewHolder> {
    private List<AlbumResponse> responseList;
    private AlbumListBinding binding;

    public AlbumAdapter(List<AlbumResponse> responseList) {
        this.responseList = responseList;
    }

    @NonNull    @Override    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        //View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.album_list,viewGroup,false);       
 binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),R.layout.album_list,viewGroup,false);
        return new MyViewHolder(binding);
    }

    @Override    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
        myViewHolder.listBinding.employeeName.setText(responseList.get(i).getUserId()+"");
        myViewHolder.listBinding.id.setText(responseList.get(i).getId()+"");
        myViewHolder.listBinding.employeeSalary.setText(responseList.get(i).getTitle()+"");

    }

    @Override    public int getItemCount() {
        return responseList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder{
        private AlbumListBinding listBinding;
        public MyViewHolder(@NonNull AlbumListBinding itemView) {
            super(itemView.getRoot());
            listBinding = itemView;
        }
    }
}

MVVM with LiveData and Retrofit example in android | How to call or make an API call using MVVM patterns with LiveData in android example

1 > Here is the basic example of MVVM using live Data. To follow MVVM pattern make following package :-
1. model:- Pojo Class 
2. view:- All Activity ,Fragment ,Adapter will come inside, view will communicate with viewModel.
3. viewModel :- viewModel will call repository where all business logic will be there.
4. repositories :- It will communicate with wenServer or database to get the data .
5. webServices :- Retrofit class , APIServices related class will be here.

I am going to call following API using Retrofit:- 


2. > Dependencies :-


//RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'
// to use retrofit2 notation like @SerializedName("") @Expose
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
//to use viewModelProviders.ofdef lifecycle_version = "1.1.1"
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
implementation 'com.android.support:recyclerview-v7:28.0.0'
// For using AndroidSchedulers for io
implementation 'io.reactivex:rxandroid:1.2.1'
3. > Now i created related all classes inside all folder :-

 AlbumResponse :- 



AlbumAdapter:-

APIServices:-

public interface APIServices {
    @GET("{albums}")
    Observable<List<AlbumResponse>> getEmpDetails(@Path("albums") String albums);
}

NetworkManager:-


public static Retrofit getRetrofitInstance() {
    if (retrofit == null) {
        retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
    }
    return retrofit;
}

MainActivityRepo:-

private MutableLiveData<List<AlbumResponse>> mutableLiveData;
private APIServices serviceAPI;

public MainActivityRepo() {
    if(mutableLiveData == null){
        mutableLiveData = new MutableLiveData<>();
    }
    serviceAPI = NetworkManager.getRetrofitInstance().create(APIServices.class);
}
//Call API
//Call APIpublic MutableLiveData<List<AlbumResponse>> getEmployeDetailAPi() {
    Observable<List<AlbumResponse>> observable = serviceAPI.getEmpDetails("albums");
    observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<List<AlbumResponse>>() {
                @Override                public void onCompleted() {
                }
                @Override                public void onError(Throwable e) {
                }
                @Override                public void onNext(List<AlbumResponse> albumResponses) {
                    mutableLiveData.setValue(albumResponses);
                }
            });
    return mutableLiveData;
}

MainActivityViewModel:-
public MutableLiveData<List<AlbumResponse>> getEmpDetailFromDB() {
    return activityRepo.getEmployeDetailAPi();
}

MainActivity:-
private void initRecyclerView(List<AlbumResponse> responses) {
    AlbumAdapter adapter = new AlbumAdapter(responses);
    RecyclerView.LayoutManager manager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(manager);
    recyclerView.setAdapter(adapter);
    recyclerView.setHasFixedSize(true);
}

private void getEmpDetailFromViewModel() {
    viewModel.getEmpDetailFromDB().observe(this, new Observer<List<AlbumResponse>>() {
        @Override        public void onChanged(@Nullable List<AlbumResponse> albumResponses) {
            initRecyclerView(albumResponses);
        }
    });
}

Output:-



Tuesday, 7 May 2019

modelView Simple use | How model view hold the data when we rotating the screen

MainActivity.java:-
public class MainActivity extends AppCompatActivity {
    private TextView randomText;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        randomText = findViewById(R.id.randomText);
        //MainActivityViewModel generator = new MainActivityViewModel();
MainActivityViewModel dataGenerator = ViewModelProviders.of(this).get(MainActivityViewModel.class);
        String reandomNumber = dataGenerator.getRandomNumber();
        randomText.setText(reandomNumber);
    }
}

MainActivityViewModel:-

public class MainActivityViewModel extends ViewModel {
    private String randomNumber;

    public String getRandomNumber() {
        if (randomNumber == null) {
            createRandonNumber();
        }
        return randomNumber;
    }

    public void createRandonNumber() {
        Random random = new Random();
        randomNumber = "Number ::=" + (random.nextInt(10 - 1) + 1);
    }
}

Dependencies:-
def lifecycle_version = "1.1.1"
implementation "android.arch.lifecycle:extensions:$lifecycle_version"


#################################################################################

Using live data in above example :-

MainActivity:-
button = findViewById(R.id.button);
final MainActivityViewModel dataGenerator = ViewModelProviders.of(this).get(MainActivityViewModel.class);
LiveData<String> reandomNumber = dataGenerator.getRandomNumber();
reandomNumber.observe(this, new Observer<String>() {
    @Override    public void onChanged(@Nullable String s) {
        Log.d("supriya",":: onChanged ::");
        randomText.setText(s);
    }
});
button.setOnClickListener(new View.OnClickListener() {
    @Override    public void onClick(View v) {
        Log.d("supriya",":: onClick ::");
        dataGenerator.createRandonNumber();
    }
});


MainActivityViewModel:-

public class MainActivityViewModel extends ViewModel {
    private MutableLiveData<String> randomNumber;

    public MutableLiveData<String> getRandomNumber() {
        if (randomNumber == null) {
            Log.d("supriya",":: getRandomNumber== null ::");
            randomNumber = new MutableLiveData<>();
            createRandonNumber();
        }
        return randomNumber;
    }

    public void createRandonNumber() {
        Log.d("supriya",":: createRandonNumber ::");
        Random random = new Random();
        randomNumber.setValue("Number ::=" + (random.nextInt(10 - 1) + 1));
    }
}