Repository: jasur-2902/CarRecognition
Branch: master
Commit: d396d20b60f4
Files: 49
Total size: 85.2 KB
Directory structure:
gitextract_t1gc80l7/
├── .gitignore
├── .idea/
│ ├── assetWizardSettings.xml
│ ├── codeStyles/
│ │ └── Project.xml
│ ├── encodings.xml
│ ├── gradle.xml
│ ├── inspectionProfiles/
│ │ └── Project_Default.xml
│ ├── misc.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── LICENSE
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── google-services.json
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── uz/
│ │ └── shukurov/
│ │ └── carrecognition/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── index.html
│ │ ├── java/
│ │ │ └── uz/
│ │ │ └── shukurov/
│ │ │ └── carrecognition/
│ │ │ ├── MainActivity.java
│ │ │ ├── ResultActivity.java
│ │ │ ├── SplashActivity.java
│ │ │ └── other/
│ │ │ ├── InternetCheck.java
│ │ │ ├── MyBounceInterpolator.java
│ │ │ └── RequestCode.java
│ │ └── res/
│ │ ├── anim/
│ │ │ └── bounce.xml
│ │ ├── drawable/
│ │ │ ├── camera_button_click.xml
│ │ │ ├── gallery_button_click.xml
│ │ │ ├── ic_arrow_back.xml
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_result.xml
│ │ │ └── activity_splash.xml
│ │ ├── menu/
│ │ │ └── main_menu.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── xml/
│ │ └── file_paths.xml
│ └── test/
│ └── java/
│ └── uz/
│ └── shukurov/
│ └── carrecognition/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/caches/build_file_checksums.ser
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild
================================================
FILE: .idea/assetWizardSettings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="launcher">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="scalingPercent" value="101" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="foregroundImage" value="$USER_HOME$/Desktop/Dumpster/logo.jpg" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/Applications/Android%20Studio.app/Contents/plugins/android/lib/android.jar!/images/material_design_icons/navigation/ic_arrow_back_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputName" value="ic_arrow_back" />
<entry key="sourceFile" value="$USER_HOME$" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>
================================================
FILE: .idea/codeStyles/Project.xml
================================================
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>
================================================
FILE: .idea/encodings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>
================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
================================================
FILE: .idea/inspectionProfiles/Project_Default.xml
================================================
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintUsingHttp" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>
================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 Jasur Shukurov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Due to the hight cost and usage, I've stopped the server :`( . This project isn't supported anymore. You can use the android client side tho, but it won't return anything.
# CarRecognition - AI Model
This is one of the best vehicle recognition applications. It can determine the car's license plate number, color, model, brand, and year.
**Author: Jasurbek Shukurov**
## Why?
This model runs with the highest accuracy compared to other models existing in the market.
## Features
- **License Plate Recognition**: Accurately detects and recognizes license plate numbers from images.
- **Vehicle Color Detection**: Identifies the primary color of the vehicle.
- **Model and Brand Identification**: Determines the specific model and brand of the vehicle.
- **Year Estimation**: Estimates the manufacturing year of the vehicle.
## Installation
Clone the repository:
```
bash
git clone https://github.com/jasur-2902/Car-Recognition.git
cd Car-Recognition
```
##Usage
Upload an image of a vehicle.
The application will process the image and display the detected information, including license plate number, vehicle color, model, brand, and estimated year.
##How it Works
The CarRecognition app uses a deep learning model trained on a large dataset of vehicle images. It processes the input image, extracts relevant features, and then applies a series of classification algorithms to determine the car's details.
###Contributing
If you'd like to contribute to this project, please fork the repository and use a feature branch. Pull requests are warmly welcome.
###License
This project is licensed under the MIT License - see the LICENSE file for details.
###Contact
For any inquiries or support, please contact jasur.shukurov29@gmail.com.
## Screenshots
<img src="screenshots/Screenshot_20190109-002106.png" alt="alt text" width="288" height="512"> <img src="screenshots/1.jpg?raw=true" alt="alt text" width="288" height="512"> <img src="screenshots/2.jpg?raw=true" alt="alt text" width="288" height="512">
<p align="center"><img src="screenshots/3.jpg" alt="alt text" width="288" height="512"> <img src="screenshots/4.jpg" alt="alt text" width="288" height="512"> </p>
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
//noinspection GradleCompatible
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "uz.shukurov.carrecognition"
minSdkVersion 18
targetSdkVersion 28
versionCode 2
versionName "1.0.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
//Design Elements
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
//Firebase
implementation 'com.google.firebase:firebase-storage:16.0.5'
implementation 'com.google.firebase:firebase-core:16.0.6'
//Json
implementation 'com.github.amirdew:JSON:v1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
apply plugin: 'com.google.gms.google-services'
================================================
FILE: app/google-services.json
================================================
{
"project_info": {
"project_number": "381266161153",
"firebase_url": "https://car-recognition-app.firebaseio.com",
"project_id": "car-recognition-app",
"storage_bucket": "car-recognition-app.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:381266161153:android:75e10f795367faff",
"android_client_info": {
"package_name": "uz.shukurov.carrecognition"
}
},
"oauth_client": [
{
"client_id": "381266161153-659ggmsld17svqnafah5ghn1rjgo1qkp.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCN_0I1080BaTJso0-j-aXajr2thOhSXws"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: app/src/androidTest/java/uz/shukurov/carrecognition/ExampleInstrumentedTest.java
================================================
package uz.shukurov.carrecognition;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("uz.shukurov.carrecognition", appContext.getPackageName());
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uz.shukurov.carrecognition">
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
</activity>
<activity
android:theme="@style/NoActionBar"
android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="uz.shukurov.carrecognition.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<!-- ressource file to create -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<activity
android:name=".ResultActivity"
android:theme="@style/NoActionBar" />
</application>
</manifest>
================================================
FILE: app/src/main/assets/index.html
================================================
<html>
<head></head>
<body>
<img src="car.gif" width="200px" align="middle">
</body>
</html>
================================================
FILE: app/src/main/java/uz/shukurov/carrecognition/MainActivity.java
================================================
package uz.shukurov.carrecognition;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import uz.shukurov.carrecognition.other.InternetCheck;
import uz.shukurov.carrecognition.other.MyBounceInterpolator;
import uz.shukurov.carrecognition.other.RequestCode;
public class MainActivity extends AppCompatActivity {
private StorageReference mStorageImage;
private ImageButton mCapture, mTakePicture;
private String downloadUri;
private Uri mImageUri = null;
private String url = "http://18.217.108.249/cgi-bin/recognize2.py?url=";
private static final String TAG = MainActivity.class.getSimpleName();
private AlertDialog mDialog;
private AlertDialog.Builder mBuilder;
private LinearLayout mLinearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStorageImage = FirebaseStorage.getInstance().getReference().child("images");
mCapture = findViewById(R.id.mCapture);
mTakePicture = findViewById(R.id.mTakePicture);
final Animation myAnim = AnimationUtils.loadAnimation(this, R.anim.bounce);
MyBounceInterpolator interpolator = new MyBounceInterpolator(0.2, 20);
myAnim.setInterpolator(interpolator);
mCapture.startAnimation(myAnim);
mTakePicture.startAnimation(myAnim);
mLinearLayout = findViewById(R.id.linearLayout);
if (!InternetCheck.isInternetAvailable(this)) {
initSnackbar();
mLinearLayout.setVisibility(View.INVISIBLE);
}
permissionRequest();
mCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent galleryIntent = new Intent();
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, RequestCode.GALLERY_REQUEST);
}
});
mTakePicture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dispatchTakePictureIntent();
}
});
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"Sorry! Your device doesn't support camera",
Toast.LENGTH_LONG).show();
// will close the app if the device does't have camera
finish();
}
}
private void initSnackbar() {
final Snackbar snackbar = Snackbar.make(mLinearLayout, R.string.no_internet, Snackbar.LENGTH_INDEFINITE).setAction(R.string.retry, new View.OnClickListener() {
@Override
public void onClick(View view) {
if (InternetCheck.isInternetAvailable(view.getContext())) {
mLinearLayout.setVisibility(View.VISIBLE);
} else initSnackbar();
}
});
//
snackbar.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_item1:
return true;
case R.id.menu_item2:
AlertDialog dialog;
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("About")
.setMessage("This is one of the best vehicle recognition applications. It can identify the car's license plate number, color, model, brand and year. The project was created by Jasur Shukurov 2018-2019")
.setPositiveButton("Okay!", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
dialog = builder.create();
dialog.show();
return true;
case R.id.menu_item3:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://home.adelphi.edu/~ja21947/car/privacy_policy.html"));
startActivity(browserIntent);
default:
return super.onOptionsItemSelected(item);
}
}
private void permissionRequest() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
RequestCode.MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case RequestCode.MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
Uri photoURI;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this,
"uz.shukurov.carrecognition.fileprovider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, RequestCode.REQUEST_TAKE_PHOTO);
}
}
}
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RequestCode.GALLERY_REQUEST && resultCode == RESULT_OK) {
mImageUri = data.getData();
uploadImage();
}
if (requestCode == RequestCode.REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
mImageUri = photoURI;
uploadImage();
}
}
//Uploading Image to Firebase
private void uploadImage() {
if (mImageUri != null) {
final StorageReference filepath = mStorageImage.child(mImageUri.getLastPathSegment());
mBuilder = new AlertDialog.Builder(MainActivity.this);
mBuilder.setTitle("Loading...")
.setMessage("Please wait, it will take some time!")
.setCancelable(false);
mDialog = mBuilder.create();
mDialog.show();
filepath.putFile(mImageUri).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
@Override
public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
mDialog.show();
throw task.getException();
}
return filepath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if (task.isSuccessful()) {
downloadUri = task.getResult().toString();
String query = downloadUri.substring(87, downloadUri.length());
new DownloadTask().execute(url + query);
} else {
mDialog.cancel();
Toast.makeText(MainActivity.this, "Upload failed: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
} else {
mDialog.cancel();
Toast.makeText(MainActivity.this, "Sorry, something went wrong!", Toast.LENGTH_SHORT).show();
}
}
private class DownloadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
//do your request in here so that you don't interrupt the UI thread
try {
return downloadContent(params[0]);
} catch (IOException e) {
return "Unable to retrieve data. URL may be invalid.";
}
}
@Override
protected void onPostExecute(String result) {
//Here you are done with the task
Intent intent = new Intent(MainActivity.this, ResultActivity.class);
String[] extra = new String[2];
extra[0] = result;
extra[1] = downloadUri;
intent.putExtra("EXTRA_SESSION_ID", extra);
mDialog.cancel();
if (result.length() < 600) {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Sorry, we can't identify this car! Please try one more time!")
.setTitle("Error, cannot detect!")
.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
} else
startActivity(intent);
}
}
private String downloadContent(String myurl) throws IOException {
InputStream is = null;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000 /* milliseconds */);
conn.setConnectTimeout(5500 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.connect();
int response = conn.getResponseCode();
Log.d(TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
System.out.println("\nSending 'Get' request to URL : " + url + "--" + response);
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response2 = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response2.append(inputLine);
}
in.close();
System.out.println("Response : -- " + response2.toString());
mDialog.cancel();
return response2.toString();
} finally {
if (is != null) {
is.close();
}
}
}
}
================================================
FILE: app/src/main/java/uz/shukurov/carrecognition/ResultActivity.java
================================================
package uz.shukurov.carrecognition;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.InputStream;
import eu.amirs.JSON;
import uz.shukurov.carrecognition.R;
public class ResultActivity extends Activity {
private String extra[] = new String[2];
private String result, plate, color, year, body_type, make_model, url_out, type, processingTime;
private ImageView mImageView, mImageBodyType, mColorImageView;
private TextView mType, mPlate, mColor, mModel, mBodyType, mYear, mProcessingTime;
private ProgressDialog mProgressDialog;
private JSON json;
private int x1, x2, x3, x4, y1, y2, y3, y4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
toolbarMethod();
jsonConverting();
givingView();
new DownloadImage().execute(url_out);
mPlate.setText(plate);
settingDataToElements();
}
private void settingDataToElements() {
setColor();
mYear.setText(year);
setBodyType();
String make_model_upperCase = make_model.substring(0, 1).toUpperCase() + make_model.substring(1);
mModel.setText(make_model_upperCase);
int separate = type.indexOf("_");
String brand = type.substring(0, separate);
String model = type.substring(separate + 1);
String car_type = brand.substring(0, 1).toUpperCase() + brand.substring(1) + " " + model.substring(0, 1).toUpperCase() + model.substring(1);
mType.setText(car_type);
mProcessingTime.setText("Processing Time: " + processingTime);
}
private void givingView() {
mImageView = findViewById(R.id.imageView);
mType = findViewById(R.id.mType);
mPlate = findViewById(R.id.mPlate);
mColor = findViewById(R.id.mColor);
mModel = findViewById(R.id.mModel);
mYear = findViewById(R.id.mYear);
mBodyType = findViewById(R.id.mBodyType);
mProcessingTime = findViewById(R.id.processingTime);
mImageBodyType = findViewById(R.id.iv_body);
mColorImageView = findViewById(R.id.mColorImage);
}
private void jsonConverting() {
extra = getIntent().getStringArrayExtra("EXTRA_SESSION_ID");
result = extra[0];
url_out = extra[1];
json = new JSON(result);
getJsonOutput();
}
private void toolbarMethod() {
Toolbar mToolbar = findViewById(R.id.toolbar);
mToolbar.setTitle(R.string.app_name);
mToolbar.setNavigationIcon(R.drawable.ic_arrow_back);
mToolbar.setTitleTextColor(getResources().getColor(R.color.white));
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
private void setColor() {
String color_upperCase = color.substring(0, 1).toUpperCase() + color.substring(1);
mColor.setText(color_upperCase);
switch (color) {
case ("white"):
mColorImageView.setColorFilter(getResources().getColor(R.color.white));
break;
case ("black"):
mColorImageView.setColorFilter(getResources().getColor(R.color.black));
break;
case ("blue"):
mColorImageView.setColorFilter(getResources().getColor(R.color.blue));
break;
case ("brown"):
mColorImageView.setColorFilter(getResources().getColor(R.color.brown));
break;
case ("gold-beige"):
mColorImageView.setColorFilter(getResources().getColor(R.color.gold_beige));
break;
case ("green"):
mColorImageView.setColorFilter(getResources().getColor(R.color.green));
break;
case ("orange"):
mColorImageView.setColorFilter(getResources().getColor(R.color.orange));
break;
case ("pink"):
mColorImageView.setColorFilter(getResources().getColor(R.color.pink));
break;
case ("purple"):
mColorImageView.setColorFilter(getResources().getColor(R.color.purple));
break;
case ("red"):
mColorImageView.setColorFilter(getResources().getColor(R.color.red));
break;
case ("silver-gray"):
mColorImageView.setColorFilter(getResources().getColor(R.color.silver_gray));
break;
case ("yellow"):
mColorImageView.setColorFilter(getResources().getColor(R.color.yellow));
break;
default:
mColorImageView.setVisibility(View.INVISIBLE);
}
}
private void setBodyType() {
switch (body_type) {
case "antique":
mBodyType.setText(getString(R.string.antique));
break;
case "missing":
mBodyType.setText(getString(R.string.missing));
break;
case "motorcycle":
mBodyType.setText(getString(R.string.motorcycle));
mImageBodyType.setVisibility(View.INVISIBLE);
break;
case "sedan-compact":
mBodyType.setText(getString(R.string.sedan_compact));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type6));
break;
case "sedan-convertible":
mBodyType.setText(getString(R.string.sedan_convertible));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type6));
break;
case "sedan-sports":
mBodyType.setText(getString(R.string.sedan_sports));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type5));
break;
case "sedan-standard":
mBodyType.setText(getString(R.string.sedan_standard));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type6));
break;
case "sedan-wagon":
mBodyType.setText(getString(R.string.sedan_wagon));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type1));
break;
case "suv-crossover":
mBodyType.setText(getString(R.string.suv_crossover));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type7));
break;
case "suv-standard":
mBodyType.setText(getString(R.string.suv_standard));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type7));
break;
case "suv-wagon":
mBodyType.setText(getString(R.string.suv_wagon));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type3));
break;
case "tractor-trailer":
mBodyType.setText(getString(R.string.tractor_trailer));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type4));
break;
case "truck-standard":
mBodyType.setText(getString(R.string.tractor_standard));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type8));
break;
case "van-full":
mBodyType.setText(getString(R.string.van_full));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type8));
break;
case "van-mini":
mBodyType.setText(getString(R.string.van_mini));
mImageBodyType.setImageDrawable(getResources().getDrawable(R.drawable.body_type2));
break;
default:
mBodyType.setText(body_type);
}
}
private void getJsonOutput() {
plate = json.key("results").index(0).key("plate").stringValue();
color = json.key("results").index(0).key("vehicle").key("color").index(0).key("name").stringValue();
make_model = json.key("results").index(0).key("vehicle").key("make").index(0).key("name").stringValue();
body_type = json.key("results").index(0).key("vehicle").key("body_type").index(0).key("name").stringValue();
year = json.key("results").index(0).key("vehicle").key("year").index(0).key("name").stringValue();
type = json.key("results").index(0).key("vehicle").key("make_model").index(0).key("name").stringValue();
processingTime = json.key("processing_time").key("plates").toString();
x1 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(0).key("x").stringValue());
y1 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(0).key("y").stringValue());
x2 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(1).key("x").stringValue());
y2 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(1).key("y").stringValue());
x3 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(2).key("x").stringValue());
y3 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(2).key("y").stringValue());
x4 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(3).key("x").stringValue());
y4 = Integer.valueOf(json.key("results").index(0).key("coordinates").index(3).key("y").stringValue());
}
// DownloadImage AsyncTask
private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(ResultActivity.this);
// Set progressdialog title
mProgressDialog.setTitle("Download Image Tutorial");
// Set progressdialog message
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
@Override
protected Bitmap doInBackground(String... URL) {
String imageURL = URL[0];
Bitmap bitmap = null;
try {
// Download Image from URL
InputStream input = new java.net.URL(imageURL).openStream();
// Decode Bitmap
bitmap = BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap decodedByte) {
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(10);
//Drawing line around plate
Bitmap tempBitmap = Bitmap.createBitmap(decodedByte.getWidth(), decodedByte.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);
tempCanvas.drawBitmap(decodedByte, 0, 0, null);
tempCanvas.drawLine(x1, y1, x2, y2, paint);
tempCanvas.drawLine(x1, y1, x4, y4, paint);
tempCanvas.drawLine(x3, y3, x4, y4, paint);
tempCanvas.drawLine(x3, y3, x2, y2, paint);
mImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));
// Close progressdialog
mProgressDialog.dismiss();
}
}
}
================================================
FILE: app/src/main/java/uz/shukurov/carrecognition/SplashActivity.java
================================================
package uz.shukurov.carrecognition;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;
import android.widget.ImageView;
public class SplashActivity extends AppCompatActivity {
ImageView mImageAnimation;
WebView webView;
public boolean isFirstStart;
Context mcontext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
webView = findViewById(R.id.webView);
webView.loadUrl("file:///android_asset/index.html");
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
SplashActivity.this.startActivity(new Intent(SplashActivity.this, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
SplashActivity.this.finish();
}
}, 3000);
}
}
================================================
FILE: app/src/main/java/uz/shukurov/carrecognition/other/InternetCheck.java
================================================
package uz.shukurov.carrecognition.other;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class InternetCheck {
public static boolean isInternetAvailable(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}
================================================
FILE: app/src/main/java/uz/shukurov/carrecognition/other/MyBounceInterpolator.java
================================================
package uz.shukurov.carrecognition.other;
public class MyBounceInterpolator implements android.view.animation.Interpolator {
private double mAmplitude = 1;
private double mFrequency = 10;
public MyBounceInterpolator(double amplitude, double frequency) {
mAmplitude = amplitude;
mFrequency = frequency;
}
public float getInterpolation(float time) {
return (float) (-1 * Math.pow(Math.E, -time/ mAmplitude) *
Math.cos(mFrequency * time) + 1);
}
}
================================================
FILE: app/src/main/java/uz/shukurov/carrecognition/other/RequestCode.java
================================================
package uz.shukurov.carrecognition.other;
public class RequestCode {
public static final int MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 999;
public static final int REQUEST_TAKE_PHOTO = 998;
public static final int GALLERY_REQUEST = 997;
}
================================================
FILE: app/src/main/res/anim/bounce.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<scale
android:duration="2000"
android:fromXScale="0.3"
android:toXScale="1.0"
android:fromYScale="0.3"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%" />
</set>
================================================
FILE: app/src/main/res/drawable/camera_button_click.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_camera_clicked2"
android:state_pressed="true" />
<item android:drawable="@drawable/camera_icon" />
</selector>
================================================
FILE: app/src/main/res/drawable/gallery_button_click.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_gallery_clicked2"
android:state_pressed="true" />
<item android:drawable="@drawable/ic_gallery" />
</selector>
================================================
FILE: app/src/main/res/drawable/ic_arrow_back.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#fff"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
================================================
FILE: app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>
================================================
FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageButton
android:id="@+id/mTakePicture"
android:layout_width="100dp"
android:layout_height="76dp"
android:layout_gravity="center_horizontal"
android:textSize="15sp"
android:background="@drawable/camera_button_click"
android:contentDescription="@string/take_picture_button_description" />
<TextView
android:padding="10dp"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/take_a_picture"
android:textAlignment="center"
android:textSize="16sp"
android:textColor="@android:color/black"
android:textStyle="bold" />
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:background="@android:color/darker_gray"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/or"
android:padding="15dp"
android:textAlignment="center"
android:textSize="16sp"
android:textColor="@android:color/black"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:background="@android:color/darker_gray"
/>
<ImageButton
android:id="@+id/mCapture"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:textSize="16sp"
android:background="@drawable/gallery_button_click"
android:contentDescription="@string/select_from_gallery_button_description" />
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/select_from_gallery"
android:textAlignment="center"
android:textSize="16sp"
android:textColor="@android:color/black"
android:textStyle="bold" />
</LinearLayout>
================================================
FILE: app/src/main/res/layout/activity_result.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
tools:context=".ResultActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark">
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="vertical">
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:padding="10dp"
app:cardCornerRadius="6dp"
app:cardElevation="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp">
<TextView
android:id="@+id/body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="0dp"
android:text="Body type: "
android:textSize="@dimen/resuly_textview_size"
android:textStyle="bold" />
<TextView
android:id="@+id/mBodyType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="0dp"
android:layout_toEndOf="@+id/body"
android:text=""
android:textSize="@dimen/resuly_textview_size" />
<ImageView
android:id="@+id/iv_body"
android:layout_width="60dp"
android:layout_height="25dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="20dp"
android:src="@drawable/body_type1" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/brand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Brand: "
android:textSize="@dimen/resuly_textview_size"
android:textStyle="bold" />
<TextView
android:id="@+id/mModel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/brand"
android:textSize="@dimen/resuly_textview_size"
tools:text="Model" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Year: "
android:textSize="@dimen/resuly_textview_size"
android:textStyle="bold" />
<TextView
android:id="@+id/mYear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/year"
android:textSize="@dimen/resuly_textview_size"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Year" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Color: "
android:textSize="@dimen/resuly_textview_size"
android:textStyle="bold" />
<TextView
android:id="@+id/mColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="@+id/color"
android:textSize="@dimen/resuly_textview_size"
tools:text="Color" />
<ImageView
android:id="@+id/mColorImage"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_centerHorizontal="true"
android:layout_marginEnd="20dp"
android:src="?attr/colorPrimary" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Model: "
android:textSize="@dimen/resuly_textview_size"
android:textStyle="bold" />
<TextView
android:id="@+id/mType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="@+id/type"
android:textSize="@dimen/resuly_textview_size"
tools:text="Car Model" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="15dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="10dp"
android:background="@android:color/darker_gray"
android:padding="10dp" />
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:paddingTop="5dp"
app:cardCornerRadius="6dp"
app:cardElevation="6dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
android:padding="10dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/mPlate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="0dp"
android:scrollbars="vertical"
android:textAlignment="center"
android:textSize="20sp"
android:textStyle="bold"
tools:text="Plate Number" />
<ImageView
android:id="@+id/imageView3"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:src="@drawable/plate" />
</RelativeLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:contentDescription="@string/car_image_description"
tools:src="@tools:sample/avatars[2]" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
<TextView
android:id="@+id/processingTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="30dp"
android:layout_marginBottom="15dp"
android:paddingTop="5dp"
android:textColor="@android:color/darker_gray"
tools:text="Processing Time " />
</RelativeLayout>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/activity_splash.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/splash_activity_background"
>
<WebView
android:id="@+id/webView"
android:layout_width="200dp"
android:layout_height="200dp"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</WebView>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_marginBottom="20dp"
android:text="@string/copyRight"
android:textColor="@color/TransparentWhite"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
================================================
FILE: app/src/main/res/menu/main_menu.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_item1"
android:title="Settings" />
<item
android:id="@+id/menu_item2"
android:title="About" />
<item
android:id="@+id/menu_item3"
android:title="Privacy Policy" />
</menu>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#4285F4</color>
<color name="colorPrimaryDark">#4285F4</color>
<color name="colorAccent">#4285F4</color>
<color name="white">#fff</color>
<color name="black">#000</color>
<color name="blue">#00f</color>
<color name="brown">#654321</color>
<color name="gold_beige">#ffd700 </color>
<color name="green">#00ff00</color>
<color name="orange">#ffa500</color>
<color name="pink">#ff69b4</color>
<color name="purple">#551a8b</color>
<color name="red">#ff0000</color>
<color name="silver_gray">#c0c0c0 </color>
<color name="yellow">#ffff00</color>
<color name="TransparentWhite">#c9c9c9</color>
<color name="colorGreen">#00dc9e</color>
<color name="splash_activity_background">#fff</color>
</resources>
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="resuly_textview_size">14sp</dimen>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">Vehicle Recognition</string>
<string name="body_type">Body type: </string>
<string name="van_mini"> VAN Mini</string>
<string name="van_full"> VAN Full</string>
<string name="tractor_standard"> Tractor Standard</string>
<string name="tractor_trailer"> Tractor Trailer</string>
<string name="suv_wagon"> SUV Wagon</string>
<string name="suv_standard"> SUV Standard</string>
<string name="suv_crossover"> SUV Crossover</string>
<string name="sedan_wagon"> Sedan Wagon</string>
<string name="sedan_standard"> Sedan Standard</string>
<string name="sedan_sports"> Sedan Sports</string>
<string name="sedan_convertible"> Sedan Convertible</string>
<string name="sedan_compact"> Sedan Compact</string>
<string name="motorcycle"> Motorcycle</string>
<string name="missing"> Missing</string>
<string name="antique"> Antique</string>
<string name="car_image_description">Processed Car Image</string>
<string name="no_internet">Ops, we could not find an active internet connection…</string>
<string name="retry">Retry</string>
<string name="copyRight">Project was created by Jasur Shukurov</string>
<string name="select_from_gallery">Select from gallery</string>
<string name="take_a_picture">Take a picture</string>
<string name="take_picture_button_description">Take Picture Button</string>
<string name="or">OR</string>
<string name="select_from_gallery_button_description">Select from gallery button</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: app/src/main/res/xml/file_paths.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>
================================================
FILE: app/src/test/java/uz/shukurov/carrecognition/ExampleUnitTest.java
================================================
package uz.shukurov.carrecognition;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
classpath 'com.google.gms:google-services:4.2.0' // google-services plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google() // Google's Maven repository
jcenter()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
include ':app'
gitextract_t1gc80l7/ ├── .gitignore ├── .idea/ │ ├── assetWizardSettings.xml │ ├── codeStyles/ │ │ └── Project.xml │ ├── encodings.xml │ ├── gradle.xml │ ├── inspectionProfiles/ │ │ └── Project_Default.xml │ ├── misc.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── LICENSE ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── google-services.json │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── uz/ │ │ └── shukurov/ │ │ └── carrecognition/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ └── index.html │ │ ├── java/ │ │ │ └── uz/ │ │ │ └── shukurov/ │ │ │ └── carrecognition/ │ │ │ ├── MainActivity.java │ │ │ ├── ResultActivity.java │ │ │ ├── SplashActivity.java │ │ │ └── other/ │ │ │ ├── InternetCheck.java │ │ │ ├── MyBounceInterpolator.java │ │ │ └── RequestCode.java │ │ └── res/ │ │ ├── anim/ │ │ │ └── bounce.xml │ │ ├── drawable/ │ │ │ ├── camera_button_click.xml │ │ │ ├── gallery_button_click.xml │ │ │ ├── ic_arrow_back.xml │ │ │ └── ic_launcher_background.xml │ │ ├── drawable-v24/ │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ ├── activity_result.xml │ │ │ └── activity_splash.xml │ │ ├── menu/ │ │ │ └── main_menu.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── xml/ │ │ └── file_paths.xml │ └── test/ │ └── java/ │ └── uz/ │ └── shukurov/ │ └── carrecognition/ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle
SYMBOL INDEX (41 symbols across 8 files)
FILE: app/src/androidTest/java/uz/shukurov/carrecognition/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: app/src/main/java/uz/shukurov/carrecognition/MainActivity.java
class MainActivity (line 51) | public class MainActivity extends AppCompatActivity {
method onCreate (line 67) | @Override
method initSnackbar (line 129) | private void initSnackbar() {
method onCreateOptionsMenu (line 142) | @Override
method onOptionsItemSelected (line 149) | @Override
method permissionRequest (line 180) | private void permissionRequest() {
method onRequestPermissionsResult (line 207) | @Override
method createImageFile (line 231) | private File createImageFile() throws IOException {
method dispatchTakePictureIntent (line 250) | private void dispatchTakePictureIntent() {
method isDeviceSupportCamera (line 271) | private boolean isDeviceSupportCamera() {
method onActivityResult (line 282) | @Override
method uploadImage (line 300) | private void uploadImage() {
class DownloadTask (line 343) | private class DownloadTask extends AsyncTask<String, Void, String> {
method doInBackground (line 345) | @Override
method onPostExecute (line 355) | @Override
method downloadContent (line 392) | private String downloadContent(String myurl) throws IOException {
FILE: app/src/main/java/uz/shukurov/carrecognition/ResultActivity.java
class ResultActivity (line 28) | public class ResultActivity extends Activity {
method onCreate (line 40) | @Override
method settingDataToElements (line 60) | private void settingDataToElements() {
method givingView (line 81) | private void givingView() {
method jsonConverting (line 95) | private void jsonConverting() {
method toolbarMethod (line 108) | private void toolbarMethod() {
method setColor (line 124) | private void setColor() {
method setBodyType (line 173) | private void setBodyType() {
method getJsonOutput (line 242) | private void getJsonOutput() {
class DownloadImage (line 268) | private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
method onPreExecute (line 270) | @Override
method doInBackground (line 284) | @Override
method onPostExecute (line 302) | @Override
FILE: app/src/main/java/uz/shukurov/carrecognition/SplashActivity.java
class SplashActivity (line 14) | public class SplashActivity extends AppCompatActivity {
method onCreate (line 22) | @Override
FILE: app/src/main/java/uz/shukurov/carrecognition/other/InternetCheck.java
class InternetCheck (line 8) | public class InternetCheck {
method isInternetAvailable (line 9) | public static boolean isInternetAvailable(Context context) {
FILE: app/src/main/java/uz/shukurov/carrecognition/other/MyBounceInterpolator.java
class MyBounceInterpolator (line 3) | public class MyBounceInterpolator implements android.view.animation.Inte...
method MyBounceInterpolator (line 7) | public MyBounceInterpolator(double amplitude, double frequency) {
method getInterpolation (line 12) | public float getInterpolation(float time) {
FILE: app/src/main/java/uz/shukurov/carrecognition/other/RequestCode.java
class RequestCode (line 3) | public class RequestCode {
FILE: app/src/test/java/uz/shukurov/carrecognition/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
Condensed preview — 49 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (95K chars).
[
{
"path": ".gitignore",
"chars": 176,
"preview": "*.iml\n.gradle\n/local.properties\n/.idea/caches/build_file_checksums.ser\n/.idea/libraries\n/.idea/modules.xml\n/.idea/worksp"
},
{
"path": ".idea/assetWizardSettings.xml",
"chars": 3808,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"WizardSettings\">\n <option name=\"child"
},
{
"path": ".idea/codeStyles/Project.xml",
"chars": 1775,
"preview": "<component name=\"ProjectCodeStyleConfiguration\">\n <code_scheme name=\"Project\" version=\"173\">\n <Objective-C-extension"
},
{
"path": ".idea/encodings.xml",
"chars": 159,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"Encoding\">\n <file url=\"PROJECT\" chars"
},
{
"path": ".idea/gradle.xml",
"chars": 626,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"GradleSettings\">\n <option name=\"linke"
},
{
"path": ".idea/inspectionProfiles/Project_Default.xml",
"chars": 267,
"preview": "<component name=\"InspectionProjectProfileManager\">\n <profile version=\"1.0\">\n <option name=\"myName\" value=\"Project De"
},
{
"path": ".idea/misc.xml",
"chars": 2101,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"NullableNotNullManager\">\n <option nam"
},
{
"path": ".idea/runConfigurations.xml",
"chars": 564,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"RunConfigurationProducerService\">\n <o"
},
{
"path": ".idea/vcs.xml",
"chars": 180,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"VcsDirectoryMappings\">\n <mapping dire"
},
{
"path": "LICENSE",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2019 Jasur Shukurov\n\nPermission is hereby granted, free of charge, to any person obtaining a "
},
{
"path": "README.md",
"chars": 2211,
"preview": "# Due to the hight cost and usage, I've stopped the server :`( . This project isn't supported anymore. You can use the a"
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/build.gradle",
"chars": 1302,
"preview": "//noinspection GradleCompatible\napply plugin: 'com.android.application'\n\n\nandroid {\n compileSdkVersion 28\n default"
},
{
"path": "app/google-services.json",
"chars": 1044,
"preview": "{\n \"project_info\": {\n \"project_number\": \"381266161153\",\n \"firebase_url\": \"https://car-recognition-app.firebaseio."
},
{
"path": "app/proguard-rules.pro",
"chars": 751,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "app/src/androidTest/java/uz/shukurov/carrecognition/ExampleInstrumentedTest.java",
"chars": 736,
"preview": "package uz.shukurov.carrecognition;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 1818,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "app/src/main/assets/index.html",
"chars": 95,
"preview": "<html>\n<head></head>\n<body>\n <img src=\"car.gif\" width=\"200px\" align=\"middle\">\n</body>\n</html>\n"
},
{
"path": "app/src/main/java/uz/shukurov/carrecognition/MainActivity.java",
"chars": 15632,
"preview": "package uz.shukurov.carrecognition;\n\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport andro"
},
{
"path": "app/src/main/java/uz/shukurov/carrecognition/ResultActivity.java",
"chars": 12324,
"preview": "package uz.shukurov.carrecognition;\n\nimport android.app.Activity;\nimport android.app.ProgressDialog;\nimport android.grap"
},
{
"path": "app/src/main/java/uz/shukurov/carrecognition/SplashActivity.java",
"chars": 1136,
"preview": "package uz.shukurov.carrecognition;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.conte"
},
{
"path": "app/src/main/java/uz/shukurov/carrecognition/other/InternetCheck.java",
"chars": 539,
"preview": "package uz.shukurov.carrecognition.other;\n\nimport android.content.Context;\nimport android.net.ConnectivityManager;\nimpor"
},
{
"path": "app/src/main/java/uz/shukurov/carrecognition/other/MyBounceInterpolator.java",
"chars": 511,
"preview": "package uz.shukurov.carrecognition.other;\n\npublic class MyBounceInterpolator implements android.view.animation.Interpola"
},
{
"path": "app/src/main/java/uz/shukurov/carrecognition/other/RequestCode.java",
"chars": 255,
"preview": "package uz.shukurov.carrecognition.other;\n\npublic class RequestCode {\n\n public static final int MY_PERMISSIONS_REQUES"
},
{
"path": "app/src/main/res/anim/bounce.xml",
"chars": 344,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n <scale\n "
},
{
"path": "app/src/main/res/drawable/camera_button_click.xml",
"chars": 272,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item a"
},
{
"path": "app/src/main/res/drawable/gallery_button_click.xml",
"chars": 272,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item a"
},
{
"path": "app/src/main/res/drawable/ic_arrow_back.xml",
"chars": 347,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "app/src/main/res/drawable/ic_launcher_background.xml",
"chars": 4867,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector\n android:height=\"108dp\"\n android:width=\"108dp\"\n android:viewport"
},
{
"path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
"chars": 1880,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:aapt=\"http://schemas.android.com/aapt\"\n "
},
{
"path": "app/src/main/res/layout/activity_main.xml",
"chars": 2760,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "app/src/main/res/layout/activity_result.xml",
"chars": 12260,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "app/src/main/res/layout/activity_splash.xml",
"chars": 1296,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
},
{
"path": "app/src/main/res/menu/main_menu.xml",
"chars": 365,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <item\n "
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 268,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 268,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 847,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#4285F4</color>\n <color name=\"color"
},
{
"path": "app/src/main/res/values/dimens.xml",
"chars": 115,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <dimen name=\"resuly_textview_size\">14sp</dimen>\n</resources>"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 1555,
"preview": "<resources>\n <string name=\"app_name\">Vehicle Recognition</string>\n <string name=\"body_type\">Body type: </string>\n "
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 665,
"preview": "<resources>\n\n <!-- Base application theme. -->\n\n\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionB"
},
{
"path": "app/src/main/res/xml/file_paths.xml",
"chars": 167,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <external-"
},
{
"path": "app/src/test/java/uz/shukurov/carrecognition/ExampleUnitTest.java",
"chars": 387,
"preview": "package uz.shukurov.carrecognition;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local uni"
},
{
"path": "build.gradle",
"chars": 693,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n \n"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "gradle.properties",
"chars": 727,
"preview": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will ov"
},
{
"path": "gradlew",
"chars": 5296,
"preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n## Gradle start up"
},
{
"path": "gradlew.bat",
"chars": 2260,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the jasur-2902/CarRecognition GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 49 files (85.2 KB), approximately 21.2k tokens, and a symbol index with 41 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.