# Anvil

[![Maven Central](https://img.shields.io/maven-central/v/com.squareup.anvil/gradle-plugin.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.squareup.anvil%22)
[![CI](https://github.com/square/anvil/workflows/CI/badge.svg)](https://github.com/square/anvil/actions?query=branch%3Amain)

> _"When all you have is an anvil, every problem looks like a hammer."_ - [Abraham Maslow](https://en.wikipedia.org/wiki/Law_of_the_instrument)

Anvil is a Kotlin compiler plugin to make dependency injection with [Dagger](https://dagger.dev/)
easier by automatically merging Dagger modules and component interfaces. In a nutshell, instead of
manually adding modules to a Dagger component and making the Dagger component extend all component
interfaces, these modules and interfaces can be included in a component automatically:

```kotlin
@Module
@ContributesTo(AppScope::class)
class DaggerModule { .. }

@ContributesTo(AppScope::class)
interface ComponentInterface {
  fun getSomething(): Something
  fun injectActivity(activity: MyActivity)
}

// The real Dagger component.
@MergeComponent(AppScope::class)
interface AppComponent
```

The generated `AppComponent` interface that Dagger sees looks like this:

```kotlin
@Component(modules = [DaggerModule::class])
interface AppComponent : ComponentInterface
```

Notice that `AppComponent` automatically includes `DaggerModule` and extends `ComponentInterface`.

## Setup

The plugin consists of a Gradle plugin and Kotlin compiler plugin. The Gradle plugin automatically
adds the Kotlin compiler plugin and annotation dependencies. It needs to be applied in all modules
that either contribute classes to the dependency graph or merge them:

```groovy
plugins {
  id 'com.squareup.anvil' version "${latest_version}"
}
```

Or you can use the old way to apply a plugin:
```groovy
buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath "com.squareup.anvil:gradle-plugin:${latest_version}"
  }
}

apply plugin: 'com.squareup.anvil'
```

## Quick Start

There are three important annotations to work with Anvil.

`@ContributesTo` can be added to Dagger modules and component interfaces that should be included
in the Dagger component. Classes with this annotation are automatically merged by the compiler
plugin as long as they are on the compile classpath.

`@MergeComponent` is used instead of the Dagger annotation `@Component`. Anvil will generate
the Dagger annotation and automatically include all modules and component interfaces that were
contributed the same scope.

`@MergeSubcomponent` is similar to `@MergeComponent` and should be used for subcomponents instead.

## Scopes

Scope classes are only markers. The class `AppScope` from the sample could look like this:

```kotlin
abstract class AppScope private constructor()
```

These scope classes help Anvil make a connection between the Dagger component and which Dagger
modules and other component interfaces to include.

Scope classes are independent of the Dagger scopes. It's still necessary to set a scope for
the Dagger component, e.g.

```kotlin
@Singleton
@MergeComponent(AppScope::class)
interface AppComponent
```

## Contributed bindings

The `@ContributesBinding` annotation generates a Dagger binding method for an annotated class and
contributes this binding method to the given scope. Imagine this example:
```kotlin
interface Authenticator

class RealAuthenticator @Inject constructor() : Authenticator

@Module
@ContributesTo(AppScope::class)
abstract class AuthenticatorModule {
  @Binds abstract fun bindRealAuthenticator(authenticator: RealAuthenticator): Authenticator
}
```
This is a lot of boilerplate if you always want to use `RealAuthenticator` when injecting
`Authenticator`. You can replace this entire Dagger module with the `@ContributesBinding`
annotation. The equivalent would be:
```kotlin
interface Authenticator

@ContributesBinding(AppScope::class)
class RealAuthenticator @Inject constructor() : Authenticator
```

`@ContributesBinding` also supports qualifiers. You can annotate the class with any qualifier
and the generated binding method will preserve the qualifier, e.g.
```kotlin
@ContributesBinding(AppScope::class)
@Named("Prod")
class RealAuthenticator @Inject constructor() : Authenticator

// Will generate:
@Binds @Named("Prod")
abstract fun bindRealAuthenticator(authenticator: RealAuthenticator): Authenticator
```

## Contributed multibindings

Similar to contributed bindings, `@ContributesMultibinding` will generate a multibindings method
for (all/an) annotated class(es). Qualifiers are supported the same way as normal bindings.
```kotlin
@ContributesMultibinding(AppScope::class)
@Named("Prod")
class MainListener @Inject constructor() : Listener

// Will generate this binding method.
@Binds @IntoSet @Named("Prod")
abstract fun bindMainListener(listener: MainListener): Listener
```
If the class is annotated with a map key annotation, then Anvil will generate a maps multibindings
method instead of adding the element to a set:
```kotlin
@MapKey
annotation class BindingKey(val value: String)

@ContributesMultibinding(AppScope::class)
@BindingKey("abc")
class MainListener @Inject constructor() : Listener

// Will generate this binding method.
@Binds @IntoMap @BindingKey("abc")
abstract fun bindMainListener(listener: MainListener): Listener
```

## Exclusions

Dagger modules and component interfaces can be excluded in two different levels.

One class can always replace another one. This is especially helpful for modules that provide
different bindings for instrumentation tests, e.g.

```kotlin
@Module
@ContributesTo(
    scope = AppScope::class,
    replaces = [DevelopmentApplicationModule::class]
)
object DevelopmentApplicationTestModule {
  @Provides
  fun provideEndpointSelector(): EndpointSelector = TestingEndpointSelector
}
```

The compiler plugin will find both classes on the classpath. Adding both modules
`DevelopmentApplicationModule` and `DevelopmentApplicationTestModule` to the Dagger graph would
lead to duplicate bindings. Anvil sees that the test module wants to replace the other and
ignores it. This replacement rule has a global effect for all applications which are including the
classes on the classpath.

Applications can exclude Dagger modules and component interfaces individually without affecting
other applications.

```kotlin
@MergeComponent(
  scope = AppScope::class,
  exclude = [
    DaggerModule::class
  ]
)
interface AppComponent
```

In a perfect build graph it’s unlikely that this feature is needed. However, due to legacy modules,
wrong imports and deeply nested dependency chains applications might need to make use of it. The
exclusion rule does what it implies. In this specific example `DaggerModule` wishes to be
contributed to this scope, but it has been excluded for this component and thus is not added.

## Dagger Factory Generation

Anvil allows you to generate Factory classes that usually the Dagger annotation processor would
generate for `@Provides` methods, `@Inject` constructors and `@Inject` fields. The benefit of this
feature is that you don't need to enable the Dagger annotation processor in this module. That often
means you can skip KAPT and the stub generating task. In addition Anvil generates Kotlin instead
of Java code, which allows Gradle to skip the Java compilation task. The result is faster
builds.

Gradle DSL

```groovy
// build.gradle
anvil {
  generateDaggerFactories = true // default is false
}
```

Gradle Properties

```properties
# gradle.properties
com.squareup.anvil.generateDaggerFactories=true # default is false
```

In our codebase we measured that modules using Dagger build 65% faster with this new Anvil feature
compared to using the Dagger annotation processor:

|| Stub generation | Kapt | Javac | Kotlinc | Sum
:--- | ---: | ---: | ---: | ---: | ---:
Dagger | 12.976 | 40.377 | 8.571 | 10.241 | 72.165
Anvil | 0 | 0 | 6.965 | 17.748 | 24.713

For full builds of applications we measured savings of 16% on average.

![Benchmark Dagger Factories](images/benchmark_dagger_factories.png?raw=true "Benchmark Dagger Factories")

This feature can only be enabled in Gradle modules that don't compile any Dagger component. Since
Anvil only processes Kotlin code, you shouldn't enable it in modules with mixed Kotlin / Java
sources either.

When you enable this feature, don't forget to remove the Dagger annotation processor. You should
keep all other dependencies.

## Extending Anvil

Every codebase has its own dependency injection patterns where certain code structures need to be
repeated over and over again. Here Anvil comes to the rescue and you can extend the compiler
plugin with your own `CodeGenerator`. For usage please take a look at the
[`compiler-api` artifact](compiler-api/README.md)

## Advantages of Anvil

Adding Dagger modules to components in a large modularized codebase with many application targets
is overhead. You need to know where components are defined when creating a new Dagger module and
which modules to add when setting up a new application. This task involves many syncs in the IDE
after adding new module dependencies in the build graph. The process is tedious and cumbersome.
With Anvil you only add a dependency in your build graph and then you can immediately test
the build.

Aligning the build graph and Dagger's dependency graph brings a lot of consistency. If code is on
the compile classpath, then it's also included in the Dagger dependency graph.

Modules implicitly have a scope, if provided objects are tied to a scope. Now the scope of a module
is clear without looking at any binding.

With Anvil you don't need any composite Dagger module anymore, which only purpose is to
combine multiple modules to avoid repeating the setup for multiple applications. Composite modules
easily become hairballs. If one application wants to exclude a module, then it has to repeat the
setup. These forked graphs are painful and confusing. With Dagger you want to make the decision
which modules fulfill dependencies as late as possible, ideally in the application module.
Anvil makes this approach a lot easier by generating the code for included modules. Composite
modules are redundant. You make the decision which bindings to use by importing the desired module
in the application module.

## Performance

Anvil is a convenience tool. Similar to Dagger it doesn't improve build speed compared to
writing all code manually before running a build. The savings are in developer time.

The median overhead of Anvil is around 4%, which often means only a few hundred milliseconds
on top. The overhead is marginal, because Kotlin code is still compiled incrementally and Kotlin
compile tasks are skipped entirely, if nothing has changed. This doesn't change with Anvil.

![Benchmark](images/benchmark.png?raw=true "Benchmark")

On top of that, Anvil provides actual build time improvements by replacing the Dagger annotation
processor in many modules if you enable [Dagger Factory generation](#dagger-factory-generation).

## Kotlin compiler plugin

We investigated whether other alternatives like a bytecode transformer and an annotation processor
would be a better option, but ultimately decided against them. For what we tried to achieve a
bytecode transformer runs too late in the build process; after the Dagger components have been
generated. An annotation processor especially when using KAPT would be too slow. Even though the
Kotlin compiler plugin API isn't stable and contains bugs we decided to write a compiler plugin.

## Limitations

#### No Java support

Anvil is a Kotlin compiler plugin, thus Java isn’t supported. You can use Anvil in
modules with mixed Java and Kotlin code for Kotlin classes, though.

#### Correct error types disabled

KAPT has the option to
[correct non-existent types](https://kotlinlang.org/docs/kapt.html#non-existent-type-correction).
This option however changes order of how compiler plugins and KAPT itself are invoked. The result
is that Anvil cannot merge supertypes before the Dagger annotation processor runs and abstract
functions won't be implemented properly in the final Dagger component.

Anvil will automatically set `correctErrorTypes` to false to avoid this issue.

#### Incremental Kotlin compilation breaks Anvil's feature to merge contributions

> [!TIP]
> Anvil now experimentally supports incremental compilation and Gradle's build caching,
> as of [v2.5.0](https://github.com/square/anvil/releases/tag/v2.5.0-beta01).
>
> This feature is disabled by default.
> It can be enabled via a Gradle property or the Gradle DSL:
>
> Gradle Properties
>
> ```properties
> # gradle.properties
> com.squareup.anvil.trackSourceFiles=true # default is false
> ```
>
>
>
> Gradle DSL
>
> ```groovy
> // build.gradle
> anvil {
>   trackSourceFiles = true // default is false
> }
> ```
>

Anvil merges Dagger component interfaces and Dagger modules during the stub generating task
when `@MergeComponent` is used. This requires scanning the compile classpath for any contributions.
Assume the scenario that a contributed type in a module dependency has changed, but the module
using `@MergeComponent` itself didn't change. With Kotlin incremental compilation enabled the
compiler will notice that the module using `@MergeComponent` doesn't need to be recompiled and
therefore doesn't invoke compiler plugins. Anvil will miss the new contributed type from the module
dependency.

To avoid this issue, Anvil must disable incremental compilation for the stub generating task, which
runs right before Dagger processes annotations. Normal Kotlin compilation isn't impacted by this
workaround. The issue is captured in
[KT-54850 Provide mechanism for compiler plugins to add custom information into binaries](https://youtrack.jetbrains.com/issue/KT-54850/Provide-mechanism-for-compiler-plugins-to-add-custom-information-into-binaries).

Disabling incremental compilation for the stub generating task could have a negative impact on
compile times, if you heavily rely on KAPT. While Anvil can
[significantly help to improve build times](#dagger-factory-generation), the wrong configuration
and using KAPT in most modules could make things worse. The
suggestion is to extract and isolate annotation processors in separate modules and avoid using Anvil
in the same modules, e.g. a common practice is to move the Dagger component using `@MergeComponent`
into the final application module with little to no other code in the app module.

## Hilt

[Hilt](https://dagger.dev/hilt/) is Google's opinionated guide how to dependency injection on
Android. It provides a similar feature with `@InstallIn` for entry points and modules as Anvil.
If you use Hilt, then you don't need to use Anvil.

Hilt includes many other features and comes with some restrictions. For us it was infeasible to
migrate a codebase to Hilt with thousands of modules and many Dagger components while we only
needed the feature to merge modules and component interfaces automatically. We also restrict the
usage of the Dagger annotation processor to only [specific modules](https://speakerdeck.com/vrallev/android-at-scale-at-square?slide=36)
for performance reasons. With Hilt we wouldn't be able to enforce this requirement anymore for
component interfaces. The development of Anvil started long before Hilt was announced and the
internal version is being used in production for a while.

## License

    Copyright 2020 Square, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.


# HTTP Shortcuts for Android

[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/Waboodoo/HTTP-Shortcuts)](https://github.com/Waboodoo/HTTP-Shortcuts/releases)
[![F-Droid](https://img.shields.io/f-droid/v/ch.rmy.android.http_shortcuts)](https://f-droid.org/en/packages/ch.rmy.android.http_shortcuts/)
![Downloads](https://PlayBadges.pavi2410.me/badge/downloads?id=ch.rmy.android.http_shortcuts&pretty)
![Ratings](https://PlayBadges.pavi2410.me/badge/ratings?id=ch.rmy.android.http_shortcuts)
[![Crowdin](https://badges.crowdin.net/http-shortcuts/localized.svg)](https://crowdin.com/project/http-shortcuts)

A simple Android app that allows you to create shortcuts that can be placed on your home screen. Each shortcut, when clicked, triggers an HTTP request, with the possibility to process and display the response in various ways.

or [download the latest APK](https://github.com/Waboodoo/HTTP-Shortcuts/releases) directly.

Find more information and documentation on the [official website](https://http-shortcuts.rmy.ch/).

[Support this app](https://http-shortcuts.rmy.ch/support-me) by helping me [translate it](https://crowdin.com/project/http-shortcuts) or by becoming a [Beta Tester](https://play.google.com/apps/testing/ch.rmy.android.http_shortcuts)!

## Features
- Supports HTTP and HTTPS, and methods GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS and TRACE
- Basic Authentication, Digest Authentication & Bearer Authentication
- Custom request headers
- Custom request body (text based, from static file, file picker, static, or camera)
- Upload files as form-data parameters
- Client Certificate Authentication
- Support for TLSv1.3
- Support for HTTP & SOCKS proxies
- Support for Self-Signed Certificates & Certificate Pinning
- Use a built-in icon or a custom image
- Display response as a toast, window or dialog, or run silently
- Display response as HTML-formatted text, as image or as web page
- Grouping into categories through tabs
- Value injection through variables (e.g., text, numbers, passwords, selections, colors, dates, …)
- Import & Export in JSON or cURL format
- 3rd party integration support (e.g. Tasker, Macrodroid or Wireguard)
- Dark Mode support
- Easy remote editing on a computer via the web editor
- Event history to see details about recently executed HTTP requests & responses
- Run arbitrary [JavaScript](https://http-shortcuts.rmy.ch/scripting) before & after execution, which allows for lots of customization with features such as:
  - compute values such as timestamps, random numbers, UUIDs, hashes, HMACs, base64, etc.
  - parse JSON, HTML or XML and extract data from it
  - show toast message or message dialogs
  - vibrate or play notification sounds
  - trigger other shortcuts to chain multiple HTTP requests
  - interact with other devices and services by sending TCP or UDP packets, MQTT messages or using Wake-on-LAN

See also the [Changelog](CHANGELOG.md) for the latest additions and updates.

## Screenshots
![Main Screen](/assets/screenshots/01.png)
![Creation Menu](/assets/screenshots/02.png)
![Shortcut Editor](/assets/screenshots/03.png)
![Built-In Icons](/assets/screenshots/04.png)
![Authentication Settings](/assets/screenshots/05.png)
![Scripting](/assets/screenshots/06.png)
![Code Snippet Picker](/assets/screenshots/07.png)
![Categories](/assets/screenshots/08.png)
![Variables](/assets/screenshots/09.png)
![Variable Editor](/assets/screenshots/10.png)
![Settings](/assets/screenshots/11.png)
![Import / Export](/assets/screenshots/12.png)
![Display Response with Meta Data](/assets/screenshots/13.png)


# Binary Eye

Yet another barcode scanner for Android. As if there weren't [enough][play].

This one is free, without any ads and open source.

Works in portrait and landscape orientation, can read inverted codes,
comes in Material Design and can also generate barcodes.

Binary Eye uses the [ZXing-C++][zxing_cpp] ("Zebra Crossing") barcode
scanning library.

If you find this app useful and wish to support its continued development,
you can [buy me a coffee](https://www.buymeacoffee.com/markusfisch) or
send some Bitcoin decimals to `bc1q2guk2rpll587aymrfadkdtpq32448x5khk5j8z`.

## Screenshots

## Download

## Supported Barcode Formats

### Read

ZXing can read the following barcode formats:
* [AZTEC][aztec]
* [CODABAR][codabar]
* [CODE 39][code_39]
* [CODE 93][code_93]
* [CODE 128][code_128]
* [DATA MATRIX][data_matrix]
* [DX FILM EDGE][dx_film_edge]
* [EAN 8][ean_8]
* [EAN 13][ean_13]
* [ITF][itf]
* [MAXICODE][maxicode] (partial)
* [PDF417][pdf417]
* [QR CODE][qr_code]
* [Micro QR Code][micro_qr_code]
* [rMQR Code][rmqr_code]
* [RSS 14][rss]
* [RSS EXPANDED][rss]
* [UPC A][upc_a]
* [UPC E][upc_e]
* [UPC EAN EXTENSION][upc_ean]

### Generate

ZXing can generate the following barcode formats:
* [AZTEC][aztec]
* [CODABAR][codabar]
* [CODE 39][code_39]
* [CODE 128][code_128]
* [DATA MATRIX][data_matrix]
* [EAN 8][ean_8]
* [EAN 13][ean_13]
* [ITF][itf]
* [PDF 417][pdf417]
* [QR CODE][qr_code]
* [UPC A][upc_a]

## Deep Links and Intents

### Deep Links

You can invoke Binary Eye with a web URI intent from anything that can
open URIs. There are two options:

1. [binaryeye://scan](binaryeye://scan)
2. [http(s)://markusfisch.de/BinaryEye](http://markusfisch.de/BinaryEye)

If you want to get the scanned contents, you can add a `ret` query
argument with a (URL encoded) URI template. For example:

[http://markusfisch.de/BinaryEye?ret=http%3A%2F%2Fexample.com%2F%3Fresult%3D{RESULT}](http://markusfisch.de/BinaryEye?ret=http%3A%2F%2Fexample.com%2F%3Fresult%3D{RESULT})

Supported symbols are:

* `RESULT` - scanned content
* `RESULT_BYTES` - raw result as a hex string
* `FORMAT` - barcode format

### SCAN Intent

You can also use Binary Eye from other apps by using the
`com.google.zxing.client.android.SCAN` Intent with
[startActivityForResult()][start_activity] like this:

```kotlin
startActivityForResult(
	Intent("com.google.zxing.client.android.SCAN"),
	SOME_NUMBER
)
```

And process the result in [onActivityResult()][on_activity_result] of your
`Activity`:

```kotlin
override fun onActivityResult(
	requestCode: Int,
	resultCode: Int,
	data: Intent?
) {
	when (requestCode) {
		SOME_NUMBER -> if (resultCode == RESULT_OK) {
			val result = data.getStringExtra("SCAN_RESULT")
			…
		}
	}
}
```

If you're using AndroidX, this would be the new,
[recommended way][intent_result]:

```kotlin
class YourActivity : AppCompatActivity() {
	private val resultLauncher = registerForActivityResult(
		ActivityResultContracts.StartActivityForResult()
	) { result ->
		if (result.resultCode == RESULT_OK) {
			val content = result.data?.getStringExtra("SCAN_RESULT")
			…
		}
	}

	fun openScanner() {
		resultLauncher.launch(Intent("com.google.zxing.client.android.SCAN"))
	}
}
```

[play]: https://play.google.com/store/search?q=barcode%20scanner&c=apps
[zxing_cpp]: https://github.com/zxing-cpp/zxing-cpp
[kotlin]: http://kotlinlang.org/
[aztec]: https://en.wikipedia.org/wiki/Aztec_Code
[codabar]: https://en.wikipedia.org/wiki/Codabar
[code_39]: https://en.wikipedia.org/wiki/Code_39
[code_93]: https://en.wikipedia.org/wiki/Code_93
[code_128]: https://en.wikipedia.org/wiki/Code_128
[data_matrix]: https://en.wikipedia.org/wiki/Data_Matrix
[dx_film_edge]: https://en.wikipedia.org/wiki/DX_encoding
[ean_8]: https://en.wikipedia.org/wiki/EAN-8
[ean_13]: https://en.wikipedia.org/wiki/International_Article_Number
[itf]: https://en.wikipedia.org/wiki/Interleaved_2_of_5
[maxicode]: https://en.wikipedia.org/wiki/MaxiCode
[pdf417]: https://en.wikipedia.org/wiki/PDF417
[qr_code]: https://en.wikipedia.org/wiki/QR_code
[micro_qr_code]: https://en.wikipedia.org/wiki/QR_code#Micro_QR_code
[rmqr_code]: https://www.qrcode.com/en/codes/rmqr.html
[rss]: https://en.wikipedia.org/wiki/GS1_DataBar
[upc_a]: https://en.wikipedia.org/wiki/Universal_Product_Code
[upc_e]: https://en.wikipedia.org/wiki/Universal_Product_Code#UPC-E
[upc_ean]: https://en.wikipedia.org/wiki/Universal_Product_Code#EAN-13
[start_activity]: https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int)
[on_activity_result]: https://developer.android.com/reference/android/app/Activity#onActivityResult(int,%20int,%20android.content.Intent)
[intent_result]: https://developer.android.com/training/basics/intents/result


# ![Xodus-DNQ](docs/images/XodusDNQ.png)

[![official JetBrains project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.jetbrains.xodus/dnq/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.jetbrains.xodus/dnq)
[![Build Status](https://travis-ci.org/JetBrains/xodus-dnq.svg?branch=master)](https://travis-ci.org/JetBrains/xodus-dnq)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
![Pure Java + Kotlin](https://img.shields.io/badge/100%25-java%2bkotlin-orange.svg)
[![Stack Overflow](https://img.shields.io/badge/stack%20overflow-xodus--dnq-brightgreen.svg)](https://stackoverflow.com/questions/tagged/xodus-dnq)

Xodus-DNQ is a Kotlin library that contains the data definition language and queries for
[Xodus](https://github.com/JetBrains/xodus), a transactional schema-less embedded database.
Xodus-DNQ provides the same support for Xodus that ORM frameworks provide for SQL databases.
With Xodus-DNQ, you can define your persistent meta-model using Kotlin classes.

JetBrains team tools [YouTrack](https://jetbrains.com/youtrack) and [Hub](https://jetbrains.com/hub) use Xodus-DNQ for
persistent layer definition.

More documentation https://jetbrains.github.io/xodus-dnq.

## Quick Start Guide

### Install to your project
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.jetbrains.xodus/dnq/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.jetbrains.xodus/dnq)

List of released versions is available at https://github.com/JetBrains/xodus-dnq/releases.

#### Gradle
```groovy
repositories {
    mavenCentral()
}
compile 'org.jetbrains.xodus:dnq:${version}'
```
#### Maven
```xml
<dependency>
    <groupId>org.jetbrains.xodus</groupId>
    <artifactId>dnq</artifactId>
    <version>$version</version>
</dependency>
```

### Use Xodus-DNQ
[See code in repository](https://github.com/JetBrains/xodus-dnq/blob/master/dnq/src/test/kotlin/kotlinx/dnq/sample/SampleShortApp.kt).
```kotlin
// Define persistent class. It should extend XdEntity
class XdPost(entity: Entity) : XdEntity(entity) {
    //  and have component object of type XdEntityType
    companion object : XdNaturalEntityType<XdPost>()

    // Define persistent property of type org.joda.time.DateTime?
    var publishedAt by xdDateTimeProp()

    // Define required persistent property of type String
    var text by xdRequiredStringProp()
}

class XdBlog(entity: Entity) : XdEntity(entity) {
    companion object : XdNaturalEntityType<XdBlog>()

    // Define multi-value link to XdPost
    val posts by xdLink0_N(XdPost)
}

fun main(args: Array<String>) {
    // Register persistent classes
    XdModel.registerNodes(XdPost, XdBlog)

    // Initialize Xodus persistent storage
    val xodusStore = StaticStoreContainer.init(
            dbFolder = File(System.getProperty("user.home"), ".xodus-dnq-blog-db"),
            environmentName = "db"
    )

    // Initialize Xodus-DNQ metadata
    initMetaData(XdModel.hierarchy, xodusStore)

    // Do in transaction
    val blog = xodusStore.transactional {
        // Find an existing blog in database
        XdBlog.all().firstOrNull()
                // or create a new one if there are no blogs yet
                ?: XdBlog.new()
    }

    xodusStore.transactional {
        // Create new post
        val post = XdPost.new {
            this.publishedAt = DateTime.now()
            this.text = args.firstOrNull() ?: "Empty post"
        }

        // Add new post to blog
        blog.posts.add(post)
    }

    // Do in read-only transaction
    xodusStore.transactional(readonly = true) {
        // Print all blog posts
        for (post in blog.posts) {
            println("${post.publishedAt}: ${post.text}")
        }
    }
}
```

## Find out more
- [Read documentation](https://jetbrains.github.io/xodus-dnq)
- [Report an issue](https://github.com/JetBrains/xodus-dnq/issues/new)
- [Ask question at Stack Overflow](https://stackoverflow.com/questions/tagged/xodus-dnq)
- [Learn more about Xodus](https://github.com/JetBrains/xodus)


#  DankChat

[![Build status](https://github.com/flex3r/DankChat/workflows/Android%20CI/badge.svg)](https://github.com/flex3r/DankChat/actions)
[](https://play.google.com/store/apps/details?id=com.flxrs.dankchat)
[](https://f-droid.org/packages/com.flxrs.dankchat)
A signed release version is available [here](https://github.com/flex3r/DankChat/releases/tag/release)
Make sure to click "install anyway" when a Play Protect dialog pops up during installation.

## Localization
DankChat uses crowdin for translations. Except for strings in the base language, resource strings don't need to be edited anymore.
If you want to contribute, request access to be a translator here: https://crowdin.com/project/dankchat

## Donate
Support the DankChat development and get a dank badge next to your name
https://streamelements.com/flex3rs/tip


# Ruuvi Station

[![License][license-image]][license-url]
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![Android Release Build](https://github.com/ruuvi/com.ruuvi.station/actions/workflows/buildRelease.yml/badge.svg?branch=dev)](https://github.com/ruuvi/com.ruuvi.station/actions/workflows/buildRelease.yml)

Ruuvi Station is an open-source Android app [available](https://play.google.com/store/apps/details?id=com.ruuvi.station) on the Google Play. You can observe the weather parameters, such as temperature, humidity, air pressure (and more) right on your Android device. Ruuvi Station is a companion app for open-source IoT BLE devices made by [Ruuvi](https://ruuvi.com).

## RuuviTag

[RuuviTag](https://ruuvi.com) is an advanced open-source sensor beacon platform designed to fulfill the needs of business customers, developers, makers, students, and can even be used in your home and as part of your personal endeavours. The device is set up to work as soon as you take it out of its box and is ready to be deployed to where you need it. Whether you need a beehive monitor in your backyard, or an industrial mesh network asset tracking system, [RuuviTag](https://ruuvi.com) gets you covered.

## Features

- [x] Temperature (°C, °F, K)
- [x] Humidity (%, g/m3, °C)
- [x] Air Pressure (Pa, hPa, mmHg, inHg)
- [x] Acceleration (g)
- [x] 10 days sensor data storage
- [x] Charts
- [x] Cloud Features
- [x] Data Forwarding

## Get in touch

Join our [Slack](https://slack.ruuvi.com) community.

Join our [Telegram](https://t.me/ruuvicom) community.

## How to buy

You can order RuuviTag sensors [online](https://shop.ruuvi.com). Find more info about the devices on [Ruuvi.com](https://ruuvi.com).

## Contribute

We would love you for the contribution to **Ruuvi Station**, check the ``LICENSE`` file for more info.

## How to build

1. Open Android Studio (4.0 or newer)
2. Select 'Get from Version Control
3. Enter repository URL: https://github.com/ruuvi/com.ruuvi.station
4. Clone repository
5. Select a branch you want to build
6. Sync project with Gradle file
7. Now you can run project on emulator or phone

Watch video showing build process:

[![Twitter][twitter-image]][twitter]
[![Facebook][facebook-image]][facebook]
[![Github][github-image]][github]

[github-image]:http://i.imgur.com/0o48UoR.png
[github]:https://github.com/ruuvi
[facebook-image]:http://i.imgur.com/P3YfQoD.png
[facebook]:https://www.facebook.com/ruuvi.cc/
[twitter-image]:http://i.imgur.com/tXSoThF.png
[twitter]:https://twitter.com/ruuvicom
[license-image]: https://img.shields.io/badge/License-BSD-blue.svg
[license-url]: LICENSE


# ORX (OPENRNDR EXTRA)

[![Download](https://maven-badges.herokuapp.com/maven-central/org.openrndr.extra/orx-parameters-jvm/badge.svg)](https://mvnrepository.com/artifact/org.openrndr.extra)

A growing library of assorted data structures, algorithms and utilities to
complement [OPENRNDR](https://github.com/openrndr/openrndr).

<!-- __orxListBegin__ -->

## Multiplatform

| name                                     | description |
| --- | --- |
| [`orx-camera`](orx-camera/) | 2D and 3D cameras controllable via mouse and keyboard. |
| [`orx-color`](orx-color/) | Color spaces, palettes, histograms, named colors. |
| [`orx-composition`](orx-composition/) | Shape composition library |
| [`orx-compositor`](orx-compositor/) | Toolkit to make composite (layered) images using blend modes and filters. |
| [`orx-compute-graph`](orx-compute-graph/) | A graph for computation. |
| [`orx-compute-graph-nodes`](orx-compute-graph-nodes/) | A collection of nodes that can be used with `orx-compute-graph`. |
| [`orx-delegate-magic`](orx-delegate-magic/) | Collection of magical property delegators. For tracking variable change or interpolate towards the value of a variable. |
| [`orx-easing`](orx-easing/) | Easing functions for smooth animation or non-linear interpolation. |
| [`orx-envelopes`](orx-envelopes/) | ADSR (Attack, Decay, Sustain, Release) envelopes and tools. |
| [`orx-expression-evaluator`](orx-expression-evaluator/) | Tools to evaluate strings containing mathematical expressions. |
| [`orx-expression-evaluator-typed`](orx-expression-evaluator-typed/) | Tools to evaluate strings containing typed mathematical expressions. |
| [`orx-fcurve`](orx-fcurve/) | FCurves are 1 dimensional function curves constructed from 2D bezier functions. They are often used to control a property over time.  `x` values don't have any units, but they often represent a duration in seconds. |
| [`orx-fft`](orx-fft/) | Simple forward and inverse FFT routine |
| [`orx-fx`](orx-fx/) | Ready-to-use GPU-based visual effects or filters. Most include [orx-parameters](https://github.com/openrndr/orx/tree/master/orx-parameters) annotations  so they can be easily controlled via orx-gui. |
| [`orx-gradient-descent`](orx-gradient-descent/) | Finds equation inputs that output a minimum value: easy to use gradient descent based minimizer. |
| [`orx-hash-grid`](orx-hash-grid/) | 2D space partitioning for fast point queries. |
| [`orx-image-fit`](orx-image-fit/) | Draws an image ensuring it fits or covers the specified `Rectangle`. |
| [`orx-integral-image`](orx-integral-image/) | CPU and GPU-based implementation for integral images (summed area tables) |
| [`orx-interval-tree`](orx-interval-tree/) | For querying a data set containing time segments (start time and end time) when we need all entries containing a specific time value. Useful when creating a timeline. |
| [`orx-jumpflood`](orx-jumpflood/) | Calculates distance or direction fields from an image. GPU accelerated, 2D. Results are provided as an image. |
| [`orx-kdtree`](orx-kdtree/) | Fast search of points closest to the queried point in a data set. 2D, 3D and 4D. |
| [`orx-marching-squares`](orx-marching-squares/) | Tools for extracting contours from functions |
| [`orx-mesh-generators`](orx-mesh-generators/) | 3D-mesh generating functions and DSL. |
| [`orx-no-clear`](orx-no-clear/) | Provides the classical "draw-without-clearing-the-screen" functionality. |
| [`orx-noise`](orx-noise/) | Randomness for every type of person: Perlin, uniform, value, simplex, fractal and many other types of noise. |
| [`orx-obj-loader`](orx-obj-loader/) | Simple loader for Wavefront .obj 3D mesh files. |
| [`orx-palette`](orx-palette/) | Provides hundreds of color palettes. |
| [`orx-parameters`](orx-parameters/) | Provides annotations and tools for turning Kotlin properties into introspectable parameters. Used by [`orx-gui`](../orx-jvm/orx-gui/README.md) to automatically generate user interfaces. |
| [`orx-property-watchers`](orx-property-watchers/) | Tools for setting up property watcher based pipelines |
| [`orx-quadtree`](orx-quadtree/) | A [Quadtree](https://en.wikipedia.org/wiki/Quadtree) is a spatial partioning tree structure meant to provide fast spatial queries such as nearest points within a range. |
| [`orx-shade-styles`](orx-shade-styles/) | Shader based fills and strokes, including various types of gradient fills. |
| [`orx-shader-phrases`](orx-shader-phrases/) | A library that provides a `#pragma import` statement for shaders. |
| [`orx-shapes`](orx-shapes/) | Collection of 2D shape generators and modifiers. |
| [`orx-svg`](orx-svg/) | SVG reader and writer library. |
| [`orx-temporal-blur`](orx-temporal-blur/) | Post-processing temporal-blur video effect. CPU intense, therefore not intended  for use with the `ScreenRecorder` extension or other real-time uses. |
| [`orx-text-writer`](orx-text-writer/) | Writing texts with layouts |
| [`orx-time-operators`](orx-time-operators/) | A collection of time-sensitive functions aimed at controlling raw data over-time,  such as Envelope and LFO. |
| [`orx-timer`](orx-timer/) | Simple timer functionality providing `repeat`, to run code with a given interval and `timeOut`, to run code once after a given delay. |
| [`orx-triangulation`](orx-triangulation/) | **Delaunay** triangulation and **Voronoi** diagrams. |
| [`orx-turtle`](orx-turtle/) | Bezier (`ShapeContour`) backed [turtle graphics](https://en.wikipedia.org/wiki/Turtle_graphics). |
| [`orx-view-box`](orx-view-box/) | To create independent views inside one program window. |

## JVM only

| name                                     | description |
| --- | --- |
| [`orx-boofcv`](orx-jvm/orx-boofcv/) | Helper functions to ease working with the BoofCV computer vision library and its data types. |
| [`orx-chataigne`](orx-jvm/orx-chataigne/) | Expose variables to [Chataigne](http://benjamin.kuperberg.fr/chataigne/en) and any other applications that can interface with it. The current implementation makes use of the OSC protocol and supports `Double` and `ColorRGBa`. |
| [`orx-depth-camera-calibrator`](orx-jvm/orx-depth-camera-calibrator/) | Class to help callibrate depth and transformation matrices when using one or more depth cameras. |
| [`orx-dnk3`](orx-jvm/orx-dnk3/) | A scene graph based 3d renderer with support for Gltf based assets |
| [`orx-file-watcher`](orx-jvm/orx-file-watcher/) | Monitor files on disk and auto-reload them if they change. |
| [`orx-git-archiver`](orx-jvm/orx-git-archiver/) | An extension that hooks into `Program.requestAssets` to commit changed code to Git and provide filenames based on the commit hash. |
| [`orx-git-archiver-gradle`](orx-jvm/orx-git-archiver-gradle/) | A Gradle plugin that turns a git history and `screenshots` directory into a markdown file. |
| [`orx-gui`](orx-jvm/orx-gui/) | Automatic UI (sliders, buttons, etc.) generated from annotated classes and properties. Uses `orx-panel` and `orx-parameters`. |
| [`orx-keyframer`](orx-jvm/orx-keyframer/) | Create animated timelines by specifying properties and times in keyframes, then play it back at any speed (even backwards) automatically interpolating properties. Save, load, use mathematical expressions and callbacks. Powerful and highly reusable. |
| [`orx-kinect-v1`](orx-jvm/orx-kinect-v1/) | Support for the Kinect V1 RGB and depth cameras. |
| [`orx-midi`](orx-jvm/orx-midi/) | MIDI support for keyboards and controllers. Send and receive note and control change events. Bind inputs to variables. |
| [`orx-minim`](orx-jvm/orx-minim/) | Simplifies working with the Minim sound library. Provides sound synthesis and analysis. |
| [`orx-olive`](orx-jvm/orx-olive/) | Provides live coding functionality: updates a running OPENRNDR program when you save your changes. |
| [`orx-osc`](orx-jvm/orx-osc/) | Open Sound Control makes it possible to send and receive messages from other OSC enabled programs in the same or a different computer. Used to create multi-application or multi-device software. |
| [`orx-panel`](orx-jvm/orx-panel/) | The OPENRNDR UI toolkit. Provides buttons, sliders, text, a color picker and much more. HTML/CSS-like. |
| [`orx-poisson-fill`](orx-jvm/orx-poisson-fill/) | Post processing effect that fills transparent parts of the image interpolating the edge pixel colors. GPU-based. |
| [`orx-rabbit-control`](orx-jvm/orx-rabbit-control/) | Creates a web-based remote UI to control your OPENRNDR program from a mobile device or a different computer. Alternative to `orx-gui`. |
| [`orx-runway`](orx-jvm/orx-runway/) | Interfaces with the RunwayML machine learning library that provides features like motion capture, image synthesis, object recognition, style transfer and more. More info at [runwayml.com](https://runwayml.com/). |
| [`orx-syphon`](orx-jvm/orx-syphon/) | Send frames to- and from OPENRNDR to other applications in real time using _Syphon_ for Mac. |
| [`orx-video-profiles`](orx-jvm/orx-video-profiles/) | GIF, H265, PNG, Prores, TIFF and Webp `VideoWriterProfile`s for `ScreenRecorder` and `VideoWriter`. |
<!-- __orxListEnd__ -->

# Developer notes

## Publish and use local builds of the library in your applications

First, build and publish [OPENRNDR](https://github.com/openrndr/openrndr) to the local maven repository:

Run (or import in IntelliJ IDEA and edit the run configuration).
```sh
# In openrndr repository
./gradlew publishToMavenLocal snapshot
```

This command will build and publish a snapshot of the next version of the library to your local maven repository.
The exact version will be shown in the console output during the build process.

Now you can run the same command again but for this repository.

```sh
# In orx repository
./gradlew publishToMavenLocal snapshot
```

It will automatically use the locally published snapshot of OPENRNDR for building ORX and will publish ORX to your local
maven repository with the same logic as before.

Once that's done, you can use the local builds of OPENRNDR and ORX in
your [openrndr-template](https://github.com/openrndr/openrndr-template) by specifying the version that was published.

Take a look at the [wiki](https://github.com/openrndr/openrndr/wiki/Building-OPENRNDR-and-ORX) for a more detailed walk-through.


The perfect starting point to integrate Algolia within your Kotlin project

  Documentation  •
  Community Forum  •
  Stack Overflow  •
  Report a bug  •
  FAQ  •
  Support

## ✨ Features

- The Kotlin client is compatible with Kotlin `1.6` and higher.
- It is compatible with Kotlin project on the JVM, such as backend and Android applications.
- It relies on the open source Kotlin libraries for seamless integration into Kotlin projects:
  - [Kotlin multiplatform](https://kotlinlang.org/docs/reference/multiplatform.html).
  - [Kotlinx serialization](https://github.com/Kotlin/kotlinx.serialization) for json parsing.
  - [Kotlinx coroutines](https://github.com/Kotlin/kotlinx.coroutines) for asynchronous operations.
  - [Ktor](https://github.com/ktorio/ktor) HTTP client.
- The Kotlin client integrates the actual Algolia documentation in each source file: Request parameters, response fields, methods and concepts; all are documented and link to the corresponding url of the Algolia doc website.
- The client is thread-safe. You can use `SearchClient`, `AnalyticsClient`, and `InsightsClient` in a multithreaded environment.

## 💡 Getting Started

Install the Kotlin client by adding the following dependency to your `gradle.build` file:

  ```gradle
  repositories {
     mavenCentral()
  }

  dependencies {
     implementation "com.algolia:algoliasearch-client-kotlin:$kotlin_client_version"
  }
  ```
Also, choose and add to your dependencies one of [Ktor http client engines](https://ktor.io/docs/http-client-engines.html).
Alternatively, you can use [algoliasearch-client-kotlin-bom](/client-bom).
For full documentation, visit the **[Algolia Kotlin API Client](https://www.algolia.com/doc/api-client/getting-started/install/kotlin/)**.

ℹ Please follow the [migration guide](docs/guide/Migrate_1.x_2.x.md) to migrate from `1.x` to the latest version.

### Coroutines

All methods performing HTTP calls in the Kotlin client are [suspending functions](https://kotlinlang.org/docs/reference/coroutines/composing-suspending-functions.html#composing-suspending-functions).
This means these functions can only be called from a coroutine.

In the example below, a coroutine is launched in the main thread.
The context is switched to a thread pool to perform the search HTTP call off the main thread.
The response can be manipulated from the main thread.

```kotlin
class Searcher : CoroutineScope {

    override val coroutineContext = Job()

    fun search() {
        launch(Dispatchers.Main) {
            val response = withContext(Dispatchers.Default) { index.search() }
        }
    }
}
```

The developer is responsible for implementing the asynchronous logic that matches their specific requirements.
The Kotlin client doesn't execute HTTP calls on any particular thread, it is up to the developer to define it explicitly using coroutines.
Learn more about [coroutines](https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html).

### Waiting for operations

Waiting for an asynchronous server task is made available via a [function literal with receiver](https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver).

Use the [apply](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html) or [run](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run.html) functions on your index or client.

```kotlin
index.apply {
    setSettings(Settings()).wait()
}
client.run {
    multipleBatchObjects(listOf<BatchOperationIndex>()).waitAll()
}
```

The `wait` functions are suspending, and should only be called from a coroutine.

### Type safety

Response and parameters objects are typed to provide extensive compile time safety coverage.

Example for creating a Client instance without mixing the application ID and the API key.

```kotlin
val appID = ApplicationID("YourApplicationID")
val apiKey = APIKey("YourAdminAPIKey")

val client = ClientSearch(appID, apiKey)
```

Example for attributes:

```kotlin
val color = Attribute("color")
val category = Attribute("category")

Query(
  attributesToRetrieve = listOf(color, category)
)
```

Sealed class are used to represent enumerated types. It allows to quickly discover possible values for each type thanks to IDE autocomplete support.
All sealed class have an `Other` class case for avoiding runtime crashes in case of unforeseen value.

```kotlin
val query = Query()

query.sortFacetsBy = SortFacetsBy.Count
// query.sortFacetsBy = SortFacetsBy.Alpha
// query.sortFacetsBy = SortFacetsBy.Other("unforeseen value")
```

### R8 / Proguard rules

If you use this library in an Android project which uses R8, there is nothing you have to do. The specific rules are
already bundled into the JAR, which can be interpreted by R8 automatically.

If however, you don’t use R8 you have to apply the rules from [this file](client/src/jvmMain/resources/META-INF/proguard/algoliasearch.pro).

### Guides

- [Getting started](https://github.com/algolia/algoliasearch-client-kotlin/tree/master/docs/GettingStarted.md)
- [DSL](https://github.com/algolia/algoliasearch-client-kotlin/tree/master/docs/DSL.md)
- [Serialization](https://github.com/algolia/algoliasearch-client-kotlin/tree/master/docs/Serialization.md)
- [ExceptionHandling](https://github.com/algolia/algoliasearch-client-kotlin/tree/master/docs/ExceptionHandling.md)
- [Configure the HTTP client](https://github.com/algolia/algoliasearch-client-kotlin/tree/master/docs/HTTPClient.md)

## ❓ Troubleshooting

Encountering an issue? Before reaching out to support, we recommend heading to our [FAQ](https://www.algolia.com/doc/api-client/troubleshooting/faq/kotlin/) where you will find answers for the most common issues and gotchas with the client.

## Use the Dockerfile

If you want to contribute to this project without installing all its dependencies, you can use our Docker image. Please check our [dedicated guide](DOCKER_README.md) to learn more.

## 📄 License

Algolia Kotlin API Client is an open-sourced software licensed under the [MIT license](LICENSE).


# Adorn

[![](https://img.shields.io/github/license/Juuxel/Adorn.svg)](LICENSE) [![](https://img.shields.io/github/release/Juuxel/Adorn.svg)](https://github.com/Juuxel/Adorn/releases) ![](http://cf.way2muchnoise.eu/versions/minecraft_adorn_all.svg) [![](http://cf.way2muchnoise.eu/adorn.svg)](https://minecraft.curseforge.com/projects/adorn)

*Decorate your home!* • [Downloads](https://github.com/Juuxel/Adorn/releases) • [CurseForge](https://minecraft.curseforge.com/projects/adorn)

## Screenshots
![](https://i.imgur.com/tQbDWVY.jpg)
![](https://i.imgur.com/lUifqTY.png)
![](https://i.imgur.com/owM5tUa.png)


### Fearless Wallet Android
[![Google Play](https://img.shields.io/badge/Google%20Play-Android-green?logo=google%20play)](https://play.google.com/store/apps/details?id=jp.co.soramitsu.fearless)

![logo](/docs/fearlesswallet_promo.png)

## About
Fearless Wallet is a mobile wallet designed for the decentralized future on the Kusama network, with support on iOS and Android platforms. The best user experience, fast performance, and secure storage for your accounts. Development of Fearless Wallet is supported by Kusama Treasury grant.

[![](https://img.shields.io/twitter/follow/FearlessWallet?label=Follow&style=social)](https://twitter.com/FearlessWallet)

## Roadmap
Fearless Wallet roadmap is available for everyone: [roadmap link](https://soramitsucoltd.aha.io/shared/97bc3006ee3c1baa0598863615cf8d14)

## Dev Status
Track features development: [board link](https://soramitsucoltd.aha.io/shared/343e5db57d53398e3f26d0048158c4a2)

## How to build

To build Fearless Wallet Android project, you need to provide several keys either in environment variables or in `local.properties` file:

### Moonpay properties
```
MOONPAY_TEST_SECRET=stub
MOONPAY_PRODUCTION_SECRET=stub
```

Note, that with stub keys buy via moonpay will not work correctly. However, other parts of the application will not be affected.

### Sora CARD SDK

For starting Sora CARD SDK initial data have to be provided via gradle properties due to security purpose.

````
// PayWings repo credentials properties for getting artifacts
PAY_WINGS_REPOSITORY_URL
PAY_WINGS_USERNAME
PAY_WINGS_PASSWORD

// Sora CARD API key
SORA_CARD_API_KEY_TEST
SORA_CARD_API_KEY_PROD
SORA_CARD_DOMAIN_TEST
SORA_CARD_DOMAIN_PROD

// Sora CARD KYC credentials
SORA_CARD_KYC_ENDPOINT_URL_TEST
SORA_CARD_KYC_ENDPOINT_URL_PROD
SORA_CARD_KYC_USERNAME_TEST
SORA_CARD_KYC_USERNAME_PROD
SORA_CARD_KYC_PASSWORD_TEST
SORA_CARD_KYC_PASSWORD_PROD

// Sora CARD backend
SORA_BACKEND_DEBUG
SORA_BACKEND_RELEASE
````

### X1 plugin

X1 is a plugin which is embedded into webView. It requires url and id for launching.

````
X1_ENDPOINT_URL_RELEASE
X1_WIDGET_ID_RELEASE

X1_ENDPOINT_URL_DEBUG
X1_WIDGET_ID_DEBUG
````

### Ethereum properties

Set of params required to deliver Ethereum connection

````
// Ethereum blast api nodes keys
FL_BLAST_API_ETHEREUM_KEY
FL_BLAST_API_BSC_KEY
FL_BLAST_API_SEPOLIA_KEY
FL_BLAST_API_GOERLI_KEY
FL_BLAST_API_POLYGON_KEY

// Ethereum history providers api keys
FL_ANDROID_ETHERSCAN_API_KEY
FL_ANDROID_BSCSCAN_API_KEY
FL_ANDROID_POLYGONSCAN_API_KEY
````

## License
Fearless Wallet Android is available under the Apache 2.0 license. See the LICENSE file for more info.


[![Actions Status](https://github.com/tari-project/wallet-android/workflows/Aurora%20Android%20Release%20Workflow/badge.svg)](https://github.com/tari-project/wallet-android/actions)

[![Actions Status](https://github.com/tari-project/wallet-android/workflows/PR%20Test%20Workflow/badge.svg)](https://github.com/tari-project/wallet-android/actions)

## What is Aurora?
Aurora is a reference-design mobile wallet app for the forthcoming [Tari](https://www.tari.com/) digital currency. The goal is for creators and developers to be able to use the open-source Aurora libraries and codebase as a starting point for developing their own Tari wallets and applications. Aurora also sets the bar for applications that use the Tari protocol. In its production-ready state, it will be a beautiful, easy to use Tari wallet focused on Tari as a default-private digital currency.

Want to contribute to Aurora? Get started here in this repository for Android or [here](https://github.com/tari-project/wallet-ios) for iOS.

## Build Instructions

1. Install [Android Studio 4.0](https://developer.android.com/studio).
2. Clone the repository: `git clone https://github.com/tari-project/wallet-android.git`
3. Open Android Studio, select `Open an existing Android Studio Project` and select the project root folder.
4. Wait until Android Studio finishes initial downloading, syncing and indexing.
5. If you have not yet configured NDK, you should see the "NDK not configured" message at the end of the build and sync process.

6. Click "Install NDK ..." link in the build log and accept the license, this will commence NDK and CMake installations. Let Android Studio do more downloading and sync.ing and wait until you see "CONFIGURE SUCCESSFUL" in the build logs.

7. At this step, please go to the `SDK Manager` and make sure that both NDK and CMake are installed.

8. Go to `Build Variants` and select `regularDebug` for the full configuration, or `privacyDebug` for privacy configuration.

9. Make project. (`Build` → `Make Project`)
10. `OPTIONAL` `secret.properties` file in the project folder contains application secrets and will be generated for you with default values during the build process. Please follow the comments in this file and edit if required.
11. `OPTIONAL` The regular build of Aurora uses [Sentry](https://sentry.io/) for error monitoring. `sentry.properties` file in the project folder contains Sentry configuration and will be created with empty values for you during the build process. Please follow the comments in this file and edit with your Sentry server values if you'd like to enable crash reporting.
12. **_Voila_** 🎉 You're now ready to run Aurora! Please follow the next item on how to setup your emulator, or you can already run it on your device.

### Emulator Configuration

Aurora Android native libraries only support `armeabi-v7a`, `arm64-v8a` and `x86_64` [ABIs](https://developer.android.com/ndk/guides/abis). Therefore you can only run Aurora on devices and emulators with a supported ABI. Android Studio emulators use the unsupported `x86` ABI as default, but you can download an `x86_64` image for your emulator and run Aurora on it. Please `Download` an `x86_64` image under the `x86 Images` tab in the `System Image` step of `Virtual Device Configuration.`

### Using Your Custom Native Library (FFI) Version

Tari native wallet library version to be used by Aurora is specified by the `ext.libwalletVersion` in the `build.gradle` file in the project root directory. Aurora build script automatically fetches the native libraries of this version into the `libwallet` folder in the root directory during the build process. Any library files you place in this folder will be deleted and replaced by this automatic download process.

If you want to disable the automatic download and use the native libraries of your choice, please comment out the line `preBuild.dependsOn("downloadLibwallet")` in the file `app/build.gradle`.

### For updating openssl
https://github.com/217heidai/openssl_for_android/releases


# LeakCanary 🐤

A memory leak detection library for Android.

### [square.github.io/leakcanary](https://square.github.io/leakcanary)

🙏 If you like LeakCanary you can show support by starring ⭐ this repository.

## License

    Copyright 2015 Square, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.


# Awesome Kotlin ([https://kotlin.link](https://kotlin.link))

A curated list of awesome Kotlin related stuff inspired by awesome-java. :octocat:

Discuss this project in [Kotlin Slack](http://slack.kotlinlang.org/), channel: **# awesome-kotlin**

[![List of Awesome List Badge](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) [![Build](https://github.com/KotlinBy/awesome-kotlin/actions/workflows/build.yml/badge.svg)](https://github.com/KotlinBy/awesome-kotlin/actions/workflows/build.yml) [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin)

:newspaper: [RSS Feed of articles, videos, slides, updates (20 latest articles)](http://kotlin.link/rss.xml)

:newspaper: [RSS Feed of articles, videos, slides, updates (full archive)](http://kotlin.link/rss-full.xml)

:octocat: [Awesome Kotlin - README.md](https://github.com/KotlinBy/awesome-kotlin/blob/readme/README.md) - README with links

## Spread Awesome Kotlin!

Here is the awesome badge for your project:

```markdown
[![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin)
```

To contribute, check [CONTRIBUTING.md](https://github.com/KotlinBy/awesome-kotlin/blob/main/.github/contributing.md).


# [![TranslationPlugin][plugin-logo]][gh:translation-plugin] TranslationPlugin

[![Plugin Homepage][badge:plugin-homepage]][plugin-homepage]
[![Build Status][badge:build]][gh:workflows-build]
[![License][badge:license]][gh:license]
[![GitHub releases][badge:release]][gh:releases]
[![Version][badge:version]][plugin-versions]
[![Downloads][badge:downloads]][plugin-homepage]
[![Financial Contributors on Open Collective][badge:open-collective]][open-collective]

Translation plugin for IntelliJ based IDEs/Android Studio.

[![Getting Started][badge:get-started-en]][get-started-en]
[![开始使用][badge:get-started-zh]][get-started-zh]
[![はじめに][badge:get-started-jp]][get-started-ja]
[![시작하기][badge:get-started-ko]][get-started-ko]

---

[![Microsoft Translator][logo:microsoft-translator]](https://www.bing.com/translator)

[![Google Translate][logo:google-translate]](https://translate.google.com)

[![OpenAI Translator][logo:openai]](https://openai.com/)

[![DeepL Translator][logo:deepl-translator]](https://www.deepl.com)

[![Youdao Translate][logo:youdao-translate]](https://ai.youdao.com)

[![Baidu Translate][logo:baidu-translate]](https://fanyi-api.baidu.com)

[![Alibaba Translate][logo:ali-translate]](https://translate.alibaba.com)

---

- [Features](#features)
- [Compatibility](#compatibility)
- [Installation](#installation)
- [Using the Plugin](#using-the-plugin)
- [Actions](#actions)
- [FAQ](#faq)
- [Support and Donations](#support-and-donations)
- [Contributors](#contributors)
    - [Code Contributors](#code-contributors)
    - [Financial Contributors](#financial-contributors)

## Features

- Multiple Translation Engines
    - Microsoft Translator
    - Google Translate
    - DeepL Translator
    - OpenAI Translator
    - Youdao Translate
    - Baidu Translate
    - Alibaba Translate
- Multiple languages inter-translation
- Text-to-speech
  - Microsoft Edge TTS
  - Google TTS
  - OpenAI TTS
- Document translation
- Automatic word selection
- Automatic word breaks
- Word Book

## Compatibility

- Android Studio
- Aqua
- AppCode
- CLion
- DataGrip
- DataSpell
- GoLand
- HUAWEI DevEco Studio
- IntelliJ IDEA Community
- IntelliJ IDEA Ultimate
- MPS
- PhpStorm
- PyCharm Community
- PyCharm Professional
- Rider
- RubyMine
- RustRover
- WebStorm

## Installation

- **Installing from the plugin repository within the IDE:**
    - Preferences(Settings) > Plugins > Marketplace > Search and find "
      Translation" > Install Plugin.

- **Installing manually:**
    - Download the plugin package on [GitHub Releases][gh:releases] or in
      the [JetBrains Plugin Repository][plugin-versions].
    - Preferences(Settings) > Plugins > ⚙ > Install plugin from disk... >
      Select the plugin package and install (no need to unzip)

Restart the **IDE** after installation.

## Using The Plugin

1. **Sign up for a translation service (optional)**

   Most translation services require user registration to access their services
   (such as OpenAI, DeepL, Youdao Translate, etc.).
   Therefore, you may need to create an account, obtain an **Authentication Key**,
   and then bind the **Authentication Key** within the plugin：Preferences(Settings) >
   Tools >
   Translation > General > Translation Engine > Configure...

2. **Begin translating**

   Select a text or hover the mouse over the text > Right-click > Translate

   Or use shortcuts for translation, as detailed in **[Actions](#actions)**.

3. **Translate and replace**

   Translate the target text and replace it. If the target language is English, the output has several formats: **in
   camel case, with a word separator** (when the output contains multiple words, the separator can be configured in the
   plugin configuration page: Translation Settings > Translate and replace > Separator)
   and in the **original format**.

   Instructions: Select a text or hover the mouse over the text > Right-click > Translate and
   Replace... (Or use shortcuts for translation, as detailed in **[Actions](#actions)**).

4. **Translate documents**

   Preferences(Settings) > Tools > Translation > Other > Translate
   documents: When you check this option, the document will be automatically translated when you view it.

5. **Switch engines**

   Click the engine widget in the status bar or use the shortcut Ctrl + Shift + S
   (Mac OS: Control + Meta + Y) to switch between
   the translation engine and the TTS engine quickly.

## Actions

- **Show Translation Dialog...**

  Open the translation dialog, which appears by default on the toolbar. Default shortcut:

    - Windows - Ctrl + Shift + O
    - Mac OS - Control + Meta + I

- **Translate**

  Extract words and translate them. If you have already selected a text, extract the words from the portion of the text
  you'd like to translate. Otherwise, words are extracted automatically from the maximum range (this extraction can be
  configured in Settings). This action is displayed by default in the editor's right-click context menu. Default
  shortcut:

    - Windows - Ctrl + Shift + Y
    - Mac OS - Control + Meta + U

- **Translate(Inclusive)**

  Extract words and translate them. Automatically extract and translate all words from a specific range, ignoring
  manually selected text. Default shortcut: (None)

- **Translate(Exclusive)**

  Extract words and translate them. Automatically extract the nearest single word, ignoring manually selected text.
  Default shortcut: (None)

- **Translate and Replace...**

  Translate and replace. The word extraction method works the same as when **translating**. Default shortcut:

    - Windows - Ctrl + Shift + X
    - Mac OS - Control + Meta + O

- **Translate Documentation**

  Translate the contents of document comments.
  This option is displayed by default in the editor's context menu (right-click to access)
  and is available when the cursor is in the document's comment block.
  Default shortcut: (None)

- **Toggle Quick Documentation Translation**

  Toggle between the original and translated texts in Quick Documentation. This option is available when the focus is on
  the Quick Documentation pop-up window or the documentation tool window. Default shortcut (same as **translation**
  shortcut):

    - Windows - Ctrl + Shift + Y
    - Mac OS - Control + Meta + U

- **Translate Text Component**

  Translate selected text in some text components (e.g. Quick Docs, popup hints, input boxes...). This does not support
  automatic word extraction. Default shortcut (same as **translation** shortcut):

    - Windows - Ctrl + Shift + Y
    - Mac OS - Control + Meta + U

- **Switch Engine**

  Quickly switch between translation engine and TTS engine. Default shortcut:

    - Windows - Ctrl + Shift + S
    - Mac OS - Control + Meta + Y

- **Word of the Day**

  Display the 'Word of the Day' dialog box. Default shortcut: (None)

- **Other**

    - Translation dialog shortcuts:

        - Display the list of source languages - Alt + S
        - Display the list of target languages - Alt + T
        - Switch between languages - Alt + Shift + S
        - Pin/unpin a window - Alt + P
        - Play TTS - Alt/Meta/Shift + Enter
        - Save to Word Book - Ctrl/Meta + F
        - Show history - Ctrl/Meta + H
        - Copy translation - Ctrl/Meta + Shift + C
        - Clear input - Ctrl/Meta + Shift + BackSpace/Delete
        - Expand more translations - Ctrl/Meta + Down
        - Hide more translations - Ctrl/Meta + UP

    - Translation balloon shortcuts:

        - Open dialog - Ctrl + Shift + Y / Control + Meta +
          U

    - Quick Documentation window shortcuts:

        - Enable/disable automatic translation - Ctrl + Shift + Y / Control
            + Meta + U

## FAQ

> *If you have any questions, please ask [here][gh:discussions-q-a].*

1. **What should I do if there is a network error or the network connection times out?**

   **A:**
    - Check the network environment and make sure the network is running smoothly.
    - Check whether a proxy is preventing the plugin from accessing the translation API.
    - Check the IDE proxy configuration to see if that is the cause of the problem.

2. **What should I do if the translated content appears garbled?**

   **A:** Garbled code generally appears when there is a lack of corresponding characters in the font. You can go to
   the Settings page of the plugin to modify the font in order to fix the garbled code (as shown below).

   ![screenshots][file:settings-font]

3. **What if I can't save the application key?**

   **A:** You can try changing the way passwords are saved to `In KeePass` (Settings > Appearance &
   Behavior > System Settings > Passwords). For more details:
    - For macOS, please refer to [#81][gh:#81]
    - For Linux, please refer to [#115][gh:#115]

4. **What if the shortcuts don't work?**

   **A:** The shortcut keys are most likely not working because they are being used in other plugins or external
   applications. You can reset shortcut keys for the corresponding operations.

## Support and Donations

You can contribute and support this project by doing any of the following:

* Star the project on GitHub
* Give feedback
* Commit PR
* Contribute your ideas/suggestions
* Share the plugin with your friends/colleagues
* If you love this plugin, please consider donating. It will inspire me to continue development on the project:

        Open Collective
        WeChat Pay
        Alipay

  > **Note**
  >
  > After using Alipay/WeChat to pay for your donation, please provide your name/nickname and website by leaving
  > a message or via email in the following format:
  >
  > `Name/Nickname [<website>][: message]` (website and message are optional.)
  >
  > Example: `Yii.Guxing <github.com/YiiGuxing>: I like the plugin!`
  >
  > If you choose to send an email, please also provide the following information:
  > ```text
  > Donation Amount: <amount>
  > Payment Platform: Alipay/WeChat Pay
  > Payment Number (last 5 digits): <number>
  > ```
  > Email address: [yii.guxing@outlook.com][mailto] (click to send email)
  >
  > The name, website and total donation amount you provide will be added to
  > the [donor list][file:financial-contributors].

**Thank you for your support!**

## Contributors

### Code Contributors

This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].

### Financial Contributors

Become a financial contributor and help us sustain our
community. [[Contribute][open-collective-contribute]]

#### Backers

Thank you to all our backers! ❤ [[Become a backer](https://opencollective.com/translation-plugin/donate)]

#### Sponsors

Support this project by becoming a sponsor! Your logo will show up here with a link to your
website. [[Become a sponsor][open-collective-contribute]]

#### Donors

| **Name**   | **Website**                                                | **Amount** |
|------------|------------------------------------------------------------|------------|
| 丿初音        |                                                            | 425.00 CNY |
| 剑平         |                                                            | 120.00 CNY |
| 山有扶苏       | [github.com/fobgochod](https://github.com/fobgochod)       | 110.00 CNY |
| Kimmy      |                                                            | 100.00 CNY |
| LiMingjun  |                                                            | 100.00 CNY |
| DarknessTM | [github.com/darknesstm](https://github.com/darknesstm)     | 100.00 CNY |
| Sunlife95  |                                                            | 100.00 CNY |
| 马强@咔丘互娱    |                                                            | 100.00 CNY |
| Rrtt\_2323 |                                                            | 100.00 CNY |
| 唐嘉         | [github.com/qq1427998646](https://github.com/qq1427998646) | 100.00 CNY |

[More donors][file:financial-contributors]

[plugin-logo]: https://yiiguxing.github.io/TranslationPlugin/img/ext/plugin-icon.svg

[badge:plugin-homepage]: https://img.shields.io/badge/plugin%20homepage-translation-4caf50.svg?style=flat-square
[badge:build]: https://img.shields.io/endpoint?label=build&style=flat-square&url=https%3A%2F%2Factions-badge.atrox.dev%2FYiiGuxing%2FTranslationPlugin%2Fbadge%3Fref%3Dmaster
[badge:license]: https://img.shields.io/github/license/YiiGuxing/TranslationPlugin.svg?style=flat-square
[badge:release]: https://img.shields.io/github/release/YiiGuxing/TranslationPlugin.svg?sort=semver&style=flat-square&colorB=0097A7
[badge:version]: https://img.shields.io/jetbrains/plugin/v/8579.svg?style=flat-square&colorB=2196F3
[badge:downloads]: https://img.shields.io/jetbrains/plugin/d/8579.svg?style=flat-square&colorB=5C6BC0
[badge:open-collective]: https://opencollective.com/translation-plugin/all/badge.svg?label=financial+contributors&style=flat-square&color=d05ce3
[badge:get-started-en]: https://img.shields.io/badge/Get%20Started-English-4CAF50?style=flat-square
[badge:get-started-zh]: https://img.shields.io/badge/%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8-%E4%B8%AD%E6%96%87-2196F3?style=flat-square
[badge:get-started-jp]: https://img.shields.io/badge/%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB-%E6%97%A5%E6%9C%AC%E8%AA%9E-009688?style=flat-square
[badge:get-started-ko]: https://img.shields.io/badge/%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-%ED%95%9C%EA%B5%AD%EC%96%B4-7CB342?style=flat-square

[gh:translation-plugin]: https://github.com/YiiGuxing/TranslationPlugin
[gh:releases]: https://github.com/YiiGuxing/TranslationPlugin/releases
[gh:workflows-build]: https://github.com/YiiGuxing/TranslationPlugin/actions/workflows/build.yml
[gh:license]: https://github.com/YiiGuxing/TranslationPlugin/blob/master/LICENSE
[gh:discussions-q-a]: https://github.com/YiiGuxing/TranslationPlugin/discussions/categories/q-a
[gh:#81]: https://github.com/YiiGuxing/TranslationPlugin/issues/81
[gh:#115]: https://github.com/YiiGuxing/TranslationPlugin/issues/115

[logo:ali-translate]: https://yiiguxing.github.io/TranslationPlugin/img/ext/ali_translate_logo.png
[logo:baidu-translate]: https://yiiguxing.github.io/TranslationPlugin/img/ext/baidu_translate_logo.svg
[logo:deepl-translator]: https://yiiguxing.github.io/TranslationPlugin/img/ext/deepl_translate_logo.svg
[logo:google-translate]: https://yiiguxing.github.io/TranslationPlugin/img/ext/google_translate_logo.svg
[logo:microsoft-translator]: https://yiiguxing.github.io/TranslationPlugin/img/ext/microsoft_translator_logo.svg
[logo:openai]: https://yiiguxing.github.io/TranslationPlugin/img/ext/openai_logo.svg
[logo:youdao-translate]: https://yiiguxing.github.io/TranslationPlugin/img/ext/youdao_translate_logo.svg

[file:settings-font]: .github/readme/settings_font.png
[file:financial-contributors]: https://github.com/YiiGuxing/TranslationPlugin/blob/master/FINANCIAL_CONTRIBUTORS.md

[get-started-en]: https://yiiguxing.github.io/TranslationPlugin/en/start.html
[get-started-zh]: https://yiiguxing.github.io/TranslationPlugin/start.html
[get-started-ja]: https://yiiguxing.github.io/TranslationPlugin/ja/start.html
[get-started-ko]: https://yiiguxing.github.io/TranslationPlugin/ko/start.html

[plugin-homepage]: https://plugins.jetbrains.com/plugin/8579-translation
[plugin-versions]: https://plugins.jetbrains.com/plugin/8579-translation/versions

[open-collective]: https://opencollective.com/translation-plugin
[open-collective-contribute]: https://opencollective.com/translation-plugin/contribute

[mailto]: mailto:yii.guxing@outlook.com?subject=Donate&body=Name%2FNickname%3Cwebsite%3E%3A%20%3Cmessage%3E%0D%0DDonation%20Amount%3A%20%3Camount%3E%0DPayment%20Platform%3A%20Alipay%2FWeChat%20Pay%0DPayment%20Number%20%28last%205%20digits%29%3A%20%3Cnumber%3E%0D%0D


![Coil](logo.svg)

An image loading library for Android backed by Kotlin Coroutines. Coil is:

- **Fast**: Coil performs a number of optimizations including memory and disk caching, downsampling the image in memory, automatically pausing/cancelling requests, and more.
- **Lightweight**: Coil adds ~2000 methods to your APK (for apps that already use OkHttp and Coroutines), which is comparable to Picasso and significantly less than Glide and Fresco.
- **Easy to use**: Coil's API leverages Kotlin's language features for simplicity and minimal boilerplate.
- **Modern**: Coil is Kotlin-first and uses modern libraries including Coroutines, OkHttp, Okio, and AndroidX Lifecycles.

Coil is an acronym for: **Co**routine **I**mage **L**oader.

Translations: [日本語](README-ja.md), [한국어](README-ko.md), [Русский](README-ru.md), [Svenska](README-sv.md), [Türkçe](README-tr.md), [中文](README-zh.md)

## Download

Coil is available on `mavenCentral()`.

```kotlin
implementation("io.coil-kt:coil:2.6.0")
```

## Quick Start

#### ImageViews

To load an image into an `ImageView`, use the `load` extension function:

```kotlin
// URL
imageView.load("https://example.com/image.jpg")

// File
imageView.load(File("/path/to/image.jpg"))

// And more...
```

Requests can be configured with an optional trailing lambda:

```kotlin
imageView.load("https://example.com/image.jpg") {
    crossfade(true)
    placeholder(R.drawable.image)
    transformations(CircleCropTransformation())
}
```

#### Jetpack Compose

Import the [Jetpack Compose](https://developer.android.com/jetpack/compose) extension library:

```kotlin
implementation("io.coil-kt:coil-compose:2.6.0")
```

To load an image, use the `AsyncImage` composable:

```kotlin
AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = null,
)
```

#### Image Loaders

Both `imageView.load` and `AsyncImage` use the singleton `ImageLoader` to execute image requests. The singleton `ImageLoader` can be accessed using a `Context` extension function:

```kotlin
val imageLoader = context.imageLoader
```

`ImageLoader`s are designed to be shareable and are most efficient when you create a single instance and share it throughout your app. That said, you can also create your own `ImageLoader` instance(s):

```kotlin
val imageLoader = ImageLoader(context)
```

If you do not want the singleton `ImageLoader`, depend on `io.coil-kt:coil-base` instead of `io.coil-kt:coil`.

#### Requests

To load an image into a custom target, `enqueue` an `ImageRequest`:

```kotlin
val request = ImageRequest.Builder(context)
    .data("https://example.com/image.jpg")
    .target { drawable ->
        // Handle the result.
    }
    .build()
val disposable = imageLoader.enqueue(request)
```

To load an image imperatively, `execute` an `ImageRequest`:

```kotlin
val request = ImageRequest.Builder(context)
    .data("https://example.com/image.jpg")
    .build()
val drawable = imageLoader.execute(request).drawable
```

Check out Coil's [full documentation here](https://coil-kt.github.io/coil/getting_started/).

## R8 / Proguard

Coil is fully compatible with R8 out of the box and doesn't require adding any extra rules.

If you use Proguard, you may need to add rules for [Coroutines](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/resources/META-INF/proguard/coroutines.pro) and [OkHttp](https://github.com/square/okhttp/blob/master/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro).

## License

    Copyright 2023 Coil Contributors

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       https://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.


# Android-Iconics

... allows to include any icon font with all its vector icons in your project. No limits. **Scale with no limit**, use **any color** at any time, provide a **contour**, and many additional customizations...

-------

    What's included 🚀 •
    Setup 🛠 •
    Migration Guide 🧬 •
    WIKI / FAQ 📖 •
    Custom Font 🖍 •
    Sample App

-------

### What's included 🚀
- No customization limitations (size, color, contour, background, padding, positioning, ...)
- Shadow support
- Use as XML Drawable starting API 24
- One icon source (no more mdpi, hdpi, ...)
- Flexibility
  - Size
  - Colors
  - Contour
  - Shadow
  - Auto mirroring for RTL (opt-in)
- If it takes a Drawable, it will also work with the IconicsDrawable!
- Save in APK size
- Compose support

**Already available fonts**
- [Google Material Design Icons](https://github.com/google/material-design-icons)
- [Material Design Iconic Font](http://zavoloklom.github.io/material-design-iconic-font)
- [Fontawesome](https://fontawesome.com/)
- [Meteocons](http://www.alessioatzeni.com/meteocons/)
- [Octicons](https://github.com/github/octicons)
- [Community Material](http://materialdesignicons.com/)
- [Weather Icons](https://erikflowers.github.io/weather-icons/)
- [Typeicons](http://typicons.com/)
- [Entypo](http://www.entypo.com/)
- [Devicon](http://devicon.fr/)
- [Foundation Icons](http://zurb.com/playground/foundation-icon-fonts-3)
- [Ionicons](http://ionicons.com/)
- [Material Design DX](https://jossef.github.io/material-design-icons-iconfont/)
- [Pixeden 7 Stroke](https://themes-pixeden.com/font-demos/7-stroke/)
- [Phosphor](https://phosphoricons.com/)
- [Simple Icons](https://simpleicons.org/)
- Or create your own font with any icon needed.

# Setup

## Latest releases 🛠

- Kotlin | [v5.4.0](https://github.com/mikepenz/Android-Iconics/tree/v5.4.0)
- Pre-Release | [v5.5.0-b01](https://github.com/mikepenz/Android-Iconics/tree/v5.5.0-b01)

## 1. Provide the gradle dependency
```gradle
dependencies {
    //the core iconics library (without any widgets)
    implementation "com.mikepenz:iconics-core:${latestAndroidIconicsRelease}"
    implementation "androidx.appcompat:appcompat:${versions.appCompat}"
}
```

## 1b. (optional) Add the view's dependency
```gradle
//this adds all ui view widgets (IconicsButton, IconicsImageView, ...)
implementation "com.mikepenz:iconics-views:${latestAndroidIconicsRelease}"
```

## 2. Choose your desired fonts

> [!NOTE]
> Fonts ending with `-kotlin` require at least v4.x of Android-Iconics
> v5.1.x or newer requires the latest font versions

```gradle
implementation 'com.mikepenz:google-material-typeface:4.0.0.3-kotlin@aar'
implementation 'com.mikepenz:google-material-typeface-{outlined|rounded|sharp}:4.0.0.2-kotlin@aar'
implementation 'com.mikepenz:material-design-iconic-typeface:2.2.0.9-kotlin@aar'
implementation 'com.mikepenz:fontawesome-typeface:5.9.0.3-kotlin@aar'
implementation 'com.mikepenz:octicons-typeface:11.1.0.1-kotlin@aar'
implementation 'com.mikepenz:meteocons-typeface:1.1.0.8-kotlin@aar'
implementation 'com.mikepenz:community-material-typeface:7.0.96.1-kotlin@aar' // note 5.3.45.1 and newer alphabetically sorts, and merges in 3 sections
implementation 'com.mikepenz:weather-icons-typeface:2.0.10.8-kotlin@aar'
implementation 'com.mikepenz:typeicons-typeface:2.0.7.8-kotlin@aar'
implementation 'com.mikepenz:entypo-typeface:1.0.0.8-kotlin@aar'
implementation 'com.mikepenz:devicon-typeface:2.0.0.8-kotlin@aar'
implementation 'com.mikepenz:foundation-icons-typeface:3.0.0.8-kotlin@aar'
implementation 'com.mikepenz:ionicons-typeface:2.0.1.8-kotlin@aar'
implementation 'com.mikepenz:pixeden-7-stroke-typeface:1.2.0.6-kotlin@aar'
implementation 'com.mikepenz:material-design-icons-dx-typeface:5.0.1.3-kotlin@aar'
implementation 'com.mikepenz:phosphor-typeface:1.0.0.1-kotlin@aar'
implementation 'com.mikepenz:simple-icons-typeface:17.0.0.3@aar'
```

> [!NOTE]
> For users of the version catalog, it is not possible to add the type, however you can do so via
> the implementation definition.
> `implementation(libs.material.typeface) { artifact { type = "aar" } }`

> [!WARNING]
> The fonts use the `jetpack startup` library to automatically register themselves.
> If `jetpack startup` is disabled,
> it is required to manually register the fonts. Please find additional details in
> the [Register fonts](#register-fonts).

# Usage

> [!NOTE]
> It might be required to call `Iconics.init(applicationContext)` if no context based APIs are used
> from the library otherwise.

## Use as drawable

```kotlin
IconicsDrawable(this, FontAwesome.Icon.faw_android).apply {
    colorInt = Color.RED
    sizeDp = 24
}
```

## Use via XML

If you use the Iconics library via XML provide the icon you want to use in the following syntax: `gmd-favorite` --> `fontId`-`iconName`. A list of the
available fonts and their `fontId` can be found [here](#available-fonts).
All icon names from the default fonts can be found via the [DEMO](https://play.google.com/store/apps/details?id=com.mikepenz.iconics.sample) application.

#### Notation within text
Use the `{` icon-definer `}` syntax
```gson
Some great text with a {faw-android} font awesome icon and {met-wind} meteocons icons.
```

### Drawable XML (API 24+)

Specify the drawable in your `drawable` folder.

```xml
<com.mikepenz.iconics.IconicsDrawable
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:ico_icon="gmd_favorite"
    app:ico_color="#0000FF"
    app:ico_contour_width="1dp"
    app:ico_contour_color="#00FFFF"
    app:ico_size="24dp" />
    // all custom theming attributes supported
```

Use like any normal drawable in your application.
This feature was suggested and initially provided by @dzamlo

### Custom Views
#### As IconicsImageView
```xml
<com.mikepenz.iconics.view.IconicsImageView
    android:layout_width="72dp"
    android:layout_height="72dp"
    app:iiv_color="@android:color/holo_red_dark"
    app:iiv_icon="gmd-favorite" />  // or @string/gmd_favorite with our generator
    //app:iiv_size="12dp"
    //app:iiv_padding="2dp"
    //app:iiv_contour_color="#FF0000"
    //app:iiv_contour_width="2dp"
    //app:iiv_background_color="#FFFF00"
    //app:iiv_corner_radius="2dp"
    //app:iiv_background_contour_color="#FF0000"
    //app:iiv_background_contour_width="1dp"
    //app:iiv_shadow_radius="4dp"
    //app:iiv_shadow_dx="1dp"
    //app:iiv_shadow_dy="1dp"
    //app:iiv_animations="spin|blink_alpha|blink_scale"
```

#### As IconicsTextView
```xml
<com.mikepenz.iconics.view.IconicsTextView
    android:text="abc{hif-test}defgh{faw-adjust}ijk{fon-test1}lmnopqrstuv{fon-test2}wxyz"
    android:textColor="@android:color/black"
    android:layout_width="wrap_content"
    android:layout_height="56dp"
    android:textSize="16sp"/>
```

#### As IconicsButton
```xml
<com.mikepenz.iconics.view.IconicsButton
    android:text="{faw-adjust} Button"
    android:layout_width="120dp"
    android:layout_height="60dp"/>
```

## Compose

To include the experimental compose support in your project add the following dependency to your project (since v5.2.0)

```gradle
implementation "com.mikepenz:iconics-compose:${latestAndroidIconicsRelease}"
```

Use the provided `Image` wrapper and set the icon.

```kotlin
Image(
    GoogleMaterial.Icon.gmd_access_alarm,
    colorFilter = ColorFilter.tint(MaterialTheme.colors.primary),
)
```

# Screenshots

![Image](https://raw.githubusercontent.com/mikepenz/Android-Iconics/develop/DEV/github/screenshots1.jpg)

# Available fonts

| Link                                                                                | Prefix          | Dependency                                                                            |
|-------------------------------------------------------------------------------------------------------------------|-----------------|---------------------------------------------------------------------------------------|
| [Google Material Design Icons](https://github.com/google/material-design-icons) **ORIGINAL by
Google**            | gmd,gmo,gmr,gms | implementation 'com.mikepenz:google-material-typeface{-outlined,rounded,sharp}:+@aar' |
| [Material Design Iconic Font](http://zavoloklom.github.io/material-design-iconic-font) **Google Material
Iconic** | gmi             | implementation 'com.mikepenz:material-design-iconic-typeface:+@aar'                   |
| [Fontawesome](https://fontawesome.com/)                                                                           | faw             | implementation 'com.mikepenz:fontawesome-typeface:+@aar'                              |
| [FontawesomeBrand](https://fontawesome.com/)                                                                      | fab             | implementation 'com.mikepenz:fontawesome-typeface:+@aar'                              |
| [FontawesomeRegular](https://fontawesome.com/)                                                                    | far             | implementation 'com.mikepenz:fontawesome-typeface:+@aar'                              |
| [Meteocons](http://www.alessioatzeni.com/meteocons/)                                                              | met             | implementation 'com.mikepenz:meteocons-typeface:+@aar'                                |
| [Octicons](https://github.com/github/octicons)                                                                    | oct             | implementation 'com.mikepenz:octicons-typeface:+@aar'                                 |
| [Community Material](http://materialdesignicons.com/)                                                             | cmd             | implementation 'com.mikepenz:community-material-typeface:+@aar'                       |
| [Weather Icons](https://erikflowers.github.io/weather-icons/)                                                     | wic             | implementation 'com.mikepenz:weather-icons-typeface:+@aar'                            |
| [Typeicons](http://typicons.com/)                                                                                | typ             | implementation 'com.mikepenz:typeicons-typeface:+@aar'                                |
| [Entypo](http://www.entypo.com/)                                                                                | ent             | implementation 'com.mikepenz:entypo-typeface:+@aar'                                   |
| [Devicon](http://devicon.fr/)                                                                                | dev             | implementation 'com.mikepenz:devicon-typeface:+@aar'                                  |
| [Foundation Icons](https://github.com/zurb/foundation-icon-fonts)                                                 | fou             | implementation 'com.mikepenz:foundation-icons-typeface:+@aar'                         |
| [Ionicons](http://ionicons.com/)                                                                                | ion             | implementation 'com.mikepenz:ionicons-typeface:+@aar'                                 |
| [Pixden7Stroke](http://themes-pixeden.com/font-demos/7-stroke/)                                                   | pe7             | implementation 'com.mikepenz:pixeden-7-stroke-typeface:+@aar'                         |
| [Material Design DX](https://jossef.github.io/material-design-icons-iconfont/)                                    | cmf             | implementation 'com.mikepenz:material-design-icons-dx-typeface:+@aar'                 |
| [Phosphor Icons](https://phosphoricons.com/)                                                                      | pho             | implementation 'com.mikepenz:phosphor-typeface:+@aar'                                 |
| [Simple Icons](https://simpleicons.org/)                                                                          | sim             | implementation 'com.mikepenz:simple-icons-typeface:+@aar'                             |

Licenses for all included fonts are linked inside the class or can be found on the coresponding repositories.

# Compatibility Note

### appcompat:1.4.x

Appcompat v1.4.x introduces default enabled emoji support into all `AppCompat*` views, which prevents the `IconicsView*` views (iconics-views module) from properly applying the spannable style.
To fix this problem, emoji support has to be disabled by doing:

```xml
app:emojiCompatEnabled="false"
```

More information on the appcompat emoji support: https://developer.android.com/jetpack/androidx/releases/appcompat#1.4.0-alpha01

# Advanced Usage

### Register fonts

If you want to add your own custom font, or a GenericFont you have to register this font (before using it). The best place to do this is the `Application`.

And initialize Iconics as you wish
```kotlin
class CustomApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        //register custom fonts like this (or also provide a font definition file)
        Iconics.registerFont(CustomFont())
    }
}
```

### Advanced IconicsBuilder
Everything is easy and simple. Right? But now you got a single icon within your textview and you need additional styling?
Just define the style for all icons or only a specific one. You can find this in the PlaygroundActivity of the sample too.
```kotlin
Iconics.Builder()
    .style(ForegroundColorSpan(Color.WHITE), BackgroundColorSpan(Color.BLACK), RelativeSizeSpan(2f))
    .styleFor(FontAwesome.Icon.faw_adjust, BackgroundColorSpan(Color.RED))
    .on(tv1)
    .build()
```

### String icon-key or typeface enum
Sometimes you won't like to use the icon-key ("faw-adjust") like this, but use the enum provided by a specific font. Both is valid:
```kotlin
IconicsDrawable(this, "faw-adjust").actionBar()
```
```kotlin
IconicsDrawable(this, FontAwesome.Icon.faw_adjust).apply {
    sizeDp = 24
    paddingDp = 1
}
```

## Create custom fonts
This is possible with only the *.ttf and *.css mapping file. And will take you 2 minutes.

You can get these two files by downloading a web icon font, or if you want to create your
own custom icon font from *.svg files then you can use following tools:
* [Fontello](http://fontello.com)
* [IcoMoon](http://icomoon.io)
* [Fontastic](http://app.fontastic.me)
* let me know if you find other tools.

After you got those two files, head over to the icon addon creation tool [android-iconics.mikepenz.com](https://android-iconics.mikepenz.com).
Enter all the information. Add the *.ttf and *.css and click the button. It will generate and download the icon font addon as
zip. (this tool is local only, no files are sent to a server, you can safely use it with any icons)

## String fields for icons
For generating string field for each of icons of your font, you can use this simple generator:
[Android-Iconics String Generator](https://github.com/zTrap/Android-Iconics-String-Generator)

## Android module generator

A awesome gradle plugin which can automatically fetch a font from Fontastic, and generate the Android Module for your project.
[Iconics-Font-Generator](https://github.com/ligol/IconicsFontGenerator)

# ProGuard / R8

ProGuard / R8 rules are bundled internally with each font.

# Special Contributor
- [Baptiste Lagache](https://github.com/ligol) Thanks for the gradle font module generator
- Also thanks for all the other contributors.

# Credits
- [Joan Zapata](https://github.com/JoanZapata) He is the creator of [Android-Iconify](https://github.com/JoanZapata/android-iconify) which gave me the idea of this project. Some core concepts and ideas were reused, but everything is written from scratch.
- [Christopher Jenkins](https://github.com/chrisjenx/) Thanks for the great usage of a custom `ContextWrapper` inside [Calligraphy](https://github.com/chrisjenx/Calligraphy/)
- [Stephan Schober](https://github.com/tehfonsi)

# Developed By

- Mike Penz
  - [mikepenz.dev](https://mikepenz.dev) - [blog.mikepenz.dev](https://blog.mikepenz.dev) - <mikepenz@gmail.com>
  - [paypal.me/mikepenz](http://paypal.me/mikepenz)
  - [Automatic changelog generation action](https://github.com/marketplace/actions/release-changelog-builder)

- Peter Gulko
  - [github.com/zTrap](https://github.com/zTrap)

# License

    Copyright 2021 Mike Penz

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.