A simple gradle plugin that lets you create a download asset from zeplin and convert them to vector drawables automatically
🐘 project using 100% Kotlin and be up and running in a few seconds.
How to use 👣
The plugin is developed based on Zeplin API, it’s used zeplin OAuth2 to verify the project have correct access.
try to add the plugin to the project.gradle you want to use,
plugins {
...
id("io.github.underwindfall.zeplin.gradle")
}
zeplinConfig {
zeplinToken.set("input the correct zeplin token")
configFile.set(file("input the correct zeplin file"))
}
then execute the script that’s it !
./gradlew your_project:updateZeplin
Zeplin Developer Token 🔍
To use this plugin, you either need to create a personal access token or a Zeplin app.
You can create them from the web app under Developer tab in your profile page.
Configuration ⚙️
Before starting directly zeplin script, besides that zeplin token above, we also need a configuration file to tell plugin
which kind of assets the plugin want to download.
tag of screens which allow you download the assets with the same name collection
outputDir
output directory where you want to assign plugin to put converted assets into
resourcePrefix
android resource prefix to avoid resource conflicts
deniedList
denied list screens in case some of screens you want to include
allowList
denied list screens in case some of screens you want to exclude
Example 📦
The example project is to display how the zeplin works and what kind of configuration needs to be added
you can check it in example folder.
Features 🎨
100% Kotlin-only.
Zeplin API and vector drawable converted automatically
Plugin build setup with composite build.
CI Setup with GitHub Actions.
Contributing 🤝
Feel free to open an issue or submit a pull request for any bugs/improvements.
This plugin is based on static analysis check, you can use preMerge task to test it.
A preMerge task on the top level build is already provided in the project. This allows you to run all the check tasks both in the top level and in the included build.
You can easily invoke it with:
./gradlew preMerge
If you need to invoke a task inside the included build with:
./gradlew -p plugin-build <task-name>
License 📄
This template is licensed under the Apache License – see the License file for details.
Please note that the generated template is offering to start with a MIT license but you can change it to whatever you wish, as long as you attribute under the MIT terms that you’re using the template.
multik-core — contains ndarrays, methods called on them and [math], [stat] and [linalg] interfaces.
multik-default — implementation including multik-kotlin and multik-openblas for performance.
multik-kotlin — implementation of [math], [stat] and [linalg] interfaces on JVM.
multik-openblas — implementation of [math], [stat] and [linalg] interfaces in native code using OpenBLAS.
Using in your projects
Gradle
In your Gradle build script:
Add the Maven Central Repository.
Add the org.jetbrains.kotlinx:multik-core:$multik_version api dependency.
Add an implementation dependency: org.jetbrains.kotlinx:multik-default:$multik_version,
org.jetbrains.kotlinx:multik-kotlin:$multik_version or org.jetbrains.kotlinx:multik-openblas:$multik_version.
For Kotlin/JS, we use the new IR.
We also use the new memory model
in Kotlin/Native. Keep this in mind when using Multik in your multiplatform projects.
Note:
on ubuntu 18.04 and older multik-openblas doesn’t work due to older versions of glibc.
multik-openblas for desktop targets (linuxX64, mingwX64, macosX64, macosArm64) is experimental and unstable.
We will improve stability and perfomance as Kotlin/Native evolves.
JVM target multik-openblas for Android only supports arm64-v8a processors.
val a = mk.ndarray(mk[1, 2, 3])
/* [1, 2, 3] */val b = mk.ndarray(mk[mk[1.5, 2.1, 3.0], mk[4.0, 5.0, 6.0]])
/*[[1.5, 2.1, 3.0],[4.0, 5.0, 6.0]]*/val c = mk.ndarray(mk[mk[mk[1.5f, 2f, 3f], mk[4f, 5f, 6f]], mk[mk[3f, 2f, 1f], mk[4f, 5f, 6f]]])
/*[[[1.5, 2.0, 3.0],[4.0, 5.0, 6.0]],[[3.0, 2.0, 1.0],[4.0, 5.0, 6.0]]]*/
mk.zeros<Double>(3, 4) // create an array of zeros/*[[0.0, 0.0, 0.0, 0.0],[0.0, 0.0, 0.0, 0.0],[0.0, 0.0, 0.0, 0.0]]*/
mk.ndarray<Float, D2>(setOf(30f, 2f, 13f, 12f), intArrayOf(2, 2)) // create an array from a collection/*[[30.0, 2.0],[13.0, 12.0]]*/val d = mk.ndarray(doubleArrayOf(1.0, 1.3, 3.0, 4.0, 9.5, 5.0), 2, 3) // create an array of shape(2, 3) from a primitive array/*[[1.0, 1.3, 3.0],[4.0, 9.5, 5.0]]*/
mk.d3array(2, 2, 3) { it * it } // create an array of 3 dimension/*[[[0, 1, 4],[9, 16, 25]],[[36, 49, 64],[81, 100, 121]]]*/
mk.d2arrayIndices(3, 3) { i, j ->ComplexFloat(i, j) }
/*[[0.0+(0.0)i, 0.0+(1.0)i, 0.0+(2.0)i],[1.0+(0.0)i, 1.0+(1.0)i, 1.0+(2.0)i],[2.0+(0.0)i, 2.0+(1.0)i, 2.0+(2.0)i]]*/
mk.arange<Long>(10, 25, 5) // creare an array with elements in the interval [10, 25) with step 5/* [10, 15, 20] */
mk.linspace<Double>(0, 2, 9) // create an array of 9 elements in the interval [0, 2]/* [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0] */val e = mk.identity<Double>(3) // create an identity array of shape (3, 3)/*[[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]*/val diag = mk.diagonal(mk[2, 4, 8]) // create a diagonal array/*[[2, 0, 0],[0, 4, 0],[0, 0, 8]]*/
Array properties
a.shape // Array dimensions
a.size // Size of array
a.dim // object Dimension
a.dim.d // number of array dimensions
a.dtype // Data type of array elements
Arithmetic operations
val f = b - d // subtraction/*[[0.5, 0.8, 0.0],[0.0, -4.5, 1.0]]*/
d + f // addition/*[[1.5, 2.1, 3.0],[4.0, 5.0, 6.0]]*/
b / d // division/*[[1.5, 1.6153846153846154, 1.0],[1.0, 0.5263157894736842, 1.2]]*/
f * d // multiplication/*[[0.5, 1.04, 0.0],[0.0, -42.75, 5.0]]*/
a.sin() // element-wise sin, equivalent to mk.math.sin(a)
a.cos() // element-wise cos, equivalent to mk.math.cos(a)
b.log() // element-wise natural logarithm, equivalent to mk.math.log(b)
b.exp() // element-wise exp, equivalent to mk.math.exp(b)
d dot e // dot product, equivalent to mk.linalg.dot(d, e)
Aggregate functions
mk.math.sum(c) // array-wise sum
mk.math.min(c) // array-wise minimum elements
mk.math.maxD3(c, axis=0) // maximum value of an array along axis 0
mk.math.cumSum(b, axis=1) // cumulative sum of the elements
mk.stat.mean(a) // mean
mk.stat.median(b) // meadian
Copying arrays
val f = a.copy() // create a copy of the array and its dataval h = b.deepCopy() // create a copy of the array and copy the meaningful data
Operations of Iterable
c.filter { it <3 } // select all elements less than 3
b.map { (it * it).toInt() } // return squares
c.groupNDArrayBy { it %2 } // group elements by condition
c.sorted() // sort elements
Indexing/Slicing/Iterating
a[2] // select the element at the 2 index
b[1, 2] // select the element at row 1 column 2
b[1] // select row 1
b[0..1, 1] // select elements at rows 0 to 1 in column 1
b[0, 0..2..1] // select elements at row 0 in columns 0 to 2 with step 1for (el in b) {
print("$el, ") // 1.5, 2.1, 3.0, 4.0, 5.0, 6.0,
}
// for n-dimensionalval q = b.asDNArray()
for (index in q.multiIndices) {
print("${q[index]}, ") // 1.5, 2.1, 3.0, 4.0, 5.0, 6.0,
}
Inplace
val a = mk.linspace<Float>(0, 1, 10)
/*a = [0.0, 0.1111111111111111, 0.2222222222222222, 0.3333333333333333, 0.4444444444444444, 0.5555555555555556, 0.6666666666666666, 0.7777777777777777, 0.8888888888888888, 1.0]*/val b = mk.linspace<Float>(8, 9, 10)
/*b = [8.0, 8.11111111111111, 8.222222222222221, 8.333333333333334, 8.444444444444445, 8.555555555555555,8.666666666666666, 8.777777777777779, 8.88888888888889, 9.0]*/
a.inplace {
math {
(this- b) * b
abs()
}
}
// a = [64.0, 64.88888, 65.77778, 66.66666, 67.55556, 68.44444, 69.333336, 70.22222, 71.111115, 72.0]
Building
To build the entire project, you need to set up an environment for building multik-openblas:
JDK 1.8 or higher
JAVA_HOME environment – to search for jni files
Compilers gcc, g++, gfortran version 8 or higher.
It is important that they are of the same version.
Run ./gradlew assemble to build all modules.
If you don’t need to build multik-openblas,
just disable the cmake_build task and build the module you need.
Contributing
There is an opportunity to contribute to the project: