Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-notes.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2024-01-20 12:47:43 +0300
committerAndy Scherzinger <info@andy-scherzinger.de>2024-01-21 18:08:06 +0300
commit064d86dca7c331545d0713bea8d4460dfb481952 (patch)
tree9d0fac61109d3bc1e6be25b831f0b66b1ead7170
parent7a8d83762a36a65680561f3723261d18f0cd7ae3 (diff)
chore(deps): AGP 8, Java 17, Kotlin 1.9.22, SSO 1.0.0
Signed-off-by: Stefan Niedermann <info@niedermann.it>
-rw-r--r--.github/workflows/android.yml30
-rw-r--r--.github/workflows/codeql.yml6
-rw-r--r--app/build.gradle48
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java4
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java3
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java4
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java4
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java6
-rw-r--r--build.gradle15
-rw-r--r--gradle.properties21
-rw-r--r--gradle/wrapper/gradle-wrapper.properties2
17 files changed, 82 insertions, 73 deletions
diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index 5ce8c09e..91b9a68b 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -15,6 +15,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4.1.1
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+ check-latest: true
+ cache: 'gradle'
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
@@ -24,8 +30,14 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4.1.1
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+ check-latest: true
+ cache: 'gradle'
- name: Lint
- run: bash ./gradlew lintDevDebug --stacktrace
+ run: bash ./gradlew lintDevDebug --stacktrace --no-configuration-cache
test:
name: Unit tests
@@ -33,8 +45,14 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4.1.1
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+ check-latest: true
+ cache: 'gradle'
- name: Unit tests
- run: bash ./gradlew test --stacktrace
+ run: bash ./gradlew test --stacktrace --no-configuration-cache
apk:
name: Generate APK
@@ -42,8 +60,14 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4.1.1
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+ check-latest: true
+ cache: 'gradle'
- name: Build debug APK
- run: bash ./gradlew assembleDev --stacktrace
+ run: bash ./gradlew assembleDev --stacktrace --no-configuration-cache
- name: Upload APK
uses: actions/upload-artifact@v4
with:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 1c3fa463..25e8ecd8 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -38,12 +38,12 @@ jobs:
- name: Set up JDK 17
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
with:
- distribution: "temurin"
- java-version: 17
+ distribution: 'temurin'
+ java-version: '17'
- name: Assemble
run: |
mkdir -p "$HOME/.gradle"
echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
- ./gradlew assembleDebug
+ ./gradlew assembleDebug --no-configuration-cache
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
diff --git a/app/build.gradle b/app/build.gradle
index beb52cdf..5cfa0091 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,18 +2,13 @@ apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
android {
- compileSdkVersion 33
-
- compileOptions {
- coreLibraryDesugaringEnabled true
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
- }
+ compileSdk 34
+ namespace 'it.niedermann.owncloud.notes'
defaultConfig {
applicationId "it.niedermann.owncloud.notes"
- minSdkVersion 24
- targetSdkVersion 33
+ minSdk 24
+ targetSdk 34
versionCode 40020000
versionName "4.2.0 Alpha1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -24,8 +19,19 @@ android {
}
}
+ compileOptions {
+ coreLibraryDesugaringEnabled true
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = '17'
+ }
+
buildFeatures {
viewBinding true
+ buildConfig true
}
buildTypes {
@@ -60,25 +66,25 @@ android {
includeAndroidResources true
}
}
- lint {
+
+ lintOptions {
abortOnError false
disable 'MissingTranslation'
}
- namespace 'it.niedermann.owncloud.notes'
}
ext {
glideVersion = '4.16.0'
- roomVersion = "2.5.1"
+ roomVersion = "2.6.1"
}
dependencies {
- coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
// Nextcloud SSO
- implementation 'com.github.nextcloud.android-common:ui:0.12.0'
- implementation 'com.github.nextcloud:Android-SingleSignOn:0.8.1'
- implementation 'com.github.stefan-niedermann:android-commons:0.2.9'
+ implementation 'com.github.nextcloud.android-common:ui:0.13.0'
+ implementation 'com.github.nextcloud:Android-SingleSignOn:1.0.0'
+ implementation 'com.github.stefan-niedermann:android-commons:0.4.0'
implementation "com.github.stefan-niedermann.nextcloud-commons:sso-glide:$commonsVersion"
implementation "com.github.stefan-niedermann.nextcloud-commons:exception:$commonsVersion"
implementation("com.github.stefan-niedermann.nextcloud-commons:markdown:$commonsVersion") {
@@ -91,16 +97,16 @@ dependencies {
// Android X
implementation 'androidx.appcompat:appcompat:1.6.1'
- implementation 'androidx.core:core-ktx:1.10.1'
+ implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.core:core-splashscreen:1.0.1'
- implementation 'androidx.fragment:fragment:1.6.1'
- implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
+ implementation 'androidx.fragment:fragment:1.6.2'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
implementation 'androidx.preference:preference:1.2.1'
implementation 'androidx.recyclerview:recyclerview-selection:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
- implementation 'androidx.work:work-runtime:2.8.1'
- implementation 'com.google.android.material:material:1.9.0'
+ implementation 'androidx.work:work-runtime:2.9.0'
+ implementation 'com.google.android.material:material:1.11.0'
// Database
implementation "androidx.room:room-runtime:${roomVersion}"
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java
index 113db2a9..a3f55c24 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java
@@ -20,7 +20,7 @@ public abstract class BrandedActivity extends AppCompatActivity implements Brand
super.onStart();
final var typedValue = new TypedValue();
- getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true);
+ getTheme().resolveAttribute(com.google.android.material.R.attr.colorAccent, typedValue, true);
colorAccent = typedValue.data;
readBrandMainColorLiveData(this).observe(this, this::applyBrand);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java
index ac197ef8..bed27575 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java
@@ -23,9 +23,9 @@ public abstract class BrandedFragment extends Fragment implements Branded {
final var context = requireContext();
final var typedValue = new TypedValue();
- context.getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true);
+ context.getTheme().resolveAttribute(com.google.android.material.R.attr.colorAccent, typedValue, true);
colorAccent = typedValue.data;
- context.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
+ context.getTheme().resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue, true);
colorPrimary = typedValue.data;
@ColorInt final int color = BrandingUtil.readBrandMainColor(context);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java
index 16245433..1d6adc0e 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java
@@ -103,7 +103,7 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
if (accountId > 0) {
/* Switch account if account id has been provided */
this.localAccount = repo.getAccountById(accountId);
- SingleAccountHelper.setCurrentAccount(requireContext().getApplicationContext(), localAccount.getAccountName());
+ SingleAccountHelper.commitCurrentAccount(requireContext().getApplicationContext(), localAccount.getAccountName());
}
isNew = false;
note = originalNote = repo.getNoteById(id);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java
index 71b43db5..2b49cc29 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java
@@ -71,7 +71,7 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment
try {
if (SingleAccountHelper.getCurrentSingleSignOnAccount(this) == null) {
- throw new NoCurrentAccountSelectedException();
+ throw new NoCurrentAccountSelectedException(this);
}
} catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) {
Toast.makeText(this, R.string.no_account_configured_yet, Toast.LENGTH_LONG).show();
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java
index 10c9510c..1ca1c5f5 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java
@@ -117,8 +117,7 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment {
searchMenuItem.collapseActionView();
- final var searchEditFrame = searchView.findViewById(R.id
- .search_edit_frame);
+ final var searchEditFrame = searchView.findViewById(androidx.appcompat.R.id.search_edit_frame);
searchEditFrame.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
int oldVisibility = -1;
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java
index 72ec0c26..c4e58079 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java
@@ -88,7 +88,7 @@ public class ImportAccountActivity extends AppCompatActivity {
AccountImporter.onActivityResult(requestCode, resultCode, data, ImportAccountActivity.this, ssoAccount -> {
runOnUiThread(() -> binding.progressCircular.setVisibility(View.VISIBLE));
- SingleAccountHelper.setCurrentAccount(getApplicationContext(), ssoAccount.name);
+ SingleAccountHelper.commitCurrentAccount(getApplicationContext(), ssoAccount.name);
executor.submit(() -> {
Log.i(TAG, "Added account: " + "name:" + ssoAccount.name + ", " + ssoAccount.url + ", userId" + ssoAccount.userId);
try {
@@ -135,7 +135,7 @@ public class ImportAccountActivity extends AppCompatActivity {
} catch (Throwable t) {
t.printStackTrace();
ApiProvider.getInstance().invalidateAPICache(ssoAccount);
- SingleAccountHelper.setCurrentAccount(this, null);
+ SingleAccountHelper.commitCurrentAccount(this, null);
runOnUiThread(() -> {
restoreCleanState();
if (t instanceof NextcloudHttpRequestFailedException && ((NextcloudHttpRequestFailedException) t).getStatusCode() == HttpURLConnection.HTTP_UNAVAILABLE) {
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java
index 75d02c52..ec725444 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java
@@ -121,7 +121,7 @@ public class MainViewModel extends AndroidViewModel {
public void postCurrentAccount(@NonNull Account account) {
state.set(KEY_CURRENT_ACCOUNT, account);
BrandingUtil.saveBrandColor(getApplication(), account.getColor());
- SingleAccountHelper.setCurrentAccount(getApplication(), account.getAccountName());
+ SingleAccountHelper.commitCurrentAccount(getApplication(), account.getAccountName());
final var currentAccount = this.currentAccount.getValue();
// If only ETag or colors change, we must not reset the navigation
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java
index 194dcbc8..6caf4f22 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java
@@ -72,7 +72,7 @@ public class MultiSelectedActionModeCallback implements Callback {
this.fragmentManager = fragmentManager;
final TypedValue typedValue = new TypedValue();
- context.getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true);
+ context.getTheme().resolveAttribute(com.google.android.material.R.attr.colorAccent, typedValue, true);
colorAccent = typedValue.data;
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java
index b625b076..6cbc199d 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java
@@ -66,7 +66,7 @@ public class ManageAccountsViewModel extends AndroidViewModel {
}
public void selectAccount(@Nullable Account account, @NonNull Context context) {
- SingleAccountHelper.setCurrentAccount(context, (account == null) ? null : account.getAccountName());
+ SingleAccountHelper.commitCurrentAccount(context, (account == null) ? null : account.getAccountName());
}
public void countUnsynchronizedNotes(long accountId, @NonNull IResponseCallback<Long> callback) {
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java
index 4be0a493..bd1ae4eb 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java
@@ -124,7 +124,7 @@ public class ApiProvider {
if (API_CACHE.containsKey(ssoAccount.name)) {
final var nextcloudAPI = API_CACHE.get(ssoAccount.name);
if (nextcloudAPI != null) {
- nextcloudAPI.stop();
+ nextcloudAPI.close();
}
API_CACHE.remove(ssoAccount.name);
}
@@ -141,7 +141,7 @@ public class ApiProvider {
if (API_CACHE.containsKey(key)) {
final var nextcloudAPI = API_CACHE.get(key);
if (nextcloudAPI != null) {
- nextcloudAPI.stop();
+ nextcloudAPI.close();
}
API_CACHE.remove(key);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java
index 1ea2f7cb..74589cbc 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java
@@ -187,7 +187,7 @@ public class NotesRepository {
public void onError(@NonNull Throwable t) {
Log.e(TAG, "… Error while importing " + account.getAccountName() + ": " + t.getMessage());
deleteAccount(account);
- SingleAccountHelper.setCurrentAccount(context, null);
+ SingleAccountHelper.commitCurrentAccount(context, null);
callback.onError(t);
}
});
@@ -195,7 +195,7 @@ public class NotesRepository {
Log.e(TAG, "… Could not find " + SingleSignOnAccount.class.getSimpleName() + " for account name " + account.getAccountName());
importExecutor.submit(() -> {
deleteAccount(account);
- SingleAccountHelper.setCurrentAccount(context, null);
+ SingleAccountHelper.commitCurrentAccount(context, null);
callback.onError(e);
});
}
@@ -203,7 +203,7 @@ public class NotesRepository {
Log.e(TAG, "… No network connection available to import " + account.getAccountName());
importExecutor.submit(() -> {
deleteAccount(account);
- SingleAccountHelper.setCurrentAccount(context, null);
+ SingleAccountHelper.commitCurrentAccount(context, null);
callback.onError(new NetworkErrorException());
});
}
diff --git a/build.gradle b/build.gradle
index 2d4c67a2..ef8ab2c5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,16 +1,18 @@
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
- kotlinVersion = '1.8.22'
- commonsVersion = '1.8.2'
+ kotlinVersion = '1.9.22'
+ commonsVersion = '1.9.0'
}
repositories {
mavenCentral()
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.4.2'
+ classpath 'com.android.tools.build:gradle:8.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
// NOTE: Do not place your application dependencies here; they belong
@@ -28,12 +30,7 @@ allprojects {
}
subprojects {
- tasks.withType(Test) {
+ tasks.withType(Test).configureEach {
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
}
- tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
- kotlinOptions {
- jvmTarget = "11"
- }
- }
}
diff --git a/gradle.properties b/gradle.properties
index 0d0f8dee..4e8e44e9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,20 +1,3 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
+org.gradle.configuration-cache=true
android.useAndroidX=true
-org.gradle.jvmargs=-Xmx4096m
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true \ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ae04661e..15de9024 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists