Some checks failed
ZaStoGram source guards / guards (push) Successful in 23s
Build three ZaStoGram APKs / build (armeabi-v7a, ZaStoGram-standalone-armeabi-v7a, Armv7, armv7) (push) Failing after 3m42s
Build three ZaStoGram APKs / build (x86, ZaStoGram-standalone-x86, X86, x86) (push) Failing after 12m39s
Build three ZaStoGram APKs / build (arm64-v8a, ZaStoGram-standalone-arm64-v8a, Arm64, arm64) (push) Failing after 15m5s
403 lines
20 KiB
Groovy
403 lines
20 KiB
Groovy
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
|
|
|
|
apply plugin: 'com.android.library'
|
|
// ZaStoGram plugin engine: embed CPython so .plugin scripts (exteraGram-compatible)
|
|
// can run. Chaquopy may be applied to exactly one module per app; TMessagesProj is the
|
|
// shared library, so every app flavor (Standalone/App/Huawei/...) inherits plugin support.
|
|
apply plugin: 'com.chaquo.python'
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
google()
|
|
}
|
|
|
|
configurations {
|
|
compile.exclude module: 'support-v4'
|
|
}
|
|
|
|
configurations.all {
|
|
exclude group: 'com.google.firebase', module: 'firebase-core'
|
|
exclude group: 'androidx.recyclerview', module: 'recyclerview'
|
|
}
|
|
|
|
dependencies {
|
|
implementation 'androidx.core:core:1.16.0'
|
|
implementation 'androidx.webkit:webkit:1.14.0'
|
|
implementation 'androidx.palette:palette:1.0.0'
|
|
implementation 'androidx.exifinterface:exifinterface:1.3.6'
|
|
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
|
|
implementation "androidx.sharetarget:sharetarget:1.2.0"
|
|
implementation 'androidx.interpolator:interpolator:1.0.0'
|
|
implementation 'androidx.biometric:biometric:1.1.0'
|
|
|
|
implementation 'com.google.android.gms:play-services-cast-framework:21.4.0'
|
|
implementation "androidx.mediarouter:mediarouter:1.7.0"
|
|
|
|
implementation 'androidx.car.app:app:1.4.0'
|
|
implementation 'androidx.car.app:app-projected:1.4.0'
|
|
implementation 'org.nanohttpd:nanohttpd:2.3.1'
|
|
|
|
compileOnly 'org.checkerframework:checker-qual:2.5.2'
|
|
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
|
|
implementation 'com.google.firebase:firebase-messaging:22.0.0'
|
|
implementation 'com.google.firebase:firebase-config:21.0.1'
|
|
implementation 'com.google.firebase:firebase-datatransport:18.1.0'
|
|
implementation 'com.google.firebase:firebase-appindexing:20.0.0'
|
|
implementation 'com.google.android.gms:play-services-maps:18.1.0'
|
|
implementation 'com.google.android.gms:play-services-auth:20.4.0'
|
|
implementation 'com.google.android.gms:play-services-vision:20.1.3'
|
|
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
|
|
implementation 'com.google.android.gms:play-services-location:21.0.1'
|
|
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
|
|
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
|
|
implementation 'com.stripe:stripe-android:2.0.2'
|
|
implementation 'com.google.mlkit:language-id:17.0.6'
|
|
implementation 'com.android.billingclient:billing:7.1.1'
|
|
implementation 'com.google.code.gson:gson:2.11.0'
|
|
implementation 'com.google.guava:guava:31.1-android'
|
|
implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
|
|
implementation 'com.google.android.gms:play-services-mlkit-image-labeling:16.0.8'
|
|
|
|
implementation "androidx.credentials:credentials:1.6.0-alpha04"
|
|
implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha04"
|
|
|
|
implementation "io.noties.markwon:core:4.6.2"
|
|
implementation "io.noties.markwon:ext-strikethrough:4.6.2"
|
|
implementation "io.noties.markwon:ext-tables:4.6.2"
|
|
implementation "io.noties.markwon:html:4.6.2"
|
|
implementation "io.noties.markwon:inline-parser:4.6.2"
|
|
implementation "io.noties.markwon:ext-latex:4.6.2"
|
|
|
|
// implementation 'com.google.mlkit:translate:17.0.3'
|
|
|
|
constraints {
|
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
|
|
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
|
|
}
|
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
|
|
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
|
|
}
|
|
}
|
|
// ZaStoGram plugin engine: Pine — dynamic ART method hooking (Xposed-compatible API).
|
|
// Supports Android 4.4(ART)-15 on arm64/armv7. The :xposed module exposes
|
|
// XC_MethodHook (before/afterHookedMethod + MethodHookParam) used by the bridge.
|
|
implementation 'top.canyie.pine:core:0.3.0'
|
|
// NOTE: the :xposed compat module's latest published version is 0.2.0 (there is no 0.3.0).
|
|
// 0.2.0 declares no dependency on :core, so it coexists with core:0.3.0. If runtime ART
|
|
// hooking ever misbehaves from version skew, pin core down to 0.2.9 to match.
|
|
implementation 'top.canyie.pine:xposed:0.2.0'
|
|
|
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
|
|
}
|
|
|
|
def isWindows = String.valueOf(DefaultNativePlatform.currentOperatingSystem.toFamilyName() == OperatingSystemFamily.WINDOWS)
|
|
// Dev and stable share this library build type, so derive the diagnostic flag
|
|
// from the build-wide release identity instead of hard-coding standalone as stable.
|
|
def zastoStandaloneDebugVersion = rootProject.ext.zastoReleaseIdentity.updateChannel == "dev"
|
|
def zastoAllNativeAbis = ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]
|
|
def zastoSingleAbiFilter = (project.findProperty("zastoAbiFilter") ?: System.getenv("ZASTO_ABI_FILTER"))?.toString()?.trim()
|
|
def zastoDeprecatedMultiAbiFilters = (project.findProperty("zastoAbiFilters") ?: System.getenv("ZASTO_ABI_FILTERS"))?.toString()?.trim()
|
|
if (zastoDeprecatedMultiAbiFilters) {
|
|
throw new GradleException(
|
|
"Multi-ABI ZaStoGram builds are disabled because Chaquopy would copy every selected ABI runtime into every APK. " +
|
|
"Build each standalone ABI in a separate Gradle invocation with -PzastoAbiFilter=<abi>."
|
|
)
|
|
}
|
|
def zastoStandaloneTaskAbis = [
|
|
Arm64Standalone: "arm64-v8a",
|
|
Armv7Standalone: "armeabi-v7a",
|
|
X86Standalone: "x86",
|
|
X64Standalone: "x86_64",
|
|
]
|
|
def zastoTaskRequestedAbis = gradle.startParameter.taskNames
|
|
.collect { taskName ->
|
|
def taskLeaf = taskName.tokenize(":").last()
|
|
zastoStandaloneTaskAbis.find { taskMarker, ignored -> taskLeaf.contains(taskMarker) }?.value
|
|
}
|
|
.findAll { it != null }
|
|
.unique()
|
|
if (zastoTaskRequestedAbis.size() > 1) {
|
|
throw new GradleException(
|
|
"Building several standalone ABIs in one Gradle invocation is disabled because it produces oversized Chaquopy APKs. " +
|
|
"Run one standalone ABI task at a time."
|
|
)
|
|
}
|
|
def zastoTaskAbiFilter = zastoTaskRequestedAbis ? zastoTaskRequestedAbis.first() : null
|
|
if (zastoSingleAbiFilter && zastoTaskAbiFilter && zastoSingleAbiFilter != zastoTaskAbiFilter) {
|
|
throw new GradleException(
|
|
"zastoAbiFilter '${zastoSingleAbiFilter}' does not match the requested standalone task ABI '${zastoTaskAbiFilter}'"
|
|
)
|
|
}
|
|
def zastoRequestedAbiFilter = zastoSingleAbiFilter ?: zastoTaskAbiFilter
|
|
def zastoTelegramCredentials = new Properties()
|
|
def zastoTelegramCredentialsFile = new File(
|
|
System.getenv("ZASTO_TELEGRAM_API_CREDENTIALS_FILE")
|
|
?: new File(System.getProperty("user.home"), ".config/zastogram-signing/telegram-api.properties").absolutePath
|
|
)
|
|
if (zastoTelegramCredentialsFile.isFile()) {
|
|
zastoTelegramCredentialsFile.withInputStream { zastoTelegramCredentials.load(it) }
|
|
}
|
|
def zastoTelegramApiIdConfigured = (
|
|
project.findProperty("telegramApiId")
|
|
?: System.getenv("TELEGRAM_API_ID")
|
|
?: zastoTelegramCredentials.getProperty("TELEGRAM_API_ID")
|
|
)?.toString()?.trim()
|
|
def zastoTelegramApiHashConfigured = (
|
|
project.findProperty("telegramApiHash")
|
|
?: System.getenv("TELEGRAM_API_HASH")
|
|
?: zastoTelegramCredentials.getProperty("TELEGRAM_API_HASH")
|
|
)?.toString()?.trim()
|
|
def zastoRequireTelegramApiCredentials = (System.getenv("ZASTO_REQUIRE_TELEGRAM_API_CREDENTIALS") ?: "0") == "1"
|
|
def zastoTelegramBuildScope = zastoRequireTelegramApiCredentials ? "release" : "Android"
|
|
if (zastoTelegramApiIdConfigured == null || zastoTelegramApiHashConfigured == null) {
|
|
throw new GradleException(
|
|
"Refusing ZaStoGram ${zastoTelegramBuildScope} build without its own Telegram API identity. " +
|
|
"Configure TELEGRAM_API_ID and TELEGRAM_API_HASH in ${zastoTelegramCredentialsFile.absolutePath} or the environment."
|
|
)
|
|
}
|
|
if (!(zastoTelegramApiIdConfigured ==~ /[1-9][0-9]*/)) {
|
|
throw new GradleException("TELEGRAM_API_ID must be a positive decimal integer")
|
|
}
|
|
if (!(zastoTelegramApiHashConfigured ==~ /[0-9a-fA-F]{32}/)) {
|
|
throw new GradleException("TELEGRAM_API_HASH must contain exactly 32 hexadecimal characters")
|
|
}
|
|
def zastoTelegramApiId = zastoTelegramApiIdConfigured
|
|
def zastoTelegramApiHash = zastoTelegramApiHashConfigured
|
|
def zastoUsesPublishedTestIdentity = zastoTelegramApiId == "4" || zastoTelegramApiHash.equalsIgnoreCase("014b35b6184100b085b0d0572f9b5103")
|
|
if (zastoUsesPublishedTestIdentity) {
|
|
throw new GradleException(
|
|
"Refusing ZaStoGram ${zastoTelegramBuildScope} build with Telegram's published test API identity. " +
|
|
"Configure TELEGRAM_API_ID and TELEGRAM_API_HASH in ${zastoTelegramCredentialsFile.absolutePath} or the environment."
|
|
)
|
|
}
|
|
if (zastoRequestedAbiFilter && !zastoAllNativeAbis.contains(zastoRequestedAbiFilter)) {
|
|
throw new GradleException("Unsupported zastoAbiFilter '${zastoRequestedAbiFilter}'. Expected one of: ${zastoAllNativeAbis.join(', ')}")
|
|
}
|
|
|
|
android {
|
|
compileSdkVersion 35
|
|
buildToolsVersion '35.0.0'
|
|
ndkVersion "27.2.12479018"
|
|
|
|
sourceSets.main.jniLibs.srcDirs = ['./jni/']
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
path 'jni/CMakeLists.txt'
|
|
}
|
|
}
|
|
|
|
lintOptions {
|
|
disable 'MissingTranslation'
|
|
disable 'ExtraTranslation'
|
|
disable 'BlockedPrivateApi'
|
|
}
|
|
|
|
compileOptions {
|
|
sourceCompatibility JavaVersion.VERSION_1_8
|
|
targetCompatibility JavaVersion.VERSION_1_8
|
|
|
|
coreLibraryDesugaringEnabled true
|
|
}
|
|
|
|
|
|
defaultConfig {
|
|
minSdkVersion 24 // ZaStoGram: Chaquopy (plugin engine) requires minSdk >= 24
|
|
targetSdkVersion 35
|
|
|
|
buildConfigField "int", "TELEGRAM_API_ID", zastoTelegramApiId
|
|
buildConfigField "String", "TELEGRAM_API_HASH", "\"${zastoTelegramApiHash.toLowerCase()}\""
|
|
|
|
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
|
|
|
|
multiDexEnabled true
|
|
|
|
// Every standalone ABI must be configured independently. Chaquopy stores part of its
|
|
// native runtime under assets, where the app flavor's normal ABI split cannot remove
|
|
// foreign architectures. Multi-ABI configuration therefore makes every APK oversized.
|
|
// Without a standalone task or explicit property, keep the universal afat fallback.
|
|
ndk {
|
|
abiFilters(*(zastoRequestedAbiFilter ? [zastoRequestedAbiFilter] : zastoAllNativeAbis))
|
|
}
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
version '3.10.2'
|
|
def cmakeArgs = ['-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21'] //, '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
|
// Route NDK compiles through ccache when the caller has configured a persistent
|
|
// cache. This is used by both Forgejo Actions and local release scripts.
|
|
if (System.getenv('USE_CCACHE') == '1') {
|
|
cmakeArgs << '-DCMAKE_C_COMPILER_LAUNCHER=ccache' << '-DCMAKE_CXX_COMPILER_LAUNCHER=ccache'
|
|
}
|
|
arguments(*cmakeArgs)
|
|
}
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
jniDebuggable true
|
|
minifyEnabled false
|
|
shrinkResources false
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PRIVATE_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "0"
|
|
}
|
|
|
|
HA_private {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PRIVATE") + "\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PRIVATE_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "1"
|
|
}
|
|
|
|
HA_public {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PUBLIC") + "\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PUBLIC_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "4"
|
|
}
|
|
|
|
HA_hardcore {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_HARDCORE") + "\""
|
|
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_HARDCORE_URL") + "\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "true"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "5"
|
|
}
|
|
|
|
standalone {
|
|
jniDebuggable false
|
|
// The standalone app module runs final R8 with this module's proguard rules.
|
|
// Running R8 here first only makes CI do an extra minify pass before the APK pass.
|
|
minifyEnabled false
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"\""
|
|
buildConfigField "String", "BETA_URL", "\"\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", zastoStandaloneDebugVersion.toString()
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "6"
|
|
}
|
|
|
|
release {
|
|
jniDebuggable false
|
|
minifyEnabled true
|
|
shrinkResources false
|
|
multiDexEnabled true
|
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
|
|
ndk.debugSymbolLevel = 'FULL'
|
|
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
|
|
buildConfigField "String", "APP_CENTER_HASH", "\"\""
|
|
buildConfigField "String", "BETA_URL", "\"\""
|
|
buildConfigField "boolean", "DEBUG_VERSION", "false"
|
|
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
|
|
buildConfigField "boolean", "BUNDLE", "false"
|
|
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
|
|
buildConfigField "int", "VERSION_NUM", "7"
|
|
}
|
|
}
|
|
|
|
namespace 'org.telegram.messenger'
|
|
}
|
|
|
|
// ZaStoGram plugin engine — Python runtime configuration.
|
|
// Host API modules live in src/main/python (base_plugin, client_utils, ui.*, ...).
|
|
// User .plugin scripts are loaded at runtime from the data dir, not bundled here.
|
|
chaquopy {
|
|
defaultConfig {
|
|
version "3.11" // matches exteraGram (Chaquopy 16, CPython 3.11)
|
|
// The build machine needs a CPython 3.11 on PATH. If Android Studio can't find
|
|
// it (common on Windows), uncomment and point at it explicitly:
|
|
// buildPython "C:/Users/<you>/AppData/Local/Programs/Python/Python311/python.exe"
|
|
pyc {
|
|
src false // ship readable .py so plugin tracebacks map to real lines
|
|
}
|
|
pip {
|
|
// Common third-party libs community plugins expect at runtime. Chaquopy can only
|
|
// install these at BUILD time (there is no runtime pip), so they must be declared
|
|
// here once and shipped in the APK — mirrors what exteraGram bundles.
|
|
install "beautifulsoup4" // common HTML parsing helper used by plugin libraries
|
|
install "debugpy" // debugger backend listed by exteraGram for plugin development
|
|
install "lxml" // XML/HTML parser bundled by exteraGram
|
|
install "packaging" // version parsing for shared plugin libraries such as ZwyLib
|
|
install "Pillow" // exposes PIL for image-processing plugins
|
|
install "PyYAML" // YAML parser bundled by exteraGram
|
|
install "pyfiglet" // ASCIIGenerator and ASCII art plugins
|
|
install "requests" // th3_proxy_tools (country flags via ip-api, URL import) + many others
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
def getProps(String propName) {
|
|
def propsFile = rootProject.file('local.properties')
|
|
if (propsFile.exists()) {
|
|
def props = new Properties()
|
|
props.load(new FileInputStream(propsFile))
|
|
return props[propName]
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
apply plugin: 'com.google.gms.google-services'
|
|
|
|
task checkVisibility {
|
|
doFirst {
|
|
def isPrivateBuild = project.gradle.startParameter.taskNames.find {
|
|
it.contains("HA_private") || it.contains("HA_hardcore") || it.contains("Debug") || it.contains("Release")
|
|
}
|
|
def isPublicAllowed = !project.hasProperty("IS_PRIVATE") || !project.property("IS_PRIVATE").toBoolean()
|
|
if (!isPrivateBuild && !isPublicAllowed) {
|
|
throw new GradleException("Building public version of private code!")
|
|
}
|
|
}
|
|
doLast {
|
|
if (project.gradle.startParameter.taskNames.find { it.contains("HA_public") }) {
|
|
def privateBuild = file("${projectDir}_AppHockeyApp/afat/HA_private/Telegram-Beta.apk")
|
|
if (privateBuild.exists()) {
|
|
privateBuild.delete()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
preBuild.dependsOn checkVisibility
|