diff --git a/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/app/DispatchersModule.kt b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/app/DispatchersModule.kt index 34a187f..5b71f23 100644 --- a/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/app/DispatchersModule.kt +++ b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/app/DispatchersModule.kt @@ -7,13 +7,16 @@ import dagger.hilt.components.SingletonComponent import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import javax.inject.Qualifier +import javax.inject.Singleton @Qualifier @Retention(AnnotationRetention.BINARY) +@Singleton annotation class MainDispatcher @Qualifier @Retention(AnnotationRetention.BINARY) +@Singleton annotation class IoDispatcher @Module @@ -21,9 +24,11 @@ annotation class IoDispatcher class DispatchersModule { @MainDispatcher @Provides + @Singleton fun providesMainDispatcher(): CoroutineDispatcher = Dispatchers.Main @IoDispatcher @Provides + @Singleton fun providesIoDispatcher(): CoroutineDispatcher = Dispatchers.IO } \ No newline at end of file diff --git a/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/data/RoomModule.kt b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/data/RoomModule.kt new file mode 100644 index 0000000..6be8ad1 --- /dev/null +++ b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/data/RoomModule.kt @@ -0,0 +1,35 @@ +package com.github.nullptroma.wallenc.app.di.modules.data + +import android.content.Context +import com.github.nullptroma.wallenc.data.db.RoomFactory +import com.github.nullptroma.wallenc.data.db.app.IAppDb +import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyDao +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Singleton + +@Module +@InstallIn(dagger.hilt.components.SingletonComponent::class) +class RoomModule { + @Provides + @Singleton + fun provideRoomFactory(@ApplicationContext appContext: Context) : RoomFactory { + return RoomFactory(appContext) + } + + @Provides + @Singleton + fun provideStorageKeyDao(database: IAppDb): StorageKeyDao { + return database.storageKeyDao + } + + @Provides + @Singleton + fun provideAppDb( + factory: RoomFactory + ): IAppDb { + return factory.buildAppDb() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/data/SingletonModule.kt b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/data/SingletonModule.kt index a4e51e1..8b26f2e 100644 --- a/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/data/SingletonModule.kt +++ b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/data/SingletonModule.kt @@ -3,7 +3,6 @@ package com.github.nullptroma.wallenc.app.di.modules.data import android.content.Context import com.github.nullptroma.wallenc.app.di.modules.app.IoDispatcher import com.github.nullptroma.wallenc.data.vaults.VaultsManager -import com.github.nullptroma.wallenc.data.vaults.local.LocalVault import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager import dagger.Module import dagger.Provides @@ -18,14 +17,8 @@ import javax.inject.Singleton class SingletonModule { @Provides @Singleton - fun provideLocalVault(@IoDispatcher ioDispatcher: CoroutineDispatcher, - @ApplicationContext context: Context): LocalVault { - return LocalVault(ioDispatcher, context) - } - - @Provides - @Singleton - fun provideVaultsManager(localVault: LocalVault): IVaultsManager { - return VaultsManager(localVault) + fun provideVaultsManager(@IoDispatcher ioDispatcher: CoroutineDispatcher, + @ApplicationContext context: Context): IVaultsManager { + return VaultsManager(ioDispatcher, context) } } \ No newline at end of file diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 49a2bee..9c36c58 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -38,9 +38,6 @@ dependencies { implementation(libs.jackson.module.kotlin) implementation(libs.jackson.datatype.jsr310) - // Timber - implementation(libs.timber) - // Room implementation(libs.room.ktx) implementation(libs.room.runtime) diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/db/RoomFactory.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/db/RoomFactory.kt new file mode 100644 index 0000000..2da78bd --- /dev/null +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/db/RoomFactory.kt @@ -0,0 +1,14 @@ +package com.github.nullptroma.wallenc.data.db + +import android.content.Context +import androidx.room.Room +import com.github.nullptroma.wallenc.data.db.app.AppDb + +class RoomFactory(private val context: Context) { + fun buildAppDb(): AppDb { + val room = Room.databaseBuilder( + context, AppDb::class.java, "app-db" + ).fallbackToDestructiveMigration().build() + return room + } +} \ No newline at end of file diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/AppDb.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/AppDb.kt new file mode 100644 index 0000000..cf300cb --- /dev/null +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/AppDb.kt @@ -0,0 +1,15 @@ +package com.github.nullptroma.wallenc.data.db.app + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyDao +import com.github.nullptroma.wallenc.data.db.app.model.DbStorageKey + +interface IAppDb { + val storageKeyDao: StorageKeyDao +} + +@Database(entities = [DbStorageKey::class], version = 1, exportSchema = false) +abstract class AppDb : IAppDb, RoomDatabase() { + abstract override val storageKeyDao: StorageKeyDao +} \ No newline at end of file diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/dao/StorageKeyDao.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/dao/StorageKeyDao.kt new file mode 100644 index 0000000..a03939a --- /dev/null +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/dao/StorageKeyDao.kt @@ -0,0 +1,9 @@ +package com.github.nullptroma.wallenc.data.db.app.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query + +@Dao +interface StorageKeyDao { +} \ No newline at end of file diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/model/DbStorageKey.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/model/DbStorageKey.kt new file mode 100644 index 0000000..0484f45 --- /dev/null +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/db/app/model/DbStorageKey.kt @@ -0,0 +1,11 @@ +package com.github.nullptroma.wallenc.data.db.app.model + +import androidx.room.ColumnInfo +import androidx.room.Entity + +@Entity(tableName = "storage_keys", primaryKeys = [ "source_uuid", "dest_uuid" ]) +data class DbStorageKey( + @ColumnInfo(name = "source_uuid") val sourceUuid: String, + @ColumnInfo(name = "dest_uuid") val destUuid: String, + @ColumnInfo(name = "key") val key: String +) diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/IStorageCallbackHandler.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/IStorageCallbackHandler.kt deleted file mode 100644 index 578e033..0000000 --- a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/IStorageCallbackHandler.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.github.nullptroma.wallenc.data.vaults - -interface IStorageCallbackHandler { - fun changeSize(delta: Int) - fun changeNumOfFiles(delta: Int) - -} \ No newline at end of file diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/UnlockManager.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/UnlockManager.kt new file mode 100644 index 0000000..577de69 --- /dev/null +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/UnlockManager.kt @@ -0,0 +1,25 @@ +package com.github.nullptroma.wallenc.data.vaults + +import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey +import com.github.nullptroma.wallenc.domain.interfaces.IStorage +import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import java.util.UUID + +class UnlockManager: IUnlockManager { + private val _openedStorages = MutableStateFlow>(mapOf()) + override val openedStorages: StateFlow> + get() = _openedStorages + + override fun open( + storage: IStorage, + key: EncryptKey + ) { + TODO("Not yet implemented") + } + + override fun close(storage: IStorage) { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/VaultsManager.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/VaultsManager.kt index 02833aa..dae6d04 100644 --- a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/VaultsManager.kt +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/VaultsManager.kt @@ -1,11 +1,15 @@ package com.github.nullptroma.wallenc.data.vaults +import android.content.Context import com.github.nullptroma.wallenc.data.vaults.local.LocalVault import com.github.nullptroma.wallenc.domain.interfaces.IVault import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.StateFlow -class VaultsManager(override val localVault: LocalVault) : IVaultsManager { +class VaultsManager(ioDispatcher: CoroutineDispatcher, context: Context) : IVaultsManager { + override val localVault = LocalVault(ioDispatcher, context) + override val remoteVaults: StateFlow> get() = TODO("Not yet implemented") diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/local/LocalStorageAccessor.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/local/LocalStorageAccessor.kt index 9e2d84b..6bf791d 100644 --- a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/local/LocalStorageAccessor.kt +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/local/LocalStorageAccessor.kt @@ -22,7 +22,6 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import timber.log.Timber import java.io.File import java.io.InputStream import java.io.OutputStream @@ -59,7 +58,6 @@ class LocalStorageAccessor( init { // запускам сканирование хранилища CoroutineScope(ioDispatcher).launch { - Timber.d("Local storage path: $_filesystemBasePath") scanSizeAndNumOfFiles() } } diff --git a/domain/src/main/java/com/github/nullptroma/wallenc/domain/interfaces/IUnlockManager.kt b/domain/src/main/java/com/github/nullptroma/wallenc/domain/interfaces/IUnlockManager.kt new file mode 100644 index 0000000..35cd6ca --- /dev/null +++ b/domain/src/main/java/com/github/nullptroma/wallenc/domain/interfaces/IUnlockManager.kt @@ -0,0 +1,15 @@ +package com.github.nullptroma.wallenc.domain.interfaces + +import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey +import kotlinx.coroutines.flow.StateFlow +import java.util.UUID + +interface IUnlockManager { + /** + * Хранилища, для которых есть ключ шифрования + */ + val openedStorages: StateFlow> + + fun open(storage: IStorage, key: EncryptKey) + fun close(storage: IStorage) +} \ No newline at end of file diff --git a/wallenc-uml.gaphor b/wallenc-uml.gaphor index df0091d..b564ac8 100644 --- a/wallenc-uml.gaphor +++ b/wallenc-uml.gaphor @@ -399,6 +399,7 @@ existing classes or even new classes with specific responsibilities. + @@ -438,6 +439,7 @@ existing classes or even new classes with specific responsibilities. + @@ -452,6 +454,9 @@ existing classes or even new classes with specific responsibilities. + + + @@ -537,14 +542,8 @@ existing classes or even new classes with specific responsibilities. - - - - - - @@ -556,12 +555,13 @@ existing classes or even new classes with specific responsibilities. + -(1.0, 0.0, 0.0, 1.0, 590.5, 986.0) +(1.0, 0.0, 0.0, 1.0, 701.5, 986.0) (0.0, 0.0) @@ -570,11 +570,14 @@ existing classes or even new classes with specific responsibilities. 374.0 -244.0 +168.0 + +0 + @@ -632,7 +635,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 560.95, 0.0) +(1.0, 0.0, 0.0, 1.0, 671.95, 0.0) (0.0, 0.0) @@ -762,7 +765,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 59.5, 1340.0) +(1.0, 0.0, 0.0, 1.0, 179.5, 1264.0) (0.0, 0.0) @@ -865,6 +868,11 @@ existing classes or even new classes with specific responsibilities. + + + + + IStorageExplorer @@ -895,7 +903,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 583.5, 1340.0) +(1.0, 0.0, 0.0, 1.0, 983.5, 1584.0) (0.0, 0.0) @@ -964,7 +972,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 461.0, 286.5) +(1.0, 0.0, 0.0, 1.0, 572.0, 286.5) (0.0, 0.0) @@ -1026,7 +1034,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 736.5, 278.0) +(1.0, 0.0, 0.0, 1.0, 847.5, 278.0) (0.0, 0.0) @@ -1115,7 +1123,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 1545.0190727547713, 182.35724811729017) -[(-668.5590727547713, 220.64275188270983), (-705.8590727547713, 330.64275188270983)] +[(-557.5590727547713, 220.64275188270983), (-594.8590727547713, 330.64275188270983)] @@ -1225,7 +1233,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 559.0, 513.0) +(1.0, 0.0, 0.0, 1.0, 670.0, 513.0) (0.0, 0.0) @@ -1299,33 +1307,6 @@ existing classes or even new classes with specific responsibilities. - - - - - -rename - - - - - - - - - -in - - -newName - - - - - -String - - @@ -1512,20 +1493,6 @@ existing classes or even new classes with specific responsibilities. Uri - - - - - -1 - - -accessor - - -IStorageAccessor - - @@ -1713,7 +1680,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 243.16039962225034, 245.31631894795726) -[(374.8896003777496, 149.18368105204274), (437.8796003777496, 267.68368105204274)] +[(485.8896003777496, 149.18368105204274), (548.8796003777496, 267.68368105204274)] @@ -1758,7 +1725,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 797.1546434276883, 342.4519561875513) -[(-19.654643427688256, 533.5480438124487), (-19.654643427688256, 643.5480438124487)] +[(91.34535657231174, 533.5480438124487), (91.34535657231174, 643.5480438124487)] @@ -1842,7 +1809,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 203.10890581080406, 345.69270684881207) -[(567.9510941891958, -177.69270684881207), (648.801094189196, -67.69270684881207)] +[(678.9510941891958, -177.69270684881207), (759.801094189196, -67.69270684881207)] @@ -1920,7 +1887,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 138.30896896823918, 350.69522175455927) -[(531.9010310317608, -182.69522175455927), (476.41103103176084, -64.19522175455927)] +[(642.9010310317608, -182.69522175455927), (587.4110310317608, -64.19522175455927)] @@ -2054,7 +2021,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 225.5, 644.5) +(1.0, 0.0, 0.0, 1.0, 345.5, 644.5) (0.0, 0.0) @@ -2117,7 +2084,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, -109.95392950161418, 1061.2568399683112) -[(422.4539295016142, -316.75683996831117), (422.4539295016142, -20.25683996831117)] +[(542.4539295016142, -316.75683996831117), (542.4539295016142, -75.25683996831117)] @@ -2159,7 +2126,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 87.5, 1660.0) +(1.0, 0.0, 0.0, 1.0, 87.5, 1626.5) (0.0, 0.0) @@ -2249,7 +2216,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 1076.5, 282.0) +(1.0, 0.0, 0.0, 1.0, 1187.5, 282.0) (0.0, 0.0) @@ -2307,7 +2274,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 810.8769280866725, 1115.1125252125555) -[(-201.90692808667245, 114.88747478744449), (-353.4369280866725, 224.8874747874445)] +[(-50.30692808667243, 38.88747478744449), (-217.9869280866725, 148.8874747874445)] @@ -2453,7 +2420,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 1070.5, 17.0) +(1.0, 0.0, 0.0, 1.0, 1181.5, 17.0) (0.0, 0.0) @@ -2491,7 +2458,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 1254.0690161527355, -112.28501339841085) -[(-38.56901615273546, 394.28501339841085), (-38.56901615273546, 263.28501339841085)] +[(72.43098384726454, 394.28501339841085), (72.43098384726454, 263.28501339841085)] @@ -2616,7 +2583,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 956.5727755485931, 1132.134334488268) -[(-179.07277554859309, 97.865665511732), (-179.07277554859309, 207.865665511732)] +[(86.62722445140696, 21.865665511732004), (220.92722445140691, 94.865665511732), (220.92722445140691, 378.865665511732), (220.92722445140691, 451.865665511732)] @@ -2747,10 +2714,11 @@ existing classes or even new classes with specific responsibilities. + -IStorageUnlockManager +IUnlockManager - uuid to opened storage @@ -2778,7 +2746,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 990.0, 1382.5) +(1.0, 0.0, 0.0, 1.0, 556.0, 1626.5) (0.0, 0.0) @@ -2813,10 +2781,10 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, -159.4625174399573, 1222.4829062905674) +(1.0, 0.0, 0.0, 1.0, -154.21251743995725, 1222.4829062905674) -[(1088.1025174399574, 7.517093709432629), (1276.9625174399573, 160.01709370943263)] +[(966.1925174399573, -68.48290629056737), (904.9625174399573, 4.517093709432629), (904.9625174399573, 288.51709370943263), (909.4625174399573, 404.01709370943263)] @@ -2863,7 +2831,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 0.0, 1895.0) +(1.0, 0.0, 0.0, 1.0, 0.0, 1904.0) (0.0, 0.0) @@ -2904,7 +2872,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 552.0090583921045, 1954.4598112542567) -[(-289.6890583921045, -169.4598112542567), (-378.2590583921045, -59.45981125425669)] +[(-280.92905839210454, -202.9598112542567), (-382.7990583921045, -50.45981125425669)] @@ -2949,7 +2917,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 1328.1356031213516, 1393.2212077158106) -[(-1015.6356031213516, 156.77879228418942), (-1015.6356031213516, 266.7787922841894)] +[(-934.9256031213515, 80.77879228418942), (-992.3756031213516, 233.27879228418942)] @@ -3021,7 +2989,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 1379.0, 38.5) +(1.0, 0.0, 0.0, 1.0, 1490.0, 38.5) (0.0, 0.0) @@ -3186,7 +3154,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 76.1644392789674, 1603.616666567455) -[(286.5155607210326, 181.383333432545), (375.0855607210326, 291.383333432545)] +[(277.7555607210326, 147.883333432545), (379.6255607210326, 300.383333432545)] @@ -3197,7 +3165,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 313.5, 1895.0) +(1.0, 0.0, 0.0, 1.0, 313.5, 1904.0) (0.0, 0.0) @@ -3306,7 +3274,7 @@ existing classes or even new classes with specific responsibilities. -(1.0, 0.0, 0.0, 1.0, 135.0, 1041.0) +(1.0, 0.0, 0.0, 1.0, 255.0, 986.0) (0.0, 0.0) @@ -3347,7 +3315,7 @@ existing classes or even new classes with specific responsibilities. (1.0, 0.0, 0.0, 1.0, 29.099681659149553, 1343.3520695479824) -[(283.40031834085045, -3.35206954798241), (283.40031834085045, -134.3520695479824)] +[(403.40031834085045, -79.35206954798241), (403.40031834085045, -189.3520695479824)] @@ -3505,4 +3473,212 @@ existing classes or even new classes with specific responsibilities. + availableSpace: StateFlow<Integer[0..1]> + + + + + + + +IStorageAccessorsManager + + + + + + + + + + + + + + + + + + + + + + + +(1.0, 0.0, 0.0, 1.0, 774.0, 1323.5) + + +(0.0, 0.0) + + +375.0 + + +91.0 + + + + + + + + +0 + + + + + + + +getAccessor + + + + + + + + + + +return + + + + + +IStorageAccessor + + + + +in + + +storage + + + + + +IStorage + + + + + + + +0 + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 1121.3345834473034, 1106.9626146481362) + + +[(-188.20458344730343, 307.5373853518638), (-321.7345834473034, 519.5373853518638)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 1222.2798748487307, 1189.6352612530745) + + +[(-313.3498748487308, -35.63526125307453), (-271.8198748487307, 133.86473874692547)] + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + + +0 + + + + + +(1.0, 0.0, 0.0, 1.0, 1131.3345834473034, 1116.9626146481362) + + +[(-139.34458344730342, 297.5373853518638), (-24.73458344730352, 467.0373853518638)] + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file