Merge remote-tracking branch 'origin/main' into fix/1161-2

pull/1315/head
Simon Marquis 2 months ago
commit 61143ca98b
No known key found for this signature in database
GPG Key ID: AC8D63F7571DC6D6

@ -1,17 +1,25 @@
Thanks for submitting a pull request. Please include the following information. **DO NOT CREATE A PULL REQUEST WITHOUT READING THESE INSTRUCTIONS**
**What I have done and why** ## Instructions
Include a summary of what your pull request contains, and why you have made these changes. Thanks for submitting a pull request. To accept your pull request we need you do a few things:
**If this is your first pull request**
- [Sign the contributors license agreement](https://cla.developers.google.com/)
**Ensure tests pass and code is formatted correctly**
Fixes #<issue_number_goes_here> - Run local tests on the `DemoDebug` variant by running `./gradlew testDemoDebug`
- Fix code formatting: `./gradlew --init-script gradle/init.gradle.kts spotlessApply`
**Do tests pass?** **Add a description**
- [ ] Run local tests on `DemoDebug` variant: `./gradlew testDemoDebug`
- [ ] Check formatting: `./gradlew --init-script gradle/init.gradle.kts spotlessApply`
**Is this your first pull request?** We need to know what you've done and why you've done it. Include a summary of what your pull request contains, and why you have made these changes. Include links to any relevant issues which it fixes.
- [ ] [Sign the CLA](https://cla.developers.google.com/)
- [ ] Run `./tools/setup.sh`
- [ ] Import the code formatting style as explained in [the setup script](/tools/setup.sh#L40).
[Here's an example](https://github.com/android/nowinandroid/pull/1257).
**NOW DELETE THIS LINE AND EVERYTHING ABOVE IT**
**What I have done and why**
\<add your PR description here\>

@ -17,6 +17,7 @@ jobs:
permissions: permissions:
contents: write contents: write
pull-requests: write
timeout-minutes: 60 timeout-minutes: 60
@ -25,7 +26,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/wrapper-validation-action@v3
- name: Copy CI gradle.properties - name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
@ -100,12 +101,13 @@ jobs:
commit_message: "🤖 Updates screenshots" commit_message: "🤖 Updates screenshots"
# Run local tests after screenshot tests to avoid wrong UP-TO-DATE. TODO: Ignore screenshots. # Run local tests after screenshot tests to avoid wrong UP-TO-DATE. TODO: Ignore screenshots.
- name: Run local tests - name: Run local tests and create report
if: always() if: always()
run: ./gradlew testDemoDebug :lint:test run: ./gradlew testDemoDebug :lint:test
# Replace task exclusions with `-Pandroidx.baselineprofile.skipgeneration` when # Replace task exclusions with `-Pandroidx.baselineprofile.skipgeneration` when
# https://android-review.googlesource.com/c/platform/frameworks/support/+/2602790 landed in a # https://android-review.googlesource.com/c/platform/frameworks/support/+/2602790 landed in a
# release build # release build
- name: Build all build type and flavor permutations - name: Build all build type and flavor permutations
run: ./gradlew :app:assemble :benchmarks:assemble run: ./gradlew :app:assemble :benchmarks:assemble
-x pixel6Api33ProdNonMinifiedReleaseAndroidTest -x pixel6Api33ProdNonMinifiedReleaseAndroidTest
@ -119,13 +121,20 @@ jobs:
name: APKs name: APKs
path: '**/build/outputs/apk/**/*.apk' path: '**/build/outputs/apk/**/*.apk'
- name: Upload test results (XML) - name: Upload JVM local results (XML)
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: test-results name: local-test-results
path: '**/build/test-results/test*UnitTest/**.xml' path: '**/build/test-results/test*UnitTest/**.xml'
- name: Upload screenshot results (PNG)
if: always()
uses: actions/upload-artifact@v4
with:
name: screenshot-test-results
path: '**/build/outputs/roborazzi/*_compare.png'
- name: Check lint - name: Check lint
run: ./gradlew :app:lintProdRelease :app-nia-catalog:lintRelease :lint:lint run: ./gradlew :app:lintProdRelease :app-nia-catalog:lintRelease :lint:lint
@ -180,10 +189,7 @@ jobs:
- name: Setup Gradle - name: Setup Gradle
uses: gradle/gradle-build-action@v3 uses: gradle/gradle-build-action@v3
- name: Build projects before running emulator - name: Build projects and run instrumentation tests
run: ./gradlew packageDemoDebug packageDemoDebugAndroidTest
- name: Run instrumentation tests
uses: reactivecircus/android-emulator-runner@v2 uses: reactivecircus/android-emulator-runner@v2
with: with:
api-level: ${{ matrix.api-level }} api-level: ${{ matrix.api-level }}
@ -193,9 +199,41 @@ jobs:
heap-size: 600M heap-size: 600M
script: ./gradlew connectedDemoDebugAndroidTest --daemon script: ./gradlew connectedDemoDebugAndroidTest --daemon
- name: Run local tests (including Roborazzi) for the combined coverage report (only API 30)
if: matrix.api-level == 30
# There is no need to verify Roborazzi tests to generate coverage.
run: ./gradlew testDemoDebugUnitTest -Proborazzi.test.verify=false # Add Prod if we ever add JVM tests for prod
# Add `createProdDebugUnitTestCoverageReport` if we ever add JVM tests for prod
- name: Generate coverage reports for Debug variants (only API 30)
if: matrix.api-level == 30
run: ./gradlew createDemoDebugCombinedCoverageReport
- name: Upload test reports - name: Upload test reports
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: test-reports-${{ matrix.api-level }} name: test-reports-${{ matrix.api-level }}
path: '**/build/reports/androidTests' path: '**/build/reports/androidTests'
- name: Display local test coverage (only API 30)
if: matrix.api-level == 30
id: jacoco
uses: madrapps/jacoco-report@v1.6.1
with:
title: Combined test coverage report
min-coverage-overall: 40
min-coverage-changed-files: 60
paths: |
${{ github.workspace }}/**/build/reports/jacoco/**/*Report.xml
token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload local coverage reports (XML + HTML) (only API 30)
if: matrix.api-level == 30
uses: actions/upload-artifact@v4
with:
name: coverage-reports
if-no-files-found: error
compression-level: 1
overwrite: false
path: '**/build/reports/jacoco/'

@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/wrapper-validation-action@v3
- name: Copy CI gradle.properties - name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

@ -59,7 +59,7 @@ android {
// To publish on the Play store a private signing key is required, but to allow anyone // To publish on the Play store a private signing key is required, but to allow anyone
// who clones the code to sign and run the release variant, use the debug signing key. // who clones the code to sign and run the release variant, use the debug signing key.
// TODO: Abstract the signing configuration to a separate file to avoid hardcoding this. // TODO: Abstract the signing configuration to a separate file to avoid hardcoding this.
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.named("debug").get()
} }
} }
} }

@ -1,6 +1,6 @@
androidx.activity:activity-compose:1.8.0 androidx.activity:activity-compose:1.8.2
androidx.activity:activity-ktx:1.8.0 androidx.activity:activity-ktx:1.8.2
androidx.activity:activity:1.8.0 androidx.activity:activity:1.8.2
androidx.annotation:annotation-experimental:1.4.0 androidx.annotation:annotation-experimental:1.4.0
androidx.annotation:annotation-jvm:1.7.1 androidx.annotation:annotation-jvm:1.7.1
androidx.annotation:annotation:1.7.1 androidx.annotation:annotation:1.7.1

@ -21,7 +21,6 @@ plugins {
alias(libs.plugins.nowinandroid.android.application.flavors) alias(libs.plugins.nowinandroid.android.application.flavors)
alias(libs.plugins.nowinandroid.android.application.jacoco) alias(libs.plugins.nowinandroid.android.application.jacoco)
alias(libs.plugins.nowinandroid.android.hilt) alias(libs.plugins.nowinandroid.android.hilt)
id("jacoco")
alias(libs.plugins.nowinandroid.android.application.firebase) alias(libs.plugins.nowinandroid.android.application.firebase)
id("com.google.android.gms.oss-licenses-plugin") id("com.google.android.gms.oss-licenses-plugin")
alias(libs.plugins.baselineprofile) alias(libs.plugins.baselineprofile)
@ -53,7 +52,7 @@ android {
// To publish on the Play store a private signing key is required, but to allow anyone // To publish on the Play store a private signing key is required, but to allow anyone
// who clones the code to sign and run the release variant, use the debug signing key. // who clones the code to sign and run the release variant, use the debug signing key.
// TODO: Abstract the signing configuration to a separate file to avoid hardcoding this. // TODO: Abstract the signing configuration to a separate file to avoid hardcoding this.
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.named("debug").get()
// Ensure Baseline Profile is fresh for release builds. // Ensure Baseline Profile is fresh for release builds.
baselineProfile.automaticGenerationDuringBuild = true baselineProfile.automaticGenerationDuringBuild = true
} }
@ -101,6 +100,7 @@ dependencies {
implementation(libs.androidx.navigation.compose) implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.profileinstaller) implementation(libs.androidx.profileinstaller)
implementation(libs.androidx.tracing.ktx) implementation(libs.androidx.tracing.ktx)
implementation(libs.androidx.window.core)
implementation(libs.kotlinx.coroutines.guava) implementation(libs.kotlinx.coroutines.guava)
implementation(libs.coil.kt) implementation(libs.coil.kt)
@ -112,9 +112,8 @@ dependencies {
kspTest(libs.hilt.compiler) kspTest(libs.hilt.compiler)
testImplementation(projects.core.dataTest) testImplementation(projects.core.dataTest)
testImplementation(libs.accompanist.testharness)
testImplementation(libs.hilt.android.testing) testImplementation(libs.hilt.android.testing)
testImplementation(libs.work.testing) testImplementation(projects.sync.syncTest)
testDemoImplementation(libs.robolectric) testDemoImplementation(libs.robolectric)
testDemoImplementation(libs.roborazzi) testDemoImplementation(libs.roborazzi)
@ -126,8 +125,7 @@ dependencies {
androidTestImplementation(projects.core.datastoreTest) androidTestImplementation(projects.core.datastoreTest)
androidTestImplementation(libs.androidx.test.espresso.core) androidTestImplementation(libs.androidx.test.espresso.core)
androidTestImplementation(libs.androidx.navigation.testing) androidTestImplementation(libs.androidx.navigation.testing)
androidTestImplementation(libs.accompanist.testharness) androidTestImplementation(libs.androidx.compose.ui.test)
androidTestImplementation(libs.bundles.androidx.compose.ui.test)
androidTestImplementation(libs.hilt.android.testing) androidTestImplementation(libs.hilt.android.testing)
baselineProfile(projects.benchmarks) baselineProfile(projects.benchmarks)

@ -1,9 +1,9 @@
androidx.activity:activity-compose:1.8.0 androidx.activity:activity-compose:1.8.2
androidx.activity:activity-ktx:1.8.0 androidx.activity:activity-ktx:1.8.2
androidx.activity:activity:1.8.0 androidx.activity:activity:1.8.2
androidx.annotation:annotation-experimental:1.4.0 androidx.annotation:annotation-experimental:1.4.0
androidx.annotation:annotation-jvm:1.7.1 androidx.annotation:annotation-jvm:1.8.0-beta01
androidx.annotation:annotation:1.7.1 androidx.annotation:annotation:1.8.0-beta01
androidx.appcompat:appcompat-resources:1.6.1 androidx.appcompat:appcompat-resources:1.6.1
androidx.appcompat:appcompat:1.6.1 androidx.appcompat:appcompat:1.6.1
androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-common:2.2.0
@ -13,20 +13,20 @@ androidx.browser:browser:1.8.0
androidx.collection:collection-jvm:1.4.0 androidx.collection:collection-jvm:1.4.0
androidx.collection:collection-ktx:1.4.0 androidx.collection:collection-ktx:1.4.0
androidx.collection:collection:1.4.0 androidx.collection:collection:1.4.0
androidx.compose.animation:animation-android:1.6.3 androidx.compose.animation:animation-android:1.7.0-alpha06
androidx.compose.animation:animation-core-android:1.6.3 androidx.compose.animation:animation-core-android:1.7.0-alpha06
androidx.compose.animation:animation-core:1.6.3 androidx.compose.animation:animation-core:1.7.0-alpha06
androidx.compose.animation:animation:1.6.3 androidx.compose.animation:animation:1.7.0-alpha06
androidx.compose.foundation:foundation-android:1.6.3 androidx.compose.foundation:foundation-android:1.7.0-alpha06
androidx.compose.foundation:foundation-layout-android:1.6.3 androidx.compose.foundation:foundation-layout-android:1.7.0-alpha06
androidx.compose.foundation:foundation-layout:1.6.3 androidx.compose.foundation:foundation-layout:1.7.0-alpha06
androidx.compose.foundation:foundation:1.6.3 androidx.compose.foundation:foundation:1.7.0-alpha06
androidx.compose.material3.adaptive:adaptive-android:1.0.0-alpha08 androidx.compose.material3.adaptive:adaptive-android:1.0.0-alpha10
androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0-alpha08 androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0-alpha10
androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha08 androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha10
androidx.compose.material3.adaptive:adaptive-navigation-android:1.0.0-alpha08 androidx.compose.material3.adaptive:adaptive-navigation-android:1.0.0-alpha10
androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha08 androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha10
androidx.compose.material3.adaptive:adaptive:1.0.0-alpha08 androidx.compose.material3.adaptive:adaptive:1.0.0-alpha10
androidx.compose.material3:material3-android:1.2.1 androidx.compose.material3:material3-android:1.2.1
androidx.compose.material3:material3-window-size-class-android:1.2.1 androidx.compose.material3:material3-window-size-class-android:1.2.1
androidx.compose.material3:material3-window-size-class:1.2.1 androidx.compose.material3:material3-window-size-class:1.2.1
@ -37,25 +37,25 @@ androidx.compose.material:material-icons-extended-android:1.6.3
androidx.compose.material:material-icons-extended:1.6.3 androidx.compose.material:material-icons-extended:1.6.3
androidx.compose.material:material-ripple-android:1.6.3 androidx.compose.material:material-ripple-android:1.6.3
androidx.compose.material:material-ripple:1.6.3 androidx.compose.material:material-ripple:1.6.3
androidx.compose.runtime:runtime-android:1.6.3 androidx.compose.runtime:runtime-android:1.7.0-alpha06
androidx.compose.runtime:runtime-saveable-android:1.6.3 androidx.compose.runtime:runtime-saveable-android:1.7.0-alpha06
androidx.compose.runtime:runtime-saveable:1.6.3 androidx.compose.runtime:runtime-saveable:1.7.0-alpha06
androidx.compose.runtime:runtime-tracing:1.0.0-beta01 androidx.compose.runtime:runtime-tracing:1.0.0-beta01
androidx.compose.runtime:runtime:1.6.3 androidx.compose.runtime:runtime:1.7.0-alpha06
androidx.compose.ui:ui-android:1.6.3 androidx.compose.ui:ui-android:1.7.0-alpha06
androidx.compose.ui:ui-geometry-android:1.6.3 androidx.compose.ui:ui-geometry-android:1.7.0-alpha06
androidx.compose.ui:ui-geometry:1.6.3 androidx.compose.ui:ui-geometry:1.7.0-alpha06
androidx.compose.ui:ui-graphics-android:1.6.3 androidx.compose.ui:ui-graphics-android:1.7.0-alpha06
androidx.compose.ui:ui-graphics:1.6.3 androidx.compose.ui:ui-graphics:1.7.0-alpha06
androidx.compose.ui:ui-text-android:1.6.3 androidx.compose.ui:ui-text-android:1.7.0-alpha06
androidx.compose.ui:ui-text:1.6.3 androidx.compose.ui:ui-text:1.7.0-alpha06
androidx.compose.ui:ui-tooling-preview-android:1.6.3 androidx.compose.ui:ui-tooling-preview-android:1.7.0-alpha06
androidx.compose.ui:ui-tooling-preview:1.6.3 androidx.compose.ui:ui-tooling-preview:1.7.0-alpha06
androidx.compose.ui:ui-unit-android:1.6.3 androidx.compose.ui:ui-unit-android:1.7.0-alpha06
androidx.compose.ui:ui-unit:1.6.3 androidx.compose.ui:ui-unit:1.7.0-alpha06
androidx.compose.ui:ui-util-android:1.6.3 androidx.compose.ui:ui-util-android:1.7.0-alpha06
androidx.compose.ui:ui-util:1.6.3 androidx.compose.ui:ui-util:1.7.0-alpha06
androidx.compose.ui:ui:1.6.3 androidx.compose.ui:ui:1.7.0-alpha06
androidx.compose:compose-bom:2024.02.02 androidx.compose:compose-bom:2024.02.02
androidx.concurrent:concurrent-futures:1.1.0 androidx.concurrent:concurrent-futures:1.1.0
androidx.core:core-ktx:1.12.0 androidx.core:core-ktx:1.12.0
@ -74,34 +74,40 @@ androidx.emoji2:emoji2-views-helper:1.3.0
androidx.emoji2:emoji2:1.3.0 androidx.emoji2:emoji2:1.3.0
androidx.exifinterface:exifinterface:1.3.7 androidx.exifinterface:exifinterface:1.3.7
androidx.fragment:fragment:1.5.1 androidx.fragment:fragment:1.5.1
androidx.graphics:graphics-path:1.0.0-beta02
androidx.hilt:hilt-common:1.1.0 androidx.hilt:hilt-common:1.1.0
androidx.hilt:hilt-navigation-compose:1.2.0 androidx.hilt:hilt-navigation-compose:1.2.0
androidx.hilt:hilt-navigation:1.2.0 androidx.hilt:hilt-navigation:1.2.0
androidx.hilt:hilt-work:1.1.0 androidx.hilt:hilt-work:1.1.0
androidx.interpolator:interpolator:1.0.0 androidx.interpolator:interpolator:1.0.0
androidx.legacy:legacy-support-core-utils:1.0.0 androidx.legacy:legacy-support-core-utils:1.0.0
androidx.lifecycle:lifecycle-common-java8:2.7.0 androidx.lifecycle:lifecycle-common-java8:2.8.0-alpha04
androidx.lifecycle:lifecycle-common:2.7.0 androidx.lifecycle:lifecycle-common-jvm:2.8.0-alpha04
androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0 androidx.lifecycle:lifecycle-common:2.8.0-alpha04
androidx.lifecycle:lifecycle-livedata-core:2.7.0 androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.0-alpha04
androidx.lifecycle:lifecycle-livedata:2.7.0 androidx.lifecycle:lifecycle-livedata-core:2.8.0-alpha04
androidx.lifecycle:lifecycle-process:2.7.0 androidx.lifecycle:lifecycle-livedata:2.8.0-alpha04
androidx.lifecycle:lifecycle-runtime-compose:2.7.0 androidx.lifecycle:lifecycle-process:2.8.0-alpha04
androidx.lifecycle:lifecycle-runtime-ktx:2.7.0 androidx.lifecycle:lifecycle-runtime-android:2.8.0-alpha04
androidx.lifecycle:lifecycle-runtime:2.7.0 androidx.lifecycle:lifecycle-runtime-compose:2.8.0-alpha04
androidx.lifecycle:lifecycle-service:2.7.0 androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0 androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0 androidx.lifecycle:lifecycle-runtime:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0 androidx.lifecycle:lifecycle-service:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel:2.7.0 androidx.lifecycle:lifecycle-viewmodel-android:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.0-alpha04
androidx.lifecycle:lifecycle-viewmodel:2.8.0-alpha04
androidx.loader:loader:1.0.0 androidx.loader:loader:1.0.0
androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
androidx.metrics:metrics-performance:1.0.0-alpha04 androidx.metrics:metrics-performance:1.0.0-alpha04
androidx.navigation:navigation-common-ktx:2.7.4 androidx.navigation:navigation-common-ktx:2.8.0-alpha06
androidx.navigation:navigation-common:2.7.4 androidx.navigation:navigation-common:2.8.0-alpha06
androidx.navigation:navigation-compose:2.7.4 androidx.navigation:navigation-compose:2.8.0-alpha06
androidx.navigation:navigation-runtime-ktx:2.7.4 androidx.navigation:navigation-runtime-ktx:2.8.0-alpha06
androidx.navigation:navigation-runtime:2.7.4 androidx.navigation:navigation-runtime:2.8.0-alpha06
androidx.print:print:1.0.0 androidx.print:print:1.0.0
androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05 androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05
androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05 androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05
@ -123,9 +129,9 @@ androidx.vectordrawable:vectordrawable:1.1.0
androidx.versionedparcelable:versionedparcelable:1.1.1 androidx.versionedparcelable:versionedparcelable:1.1.1
androidx.viewpager:viewpager:1.0.0 androidx.viewpager:viewpager:1.0.0
androidx.window.extensions.core:core:1.0.0 androidx.window.extensions.core:core:1.0.0
androidx.window:window-core-android:1.3.0-alpha02 androidx.window:window-core-android:1.3.0-alpha03
androidx.window:window-core:1.3.0-alpha02 androidx.window:window-core:1.3.0-alpha03
androidx.window:window:1.3.0-alpha02 androidx.window:window:1.3.0-alpha03
androidx.work:work-runtime-ktx:2.9.0 androidx.work:work-runtime-ktx:2.9.0
androidx.work:work-runtime:2.9.0 androidx.work:work-runtime:2.9.0
com.caverock:androidsvg-aar:1.4 com.caverock:androidsvg-aar:1.4
@ -182,8 +188,8 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:31.1-android com.google.guava:guava:31.1-android
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3 com.google.j2objc:j2objc-annotations:1.3
com.google.protobuf:protobuf-javalite:3.25.2 com.google.protobuf:protobuf-javalite:4.26.0
com.google.protobuf:protobuf-kotlin-lite:3.25.2 com.google.protobuf:protobuf-kotlin-lite:4.26.0
com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0 com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0
com.squareup.okhttp3:logging-interceptor:4.12.0 com.squareup.okhttp3:logging-interceptor:4.12.0
com.squareup.okhttp3:okhttp:4.12.0 com.squareup.okhttp3:okhttp:4.12.0

@ -6,9 +6,9 @@ uses-permission: name='android.permission.ACCESS_NETWORK_STATE'
uses-permission: name='android.permission.POST_NOTIFICATIONS' uses-permission: name='android.permission.POST_NOTIFICATIONS'
uses-permission: name='android.permission.WAKE_LOCK' uses-permission: name='android.permission.WAKE_LOCK'
uses-permission: name='com.google.android.c2dm.permission.RECEIVE' uses-permission: name='com.google.android.c2dm.permission.RECEIVE'
uses-permission: name='com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE'
uses-permission: name='android.permission.RECEIVE_BOOT_COMPLETED' uses-permission: name='android.permission.RECEIVE_BOOT_COMPLETED'
uses-permission: name='android.permission.FOREGROUND_SERVICE' uses-permission: name='android.permission.FOREGROUND_SERVICE'
uses-permission: name='com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE'
uses-permission: name='com.google.samples.apps.nowinandroid.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION' uses-permission: name='com.google.samples.apps.nowinandroid.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION'
application-label:'Now in Android' application-label:'Now in Android'
application-label-af:'Now in Android' application-label-af:'Now in Android'
@ -105,9 +105,9 @@ application-icon-640:'res/mipmap-anydpi-v26/ic_launcher.xml'
application-icon-65534:'res/mipmap-anydpi-v26/ic_launcher.xml' application-icon-65534:'res/mipmap-anydpi-v26/ic_launcher.xml'
application: label='Now in Android' icon='res/mipmap-anydpi-v26/ic_launcher.xml' application: label='Now in Android' icon='res/mipmap-anydpi-v26/ic_launcher.xml'
launchable-activity: name='com.google.samples.apps.nowinandroid.MainActivity' label='' icon='' launchable-activity: name='com.google.samples.apps.nowinandroid.MainActivity' label='' icon=''
uses-library-not-required:'android.ext.adservices'
uses-library-not-required:'androidx.window.extensions' uses-library-not-required:'androidx.window.extensions'
uses-library-not-required:'androidx.window.sidecar' uses-library-not-required:'androidx.window.sidecar'
uses-library-not-required:'android.ext.adservices'
feature-group: label='' feature-group: label=''
uses-feature: name='android.hardware.faketouch' uses-feature: name='android.hardware.faketouch'
uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps' uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps'
@ -119,3 +119,4 @@ supports-screens: 'small' 'normal' 'large' 'xlarge'
supports-any-density: 'true' supports-any-density: 'true'
locales: '--_--' 'af' 'am' 'ar' 'as' 'az' 'be' 'bg' 'bn' 'bs' 'ca' 'cs' 'da' 'de' 'el' 'en-AU' 'en-CA' 'en-GB' 'en-IN' 'en-XC' 'es' 'es-US' 'et' 'eu' 'fa' 'fi' 'fr' 'fr-CA' 'gl' 'gu' 'hi' 'hr' 'hu' 'hy' 'in' 'is' 'it' 'iw' 'ja' 'ka' 'kk' 'km' 'kn' 'ko' 'ky' 'lo' 'lt' 'lv' 'mk' 'ml' 'mn' 'mr' 'ms' 'my' 'nb' 'ne' 'nl' 'or' 'pa' 'pl' 'pt' 'pt-BR' 'pt-PT' 'ro' 'ru' 'si' 'sk' 'sl' 'sq' 'sr' 'sr-Latn' 'sv' 'sw' 'ta' 'te' 'th' 'tl' 'tr' 'uk' 'ur' 'uz' 'vi' 'zh-CN' 'zh-HK' 'zh-TW' 'zu' locales: '--_--' 'af' 'am' 'ar' 'as' 'az' 'be' 'bg' 'bn' 'bs' 'ca' 'cs' 'da' 'de' 'el' 'en-AU' 'en-CA' 'en-GB' 'en-IN' 'en-XC' 'es' 'es-US' 'et' 'eu' 'fa' 'fi' 'fr' 'fr-CA' 'gl' 'gu' 'hi' 'hr' 'hu' 'hy' 'in' 'is' 'it' 'iw' 'ja' 'ka' 'kk' 'km' 'kn' 'ko' 'ky' 'lo' 'lt' 'lv' 'mk' 'ml' 'mn' 'mr' 'ms' 'my' 'nb' 'ne' 'nl' 'or' 'pa' 'pl' 'pt' 'pt-BR' 'pt-PT' 'ro' 'ru' 'si' 'sk' 'sl' 'sq' 'sr' 'sr-Latn' 'sv' 'sw' 'ta' 'te' 'th' 'tl' 'tr' 'uk' 'ur' 'uz' 'vi' 'zh-CN' 'zh-HK' 'zh-TW' 'zu'
densities: '120' '160' '240' '320' '480' '640' '65534' densities: '120' '160' '240' '320' '480' '640' '65534'
native-code: 'arm64-v8a' 'armeabi-v7a' 'x86' 'x86_64'

@ -20,13 +20,14 @@ import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.ForcedSize
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
@ -95,7 +96,9 @@ class NavigationUiTest {
@Test @Test
fun compactWidth_compactHeight_showsNavigationBar() { fun compactWidth_compactHeight_showsNavigationBar() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(400.dp, 400.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(400.dp, 400.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -109,7 +112,9 @@ class NavigationUiTest {
@Test @Test
fun mediumWidth_compactHeight_showsNavigationRail() { fun mediumWidth_compactHeight_showsNavigationRail() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(610.dp, 400.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(610.dp, 400.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -123,7 +128,9 @@ class NavigationUiTest {
@Test @Test
fun expandedWidth_compactHeight_showsNavigationRail() { fun expandedWidth_compactHeight_showsNavigationRail() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(900.dp, 400.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(900.dp, 400.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -137,7 +144,9 @@ class NavigationUiTest {
@Test @Test
fun compactWidth_mediumHeight_showsNavigationBar() { fun compactWidth_mediumHeight_showsNavigationBar() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(400.dp, 500.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(400.dp, 500.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -151,7 +160,9 @@ class NavigationUiTest {
@Test @Test
fun mediumWidth_mediumHeight_showsNavigationRail() { fun mediumWidth_mediumHeight_showsNavigationRail() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(610.dp, 500.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(610.dp, 500.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -165,7 +176,9 @@ class NavigationUiTest {
@Test @Test
fun expandedWidth_mediumHeight_showsNavigationRail() { fun expandedWidth_mediumHeight_showsNavigationRail() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(900.dp, 500.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(900.dp, 500.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -179,7 +192,9 @@ class NavigationUiTest {
@Test @Test
fun compactWidth_expandedHeight_showsNavigationBar() { fun compactWidth_expandedHeight_showsNavigationBar() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(400.dp, 1000.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(400.dp, 1000.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -193,7 +208,9 @@ class NavigationUiTest {
@Test @Test
fun mediumWidth_expandedHeight_showsNavigationRail() { fun mediumWidth_expandedHeight_showsNavigationRail() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(610.dp, 1000.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(610.dp, 1000.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }
@ -207,7 +224,9 @@ class NavigationUiTest {
@Test @Test
fun expandedWidth_expandedHeight_showsNavigationRail() { fun expandedWidth_expandedHeight_showsNavigationRail() {
composeTestRule.setContent { composeTestRule.setContent {
TestHarness(size = DpSize(900.dp, 1000.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(900.dp, 1000.dp)),
) {
BoxWithConstraints { BoxWithConstraints {
NiaApp(fakeAppState(maxWidth, maxHeight)) NiaApp(fakeAppState(maxWidth, maxHeight))
} }

@ -16,6 +16,7 @@
package com.google.samples.apps.nowinandroid.ui package com.google.samples.apps.nowinandroid.ui
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
@ -75,17 +76,13 @@ import com.google.samples.apps.nowinandroid.navigation.NiaNavHost
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination
import com.google.samples.apps.nowinandroid.feature.settings.R as settingsR import com.google.samples.apps.nowinandroid.feature.settings.R as settingsR
@OptIn(
ExperimentalMaterial3Api::class,
ExperimentalComposeUiApi::class,
)
@Composable @Composable
fun NiaApp(appState: NiaAppState) { fun NiaApp(appState: NiaAppState, modifier: Modifier = Modifier) {
val shouldShowGradientBackground = val shouldShowGradientBackground =
appState.currentTopLevelDestination == TopLevelDestination.FOR_YOU appState.currentTopLevelDestination == TopLevelDestination.FOR_YOU
var showSettingsDialog by rememberSaveable { mutableStateOf(false) } var showSettingsDialog by rememberSaveable { mutableStateOf(false) }
NiaBackground { NiaBackground(modifier = modifier) {
NiaGradientBackground( NiaGradientBackground(
gradientColors = if (shouldShowGradientBackground) { gradientColors = if (shouldShowGradientBackground) {
LocalGradientColors.current LocalGradientColors.current
@ -108,95 +105,125 @@ fun NiaApp(appState: NiaAppState) {
} }
} }
if (showSettingsDialog) { NiaApp(
SettingsDialog( appState = appState,
onDismiss = { showSettingsDialog = false }, snackbarHostState = snackbarHostState,
showSettingsDialog = showSettingsDialog,
onSettingsDismissed = { showSettingsDialog = false },
onTopAppBarActionClick = { showSettingsDialog = true },
)
}
}
}
@Composable
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
internal fun NiaApp(
appState: NiaAppState,
snackbarHostState: SnackbarHostState,
showSettingsDialog: Boolean,
onSettingsDismissed: () -> Unit,
onTopAppBarActionClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val unreadDestinations by appState.topLevelDestinationsWithUnreadResources
.collectAsStateWithLifecycle()
if (showSettingsDialog) {
SettingsDialog(
onDismiss = { onSettingsDismissed() },
)
}
Scaffold(
modifier = modifier.semantics {
testTagsAsResourceId = true
},
containerColor = Color.Transparent,
contentColor = MaterialTheme.colorScheme.onBackground,
contentWindowInsets = WindowInsets(0, 0, 0, 0),
snackbarHost = { SnackbarHost(snackbarHostState) },
bottomBar = {
if (appState.shouldShowBottomBar) {
NiaBottomBar(
destinations = appState.topLevelDestinations,
destinationsWithUnreadResources = unreadDestinations,
onNavigateToDestination = appState::navigateToTopLevelDestination,
currentDestination = appState.currentDestination,
modifier = Modifier.testTag("NiaBottomBar"),
)
}
},
) { padding ->
Row(
Modifier
.fillMaxSize()
.padding(padding)
.consumeWindowInsets(padding)
.windowInsetsPadding(
WindowInsets.safeDrawing.only(
WindowInsetsSides.Horizontal,
),
),
) {
if (appState.shouldShowNavRail) {
NiaNavRail(
destinations = appState.topLevelDestinations,
destinationsWithUnreadResources = unreadDestinations,
onNavigateToDestination = appState::navigateToTopLevelDestination,
currentDestination = appState.currentDestination,
modifier = Modifier
.testTag("NiaNavRail")
.safeDrawingPadding(),
) )
} }
val unreadDestinations by appState.topLevelDestinationsWithUnreadResources.collectAsStateWithLifecycle() Column(Modifier.fillMaxSize()) {
// Show the top app bar on top level destinations.
Scaffold( val destination = appState.currentTopLevelDestination
modifier = Modifier.semantics { val shouldShowTopAppBar = destination != null
testTagsAsResourceId = true if (destination != null) {
}, NiaTopAppBar(
containerColor = Color.Transparent, titleRes = destination.titleTextId,
contentColor = MaterialTheme.colorScheme.onBackground, navigationIcon = NiaIcons.Search,
contentWindowInsets = WindowInsets(0, 0, 0, 0), navigationIconContentDescription = stringResource(
snackbarHost = { SnackbarHost(snackbarHostState) }, id = settingsR.string.feature_settings_top_app_bar_navigation_icon_description,
bottomBar = {
if (appState.shouldShowBottomBar) {
NiaBottomBar(
destinations = appState.topLevelDestinations,
destinationsWithUnreadResources = unreadDestinations,
onNavigateToDestination = appState::navigateToTopLevelDestination,
currentDestination = appState.currentDestination,
modifier = Modifier.testTag("NiaBottomBar"),
)
}
},
) { padding ->
Row(
Modifier
.fillMaxSize()
.padding(padding)
.consumeWindowInsets(padding)
.windowInsetsPadding(
WindowInsets.safeDrawing.only(
WindowInsetsSides.Horizontal,
),
), ),
) { actionIcon = NiaIcons.Settings,
if (appState.shouldShowNavRail) { actionIconContentDescription = stringResource(
NiaNavRail( id = settingsR.string.feature_settings_top_app_bar_action_icon_description,
destinations = appState.topLevelDestinations, ),
destinationsWithUnreadResources = unreadDestinations, colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
onNavigateToDestination = appState::navigateToTopLevelDestination, containerColor = Color.Transparent,
currentDestination = appState.currentDestination, ),
modifier = Modifier onActionClick = { onTopAppBarActionClick() },
.testTag("NiaNavRail") onNavigationClick = { appState.navigateToSearch() },
.safeDrawingPadding(), )
) }
}
Column(Modifier.fillMaxSize()) {
// Show the top app bar on top level destinations.
val destination = appState.currentTopLevelDestination
if (destination != null) {
NiaTopAppBar(
titleRes = destination.titleTextId,
navigationIcon = NiaIcons.Search,
navigationIconContentDescription = stringResource(
id = settingsR.string.feature_settings_top_app_bar_navigation_icon_description,
),
actionIcon = NiaIcons.Settings,
actionIconContentDescription = stringResource(
id = settingsR.string.feature_settings_top_app_bar_action_icon_description,
),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent,
),
onActionClick = { showSettingsDialog = true },
onNavigationClick = { appState.navigateToSearch() },
)
}
NiaNavHost( Box(
appState = appState, modifier = if (shouldShowTopAppBar) {
onShowSnackbar = { message, action -> Modifier.consumeWindowInsets(
snackbarHostState.showSnackbar( WindowInsets.safeDrawing.only(WindowInsetsSides.Top),
message = message,
actionLabel = action,
duration = Short,
) == ActionPerformed
},
) )
} } else {
Modifier
// TODO: We may want to add padding or spacer when the snackbar is shown so that },
// content doesn't display behind it. ) {
NiaNavHost(
appState = appState,
onShowSnackbar = { message, action ->
snackbarHostState.showSnackbar(
message = message,
actionLabel = action,
duration = Short,
) == ActionPerformed
},
)
} }
} }
// TODO: We may want to add padding or spacer when the snackbar is shown so that
// content doesn't display behind it.
} }
} }
} }

@ -27,7 +27,8 @@ import javax.inject.Inject
class Interests2PaneViewModel @Inject constructor( class Interests2PaneViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle, private val savedStateHandle: SavedStateHandle,
) : ViewModel() { ) : ViewModel() {
val selectedTopicId: StateFlow<String?> = savedStateHandle.getStateFlow(TOPIC_ID_ARG, null) val selectedTopicId: StateFlow<String?> =
savedStateHandle.getStateFlow(TOPIC_ID_ARG, savedStateHandle[TOPIC_ID_ARG])
fun onTopicClick(topicId: String?) { fun onTopicClick(topicId: String?) {
savedStateHandle[TOPIC_ID_ARG] = topicId savedStateHandle[TOPIC_ID_ARG] = topicId

@ -18,14 +18,21 @@ package com.google.samples.apps.nowinandroid.ui.interests2pane
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.material3.adaptive.layout.AnimatedPane
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
import androidx.compose.material3.adaptive.layout.PaneAdaptedValue import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavGraphBuilder import androidx.navigation.NavGraphBuilder
@ -39,8 +46,10 @@ import com.google.samples.apps.nowinandroid.feature.interests.navigation.INTERES
import com.google.samples.apps.nowinandroid.feature.interests.navigation.TOPIC_ID_ARG import com.google.samples.apps.nowinandroid.feature.interests.navigation.TOPIC_ID_ARG
import com.google.samples.apps.nowinandroid.feature.topic.TopicDetailPlaceholder import com.google.samples.apps.nowinandroid.feature.topic.TopicDetailPlaceholder
import com.google.samples.apps.nowinandroid.feature.topic.navigation.TOPIC_ROUTE import com.google.samples.apps.nowinandroid.feature.topic.navigation.TOPIC_ROUTE
import com.google.samples.apps.nowinandroid.feature.topic.navigation.createTopicRoute
import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic
import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen
import java.util.UUID
private const val DETAIL_PANE_NAVHOST_ROUTE = "detail_pane_route" private const val DETAIL_PANE_NAVHOST_ROUTE = "detail_pane_route"
@ -76,17 +85,42 @@ internal fun InterestsListDetailScreen(
selectedTopicId: String?, selectedTopicId: String?,
onTopicClick: (String) -> Unit, onTopicClick: (String) -> Unit,
) { ) {
val listDetailNavigator = rememberListDetailPaneScaffoldNavigator<Nothing>() val listDetailNavigator = rememberListDetailPaneScaffoldNavigator(
initialDestinationHistory = listOfNotNull(
ThreePaneScaffoldDestinationItem(ListDetailPaneScaffoldRole.List),
ThreePaneScaffoldDestinationItem<Nothing>(ListDetailPaneScaffoldRole.Detail).takeIf {
selectedTopicId != null
},
),
)
BackHandler(listDetailNavigator.canNavigateBack()) { BackHandler(listDetailNavigator.canNavigateBack()) {
listDetailNavigator.navigateBack() listDetailNavigator.navigateBack()
} }
val nestedNavController = rememberNavController() var nestedNavHostStartDestination by remember {
mutableStateOf(selectedTopicId?.let(::createTopicRoute) ?: TOPIC_ROUTE)
}
var nestedNavKey by rememberSaveable(
stateSaver = Saver({ it.toString() }, UUID::fromString),
) {
mutableStateOf(UUID.randomUUID())
}
val nestedNavController = key(nestedNavKey) {
rememberNavController()
}
fun onTopicClickShowDetailPane(topicId: String) { fun onTopicClickShowDetailPane(topicId: String) {
onTopicClick(topicId) onTopicClick(topicId)
nestedNavController.navigateToTopic(topicId) { if (listDetailNavigator.isDetailPaneVisible()) {
popUpTo(DETAIL_PANE_NAVHOST_ROUTE) // If the detail pane was visible, then use the nestedNavController navigate call
// directly
nestedNavController.navigateToTopic(topicId) {
popUpTo(DETAIL_PANE_NAVHOST_ROUTE)
}
} else {
// Otherwise, recreate the NavHost entirely, and start at the new destination
nestedNavHostStartDestination = createTopicRoute(topicId)
nestedNavKey = UUID.randomUUID()
} }
listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail) listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
} }
@ -95,34 +129,34 @@ internal fun InterestsListDetailScreen(
value = listDetailNavigator.scaffoldValue, value = listDetailNavigator.scaffoldValue,
directive = listDetailNavigator.scaffoldDirective, directive = listDetailNavigator.scaffoldDirective,
listPane = { listPane = {
InterestsRoute( AnimatedPane {
onTopicClick = ::onTopicClickShowDetailPane, InterestsRoute(
highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
)
},
detailPane = {
NavHost(
navController = nestedNavController,
startDestination = TOPIC_ROUTE,
route = DETAIL_PANE_NAVHOST_ROUTE,
) {
topicScreen(
showBackButton = !listDetailNavigator.isListPaneVisible(),
onBackClick = listDetailNavigator::navigateBack,
onTopicClick = ::onTopicClickShowDetailPane, onTopicClick = ::onTopicClickShowDetailPane,
highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
) )
composable(route = TOPIC_ROUTE) { }
TopicDetailPlaceholder() },
detailPane = {
AnimatedPane {
key(nestedNavKey) {
NavHost(
navController = nestedNavController,
startDestination = nestedNavHostStartDestination,
route = DETAIL_PANE_NAVHOST_ROUTE,
) {
topicScreen(
showBackButton = !listDetailNavigator.isListPaneVisible(),
onBackClick = listDetailNavigator::navigateBack,
onTopicClick = ::onTopicClickShowDetailPane,
)
composable(route = TOPIC_ROUTE) {
TopicDetailPlaceholder()
}
}
} }
} }
}, },
) )
LaunchedEffect(Unit) {
if (selectedTopicId != null) {
// Initial topic ID was provided when navigating to Interests, so show its details.
onTopicClickShowDetailPane(selectedTopicId)
}
}
} }
@OptIn(ExperimentalMaterial3AdaptiveApi::class) @OptIn(ExperimentalMaterial3AdaptiveApi::class)

@ -16,23 +16,18 @@
package com.google.samples.apps.nowinandroid.ui package com.google.samples.apps.nowinandroid.ui
import android.util.Log
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.ForcedSize
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.test.platform.app.InstrumentationRegistry
import androidx.work.Configuration
import androidx.work.testing.SynchronousExecutor
import androidx.work.testing.WorkManagerTestInitHelper
import com.github.takahirom.roborazzi.captureRoboImage import com.github.takahirom.roborazzi.captureRoboImage
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
@ -109,17 +104,6 @@ class NiaAppScreenSizesScreenshotTests {
@Before @Before
fun setup() { fun setup() {
val config = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(SynchronousExecutor())
.build()
// Initialize WorkManager for instrumentation tests.
WorkManagerTestInitHelper.initializeTestWorkManager(
InstrumentationRegistry.getInstrumentation().context,
config,
)
hiltRule.inject() hiltRule.inject()
// Configure user data // Configure user data
@ -143,19 +127,19 @@ class NiaAppScreenSizesScreenshotTests {
CompositionLocalProvider( CompositionLocalProvider(
LocalInspectionMode provides true, LocalInspectionMode provides true,
) { ) {
TestHarness(size = DpSize(width, height)) { DeviceConfigurationOverride(
BoxWithConstraints { override = DeviceConfigurationOverride.ForcedSize(DpSize(width, height)),
NiaTheme { ) {
val fakeAppState = rememberNiaAppState( NiaTheme {
windowSizeClass = WindowSizeClass.calculateFromSize( val fakeAppState = rememberNiaAppState(
DpSize(maxWidth, maxHeight), windowSizeClass = WindowSizeClass.calculateFromSize(
), DpSize(width, height),
networkMonitor = networkMonitor, ),
userNewsResourceRepository = userNewsResourceRepository, networkMonitor = networkMonitor,
timeZoneMonitor = timeZoneMonitor, userNewsResourceRepository = userNewsResourceRepository,
) timeZoneMonitor = timeZoneMonitor,
NiaApp(fakeAppState) )
} NiaApp(fakeAppState)
} }
} }
} }

@ -0,0 +1,239 @@
/*
* Copyright 2023 The Android Open Source Project
*
* 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.
*/
package com.google.samples.apps.nowinandroid.ui
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.material3.SnackbarDuration.Indefinite
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.ForcedSize
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import com.github.takahirom.roborazzi.captureRoboImage
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.data.test.repository.FakeUserDataRepository
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions
import com.google.samples.apps.nowinandroid.uitesthiltmanifest.HiltComponentActivity
import dagger.hilt.android.testing.BindValue
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.HiltTestApplication
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.GraphicsMode
import org.robolectric.annotation.LooperMode
import java.util.TimeZone
import javax.inject.Inject
/**
* Tests that the Snackbar is correctly displayed on different screen sizes.
*/
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@RunWith(RobolectricTestRunner::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
// Configure Robolectric to use a very large screen size that can fit all of the test sizes.
// This allows enough room to render the content under test without clipping or scaling.
@Config(application = HiltTestApplication::class, qualifiers = "w1000dp-h1000dp-480dpi")
@LooperMode(LooperMode.Mode.PAUSED)
@HiltAndroidTest
class SnackbarScreenshotTests {
/**
* Manages the components' state and is used to perform injection on your test
*/
@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)
/**
* Create a temporary folder used to create a Data Store file. This guarantees that
* the file is removed in between each test, preventing a crash.
*/
@BindValue
@get:Rule(order = 1)
val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build()
/**
* Use a test activity to set the content on.
*/
@get:Rule(order = 2)
val composeTestRule = createAndroidComposeRule<HiltComponentActivity>()
@Inject
lateinit var networkMonitor: NetworkMonitor
@Inject
lateinit var timeZoneMonitor: TimeZoneMonitor
@Inject
lateinit var userDataRepository: FakeUserDataRepository
@Inject
lateinit var topicsRepository: TopicsRepository
@Inject
lateinit var userNewsResourceRepository: UserNewsResourceRepository
@Before
fun setup() {
hiltRule.inject()
// Configure user data
runBlocking {
userDataRepository.setShouldHideOnboarding(true)
userDataRepository.setFollowedTopicIds(
setOf(topicsRepository.getTopics().first().first().id),
)
}
}
@Before
fun setTimeZone() {
// Make time zone deterministic in tests
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
}
@Test
fun phone_noSnackbar() {
val snackbarHostState = SnackbarHostState()
testSnackbarScreenshotWithSize(
snackbarHostState,
400.dp,
500.dp,
"snackbar_compact_medium_noSnackbar",
action = { },
)
}
@Test
fun snackbarShown_phone() {
val snackbarHostState = SnackbarHostState()
testSnackbarScreenshotWithSize(
snackbarHostState,
400.dp,
500.dp,
"snackbar_compact_medium",
) {
snackbarHostState.showSnackbar(
"This is a test snackbar message",
actionLabel = "Action Label",
duration = Indefinite,
)
}
}
@Test
fun snackbarShown_foldable() {
val snackbarHostState = SnackbarHostState()
testSnackbarScreenshotWithSize(
snackbarHostState,
600.dp,
600.dp,
"snackbar_medium_medium",
) {
snackbarHostState.showSnackbar(
"This is a test snackbar message",
actionLabel = "Action Label",
duration = Indefinite,
)
}
}
@Test
fun snackbarShown_tablet() {
val snackbarHostState = SnackbarHostState()
testSnackbarScreenshotWithSize(
snackbarHostState,
900.dp,
900.dp,
"snackbar_expanded_expanded",
) {
snackbarHostState.showSnackbar(
"This is a test snackbar message",
actionLabel = "Action Label",
duration = Indefinite,
)
}
}
private fun testSnackbarScreenshotWithSize(
snackbarHostState: SnackbarHostState,
width: Dp,
height: Dp,
screenshotName: String,
action: suspend () -> Unit,
) {
lateinit var scope: CoroutineScope
composeTestRule.setContent {
CompositionLocalProvider(
// Replaces images with placeholders
LocalInspectionMode provides true,
) {
scope = rememberCoroutineScope()
DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(width, height)),
) {
BoxWithConstraints {
val appState = rememberNiaAppState(
windowSizeClass = WindowSizeClass.calculateFromSize(
DpSize(maxWidth, maxHeight),
),
networkMonitor = networkMonitor,
userNewsResourceRepository = userNewsResourceRepository,
timeZoneMonitor = timeZoneMonitor,
)
NiaTheme {
NiaApp(appState, snackbarHostState, false, {}, {})
}
}
}
}
}
scope.launch {
action()
}
composeTestRule.onRoot()
.captureRoboImage(
"src/testDemo/screenshots/$screenshotName.png",
roborazziOptions = DefaultRoborazziOptions,
)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

@ -15,6 +15,7 @@
*/ */
import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import com.google.samples.apps.nowinandroid.configureJacoco import com.google.samples.apps.nowinandroid.configureJacoco
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
@ -23,13 +24,15 @@ import org.gradle.kotlin.dsl.getByType
class AndroidApplicationJacocoConventionPlugin : Plugin<Project> { class AndroidApplicationJacocoConventionPlugin : Plugin<Project> {
override fun apply(target: Project) { override fun apply(target: Project) {
with(target) { with(target) {
with(pluginManager) { pluginManager.apply("jacoco")
apply("org.gradle.jacoco") val androidExtension = extensions.getByType<BaseAppModuleExtension>()
apply("com.android.application")
androidExtension.buildTypes.configureEach {
enableAndroidTestCoverage = true
enableUnitTestCoverage = true
} }
val extension = extensions.getByType<ApplicationAndroidComponentsExtension>()
configureJacoco(extension) configureJacoco(extensions.getByType<ApplicationAndroidComponentsExtension>())
} }
} }
}
}

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.google.samples.apps.nowinandroid.configureJacoco import com.google.samples.apps.nowinandroid.configureJacoco
import org.gradle.api.Plugin import org.gradle.api.Plugin
@ -23,13 +25,15 @@ import org.gradle.kotlin.dsl.getByType
class AndroidLibraryJacocoConventionPlugin : Plugin<Project> { class AndroidLibraryJacocoConventionPlugin : Plugin<Project> {
override fun apply(target: Project) { override fun apply(target: Project) {
with(target) { with(target) {
with(pluginManager) { pluginManager.apply("jacoco")
apply("org.gradle.jacoco") val androidExtension = extensions.getByType<LibraryExtension>()
apply("com.android.library")
androidExtension.buildTypes.configureEach {
enableAndroidTestCoverage = true
enableUnitTestCoverage = true
} }
val extension = extensions.getByType<LibraryAndroidComponentsExtension>()
configureJacoco(extension) configureJacoco(extensions.getByType<LibraryAndroidComponentsExtension>())
} }
} }
}
}

@ -15,6 +15,7 @@
*/ */
import androidx.room.gradle.RoomExtension import androidx.room.gradle.RoomExtension
import com.google.devtools.ksp.gradle.KspExtension
import com.google.samples.apps.nowinandroid.libs import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
@ -28,6 +29,10 @@ class AndroidRoomConventionPlugin : Plugin<Project> {
pluginManager.apply("androidx.room") pluginManager.apply("androidx.room")
pluginManager.apply("com.google.devtools.ksp") pluginManager.apply("com.google.devtools.ksp")
extensions.configure<KspExtension> {
arg("room.generateKotlin", "true")
}
extensions.configure<RoomExtension> { extensions.configure<RoomExtension> {
// The schemas directory contains a schema file for each version of the Room database. // The schemas directory contains a schema file for each version of the Room database.
// This is required to enable Room auto migrations. // This is required to enable Room auto migrations.

@ -57,6 +57,7 @@ internal fun Project.configureAndroidCompose(
kotlinOptions { kotlinOptions {
freeCompilerArgs += buildComposeMetricsParameters() freeCompilerArgs += buildComposeMetricsParameters()
freeCompilerArgs += stabilityConfiguration() freeCompilerArgs += stabilityConfiguration()
freeCompilerArgs += strongSkippingConfiguration()
} }
} }
} }
@ -84,6 +85,7 @@ private fun Project.buildComposeMetricsParameters(): List<String> {
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath
) )
} }
return metricParameters.toList() return metricParameters.toList()
} }
@ -91,3 +93,8 @@ private fun Project.stabilityConfiguration() = listOf(
"-P", "-P",
"plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=${project.rootDir.absolutePath}/compose_compiler_config.conf", "plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=${project.rootDir.absolutePath}/compose_compiler_config.conf",
) )
private fun Project.strongSkippingConfiguration() = listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:experimentalStrongSkipping=true",
)

@ -1,5 +1,5 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2024 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,8 +16,13 @@
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
import com.android.build.api.artifact.ScopedArtifact
import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.ScopedArtifacts
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.testing.Test import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.register import org.gradle.kotlin.dsl.register
@ -32,13 +37,24 @@ private val coverageExclusions = listOf(
"**/R.class", "**/R.class",
"**/R\$*.class", "**/R\$*.class",
"**/BuildConfig.*", "**/BuildConfig.*",
"**/Manifest*.*" "**/Manifest*.*",
"**/*_Hilt*.class",
"**/Hilt_*.class",
) )
private fun String.capitalize() = replaceFirstChar { private fun String.capitalize() = replaceFirstChar {
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
} }
/**
* Creates a new task that generates a combined coverage report with data from local and
* instrumented tests.
*
* `create{variant}CombinedCoverageReport`
*
* Note that coverage data must exist before running the task. This allows us to run device
* tests on CI using a different Github Action or an external device farm.
*/
internal fun Project.configureJacoco( internal fun Project.configureJacoco(
androidComponentsExtension: AndroidComponentsExtension<*, *, *>, androidComponentsExtension: AndroidComponentsExtension<*, *, *>,
) { ) {
@ -46,37 +62,53 @@ internal fun Project.configureJacoco(
toolVersion = libs.findVersion("jacoco").get().toString() toolVersion = libs.findVersion("jacoco").get().toString()
} }
val jacocoTestReport = tasks.create("jacocoTestReport")
androidComponentsExtension.onVariants { variant -> androidComponentsExtension.onVariants { variant ->
val testTaskName = "test${variant.name.capitalize()}UnitTest" val myObjFactory = project.objects
val buildDir = layout.buildDirectory.get().asFile val buildDir = layout.buildDirectory.get().asFile
val reportTask = tasks.register("jacoco${testTaskName.capitalize()}Report", JacocoReport::class) { val allJars: ListProperty<RegularFile> = myObjFactory.listProperty(RegularFile::class.java)
dependsOn(testTaskName) val allDirectories: ListProperty<Directory> = myObjFactory.listProperty(Directory::class.java)
val reportTask =
tasks.register("create${variant.name.capitalize()}CombinedCoverageReport", JacocoReport::class) {
reports { classDirectories.setFrom(
xml.required.set(true) allJars,
html.required.set(true) allDirectories.map { dirs ->
} dirs.map { dir ->
myObjFactory.fileTree().setDir(dir).exclude(coverageExclusions)
classDirectories.setFrom( }
fileTree("$buildDir/tmp/kotlin-classes/${variant.name}") { }
exclude(coverageExclusions) )
reports {
xml.required.set(true)
html.required.set(true)
} }
)
sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin")) // TODO: This is missing files in src/debug/, src/prod, src/demo, src/demoDebug...
executionData.setFrom(file("$buildDir/jacoco/$testTaskName.exec")) sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin"))
}
executionData.setFrom(
project.fileTree("$buildDir/outputs/unit_test_code_coverage/${variant.name}UnitTest")
.matching { include("**/*.exec") },
project.fileTree("$buildDir/outputs/code_coverage/${variant.name}AndroidTest")
.matching { include("**/*.ec") }
)
}
jacocoTestReport.dependsOn(reportTask) variant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT)
.use(reportTask)
.toGet(
ScopedArtifact.CLASSES,
{ _ -> allJars },
{ _ -> allDirectories },
)
} }
tasks.withType<Test>().configureEach { tasks.withType<Test>().configureEach {
configure<JacocoTaskExtension> { configure<JacocoTaskExtension> {
// Required for JaCoCo + Robolectric // Required for JaCoCo + Robolectric
// https://github.com/robolectric/robolectric/issues/2230 // https://github.com/robolectric/robolectric/issues/2230
// TODO: Consider removing if not we don't add Robolectric
isIncludeNoLocationClasses = true isIncludeNoLocationClasses = true
// Required for JDK 11 with the above // Required for JDK 11 with the above

@ -2,5 +2,10 @@
// It allows us to define classes that our not part of our codebase without wrapping them in a stable class. // It allows us to define classes that our not part of our codebase without wrapping them in a stable class.
// For more information, check https://developer.android.com/jetpack/compose/performance/stability/fix#configuration-file // For more information, check https://developer.android.com/jetpack/compose/performance/stability/fix#configuration-file
// We always use immutable classes for our data model, to avoid running the Compose compiler
// in the module we declare it to be stable here.
com.google.samples.apps.nowinandroid.core.model.data.*
// Java standard library classes
java.time.ZoneId java.time.ZoneId
java.time.ZoneOffset java.time.ZoneOffset

@ -39,7 +39,7 @@ import javax.inject.Inject
* This allows us to run the app with fake data, without needing an internet connection or working * This allows us to run the app with fake data, without needing an internet connection or working
* backend. * backend.
*/ */
internal class FakeNewsRepository @Inject constructor( class FakeNewsRepository @Inject constructor(
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
private val datasource: DemoNiaNetworkDataSource, private val datasource: DemoNiaNetworkDataSource,
) : NewsRepository { ) : NewsRepository {

@ -30,7 +30,7 @@ import javax.inject.Inject
* This allows us to run the app with fake data, without needing an internet connection or working * This allows us to run the app with fake data, without needing an internet connection or working
* backend. * backend.
*/ */
internal class FakeUserDataRepository @Inject constructor( class FakeUserDataRepository @Inject constructor(
private val niaPreferencesDataSource: NiaPreferencesDataSource, private val niaPreferencesDataSource: NiaPreferencesDataSource,
) : UserDataRepository { ) : UserDataRepository {

@ -26,57 +26,68 @@ import android.net.NetworkRequest.Builder
import android.os.Build.VERSION import android.os.Build.VERSION
import android.os.Build.VERSION_CODES import android.os.Build.VERSION_CODES
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.tracing.trace
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import javax.inject.Inject import javax.inject.Inject
internal class ConnectivityManagerNetworkMonitor @Inject constructor( internal class ConnectivityManagerNetworkMonitor @Inject constructor(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
) : NetworkMonitor { ) : NetworkMonitor {
override val isOnline: Flow<Boolean> = callbackFlow { override val isOnline: Flow<Boolean> = callbackFlow {
val connectivityManager = context.getSystemService<ConnectivityManager>() trace("NetworkMonitor.callbackFlow") {
if (connectivityManager == null) { val connectivityManager = context.getSystemService<ConnectivityManager>()
channel.trySend(false) if (connectivityManager == null) {
channel.close() channel.trySend(false)
return@callbackFlow channel.close()
} return@callbackFlow
}
/** /**
* The callback's methods are invoked on changes to *any* network matching the [NetworkRequest], * The callback's methods are invoked on changes to *any* network matching the [NetworkRequest],
* not just the active network. So we can simply track the presence (or absence) of such [Network]. * not just the active network. So we can simply track the presence (or absence) of such [Network].
*/ */
val callback = object : NetworkCallback() { val callback = object : NetworkCallback() {
private val networks = mutableSetOf<Network>() private val networks = mutableSetOf<Network>()
override fun onAvailable(network: Network) { override fun onAvailable(network: Network) {
networks += network networks += network
channel.trySend(true) channel.trySend(true)
} }
override fun onLost(network: Network) { override fun onLost(network: Network) {
networks -= network networks -= network
channel.trySend(networks.isNotEmpty()) channel.trySend(networks.isNotEmpty())
}
} }
}
val request = Builder() trace("NetworkMonitor.registerNetworkCallback") {
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) val request = Builder()
.build() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
connectivityManager.registerNetworkCallback(request, callback) .build()
connectivityManager.registerNetworkCallback(request, callback)
}
/** /**
* Sends the latest connectivity status to the underlying channel. * Sends the latest connectivity status to the underlying channel.
*/ */
channel.trySend(connectivityManager.isCurrentlyConnected()) channel.trySend(connectivityManager.isCurrentlyConnected())
awaitClose { awaitClose {
connectivityManager.unregisterNetworkCallback(callback) connectivityManager.unregisterNetworkCallback(callback)
}
} }
} }
.flowOn(ioDispatcher)
.conflate() .conflate()
@Suppress("DEPRECATION") @Suppress("DEPRECATION")

@ -1,5 +1,5 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2024 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,8 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.core.database package com.google.samples.apps.nowinandroid.core.database.di
import com.google.samples.apps.nowinandroid.core.database.NiaDatabase
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao
import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao

@ -1,5 +1,5 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2024 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,10 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.core.database package com.google.samples.apps.nowinandroid.core.database.di
import android.content.Context import android.content.Context
import androidx.room.Room import androidx.room.Room
import com.google.samples.apps.nowinandroid.core.database.NiaDatabase
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn

@ -40,7 +40,8 @@ dependencies {
implementation(libs.coil.kt.compose) implementation(libs.coil.kt.compose)
testImplementation(libs.androidx.compose.ui.test) testImplementation(libs.androidx.compose.ui.test)
testImplementation(libs.accompanist.testharness) testImplementation(libs.androidx.compose.ui.testManifest)
testImplementation(libs.hilt.android.testing) testImplementation(libs.hilt.android.testing)
testImplementation(libs.robolectric) testImplementation(libs.robolectric)
testImplementation(projects.core.screenshotTesting) testImplementation(projects.core.screenshotTesting)

@ -23,7 +23,6 @@ import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.outlined.Bookmarks import androidx.compose.material.icons.outlined.Bookmarks
import androidx.compose.material.icons.outlined.Upcoming import androidx.compose.material.icons.outlined.Upcoming
import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Bookmark import androidx.compose.material.icons.rounded.Bookmark
import androidx.compose.material.icons.rounded.BookmarkBorder import androidx.compose.material.icons.rounded.BookmarkBorder
import androidx.compose.material.icons.rounded.Bookmarks import androidx.compose.material.icons.rounded.Bookmarks
@ -33,7 +32,6 @@ import androidx.compose.material.icons.rounded.Grid3x3
import androidx.compose.material.icons.rounded.Person import androidx.compose.material.icons.rounded.Person
import androidx.compose.material.icons.rounded.Search import androidx.compose.material.icons.rounded.Search
import androidx.compose.material.icons.rounded.Settings import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.ShortText
import androidx.compose.material.icons.rounded.Upcoming import androidx.compose.material.icons.rounded.Upcoming
import androidx.compose.material.icons.rounded.ViewDay import androidx.compose.material.icons.rounded.ViewDay
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector

@ -21,12 +21,15 @@ import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.FontScale
import androidx.compose.ui.test.ForcedSize
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.then
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.github.takahirom.roborazzi.captureRoboImage import com.github.takahirom.roborazzi.captureRoboImage
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilterChip import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilterChip
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@ -78,7 +81,10 @@ class FilterChipScreenshotTests {
CompositionLocalProvider( CompositionLocalProvider(
LocalInspectionMode provides true, LocalInspectionMode provides true,
) { ) {
TestHarness(fontScale = 2f, size = DpSize(80.dp, 40.dp)) { DeviceConfigurationOverride(
DeviceConfigurationOverride.FontScale(2f) then
DeviceConfigurationOverride.ForcedSize(DpSize(80.dp, 40.dp)),
) {
NiaTheme { NiaTheme {
NiaBackground { NiaBackground {
NiaFilterChip(selected = true, onSelectedChange = {}) { NiaFilterChip(selected = true, onSelectedChange = {}) {

@ -23,10 +23,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.FontScale
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot
import com.github.takahirom.roborazzi.captureRoboImage import com.github.takahirom.roborazzi.captureRoboImage
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBar import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBar
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBarItem import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBarItem
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
@ -66,7 +67,9 @@ class NavigationScreenshotTests {
CompositionLocalProvider( CompositionLocalProvider(
LocalInspectionMode provides true, LocalInspectionMode provides true,
) { ) {
TestHarness(fontScale = 2f) { DeviceConfigurationOverride(
DeviceConfigurationOverride.FontScale(2f),
) {
NiaTheme { NiaTheme {
NiaNavigationBarExample("Looong item") NiaNavigationBarExample("Looong item")
} }

@ -22,10 +22,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.FontScale
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot
import com.github.takahirom.roborazzi.captureRoboImage import com.github.takahirom.roborazzi.captureRoboImage
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTab import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTab
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTabRow import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTabRow
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@ -62,7 +63,9 @@ class TabsScreenshotTests {
CompositionLocalProvider( CompositionLocalProvider(
LocalInspectionMode provides true, LocalInspectionMode provides true,
) { ) {
TestHarness(fontScale = 2f) { DeviceConfigurationOverride(
DeviceConfigurationOverride.FontScale(2f),
) {
NiaTheme { NiaTheme {
NiaTabsExample("Looooong item") NiaTabsExample("Looooong item")
} }

@ -20,10 +20,11 @@ import androidx.activity.ComponentActivity
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.FontScale
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot
import com.github.takahirom.roborazzi.captureRoboImage import com.github.takahirom.roborazzi.captureRoboImage
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions
@ -61,7 +62,9 @@ class TagScreenshotTests {
CompositionLocalProvider( CompositionLocalProvider(
LocalInspectionMode provides true, LocalInspectionMode provides true,
) { ) {
TestHarness(fontScale = 2f) { DeviceConfigurationOverride(
DeviceConfigurationOverride.Companion.FontScale(2f),
) {
NiaTheme { NiaTheme {
NiaTopicTag(followed = true, onClick = {}) { NiaTopicTag(followed = true, onClick = {}) {
Text("LOOOOONG TOPIC") Text("LOOOOONG TOPIC")

@ -44,6 +44,8 @@ import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.designsystem.theme.TintTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.TintTheme
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import kotlin.test.assertEquals import kotlin.test.assertEquals
/** /**
@ -54,6 +56,7 @@ import kotlin.test.assertEquals
* [LocalBackgroundTheme] have the expected values for a given theme mode, as specified by the * [LocalBackgroundTheme] have the expected values for a given theme mode, as specified by the
* design system. * design system.
*/ */
@RunWith(RobolectricTestRunner::class)
class ThemeTest { class ThemeTest {
@get:Rule @get:Rule

@ -16,16 +16,16 @@
package com.google.samples.apps.nowinandroid.core.designsystem package com.google.samples.apps.nowinandroid.core.designsystem
import android.R.string
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.FontScale
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot
import com.github.takahirom.roborazzi.captureRoboImage import com.github.takahirom.roborazzi.captureRoboImage
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@ -63,7 +63,9 @@ class TopAppBarScreenshotTests {
CompositionLocalProvider( CompositionLocalProvider(
LocalInspectionMode provides true, LocalInspectionMode provides true,
) { ) {
TestHarness(fontScale = 2f) { DeviceConfigurationOverride(
DeviceConfigurationOverride.FontScale(2f),
) {
NiaTheme { NiaTheme {
NiaTopAppBarExample() NiaTopAppBarExample()
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 B

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

@ -1,31 +0,0 @@
/*
* Copyright 2023 The Android Open Source Project
*
* 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.
*/
package com.google.samples.apps.nowinandroid.core.domain
import com.google.samples.apps.nowinandroid.core.data.repository.SearchContentsRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
/**
* A use case which returns total count of *Fts tables
*/
class GetSearchContentsCountUseCase @Inject constructor(
private val searchContentsRepository: SearchContentsRepository,
) {
operator fun invoke(): Flow<Int> =
searchContentsRepository.getSearchContentsCount()
}

@ -26,7 +26,7 @@ android {
dependencies { dependencies {
api(libs.bundles.androidx.compose.ui.test) api(libs.bundles.androidx.compose.ui.test)
api(libs.roborazzi) api(libs.roborazzi)
implementation(libs.accompanist.testharness) implementation(libs.androidx.compose.ui.test)
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)
implementation(libs.robolectric) implementation(libs.robolectric)
implementation(projects.core.designsystem) implementation(projects.core.designsystem)

@ -25,6 +25,8 @@ import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DarkMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot
import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.rules.ActivityScenarioRule
@ -32,7 +34,6 @@ import com.github.takahirom.roborazzi.RoborazziOptions
import com.github.takahirom.roborazzi.RoborazziOptions.CompareOptions import com.github.takahirom.roborazzi.RoborazziOptions.CompareOptions
import com.github.takahirom.roborazzi.RoborazziOptions.RecordOptions import com.github.takahirom.roborazzi.RoborazziOptions.RecordOptions
import com.github.takahirom.roborazzi.captureRoboImage import com.github.takahirom.roborazzi.captureRoboImage
import com.google.accompanist.testharness.TestHarness
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import org.robolectric.RuntimeEnvironment import org.robolectric.RuntimeEnvironment
@ -75,7 +76,9 @@ fun <A : ComponentActivity> AndroidComposeTestRule<ActivityScenarioRule<A>, A>.c
CompositionLocalProvider( CompositionLocalProvider(
LocalInspectionMode provides true, LocalInspectionMode provides true,
) { ) {
TestHarness(darkMode = darkMode) { DeviceConfigurationOverride(
override = DeviceConfigurationOverride.Companion.DarkMode(darkMode),
) {
body() body()
} }
} }

@ -1,463 +1,383 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1212pt" height="404pt" viewBox="0.00 0.00 1212.13 404.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 400)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-400 1208.13,-400 1208.13,4 -4,4"/>
<svg width="1178pt" height="404pt" <g id="node1" class="node">
viewBox="0.00 0.00 1178.13 404.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:app</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 400)"> <ellipse fill="none" stroke="black" cx="645.13" cy="-378" rx="27.66" ry="18"/>
<title>G</title> <text text-anchor="middle" x="645.13" y="-373.8" font-family="Times,serif" font-size="14.00">:app</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-400 1174.13,-400 1174.13,4 -4,4"/> </g>
<!-- :app --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:feature:interests</title>
<title>:app</title> <ellipse fill="none" stroke="black" cx="297.13" cy="-306" rx="75.39" ry="18"/>
<ellipse fill="none" stroke="black" cx="626.13" cy="-378" rx="27" ry="18"/> <text text-anchor="middle" x="297.13" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:interests</text>
<text text-anchor="middle" x="626.13" y="-372.95" font-family="Times,serif" font-size="14.00">:app</text> </g>
</g> <g id="edge1" class="edge">
<!-- :feature:interests --> <title>:app-&gt;:feature:interests</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M618.9,-371.75C571.45,-362.24 468.2,-341.55 381.13,-324 375.62,-322.89 369.9,-321.74 364.17,-320.58"/>
<title>:feature:interests</title> <polygon fill="red" stroke="red" stroke-width="2" points="366.62,-317.5 356.12,-318.95 365.23,-324.36 366.62,-317.5"/>
<ellipse fill="none" stroke="black" cx="289.13" cy="-306" rx="72.34" ry="18"/> </g>
<text text-anchor="middle" x="289.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:interests</text> <g id="node3" class="node">
</g> <title>:feature:foryou</title>
<!-- :app&#45;&gt;:feature:interests --> <ellipse fill="none" stroke="black" cx="135.13" cy="-306" rx="68.95" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="135.13" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:foryou</text>
<title>:app&#45;&gt;:feature:interests</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M600.52,-371.68C548.58,-360.89 429.43,-336.14 354.49,-320.58"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="356.78,-317.48 346.28,-318.87 355.36,-324.33 356.78,-317.48"/> <title>:app-&gt;:feature:foryou</title>
</g> <path fill="none" stroke="black" d="M617.71,-374.52C549.19,-368.15 365.1,-349.83 213.13,-324 207.63,-323.07 201.94,-322.01 196.25,-320.88"/>
<!-- :feature:foryou --> <polygon fill="black" stroke="black" points="197.33,-317.53 186.83,-318.96 195.93,-324.39 197.33,-317.53"/>
<g id="node3" class="node"> </g>
<title>:feature:foryou</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="132.13" cy="-306" rx="66.19" ry="18"/> <title>:feature:bookmarks</title>
<text text-anchor="middle" x="132.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:foryou</text> <ellipse fill="none" stroke="black" cx="812.13" cy="-306" rx="86.12" ry="18"/>
</g> <text text-anchor="middle" x="812.13" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:bookmarks</text>
<!-- :app&#45;&gt;:feature:foryou --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:app&#45;&gt;:feature:foryou</title> <title>:app-&gt;:feature:bookmarks</title>
<path fill="none" stroke="black" d="M599.59,-374.51C533.28,-368.1 355.12,-349.7 208.13,-324 202.83,-323.07 197.34,-322.02 191.85,-320.91"/> <path fill="none" stroke="black" d="M668,-367.41C692.72,-357.05 732.82,-340.24 764.45,-326.98"/>
<polygon fill="black" stroke="black" points="192.63,-317.5 182.12,-318.88 191.19,-324.35 192.63,-317.5"/> <polygon fill="black" stroke="black" points="765.56,-330.32 773.43,-323.22 762.85,-323.86 765.56,-330.32"/>
</g> </g>
<!-- :feature:bookmarks --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:feature:topic</title>
<title>:feature:bookmarks</title> <ellipse fill="none" stroke="black" cx="645.13" cy="-306" rx="62.51" ry="18"/>
<ellipse fill="none" stroke="black" cx="787.13" cy="-306" rx="83.08" ry="18"/> <text text-anchor="middle" x="645.13" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:topic</text>
<text text-anchor="middle" x="787.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:bookmarks</text> </g>
</g> <g id="edge4" class="edge">
<!-- :app&#45;&gt;:feature:bookmarks --> <title>:app-&gt;:feature:topic</title>
<g id="edge3" class="edge"> <path fill="none" stroke="black" d="M645.13,-359.7C645.13,-352.41 645.13,-343.73 645.13,-335.54"/>
<title>:app&#45;&gt;:feature:bookmarks</title> <polygon fill="black" stroke="black" points="648.63,-335.62 645.13,-325.62 641.63,-335.62 648.63,-335.62"/>
<path fill="none" stroke="black" d="M648.51,-367.27C672.32,-356.92 710.64,-340.25 740.97,-327.07"/> </g>
<polygon fill="black" stroke="black" points="742.16,-330.37 749.93,-323.17 739.37,-323.95 742.16,-330.37"/> <g id="node6" class="node">
</g> <title>:feature:search</title>
<!-- :feature:topic --> <ellipse fill="none" stroke="black" cx="458.13" cy="-306" rx="67.87" ry="18"/>
<g id="node5" class="node"> <text text-anchor="middle" x="458.13" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:search</text>
<title>:feature:topic</title> </g>
<ellipse fill="none" stroke="black" cx="626.13" cy="-306" rx="60.05" ry="18"/> <g id="edge5" class="edge">
<text text-anchor="middle" x="626.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:topic</text> <title>:app-&gt;:feature:search</title>
</g> <path fill="none" stroke="black" d="M621.45,-368.13C592.73,-357.39 543.61,-339 506.72,-325.19"/>
<!-- :app&#45;&gt;:feature:topic --> <polygon fill="black" stroke="black" points="508.19,-322 497.6,-321.78 505.74,-328.56 508.19,-322"/>
<g id="edge4" class="edge"> </g>
<title>:app&#45;&gt;:feature:topic</title> <g id="node7" class="node">
<path fill="none" stroke="black" d="M626.13,-359.7C626.13,-352.41 626.13,-343.73 626.13,-335.54"/> <title>:feature:settings</title>
<polygon fill="black" stroke="black" points="629.63,-335.62 626.13,-325.62 622.63,-335.62 629.63,-335.62"/> <ellipse fill="none" stroke="black" cx="989.13" cy="-306" rx="72.71" ry="18"/>
</g> <text text-anchor="middle" x="989.13" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:settings</text>
<!-- :feature:search --> </g>
<g id="node6" class="node"> <g id="edge6" class="edge">
<title>:feature:search</title> <title>:app-&gt;:feature:settings</title>
<ellipse fill="none" stroke="black" cx="445.13" cy="-306" rx="65.17" ry="18"/> <path fill="none" stroke="black" d="M671.54,-371.7C718.81,-362.21 820.98,-341.64 907.13,-324 912.6,-322.88 918.27,-321.71 923.96,-320.54"/>
<text text-anchor="middle" x="445.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:search</text> <polygon fill="black" stroke="black" points="924.32,-324.04 933.4,-318.59 922.9,-317.19 924.32,-324.04"/>
</g> </g>
<!-- :app&#45;&gt;:feature:search --> <g id="node8" class="node">
<g id="edge5" class="edge"> <title>:core:common</title>
<title>:app&#45;&gt;:feature:search</title> <ellipse fill="none" stroke="black" cx="795.13" cy="-18" rx="66.81" ry="18"/>
<path fill="none" stroke="black" d="M603.2,-368.13C575.53,-357.43 528.27,-339.16 492.62,-325.37"/> <text text-anchor="middle" x="795.13" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<polygon fill="black" stroke="black" points="493.96,-322.13 483.37,-321.79 491.44,-328.66 493.96,-322.13"/> </g>
</g> <g id="edge7" class="edge">
<!-- :feature:settings --> <title>:app-&gt;:core:common</title>
<g id="node7" class="node"> <path fill="none" stroke="black" d="M672.95,-377.23C766.59,-377.52 1068.86,-374.44 1149.13,-324 1188.5,-299.26 1204.13,-281.5 1204.13,-235 1204.13,-235 1204.13,-235 1204.13,-161 1204.13,-116.87 1196.1,-97.56 1160.13,-72 1107.37,-34.51 934.89,-47.08 871.13,-36 865.91,-35.09 860.51,-34.07 855.1,-32.98"/>
<title>:feature:settings</title> <polygon fill="black" stroke="black" points="856.04,-29.6 845.53,-30.98 854.61,-36.45 856.04,-29.6"/>
<ellipse fill="none" stroke="black" cx="958.13" cy="-306" rx="69.78" ry="18"/> </g>
<text text-anchor="middle" x="958.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:settings</text> <g id="node9" class="node">
</g> <title>:core:ui</title>
<!-- :app&#45;&gt;:feature:settings --> <ellipse fill="none" stroke="black" cx="553.13" cy="-234" rx="40.53" ry="18"/>
<g id="edge6" class="edge"> <text text-anchor="middle" x="553.13" y="-229.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<title>:app&#45;&gt;:feature:settings</title> </g>
<path fill="none" stroke="black" d="M651.63,-371.7C697.28,-362.22 795.94,-341.66 879.13,-324 884.26,-322.91 889.58,-321.78 894.92,-320.63"/> <g id="edge8" class="edge">
<polygon fill="black" stroke="black" points="895.34,-324.12 904.39,-318.6 893.88,-317.28 895.34,-324.12"/> <title>:app-&gt;:core:ui</title>
</g> <path fill="none" stroke="black" d="M623.54,-366.56C607.2,-357.54 585.52,-342.97 573.13,-324 561.41,-306.05 556.49,-282.21 554.46,-263.71"/>
<!-- :core:common --> <polygon fill="black" stroke="black" points="557.96,-263.62 553.63,-253.96 550.99,-264.22 557.96,-263.62"/>
<g id="node8" class="node"> </g>
<title>:core:common</title> <g id="node10" class="node">
<ellipse fill="none" stroke="black" cx="760.13" cy="-18" rx="65.17" ry="18"/> <title>:core:designsystem</title>
<text text-anchor="middle" x="760.13" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <ellipse fill="none" stroke="black" cx="774.13" cy="-162" rx="85.06" ry="18"/>
</g> <text text-anchor="middle" x="774.13" y="-157.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<!-- :app&#45;&gt;:core:common --> </g>
<g id="edge7" class="edge"> <g id="edge9" class="edge">
<title>:app&#45;&gt;:core:common</title> <title>:app-&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M653.52,-377.16C744.97,-377.21 1038.43,-373.43 1116.13,-324 1155.16,-299.17 1170.13,-281.27 1170.13,-235 1170.13,-235 1170.13,-235 1170.13,-161 1170.13,-114.96 1155.63,-97.23 1117.13,-72 1064.1,-37.25 896.54,-47.11 834.13,-36 829.18,-35.12 824.06,-34.12 818.93,-33.06"/> <path fill="none" stroke="black" d="M673,-375.63C763.47,-370.92 1044.67,-353.95 1071.13,-324 1081.72,-312.01 1079.98,-301.33 1071.13,-288 1056.87,-266.53 909.24,-211.2 827.64,-181.88"/>
<polygon fill="black" stroke="black" points="819.74,-29.66 809.23,-30.99 818.28,-36.51 819.74,-29.66"/> <polygon fill="black" stroke="black" points="828.85,-178.59 818.25,-178.52 826.49,-185.18 828.85,-178.59"/>
</g> </g>
<!-- :core:ui --> <g id="node11" class="node">
<g id="node9" class="node"> <title>:core:data</title>
<title>:core:ui</title> <ellipse fill="none" stroke="black" cx="584.13" cy="-162" rx="49.1" ry="18"/>
<ellipse fill="none" stroke="black" cx="530.13" cy="-234" rx="39.07" ry="18"/> <text text-anchor="middle" x="584.13" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<text text-anchor="middle" x="530.13" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text> </g>
</g> <g id="edge10" class="edge">
<!-- :app&#45;&gt;:core:ui --> <title>:app-&gt;:core:data</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M617.3,-376.64C505.79,-374.93 95.33,-365.8 57.13,-324 -77.67,-176.51 358.28,-162.51 523.4,-162.36"/>
<title>:app&#45;&gt;:core:ui</title> <polygon fill="black" stroke="black" points="523.29,-165.86 533.29,-162.37 523.29,-158.86 523.29,-165.86"/>
<path fill="none" stroke="black" d="M605.49,-365.91C590.07,-356.62 569.59,-342.01 557.13,-324 544.69,-306.03 537.86,-282.18 534.18,-263.69"/> </g>
<polygon fill="black" stroke="black" points="537.64,-263.17 532.45,-253.93 530.75,-264.38 537.64,-263.17"/> <g id="node12" class="node">
</g> <title>:core:model</title>
<!-- :core:designsystem --> <ellipse fill="none" stroke="black" cx="412.13" cy="-18" rx="57.16" ry="18"/>
<g id="node10" class="node"> <text text-anchor="middle" x="412.13" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<title>:core:designsystem</title> </g>
<ellipse fill="none" stroke="black" cx="749.13" cy="-162" rx="82.06" ry="18"/> <g id="edge11" class="edge">
<text text-anchor="middle" x="749.13" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <title>:app-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M617.23,-376.35C503.4,-373.48 77.9,-360.37 31.13,-324 -1.94,-298.29 0.13,-276.89 0.13,-235 0.13,-235 0.13,-235 0.13,-161 0.13,-88.15 233.3,-44.54 348.81,-27.41"/>
<!-- :app&#45;&gt;:core:designsystem --> <polygon fill="black" stroke="black" points="349.06,-30.91 358.45,-26.01 348.05,-23.99 349.06,-30.91"/>
<g id="edge9" class="edge"> </g>
<title>:app&#45;&gt;:core:designsystem</title> <g id="node13" class="node">
<path fill="none" stroke="black" d="M653.33,-375.54C740.95,-370.56 1011.68,-352.94 1037.13,-324 1047.69,-311.98 1045.9,-301.38 1037.13,-288 1023.35,-267 880.1,-211.43 800.97,-181.97"/> <title>:core:analytics</title>
<polygon fill="black" stroke="black" points="802.26,-178.71 791.67,-178.52 799.82,-185.28 802.26,-178.71"/> <ellipse fill="none" stroke="black" cx="1084.13" cy="-90" rx="67.34" ry="18"/>
</g> <text text-anchor="middle" x="1084.13" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<!-- :core:data --> </g>
<g id="node11" class="node"> <g id="edge12" class="edge">
<title>:core:data</title> <title>:app-&gt;:core:analytics</title>
<ellipse fill="none" stroke="black" cx="564.13" cy="-162" rx="47.26" ry="18"/> <path fill="none" stroke="black" d="M672.84,-375.63C769.36,-370.63 1086.84,-352.17 1122.13,-324 1160.64,-293.26 1158.53,-263.93 1147.13,-216 1138.52,-179.8 1117.67,-142.18 1102.3,-117.8"/>
<text text-anchor="middle" x="564.13" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> <polygon fill="black" stroke="black" points="1105.29,-115.97 1096.93,-109.47 1099.41,-119.77 1105.29,-115.97"/>
</g> </g>
<!-- :app&#45;&gt;:core:data --> <g id="node14" class="node">
<g id="edge10" class="edge"> <title>:sync:work</title>
<title>:app&#45;&gt;:core:data</title> <ellipse fill="none" stroke="black" cx="1084.13" cy="-234" rx="53.95" ry="18"/>
<path fill="none" stroke="black" d="M598.83,-376.56C490.37,-374.55 94,-364.47 57.13,-324 -72.66,-181.56 345.93,-164.36 505.2,-162.87"/> <text text-anchor="middle" x="1084.13" y="-229.8" font-family="Times,serif" font-size="14.00">:sync:work</text>
<polygon fill="black" stroke="black" points="505.17,-166.37 515.14,-162.79 505.12,-159.37 505.17,-166.37"/> </g>
</g> <g id="edge13" class="edge">
<!-- :core:model --> <title>:app-&gt;:sync:work</title>
<g id="node12" class="node"> <path fill="none" stroke="black" d="M672.8,-375.91C767.64,-371.87 1075.28,-356.38 1104.13,-324 1119.22,-307.06 1111.16,-281.21 1101.13,-261.73"/>
<title>:core:model</title> <polygon fill="black" stroke="black" points="1104.33,-260.27 1096.4,-253.25 1098.22,-263.69 1104.33,-260.27"/>
<ellipse fill="none" stroke="black" cx="391.13" cy="-18" rx="55.45" ry="18"/> </g>
<text text-anchor="middle" x="391.13" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <g id="edge14" class="edge">
</g> <title>:feature:interests-&gt;:core:ui</title>
<!-- :app&#45;&gt;:core:model --> <path fill="none" stroke="black" d="M345.28,-291.83C392.01,-279.06 462.39,-259.81 508.05,-247.33"/>
<g id="edge11" class="edge"> <polygon fill="black" stroke="black" points="508.91,-250.72 517.64,-244.7 507.07,-243.97 508.91,-250.72"/>
<title>:app&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="black" d="M599.09,-376.3C488.77,-373.19 76.42,-359.31 31.13,-324 -1.91,-298.24 0.13,-276.89 0.13,-235 0.13,-235 0.13,-235 0.13,-161 0.13,-91.6 220.52,-46.37 330.37,-28.13"/> <g id="edge15" class="edge">
<polygon fill="black" stroke="black" points="330.81,-31.61 340.11,-26.54 329.68,-24.7 330.81,-31.61"/> <title>:feature:interests-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M331.47,-289.69C385.46,-265.68 485.87,-221.35 503.13,-216 565.44,-196.69 638.07,-182.94 692.45,-174.29"/>
<!-- :core:analytics --> <polygon fill="black" stroke="black" points="692.93,-177.75 702.27,-172.75 691.85,-170.84 692.93,-177.75"/>
<g id="node13" class="node"> </g>
<title>:core:analytics</title> <g id="edge16" class="edge">
<ellipse fill="none" stroke="black" cx="1043.13" cy="-90" rx="64.66" ry="18"/> <title>:feature:interests-&gt;:core:data</title>
<text text-anchor="middle" x="1043.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <path fill="none" stroke="black" d="M318.57,-288.44C344.39,-269.08 389.6,-237.03 432.13,-216 465.15,-199.67 504.47,-186.11 534.84,-176.79"/>
</g> <polygon fill="black" stroke="black" points="535.58,-180.22 544.14,-173.99 533.56,-173.52 535.58,-180.22"/>
<!-- :app&#45;&gt;:core:analytics --> </g>
<g id="edge12" class="edge"> <g id="node15" class="node">
<title>:app&#45;&gt;:core:analytics</title> <title>:core:domain</title>
<path fill="none" stroke="black" d="M653.6,-377.55C742.51,-378.76 1020.63,-378.07 1088.13,-324 1126.58,-293.2 1125.57,-263.67 1113.13,-216 1103.47,-178.98 1080.15,-141.32 1063.07,-117.16"/> <ellipse fill="none" stroke="black" cx="280.13" cy="-234" rx="61.99" ry="18"/>
<polygon fill="black" stroke="black" points="1066,-115.25 1057.3,-109.2 1060.33,-119.35 1066,-115.25"/> <text text-anchor="middle" x="280.13" y="-229.8" font-family="Times,serif" font-size="14.00">:core:domain</text>
</g> </g>
<!-- :sync:work --> <g id="edge17" class="edge">
<g id="node14" class="node"> <title>:feature:interests-&gt;:core:domain</title>
<title>:sync:work</title> <path fill="none" stroke="red" stroke-width="2" d="M292.93,-287.7C291.14,-280.32 289,-271.52 286.99,-263.25"/>
<ellipse fill="none" stroke="black" cx="1052.13" cy="-234" rx="51.86" ry="18"/> <polygon fill="red" stroke="red" stroke-width="2" points="290.76,-263.94 285,-255.05 283.96,-265.59 290.76,-263.94"/>
<text text-anchor="middle" x="1052.13" y="-228.95" font-family="Times,serif" font-size="14.00">:sync:work</text> </g>
</g> <g id="edge37" class="edge">
<!-- :app&#45;&gt;:sync:work --> <title>:feature:foryou-&gt;:core:ui</title>
<g id="edge13" class="edge"> <path fill="none" stroke="black" d="M185.81,-293.49C194.89,-291.56 204.27,-289.65 213.13,-288 315.89,-268.81 437.04,-251.09 503.41,-241.8"/>
<title>:app&#45;&gt;:sync:work</title> <polygon fill="black" stroke="black" points="503.84,-245.27 513.26,-240.43 502.87,-238.34 503.84,-245.27"/>
<path fill="none" stroke="black" d="M653.22,-375.82C745.34,-371.53 1042.3,-355.35 1070.13,-324 1085.05,-307.19 1077.76,-281.49 1068.38,-262.03"/> </g>
<polygon fill="black" stroke="black" points="1071.54,-260.51 1063.78,-253.29 1065.34,-263.77 1071.54,-260.51"/> <g id="edge38" class="edge">
</g> <title>:feature:foryou-&gt;:core:designsystem</title>
<!-- :feature:interests&#45;&gt;:core:ui --> <path fill="none" stroke="black" d="M185.66,-293.33C244.53,-279.61 335.74,-257.97 351.13,-252 382.28,-239.92 385.45,-226.62 417.13,-216 442.63,-207.45 594.52,-186.53 691.79,-173.68"/>
<g id="edge14" class="edge"> <polygon fill="black" stroke="black" points="692.12,-177.16 701.57,-172.39 691.2,-170.22 692.12,-177.16"/>
<title>:feature:interests&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M335.02,-291.67C378.65,-279 443.79,-260.08 486.61,-247.64"/> <g id="edge39" class="edge">
<polygon fill="black" stroke="black" points="487.45,-251.04 496.07,-244.89 485.49,-244.32 487.45,-251.04"/> <title>:feature:foryou-&gt;:core:data</title>
</g> <path fill="none" stroke="black" d="M144.05,-287.98C155.92,-267.22 178.94,-232.84 209.13,-216 261.93,-186.55 432.36,-172.06 524.19,-166.24"/>
<!-- :feature:interests&#45;&gt;:core:designsystem --> <polygon fill="black" stroke="black" points="524.25,-169.74 534.02,-165.63 523.82,-162.75 524.25,-169.74"/>
<g id="edge15" class="edge"> </g>
<title>:feature:interests&#45;&gt;:core:designsystem</title> <g id="edge40" class="edge">
<path fill="none" stroke="black" d="M320.56,-289.4C366.58,-266.76 450.28,-226.34 482.13,-216 543.5,-196.07 615.36,-182.32 669.06,-173.83"/> <title>:feature:foryou-&gt;:core:domain</title>
<polygon fill="black" stroke="black" points="669.39,-177.32 678.73,-172.33 668.32,-170.41 669.39,-177.32"/> <path fill="none" stroke="black" d="M166.95,-289.64C188.2,-279.38 216.36,-265.79 239.26,-254.73"/>
</g> <polygon fill="black" stroke="black" points="240.53,-258 248.01,-250.5 237.49,-251.7 240.53,-258"/>
<!-- :feature:interests&#45;&gt;:core:data --> </g>
<g id="edge16" class="edge"> <g id="edge41" class="edge">
<title>:feature:interests&#45;&gt;:core:data</title> <title>:feature:bookmarks-&gt;:core:ui</title>
<path fill="none" stroke="black" d="M308.22,-288.26C331.27,-268.74 371.86,-236.53 411.13,-216 444.18,-198.71 484.08,-185.11 514.85,-176.01"/> <path fill="none" stroke="black" d="M760.96,-291.17C713.53,-278.35 643.64,-259.46 598.25,-247.19"/>
<polygon fill="black" stroke="black" points="515.65,-179.42 524.28,-173.28 513.7,-172.7 515.65,-179.42"/> <polygon fill="black" stroke="black" points="599.29,-243.85 588.73,-244.62 597.47,-250.61 599.29,-243.85"/>
</g> </g>
<!-- :core:domain --> <g id="edge42" class="edge">
<g id="node15" class="node"> <title>:feature:bookmarks-&gt;:core:designsystem</title>
<title>:core:domain</title> <path fill="none" stroke="black" d="M807.47,-287.59C801.02,-263.5 789.32,-219.75 781.63,-191.03"/>
<ellipse fill="none" stroke="black" cx="261.13" cy="-234" rx="60.05" ry="18"/> <polygon fill="black" stroke="black" points="785.07,-190.33 779.1,-181.57 778.3,-192.14 785.07,-190.33"/>
<text text-anchor="middle" x="261.13" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text> </g>
</g> <g id="edge43" class="edge">
<!-- :feature:interests&#45;&gt;:core:domain --> <title>:feature:bookmarks-&gt;:core:data</title>
<g id="edge17" class="edge"> <path fill="none" stroke="black" d="M783.58,-288.58C765.8,-278.26 742.5,-264.56 722.13,-252 685.6,-229.48 644.32,-202.68 616.51,-184.41"/>
<title>:feature:interests&#45;&gt;:core:domain</title> <polygon fill="black" stroke="black" points="618.44,-181.49 608.17,-178.92 614.6,-187.34 618.44,-181.49"/>
<path fill="none" stroke="red" stroke-width="2" d="M282.21,-287.7C279.19,-280.15 275.57,-271.12 272.2,-262.68"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="276.06,-262.9 269.09,-254.91 269.56,-265.5 276.06,-262.9"/> <g id="edge44" class="edge">
</g> <title>:feature:topic-&gt;:core:ui</title>
<!-- :feature:foryou&#45;&gt;:core:ui --> <path fill="none" stroke="black" d="M623.79,-288.76C611.28,-279.25 595.32,-267.1 581.74,-256.77"/>
<g id="edge37" class="edge"> <polygon fill="black" stroke="black" points="584.06,-254.14 573.99,-250.87 579.82,-259.71 584.06,-254.14"/>
<title>:feature:foryou&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M181.1,-293.62C190.07,-291.65 199.37,-289.7 208.13,-288 304.99,-269.21 419.09,-251.46 482.14,-242.03"/> <g id="edge45" class="edge">
<polygon fill="black" stroke="black" points="482.43,-245.52 491.81,-240.59 481.4,-238.6 482.43,-245.52"/> <title>:feature:topic-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M660.43,-288.15C682.93,-263.39 725.1,-216.97 751.27,-188.16"/>
<!-- :feature:foryou&#45;&gt;:core:designsystem --> <polygon fill="black" stroke="black" points="753.69,-190.7 757.83,-180.95 748.51,-185.99 753.69,-190.7"/>
<g id="edge38" class="edge"> </g>
<title>:feature:foryou&#45;&gt;:core:designsystem</title> <g id="edge46" class="edge">
<path fill="none" stroke="black" d="M180.42,-293.47C229.84,-281.43 303.12,-262.8 330.13,-252 361.15,-239.59 364.45,-226.64 396.13,-216 421.45,-207.49 572.8,-186.4 668.92,-173.54"/> <title>:feature:topic-&gt;:core:data</title>
<polygon fill="black" stroke="black" points="669.12,-177.04 678.56,-172.25 668.19,-170.1 669.12,-177.04"/> <path fill="none" stroke="black" d="M637.77,-287.87C627.37,-263.67 608.28,-219.21 595.9,-190.39"/>
</g> <polygon fill="black" stroke="black" points="599.27,-189.39 592.11,-181.58 592.84,-192.15 599.27,-189.39"/>
<!-- :feature:foryou&#45;&gt;:core:data --> </g>
<g id="edge39" class="edge"> <g id="edge47" class="edge">
<title>:feature:foryou&#45;&gt;:core:data</title> <title>:feature:search-&gt;:core:ui</title>
<path fill="none" stroke="black" d="M138.65,-287.67C147.42,-266.94 165.12,-232.91 192.13,-216 243.29,-183.95 414.92,-170.54 506.08,-165.57"/> <path fill="none" stroke="black" d="M480.16,-288.76C493.08,-279.25 509.56,-267.1 523.59,-256.77"/>
<polygon fill="black" stroke="black" points="506.01,-169.08 515.81,-165.06 505.64,-162.09 506.01,-169.08"/> <polygon fill="black" stroke="black" points="525.64,-259.6 531.62,-250.85 521.49,-253.96 525.64,-259.6"/>
</g> </g>
<!-- :feature:foryou&#45;&gt;:core:domain --> <g id="edge48" class="edge">
<g id="edge40" class="edge"> <title>:feature:search-&gt;:core:designsystem</title>
<title>:feature:foryou&#45;&gt;:core:domain</title> <path fill="none" stroke="black" d="M499.63,-291.43C528.93,-281.46 568.92,-267.08 603.13,-252 649.76,-231.45 701.4,-203.86 735.61,-184.88"/>
<path fill="none" stroke="black" d="M160.76,-289.46C179.09,-279.52 203.09,-266.5 223.02,-255.68"/> <polygon fill="black" stroke="black" points="737.29,-187.95 744.32,-180.02 733.88,-181.84 737.29,-187.95"/>
<polygon fill="black" stroke="black" points="224.57,-258.82 231.69,-250.97 221.23,-252.67 224.57,-258.82"/> </g>
</g> <g id="edge49" class="edge">
<!-- :feature:bookmarks&#45;&gt;:core:ui --> <title>:feature:search-&gt;:core:data</title>
<g id="edge41" class="edge"> <path fill="none" stroke="black" d="M463.8,-287.68C470.73,-268.48 483.97,-237.42 503.13,-216 515.05,-202.67 531.07,-191.26 545.7,-182.48"/>
<title>:feature:bookmarks&#45;&gt;:core:ui</title> <polygon fill="black" stroke="black" points="547.31,-185.6 554.24,-177.59 543.82,-179.53 547.31,-185.6"/>
<path fill="none" stroke="black" d="M736.66,-291.25C689.36,-278.37 619.35,-259.3 574.23,-247.01"/> </g>
<polygon fill="black" stroke="black" points="575.36,-243.69 564.79,-244.44 573.52,-250.45 575.36,-243.69"/> <g id="edge50" class="edge">
</g> <title>:feature:search-&gt;:core:domain</title>
<!-- :feature:bookmarks&#45;&gt;:core:designsystem --> <path fill="none" stroke="black" d="M421.25,-290.5C393.77,-279.69 356.05,-264.86 326.53,-253.25"/>
<g id="edge42" class="edge"> <polygon fill="black" stroke="black" points="328.05,-250.08 317.46,-249.68 325.49,-256.6 328.05,-250.08"/>
<title>:feature:bookmarks&#45;&gt;:core:designsystem</title> </g>
<path fill="none" stroke="black" d="M782.47,-287.59C776.02,-263.5 764.31,-219.75 756.63,-191.03"/> <g id="edge51" class="edge">
<polygon fill="black" stroke="black" points="760.06,-190.33 754.1,-181.57 753.3,-192.14 760.06,-190.33"/> <title>:feature:settings-&gt;:core:ui</title>
</g> <path fill="none" stroke="black" d="M935.84,-293.5C926.3,-291.57 916.43,-289.66 907.13,-288 799.13,-268.74 671.74,-250.84 603.06,-241.58"/>
<!-- :feature:bookmarks&#45;&gt;:core:data --> <polygon fill="black" stroke="black" points="603.62,-238.13 593.25,-240.26 602.69,-245.06 603.62,-238.13"/>
<g id="edge43" class="edge"> </g>
<title>:feature:bookmarks&#45;&gt;:core:data</title> <g id="edge52" class="edge">
<path fill="none" stroke="black" d="M758.5,-288.7C740.69,-278.43 717.39,-264.73 697.13,-252 661.72,-229.75 621.97,-202.9 595.23,-184.55"/> <title>:feature:settings-&gt;:core:designsystem</title>
<polygon fill="black" stroke="black" points="597.46,-181.84 587.24,-179.05 593.49,-187.6 597.46,-181.84"/> <path fill="none" stroke="black" d="M964.47,-288.71C926.11,-263.38 852.07,-214.48 808.5,-185.7"/>
</g> <polygon fill="black" stroke="black" points="810.7,-182.96 800.43,-180.37 806.85,-188.8 810.7,-182.96"/>
<!-- :feature:topic&#45;&gt;:core:ui --> </g>
<g id="edge44" class="edge"> <g id="edge53" class="edge">
<title>:feature:topic&#45;&gt;:core:ui</title> <title>:feature:settings-&gt;:core:data</title>
<path fill="none" stroke="black" d="M604.34,-289.12C591,-279.39 573.76,-266.82 559.26,-256.24"/> <path fill="none" stroke="black" d="M948.44,-290.73C872.29,-264.03 708.77,-206.7 629.31,-178.84"/>
<polygon fill="black" stroke="black" points="561.55,-253.58 551.41,-250.52 557.43,-259.24 561.55,-253.58"/> <polygon fill="black" stroke="black" points="630.7,-175.62 620.11,-175.61 628.38,-182.23 630.7,-175.62"/>
</g> </g>
<!-- :feature:topic&#45;&gt;:core:designsystem --> <g id="edge19" class="edge">
<g id="edge45" class="edge"> <title>:core:ui-&gt;:core:designsystem</title>
<title>:feature:topic&#45;&gt;:core:designsystem</title> <path fill="none" stroke="black" d="M585.26,-222.82C619.77,-211.89 675.28,-194.31 717.21,-181.03"/>
<path fill="none" stroke="black" d="M640.72,-288.15C662.17,-263.39 702.37,-216.97 727.33,-188.16"/> <polygon fill="black" stroke="black" points="718.19,-184.39 726.66,-178.03 716.07,-177.72 718.19,-184.39"/>
<polygon fill="black" stroke="black" points="729.66,-190.82 733.56,-180.97 724.37,-186.24 729.66,-190.82"/> </g>
</g> <g id="edge20" class="edge">
<!-- :feature:topic&#45;&gt;:core:data --> <title>:core:ui-&gt;:core:model</title>
<g id="edge46" class="edge"> <path fill="none" stroke="black" d="M518.04,-224.47C467.55,-210.1 376.2,-175.75 337.13,-108 329.14,-94.14 329.77,-86.21 337.13,-72 344.26,-58.24 356.79,-47.28 369.59,-38.99"/>
<title>:feature:topic&#45;&gt;:core:data</title> <polygon fill="black" stroke="black" points="371.25,-42.07 378.05,-33.94 367.67,-36.06 371.25,-42.07"/>
<path fill="none" stroke="black" d="M618.65,-287.87C608.08,-263.67 588.67,-219.21 576.09,-190.39"/> </g>
<polygon fill="black" stroke="black" points="579.45,-189.34 572.24,-181.58 573.03,-192.14 579.45,-189.34"/> <g id="edge18" class="edge">
</g> <title>:core:ui-&gt;:core:analytics</title>
<!-- :feature:search&#45;&gt;:core:ui --> <path fill="none" stroke="black" d="M578.63,-219.79C596.96,-209.82 621.91,-195.3 642.13,-180 660.68,-165.96 659.02,-153.78 680.13,-144 813.2,-82.35 863.46,-132.04 1008.13,-108 1013.36,-107.13 1018.76,-106.13 1024.17,-105.06"/>
<g id="edge47" class="edge"> <polygon fill="black" stroke="black" points="1024.66,-108.53 1033.74,-103.08 1023.24,-101.68 1024.66,-108.53"/>
<title>:feature:search&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M465.27,-288.41C476.46,-279.2 490.54,-267.6 502.72,-257.57"/> <g id="edge21" class="edge">
<polygon fill="black" stroke="black" points="504.92,-260.29 510.41,-251.24 500.47,-254.89 504.92,-260.29"/> <title>:core:data-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M622.36,-150.33C630.51,-148.16 639.09,-145.94 647.13,-144 721.78,-125.99 767.81,-167.69 816.13,-108 830.29,-90.51 822.33,-65.1 812.4,-45.91"/>
<!-- :feature:search&#45;&gt;:core:designsystem --> <polygon fill="black" stroke="black" points="815.51,-44.29 807.56,-37.29 809.41,-47.72 815.51,-44.29"/>
<g id="edge48" class="edge"> </g>
<title>:feature:search&#45;&gt;:core:designsystem</title> <g id="edge25" class="edge">
<path fill="none" stroke="black" d="M483.1,-291.03C509.94,-280.88 546.6,-266.44 578.13,-252 624.31,-230.84 675.85,-203.48 710.15,-184.72"/> <title>:core:data-&gt;:core:analytics</title>
<polygon fill="black" stroke="black" points="711.82,-187.8 718.89,-179.91 708.44,-181.66 711.82,-187.8"/> <path fill="none" stroke="black" d="M621.21,-149.91C629.67,-147.68 638.66,-145.55 647.13,-144 805.72,-114.9 848.94,-133.65 1008.13,-108 1013.44,-107.14 1018.93,-106.14 1024.43,-105.07"/>
</g> <polygon fill="black" stroke="black" points="1025.07,-108.51 1034.16,-103.06 1023.66,-101.65 1025.07,-108.51"/>
<!-- :feature:search&#45;&gt;:core:data --> </g>
<g id="edge49" class="edge"> <g id="node16" class="node">
<title>:feature:search&#45;&gt;:core:data</title> <title>:core:database</title>
<path fill="none" stroke="black" d="M449.03,-287.64C454.05,-268.42 464.33,-237.33 482.13,-216 493.69,-202.15 509.81,-190.65 524.7,-181.95"/> <ellipse fill="none" stroke="black" cx="412.13" cy="-90" rx="66.26" ry="18"/>
<polygon fill="black" stroke="black" points="526.38,-185.02 533.42,-177.11 522.98,-178.9 526.38,-185.02"/> <text text-anchor="middle" x="412.13" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
</g> </g>
<!-- :feature:search&#45;&gt;:core:domain --> <g id="edge22" class="edge">
<g id="edge50" class="edge"> <title>:core:data-&gt;:core:database</title>
<title>:feature:search&#45;&gt;:core:domain</title> <path fill="none" stroke="red" stroke-width="2" d="M552.18,-148C525.79,-137.26 487.98,-121.87 458.3,-109.79"/>
<path fill="none" stroke="black" d="M407.89,-290.83C379.05,-279.86 338.93,-264.6 307.92,-252.8"/> <polygon fill="red" stroke="red" stroke-width="2" points="461.15,-107.17 450.57,-106.64 458.51,-113.66 461.15,-107.17"/>
<polygon fill="black" stroke="black" points="309.37,-249.61 298.78,-249.32 306.88,-256.15 309.37,-249.61"/> </g>
</g> <g id="node17" class="node">
<!-- :feature:settings&#45;&gt;:core:ui --> <title>:core:datastore</title>
<g id="edge51" class="edge"> <ellipse fill="none" stroke="black" cx="931.13" cy="-90" rx="67.87" ry="18"/>
<title>:feature:settings&#45;&gt;:core:ui</title> <text text-anchor="middle" x="931.13" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<path fill="none" stroke="black" d="M906.8,-293.48C897.6,-291.55 888.1,-289.64 879.13,-288 772.28,-268.41 646.09,-250.54 578.56,-241.4"/> </g>
<polygon fill="black" stroke="black" points="579.32,-237.97 568.94,-240.1 578.38,-244.91 579.32,-237.97"/> <g id="edge23" class="edge">
</g> <title>:core:data-&gt;:core:datastore</title>
<!-- :feature:settings&#45;&gt;:core:designsystem --> <path fill="none" stroke="black" d="M621.98,-150.21C630.23,-148.02 638.95,-145.83 647.13,-144 736.12,-124.1 759.58,-125.26 849.13,-108 855.44,-106.78 862.02,-105.48 868.58,-104.16"/>
<g id="edge52" class="edge"> <polygon fill="black" stroke="black" points="868.97,-107.65 878.07,-102.22 867.58,-100.79 868.97,-107.65"/>
<title>:feature:settings&#45;&gt;:core:designsystem</title> </g>
<path fill="none" stroke="black" d="M934.15,-288.71C896.95,-263.43 825.2,-214.68 782.81,-185.88"/> <g id="node18" class="node">
<polygon fill="black" stroke="black" points="784.96,-183.11 774.72,-180.39 781.02,-188.9 784.96,-183.11"/> <title>:core:network</title>
</g> <ellipse fill="none" stroke="black" cx="742.13" cy="-90" rx="64.66" ry="18"/>
<!-- :feature:settings&#45;&gt;:core:data --> <text text-anchor="middle" x="742.13" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<g id="edge53" class="edge"> </g>
<title>:feature:settings&#45;&gt;:core:data</title> <g id="edge24" class="edge">
<path fill="none" stroke="black" d="M918.54,-290.73C844.61,-264.09 686.03,-206.93 608.56,-179.01"/> <title>:core:data-&gt;:core:network</title>
<polygon fill="black" stroke="black" points="609.75,-175.72 599.16,-175.63 607.38,-182.31 609.75,-175.72"/> <path fill="none" stroke="black" d="M614.59,-147.5C638.42,-136.95 671.87,-122.13 698.53,-110.31"/>
</g> <polygon fill="black" stroke="black" points="699.65,-113.65 707.37,-106.4 696.81,-107.25 699.65,-113.65"/>
<!-- :core:ui&#45;&gt;:core:designsystem --> </g>
<g id="edge19" class="edge"> <g id="node19" class="node">
<title>:core:ui&#45;&gt;:core:designsystem</title> <title>:core:notifications</title>
<path fill="none" stroke="black" d="M561.51,-222.93C568.62,-220.65 576.13,-218.24 583.13,-216 619.89,-204.24 661.23,-191.03 693.47,-180.75"/> <ellipse fill="none" stroke="black" cx="578.13" cy="-90" rx="81.29" ry="18"/>
<polygon fill="black" stroke="black" points="694.13,-184.21 702.59,-177.84 692,-177.55 694.13,-184.21"/> <text text-anchor="middle" x="578.13" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
</g> </g>
<!-- :core:ui&#45;&gt;:core:model --> <g id="edge26" class="edge">
<g id="edge20" class="edge"> <title>:core:data-&gt;:core:notifications</title>
<title>:core:ui&#45;&gt;:core:model</title> <path fill="none" stroke="black" d="M582.65,-143.7C582.02,-136.41 581.28,-127.73 580.58,-119.54"/>
<path fill="none" stroke="black" d="M496.49,-224.51C447.08,-210.02 356.59,-175.34 318.13,-108 310.19,-94.11 310.86,-86.25 318.13,-72 325.1,-58.32 337.43,-47.35 350,-39.02"/> <polygon fill="black" stroke="black" points="584.07,-119.28 579.72,-109.61 577.09,-119.87 584.07,-119.28"/>
<polygon fill="black" stroke="black" points="351.58,-42.15 358.28,-33.95 347.93,-36.18 351.58,-42.15"/> </g>
</g> <g id="edge55" class="edge">
<!-- :core:ui&#45;&gt;:core:analytics --> <title>:sync:work-&gt;:core:data</title>
<g id="edge18" class="edge"> <path fill="none" stroke="black" d="M1033.64,-227.11C957.06,-218.02 807.03,-199.55 680.13,-180 666.54,-177.91 651.9,-175.43 638.26,-173.02"/>
<title>:core:ui&#45;&gt;:core:analytics</title> <polygon fill="black" stroke="black" points="639.02,-169.6 628.56,-171.29 637.79,-176.49 639.02,-169.6"/>
<path fill="none" stroke="black" d="M555.54,-220.04C574.11,-210.1 599.56,-195.49 620.13,-180 638.71,-166.01 637.05,-153.85 658.13,-144 782.97,-85.63 830.22,-130.89 966.13,-108 972.03,-107.01 978.17,-105.85 984.28,-104.63"/> </g>
<polygon fill="black" stroke="black" points="984.65,-108.13 993.73,-102.67 983.23,-101.27 984.65,-108.13"/> <g id="edge54" class="edge">
</g> <title>:sync:work-&gt;:core:analytics</title>
<!-- :core:data&#45;&gt;:core:common --> <path fill="none" stroke="black" d="M1084.13,-215.59C1084.13,-191.61 1084.13,-148.14 1084.13,-119.42"/>
<g id="edge21" class="edge"> <polygon fill="black" stroke="black" points="1087.63,-119.62 1084.13,-109.62 1080.63,-119.62 1087.63,-119.62"/>
<title>:core:data&#45;&gt;:core:common</title> </g>
<path fill="none" stroke="black" d="M601.15,-150.4C609.05,-148.22 617.35,-145.99 625.13,-144 693.65,-126.5 736.14,-163.38 780.13,-108 794.09,-90.42 786.46,-65.02 776.87,-45.85"/> <g id="edge35" class="edge">
<polygon fill="black" stroke="black" points="780.04,-44.37 772.18,-37.26 773.9,-47.72 780.04,-44.37"/> <title>:core:domain-&gt;:core:data</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M327.63,-222.06C383.21,-209.27 474.91,-188.15 532.29,-174.94"/>
<!-- :core:data&#45;&gt;:core:analytics --> <polygon fill="red" stroke="red" stroke-width="2" points="531.38,-178.74 540.34,-173.08 529.81,-171.92 531.38,-178.74"/>
<g id="edge25" class="edge"> </g>
<title>:core:data&#45;&gt;:core:analytics</title> <g id="edge36" class="edge">
<path fill="none" stroke="black" d="M600.02,-149.93C608.21,-147.7 616.92,-145.57 625.13,-144 774.83,-115.44 815.71,-132.47 966.13,-108 972.04,-107.04 978.18,-105.91 984.3,-104.7"/> <title>:core:domain-&gt;:core:model</title>
<polygon fill="black" stroke="black" points="984.66,-108.2 993.75,-102.75 983.25,-101.34 984.66,-108.2"/> <path fill="none" stroke="black" d="M277.82,-215.56C274.59,-183.75 272.27,-115.57 304.13,-72 317.19,-54.13 337.94,-41.98 357.78,-33.87"/>
</g> <polygon fill="black" stroke="black" points="358.8,-37.22 366.92,-30.41 356.33,-30.67 358.8,-37.22"/>
<!-- :core:database --> </g>
<g id="node16" class="node"> <g id="edge27" class="edge">
<title>:core:database</title> <title>:core:database-&gt;:core:model</title>
<ellipse fill="none" stroke="black" cx="391.13" cy="-90" rx="63.63" ry="18"/> <path fill="none" stroke="red" stroke-width="2" d="M412.13,-71.7C412.13,-64.41 412.13,-55.73 412.13,-47.54"/>
<text text-anchor="middle" x="391.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <polygon fill="red" stroke="red" stroke-width="2" points="415.63,-49.13 412.13,-39.13 408.63,-49.13 415.63,-49.13"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:database --> <g id="edge30" class="edge">
<g id="edge22" class="edge"> <title>:core:datastore-&gt;:core:common</title>
<title>:core:data&#45;&gt;:core:database</title> <path fill="none" stroke="black" d="M900.95,-73.46C881.67,-63.54 856.44,-50.56 835.45,-39.75"/>
<path fill="none" stroke="red" stroke-width="2" d="M532.8,-148.32C506.06,-137.5 467.25,-121.8 437,-109.56"/> <polygon fill="black" stroke="black" points="837.07,-36.65 826.57,-35.18 833.86,-42.87 837.07,-36.65"/>
<polygon fill="red" stroke="red" stroke-width="2" points="440.09,-107.03 429.5,-106.53 437.46,-113.52 440.09,-107.03"/> </g>
</g> <g id="edge29" class="edge">
<!-- :core:datastore --> <title>:core:datastore-&gt;:core:model</title>
<g id="node17" class="node"> <path fill="none" stroke="black" d="M873.24,-80.25C854.98,-77.55 834.72,-74.59 816.13,-72 695.93,-55.23 555.39,-37.14 475.76,-27.02"/>
<title>:core:datastore</title> <polygon fill="black" stroke="black" points="476.33,-23.57 465.96,-25.78 475.44,-30.51 476.33,-23.57"/>
<ellipse fill="none" stroke="black" cx="892.13" cy="-90" rx="65.17" ry="18"/> </g>
<text text-anchor="middle" x="892.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <g id="node20" class="node">
</g> <title>:core:datastore-proto</title>
<!-- :core:data&#45;&gt;:core:datastore --> <ellipse fill="none" stroke="black" cx="971.13" cy="-18" rx="91.47" ry="18"/>
<g id="edge23" class="edge"> <text text-anchor="middle" x="971.13" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<title>:core:data&#45;&gt;:core:datastore</title> </g>
<path fill="none" stroke="black" d="M600.77,-150.26C608.77,-148.06 617.21,-145.86 625.13,-144 707.95,-124.56 729.76,-124.95 813.13,-108 819.06,-106.79 825.23,-105.51 831.4,-104.21"/> <g id="edge28" class="edge">
<polygon fill="black" stroke="black" points="831.9,-107.69 840.95,-102.19 830.45,-100.84 831.9,-107.69"/> <title>:core:datastore-&gt;:core:datastore-proto</title>
</g> <path fill="none" stroke="black" d="M941.02,-71.7C945.47,-63.9 950.84,-54.51 955.8,-45.83"/>
<!-- :core:network --> <polygon fill="black" stroke="black" points="958.68,-47.84 960.6,-37.42 952.6,-44.36 958.68,-47.84"/>
<g id="node18" class="node"> </g>
<title>:core:network</title> <g id="edge31" class="edge">
<ellipse fill="none" stroke="black" cx="709.13" cy="-90" rx="62.1" ry="18"/> <title>:core:network-&gt;:core:common</title>
<text text-anchor="middle" x="709.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <path fill="none" stroke="black" d="M754.96,-72.05C761.14,-63.89 768.7,-53.91 775.58,-44.82"/>
</g> <polygon fill="black" stroke="black" points="778.26,-47.08 781.5,-37 772.68,-42.86 778.26,-47.08"/>
<!-- :core:data&#45;&gt;:core:network --> </g>
<g id="edge24" class="edge"> <g id="edge32" class="edge">
<title>:core:data&#45;&gt;:core:network</title> <title>:core:network-&gt;:core:model</title>
<path fill="none" stroke="black" d="M592.43,-147.34C613.89,-136.97 643.72,-122.58 667.85,-110.93"/> <path fill="none" stroke="black" d="M693.6,-77.69C685.12,-75.76 676.37,-73.8 668.13,-72 600.38,-57.21 522.31,-41.19 470.37,-30.68"/>
<polygon fill="black" stroke="black" points="669.29,-114.12 676.77,-106.62 666.25,-107.82 669.29,-114.12"/> <polygon fill="black" stroke="black" points="471.36,-27.31 460.86,-28.76 469.97,-34.17 471.36,-27.31"/>
</g> </g>
<!-- :core:notifications --> <g id="edge34" class="edge">
<g id="node19" class="node"> <title>:core:notifications-&gt;:core:common</title>
<title>:core:notifications</title> <path fill="none" stroke="black" d="M622.83,-74.58C657.72,-63.32 706.27,-47.66 742.94,-35.83"/>
<ellipse fill="none" stroke="black" cx="551.13" cy="-90" rx="77.97" ry="18"/> <polygon fill="black" stroke="black" points="743.55,-39.32 751.99,-32.92 741.4,-32.66 743.55,-39.32"/>
<text text-anchor="middle" x="551.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> </g>
</g> <g id="edge33" class="edge">
<!-- :core:data&#45;&gt;:core:notifications --> <title>:core:notifications-&gt;:core:model</title>
<g id="edge26" class="edge"> <path fill="none" stroke="black" d="M541.7,-73.64C516.45,-62.99 482.7,-48.76 455.98,-37.49"/>
<title>:core:data&#45;&gt;:core:notifications</title> <polygon fill="black" stroke="black" points="457.34,-34.27 446.77,-33.61 454.62,-40.72 457.34,-34.27"/>
<path fill="none" stroke="black" d="M560.91,-143.7C559.54,-136.32 557.91,-127.52 556.37,-119.25"/> </g>
<polygon fill="black" stroke="black" points="559.85,-118.79 554.58,-109.59 552.96,-120.06 559.85,-118.79"/> </g>
</g>
<!-- :sync:work&#45;&gt;:core:data -->
<g id="edge55" class="edge">
<title>:sync:work&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M1003.5,-227.18C929,-218.09 782.21,-199.56 658.13,-180 644.69,-177.88 630.21,-175.38 616.74,-172.95"/>
<polygon fill="black" stroke="black" points="617.66,-169.56 607.19,-171.21 616.4,-176.44 617.66,-169.56"/>
</g>
<!-- :sync:work&#45;&gt;:core:analytics -->
<g id="edge54" class="edge">
<title>:sync:work&#45;&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M1051.02,-215.59C1049.5,-191.61 1046.75,-148.14 1044.93,-119.42"/>
<polygon fill="black" stroke="black" points="1048.43,-119.38 1044.31,-109.62 1041.45,-119.82 1048.43,-119.38"/>
</g>
<!-- :core:domain&#45;&gt;:core:data -->
<g id="edge35" class="edge">
<title>:core:domain&#45;&gt;:core:data</title>
<path fill="none" stroke="red" stroke-width="2" d="M307.48,-222.29C363.12,-209.44 456.09,-187.96 513.55,-174.68"/>
<polygon fill="red" stroke="red" stroke-width="2" points="512.64,-178.49 521.6,-172.83 511.06,-171.67 512.64,-178.49"/>
</g>
<!-- :core:domain&#45;&gt;:core:model -->
<g id="edge36" class="edge">
<title>:core:domain&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M258.85,-215.58C255.67,-183.81 253.43,-115.69 285.13,-72 297.97,-54.29 318.43,-42.15 337.96,-34.01"/>
<polygon fill="black" stroke="black" points="339.18,-37.29 347.25,-30.43 336.66,-30.76 339.18,-37.29"/>
</g>
<!-- :core:database&#45;&gt;:core:model -->
<g id="edge27" class="edge">
<title>:core:database&#45;&gt;:core:model</title>
<path fill="none" stroke="red" stroke-width="2" d="M391.13,-71.7C391.13,-64.41 391.13,-55.73 391.13,-47.54"/>
<polygon fill="red" stroke="red" stroke-width="2" points="394.63,-49.13 391.13,-39.13 387.63,-49.13 394.63,-49.13"/>
</g>
<!-- :core:datastore&#45;&gt;:core:common -->
<g id="edge30" class="edge">
<title>:core:datastore&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M862.83,-73.46C844.12,-63.54 819.63,-50.56 799.26,-39.75"/>
<polygon fill="black" stroke="black" points="801.15,-36.79 790.68,-35.2 797.87,-42.98 801.15,-36.79"/>
</g>
<!-- :core:datastore&#45;&gt;:core:model -->
<g id="edge29" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M836.32,-80.36C818.39,-77.63 798.43,-74.64 780.13,-72 664.78,-55.39 530,-37.33 453.19,-27.16"/>
<polygon fill="black" stroke="black" points="453.7,-23.7 443.33,-25.86 452.78,-30.64 453.7,-23.7"/>
</g>
<!-- :core:datastore&#45;proto -->
<g id="node20" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="931.13" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="931.13" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge28" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M901.57,-72.05C905.91,-64.26 911.17,-54.82 916.04,-46.08"/>
<polygon fill="black" stroke="black" points="918.96,-48.04 920.77,-37.6 912.84,-44.63 918.96,-48.04"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge31" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M721.47,-72.05C727.42,-63.89 734.69,-53.91 741.31,-44.82"/>
<polygon fill="black" stroke="black" points="743.94,-47.16 747,-37.01 738.29,-43.03 743.94,-47.16"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge32" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M662.57,-77.69C654.43,-75.76 646.04,-73.8 638.13,-72 573.05,-57.23 498.08,-41.3 447.97,-30.8"/>
<polygon fill="black" stroke="black" points="448.71,-27.38 438.2,-28.76 447.28,-34.23 448.71,-27.38"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge34" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M594.18,-74.58C627.64,-63.37 674.14,-47.8 709.41,-35.99"/>
<polygon fill="black" stroke="black" points="710.16,-39.43 718.53,-32.93 707.94,-32.79 710.16,-39.43"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge33" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M516.01,-73.64C491.68,-62.99 459.15,-48.76 433.39,-37.49"/>
<polygon fill="black" stroke="black" points="435.12,-34.43 424.55,-33.62 432.31,-40.84 435.12,-34.43"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

@ -1,73 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="462pt" height="188pt" viewBox="0.00 0.00 462.21 188.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-184 458.21,-184 458.21,4 -4,4"/>
<svg width="449pt" height="188pt" <g id="node1" class="node">
viewBox="0.00 0.00 448.51 188.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:app-nia-catalog</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)"> <ellipse fill="none" stroke="black" cx="169.06" cy="-162" rx="73.77" ry="18"/>
<title>G</title> <text text-anchor="middle" x="169.06" y="-157.8" font-family="Times,serif" font-size="14.00">:app-nia-catalog</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-184 444.51,-184 444.51,4 -4,4"/> </g>
<!-- :app&#45;nia&#45;catalog --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:designsystem</title>
<title>:app&#45;nia&#45;catalog</title> <ellipse fill="none" stroke="black" cx="85.06" cy="-18" rx="85.06" ry="18"/>
<ellipse fill="none" stroke="black" cx="164.06" cy="-162" rx="70.8" ry="18"/> <text text-anchor="middle" x="85.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<text text-anchor="middle" x="164.06" y="-156.95" font-family="Times,serif" font-size="14.00">:app&#45;nia&#45;catalog</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:designsystem --> <title>:app-nia-catalog-&gt;:core:designsystem</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M158.93,-143.87C144.55,-119.56 118.08,-74.82 101.04,-46.01"/>
<title>:core:designsystem</title> <polygon fill="black" stroke="black" points="104.1,-44.32 96,-37.49 98.08,-47.88 104.1,-44.32"/>
<ellipse fill="none" stroke="black" cx="82.06" cy="-18" rx="82.06" ry="18"/> </g>
<text text-anchor="middle" x="82.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <g id="node3" class="node">
</g> <title>:core:ui</title>
<!-- :app&#45;nia&#45;catalog&#45;&gt;:core:designsystem --> <ellipse fill="none" stroke="black" cx="229.06" cy="-90" rx="40.53" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="229.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<title>:app&#45;nia&#45;catalog&#45;&gt;:core:designsystem</title> </g>
<path fill="none" stroke="black" d="M154.17,-143.87C140.13,-119.56 114.29,-74.82 97.66,-46.01"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="100.77,-44.41 92.74,-37.5 94.71,-47.91 100.77,-44.41"/> <title>:app-nia-catalog-&gt;:core:ui</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M183.58,-144.05C190.84,-135.59 199.75,-125.19 207.76,-115.84"/>
<!-- :core:ui --> <polygon fill="red" stroke="red" stroke-width="2" points="209.26,-119.48 213.11,-109.61 203.94,-114.92 209.26,-119.48"/>
<g id="node3" class="node"> </g>
<title>:core:ui</title> <g id="edge4" class="edge">
<ellipse fill="none" stroke="black" cx="222.06" cy="-90" rx="39.07" ry="18"/> <title>:core:ui-&gt;:core:designsystem</title>
<text text-anchor="middle" x="222.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <path fill="none" stroke="black" d="M202.31,-76C181.55,-65.91 152.35,-51.71 128.28,-40.01"/>
</g> <polygon fill="black" stroke="black" points="129.87,-36.89 119.34,-35.67 126.81,-43.19 129.87,-36.89"/>
<!-- :app&#45;nia&#45;catalog&#45;&gt;:core:ui --> </g>
<g id="edge2" class="edge"> <g id="node4" class="node">
<title>:app&#45;nia&#45;catalog&#45;&gt;:core:ui</title> <title>:core:analytics</title>
<path fill="none" stroke="red" stroke-width="2" d="M178.1,-144.05C185.04,-135.68 193.55,-125.4 201.23,-116.13"/> <ellipse fill="none" stroke="black" cx="255.06" cy="-18" rx="67.34" ry="18"/>
<polygon fill="red" stroke="red" stroke-width="2" points="202.93,-119.57 206.62,-109.64 197.54,-115.11 202.93,-119.57"/> <text text-anchor="middle" x="255.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
</g> </g>
<!-- :core:ui&#45;&gt;:core:designsystem --> <g id="edge3" class="edge">
<g id="edge4" class="edge"> <title>:core:ui-&gt;:core:analytics</title>
<title>:core:ui&#45;&gt;:core:designsystem</title> <path fill="none" stroke="red" stroke-width="2" d="M235.35,-72.05C238.15,-64.52 241.52,-55.44 244.68,-46.94"/>
<path fill="none" stroke="black" d="M196.38,-76.16C176.17,-66.05 147.57,-51.76 124.04,-39.99"/> <polygon fill="red" stroke="red" stroke-width="2" points="247.39,-49.71 247.59,-39.11 240.82,-47.27 247.39,-49.71"/>
<polygon fill="black" stroke="black" points="125.83,-36.97 115.32,-35.63 122.7,-43.23 125.83,-36.97"/> </g>
</g> <g id="node5" class="node">
<!-- :core:analytics --> <title>:core:model</title>
<g id="node4" class="node"> <ellipse fill="none" stroke="black" cx="397.06" cy="-18" rx="57.16" ry="18"/>
<title>:core:analytics</title> <text text-anchor="middle" x="397.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<ellipse fill="none" stroke="black" cx="247.06" cy="-18" rx="64.66" ry="18"/> </g>
<text text-anchor="middle" x="247.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <g id="edge5" class="edge">
</g> <title>:core:ui-&gt;:core:model</title>
<!-- :core:ui&#45;&gt;:core:analytics --> <path fill="none" stroke="black" d="M257.94,-76.97C284.09,-66.07 323.01,-49.86 353.03,-37.34"/>
<g id="edge3" class="edge"> <polygon fill="black" stroke="black" points="354.37,-40.58 362.26,-33.5 351.68,-34.12 354.37,-40.58"/>
<title>:core:ui&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M228.11,-72.05C230.8,-64.52 234.05,-55.44 237.08,-46.94"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="239.8,-49.72 239.87,-39.13 233.21,-47.37 239.8,-49.72"/>
</g>
<!-- :core:model -->
<g id="node5" class="node">
<title>:core:model</title>
<ellipse fill="none" stroke="black" cx="385.06" cy="-18" rx="55.45" ry="18"/>
<text text-anchor="middle" x="385.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text>
</g>
<!-- :core:ui&#45;&gt;:core:model -->
<g id="edge5" class="edge">
<title>:core:ui&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M250.08,-76.97C275.45,-66.07 313.21,-49.86 342.35,-37.34"/>
<polygon fill="black" stroke="black" points="343.45,-40.68 351.26,-33.52 340.69,-34.25 343.45,-40.68"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -1,19 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="143pt" height="44pt" viewBox="0.00 0.00 142.68 44.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-40 138.68,-40 138.68,4 -4,4"/>
<svg width="137pt" height="44pt" <g id="node1" class="node">
viewBox="0.00 0.00 137.32 44.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:analytics</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)"> <ellipse fill="none" stroke="black" cx="67.34" cy="-18" rx="67.34" ry="18"/>
<title>G</title> <text text-anchor="middle" x="67.34" y="-13.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-40 133.32,-40 133.32,4 -4,4"/> </g>
<!-- :core:analytics --> </g>
<g id="node1" class="node">
<title>:core:analytics</title>
<ellipse fill="none" stroke="black" cx="64.66" cy="-18" rx="64.66" ry="18"/>
<text text-anchor="middle" x="64.66" y="-12.95" font-family="Times,serif" font-size="14.00">:core:analytics</text>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 863 B

After

Width:  |  Height:  |  Size: 784 B

@ -1,19 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="142pt" height="44pt" viewBox="0.00 0.00 141.63 44.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-40 137.63,-40 137.63,4 -4,4"/>
<svg width="138pt" height="44pt" <g id="node1" class="node">
viewBox="0.00 0.00 138.34 44.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:common</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)"> <ellipse fill="none" stroke="black" cx="66.81" cy="-18" rx="66.81" ry="18"/>
<title>G</title> <text text-anchor="middle" x="66.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-40 134.34,-40 134.34,4 -4,4"/> </g>
<!-- :core:common --> </g>
<g id="node1" class="node">
<title>:core:common</title>
<ellipse fill="none" stroke="black" cx="65.17" cy="-18" rx="65.17" ry="18"/>
<text text-anchor="middle" x="65.17" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 854 B

After

Width:  |  Height:  |  Size: 778 B

@ -1,151 +1,123 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="791pt" height="188pt" viewBox="0.00 0.00 791.30 188.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-184 787.3,-184 787.3,4 -4,4"/>
<svg width="763pt" height="188pt" <g id="node1" class="node">
viewBox="0.00 0.00 762.55 188.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:data</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)"> <ellipse fill="none" stroke="black" cx="327.95" cy="-162" rx="49.1" ry="18"/>
<title>G</title> <text text-anchor="middle" x="327.95" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-184 758.55,-184 758.55,4 -4,4"/> </g>
<!-- :core:data --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:common</title>
<title>:core:data</title> <ellipse fill="none" stroke="black" cx="91.95" cy="-18" rx="66.81" ry="18"/>
<ellipse fill="none" stroke="black" cx="315.89" cy="-162" rx="47.26" ry="18"/> <text text-anchor="middle" x="91.95" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<text text-anchor="middle" x="315.89" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:common --> <title>:core:data-&gt;:core:common</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M278.66,-160.32C197.49,-158.04 41.21,-148.38 6.95,-108 -3.4,-95.8 -0.81,-85.99 6.95,-72 15.05,-57.42 29,-46.33 43.29,-38.16"/>
<title>:core:common</title> <polygon fill="black" stroke="black" points="44.61,-41.42 51.83,-33.66 41.35,-35.22 44.61,-41.42"/>
<ellipse fill="none" stroke="black" cx="87.89" cy="-18" rx="65.17" ry="18"/> </g>
<text text-anchor="middle" x="87.89" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <g id="node3" class="node">
</g> <title>:core:database</title>
<!-- :core:data&#45;&gt;:core:common --> <ellipse fill="none" stroke="black" cx="563.95" cy="-90" rx="66.26" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="563.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<title>:core:data&#45;&gt;:core:common</title> </g>
<path fill="none" stroke="black" d="M268.42,-160.03C190.25,-157.31 39.78,-147.01 6.89,-108 -3.42,-95.77 -0.72,-86.07 6.89,-72 14.54,-57.84 27.81,-46.86 41.41,-38.66"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="42.93,-41.82 49.97,-33.91 39.53,-35.7 42.93,-41.82"/> <title>:core:data-&gt;:core:database</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M365.35,-149.91C404.17,-138.39 465.29,-120.27 509.48,-107.16"/>
<!-- :core:database --> <polygon fill="red" stroke="red" stroke-width="2" points="508.83,-111 517.42,-104.8 506.84,-104.29 508.83,-111"/>
<g id="node3" class="node"> </g>
<title>:core:database</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="543.89" cy="-90" rx="63.63" ry="18"/> <title>:core:datastore</title>
<text text-anchor="middle" x="543.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <ellipse fill="none" stroke="black" cx="411.95" cy="-90" rx="67.87" ry="18"/>
</g> <text text-anchor="middle" x="411.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<!-- :core:data&#45;&gt;:core:database --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:core:data&#45;&gt;:core:database</title> <title>:core:data-&gt;:core:datastore</title>
<path fill="none" stroke="red" stroke-width="2" d="M352.02,-149.91C389.56,-138.38 448.68,-120.23 491.38,-107.12"/> <path fill="none" stroke="black" d="M347.02,-145.12C357.74,-136.18 371.34,-124.85 383.32,-114.86"/>
<polygon fill="red" stroke="red" stroke-width="2" points="490.71,-110.99 499.24,-104.71 488.65,-104.3 490.71,-110.99"/> <polygon fill="black" stroke="black" points="385.49,-117.61 390.93,-108.52 381.01,-112.23 385.49,-117.61"/>
</g> </g>
<!-- :core:datastore --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:network</title>
<title>:core:datastore</title> <ellipse fill="none" stroke="black" cx="80.95" cy="-90" rx="64.66" ry="18"/>
<ellipse fill="none" stroke="black" cx="396.89" cy="-90" rx="65.17" ry="18"/> <text text-anchor="middle" x="80.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<text text-anchor="middle" x="396.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> </g>
</g> <g id="edge4" class="edge">
<!-- :core:data&#45;&gt;:core:datastore --> <title>:core:data-&gt;:core:network</title>
<g id="edge3" class="edge"> <path fill="none" stroke="black" d="M289.9,-150.22C248.69,-138.53 182.56,-119.8 135.75,-106.53"/>
<title>:core:data&#45;&gt;:core:datastore</title> <polygon fill="black" stroke="black" points="136.92,-103.22 126.35,-103.86 135.01,-109.96 136.92,-103.22"/>
<path fill="none" stroke="black" d="M334.27,-145.12C344.61,-136.18 357.73,-124.85 369.28,-114.86"/> </g>
<polygon fill="black" stroke="black" points="371.31,-117.73 376.59,-108.54 366.74,-112.43 371.31,-117.73"/> <g id="node6" class="node">
</g> <title>:core:analytics</title>
<!-- :core:network --> <ellipse fill="none" stroke="black" cx="715.95" cy="-90" rx="67.34" ry="18"/>
<g id="node5" class="node"> <text text-anchor="middle" x="715.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<title>:core:network</title> </g>
<ellipse fill="none" stroke="black" cx="77.89" cy="-90" rx="62.1" ry="18"/> <g id="edge5" class="edge">
<text text-anchor="middle" x="77.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <title>:core:data-&gt;:core:analytics</title>
</g> <path fill="none" stroke="black" d="M372.63,-154.09C433.15,-144.56 544.48,-126.47 638.95,-108 644.14,-106.99 649.51,-105.89 654.9,-104.76"/>
<!-- :core:data&#45;&gt;:core:network --> <polygon fill="black" stroke="black" points="655.38,-108.24 664.43,-102.73 653.92,-101.39 655.38,-108.24"/>
<g id="edge4" class="edge"> </g>
<title>:core:data&#45;&gt;:core:network</title> <g id="node7" class="node">
<path fill="none" stroke="black" d="M279.22,-150.22C239.68,-138.58 176.33,-119.95 131.26,-106.7"/> <title>:core:notifications</title>
<polygon fill="black" stroke="black" points="132.26,-103.34 121.68,-103.88 130.28,-110.06 132.26,-103.34"/> <ellipse fill="none" stroke="black" cx="244.95" cy="-90" rx="81.29" ry="18"/>
</g> <text text-anchor="middle" x="244.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<!-- :core:analytics --> </g>
<g id="node6" class="node"> <g id="edge6" class="edge">
<title>:core:analytics</title> <title>:core:data-&gt;:core:notifications</title>
<ellipse fill="none" stroke="black" cx="689.89" cy="-90" rx="64.66" ry="18"/> <path fill="none" stroke="black" d="M309.12,-145.12C298.6,-136.24 285.28,-125.01 273.5,-115.08"/>
<text text-anchor="middle" x="689.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <polygon fill="black" stroke="black" points="275.93,-112.54 266.03,-108.77 271.42,-117.9 275.93,-112.54"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:analytics --> <g id="node8" class="node">
<g id="edge5" class="edge"> <title>:core:model</title>
<title>:core:data&#45;&gt;:core:analytics</title> <ellipse fill="none" stroke="black" cx="244.95" cy="-18" rx="57.16" ry="18"/>
<path fill="none" stroke="black" d="M358.9,-154.18C417.44,-144.73 525.39,-126.69 616.89,-108 621.48,-107.06 626.22,-106.05 630.98,-105.01"/> <text text-anchor="middle" x="244.95" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<polygon fill="black" stroke="black" points="631.59,-108.46 640.59,-102.86 630.07,-101.63 631.59,-108.46"/> </g>
</g> <g id="edge7" class="edge">
<!-- :core:notifications --> <title>:core:database-&gt;:core:model</title>
<g id="node7" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M514.77,-77.69C506.17,-75.76 497.31,-73.8 488.95,-72 410.47,-55.13 390.22,-53.88 311.95,-36 307.67,-35.02 303.24,-33.97 298.79,-32.9"/>
<title>:core:notifications</title> <polygon fill="red" stroke="red" stroke-width="2" points="301.26,-29.9 290.71,-30.91 299.59,-36.7 301.26,-29.9"/>
<ellipse fill="none" stroke="black" cx="235.89" cy="-90" rx="77.97" ry="18"/> </g>
<text text-anchor="middle" x="235.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <g id="edge10" class="edge">
</g> <title>:core:datastore-&gt;:core:common</title>
<!-- :core:data&#45;&gt;:core:notifications --> <path fill="none" stroke="black" d="M361.01,-77.73C352.32,-75.82 343.38,-73.85 334.95,-72 273.33,-58.48 202.89,-43.12 153.77,-32.44"/>
<g id="edge6" class="edge"> <polygon fill="black" stroke="black" points="154.69,-29.05 144.17,-30.35 153.2,-35.89 154.69,-29.05"/>
<title>:core:data&#45;&gt;:core:notifications</title> </g>
<path fill="none" stroke="black" d="M297.74,-145.12C287.7,-136.33 275.01,-125.23 263.74,-115.37"/> <g id="edge9" class="edge">
<polygon fill="black" stroke="black" points="266.06,-112.75 256.23,-108.79 261.45,-118.01 266.06,-112.75"/> <title>:core:datastore-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M376.95,-74.33C351.28,-63.57 316.25,-48.89 288.73,-37.35"/>
<!-- :core:model --> <polygon fill="black" stroke="black" points="290.18,-34.16 279.61,-33.52 287.48,-40.62 290.18,-34.16"/>
<g id="node8" class="node"> </g>
<title>:core:model</title> <g id="node9" class="node">
<ellipse fill="none" stroke="black" cx="235.89" cy="-18" rx="55.45" ry="18"/> <title>:core:datastore-proto</title>
<text text-anchor="middle" x="235.89" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <ellipse fill="none" stroke="black" cx="411.95" cy="-18" rx="91.47" ry="18"/>
</g> <text text-anchor="middle" x="411.95" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<!-- :core:database&#45;&gt;:core:model --> </g>
<g id="edge7" class="edge"> <g id="edge8" class="edge">
<title>:core:database&#45;&gt;:core:model</title> <title>:core:datastore-&gt;:core:datastore-proto</title>
<path fill="none" stroke="red" stroke-width="2" d="M496.02,-77.7C487.65,-75.77 479.02,-73.8 470.89,-72 395.06,-55.19 375.45,-53.98 299.89,-36 296.08,-35.09 292.16,-34.13 288.21,-33.14"/> <path fill="none" stroke="black" d="M411.95,-71.7C411.95,-64.41 411.95,-55.73 411.95,-47.54"/>
<polygon fill="red" stroke="red" stroke-width="2" points="290.61,-30.14 280.06,-31.04 288.87,-36.92 290.61,-30.14"/> <polygon fill="black" stroke="black" points="415.45,-47.62 411.95,-37.62 408.45,-47.62 415.45,-47.62"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:common --> <g id="edge11" class="edge">
<g id="edge10" class="edge"> <title>:core:network-&gt;:core:common</title>
<title>:core:datastore&#45;&gt;:core:common</title> <path fill="none" stroke="black" d="M83.67,-71.7C84.83,-64.32 86.22,-55.52 87.52,-47.25"/>
<path fill="none" stroke="black" d="M347.94,-77.72C339.58,-75.81 330.99,-73.84 322.89,-72 263.62,-58.51 195.9,-43.25 148.43,-32.58"/> <polygon fill="black" stroke="black" points="90.94,-48.02 89.03,-37.6 84.02,-46.93 90.94,-48.02"/>
<polygon fill="black" stroke="black" points="149.42,-29.22 138.89,-30.44 147.88,-36.05 149.42,-29.22"/> </g>
</g> <g id="edge12" class="edge">
<!-- :core:datastore&#45;&gt;:core:model --> <title>:core:network-&gt;:core:model</title>
<g id="edge9" class="edge"> <path fill="none" stroke="black" d="M115.33,-74.33C140.46,-63.6 174.71,-48.98 201.7,-37.46"/>
<title>:core:datastore&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="202.8,-40.8 210.63,-33.65 200.06,-34.36 202.8,-40.8"/>
<path fill="none" stroke="black" d="M363.14,-74.33C338.58,-63.65 305.15,-49.11 278.71,-37.62"/> </g>
<polygon fill="black" stroke="black" points="280.18,-34.44 269.61,-33.66 277.39,-40.86 280.18,-34.44"/> <g id="edge14" class="edge">
</g> <title>:core:notifications-&gt;:core:common</title>
<!-- :core:datastore&#45;proto --> <path fill="none" stroke="black" d="M210.62,-73.29C188.29,-63.07 158.98,-49.66 135.08,-38.73"/>
<g id="node9" class="node"> <polygon fill="black" stroke="black" points="136.79,-35.66 126.24,-34.69 133.88,-42.03 136.79,-35.66"/>
<title>:core:datastore&#45;proto</title> </g>
<ellipse fill="none" stroke="black" cx="396.89" cy="-18" rx="87.69" ry="18"/> <g id="edge13" class="edge">
<text text-anchor="middle" x="396.89" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> <title>:core:notifications-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M244.95,-71.7C244.95,-64.41 244.95,-55.73 244.95,-47.54"/>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto --> <polygon fill="black" stroke="black" points="248.45,-47.62 244.95,-37.62 241.45,-47.62 248.45,-47.62"/>
<g id="edge8" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title> </g>
<path fill="none" stroke="black" d="M396.89,-71.7C396.89,-64.41 396.89,-55.73 396.89,-47.54"/>
<polygon fill="black" stroke="black" points="400.39,-47.62 396.89,-37.62 393.39,-47.62 400.39,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge11" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M80.36,-71.7C81.42,-64.32 82.67,-55.52 83.85,-47.25"/>
<polygon fill="black" stroke="black" points="87.28,-48 85.23,-37.6 80.35,-47.01 87.28,-48"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge12" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M111.01,-74.33C135.11,-63.65 167.92,-49.11 193.87,-37.62"/>
<polygon fill="black" stroke="black" points="195.05,-40.92 202.78,-33.67 192.21,-34.52 195.05,-40.92"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge14" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M202.68,-73.29C181.17,-63.12 152.98,-49.79 129.92,-38.88"/>
<polygon fill="black" stroke="black" points="131.63,-35.82 121.09,-34.7 128.64,-42.14 131.63,-35.82"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge13" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M235.89,-71.7C235.89,-64.41 235.89,-55.73 235.89,-47.54"/>
<polygon fill="black" stroke="black" points="239.39,-47.62 235.89,-37.62 232.39,-47.62 239.39,-47.62"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

@ -1,163 +1,133 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="791pt" height="260pt" viewBox="0.00 0.00 791.30 260.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-256 787.3,-256 787.3,4 -4,4"/>
<svg width="763pt" height="260pt" <g id="node1" class="node">
viewBox="0.00 0.00 762.55 260.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:data-test</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)"> <ellipse fill="none" stroke="black" cx="327.95" cy="-234" rx="65.73" ry="18"/>
<title>G</title> <text text-anchor="middle" x="327.95" y="-229.8" font-family="Times,serif" font-size="14.00">:core:data-test</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-256 758.55,-256 758.55,4 -4,4"/> </g>
<!-- :core:data&#45;test --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:data</title>
<title>:core:data&#45;test</title> <ellipse fill="none" stroke="black" cx="327.95" cy="-162" rx="49.1" ry="18"/>
<ellipse fill="none" stroke="black" cx="315.89" cy="-234" rx="63.12" ry="18"/> <text text-anchor="middle" x="327.95" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<text text-anchor="middle" x="315.89" y="-228.95" font-family="Times,serif" font-size="14.00">:core:data&#45;test</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:data --> <title>:core:data-test-&gt;:core:data</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M327.95,-215.7C327.95,-208.41 327.95,-199.73 327.95,-191.54"/>
<title>:core:data</title> <polygon fill="red" stroke="red" stroke-width="2" points="331.45,-193.13 327.95,-183.13 324.45,-193.13 331.45,-193.13"/>
<ellipse fill="none" stroke="black" cx="315.89" cy="-162" rx="47.26" ry="18"/> </g>
<text text-anchor="middle" x="315.89" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> <g id="node3" class="node">
</g> <title>:core:common</title>
<!-- :core:data&#45;test&#45;&gt;:core:data --> <ellipse fill="none" stroke="black" cx="91.95" cy="-18" rx="66.81" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="91.95" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<title>:core:data&#45;test&#45;&gt;:core:data</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M315.89,-215.7C315.89,-208.41 315.89,-199.73 315.89,-191.54"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="319.39,-193.13 315.89,-183.13 312.39,-193.13 319.39,-193.13"/> <title>:core:data-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M278.66,-160.32C197.49,-158.04 41.21,-148.38 6.95,-108 -3.4,-95.8 -0.81,-85.99 6.95,-72 15.05,-57.42 29,-46.33 43.29,-38.16"/>
<!-- :core:common --> <polygon fill="black" stroke="black" points="44.61,-41.42 51.83,-33.66 41.35,-35.22 44.61,-41.42"/>
<g id="node3" class="node"> </g>
<title>:core:common</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="87.89" cy="-18" rx="65.17" ry="18"/> <title>:core:database</title>
<text text-anchor="middle" x="87.89" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <ellipse fill="none" stroke="black" cx="563.95" cy="-90" rx="66.26" ry="18"/>
</g> <text text-anchor="middle" x="563.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<!-- :core:data&#45;&gt;:core:common --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:core:data&#45;&gt;:core:common</title> <title>:core:data-&gt;:core:database</title>
<path fill="none" stroke="black" d="M268.42,-160.03C190.25,-157.31 39.78,-147.01 6.89,-108 -3.42,-95.77 -0.72,-86.07 6.89,-72 14.54,-57.84 27.81,-46.86 41.41,-38.66"/> <path fill="none" stroke="red" stroke-width="2" d="M365.35,-149.91C404.17,-138.39 465.29,-120.27 509.48,-107.16"/>
<polygon fill="black" stroke="black" points="42.93,-41.82 49.97,-33.91 39.53,-35.7 42.93,-41.82"/> <polygon fill="red" stroke="red" stroke-width="2" points="508.83,-111 517.42,-104.8 506.84,-104.29 508.83,-111"/>
</g> </g>
<!-- :core:database --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:datastore</title>
<title>:core:database</title> <ellipse fill="none" stroke="black" cx="411.95" cy="-90" rx="67.87" ry="18"/>
<ellipse fill="none" stroke="black" cx="543.89" cy="-90" rx="63.63" ry="18"/> <text text-anchor="middle" x="411.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<text text-anchor="middle" x="543.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> </g>
</g> <g id="edge4" class="edge">
<!-- :core:data&#45;&gt;:core:database --> <title>:core:data-&gt;:core:datastore</title>
<g id="edge3" class="edge"> <path fill="none" stroke="black" d="M347.02,-145.12C357.74,-136.18 371.34,-124.85 383.32,-114.86"/>
<title>:core:data&#45;&gt;:core:database</title> <polygon fill="black" stroke="black" points="385.49,-117.61 390.93,-108.52 381.01,-112.23 385.49,-117.61"/>
<path fill="none" stroke="red" stroke-width="2" d="M352.02,-149.91C389.56,-138.38 448.68,-120.23 491.38,-107.12"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="490.71,-110.99 499.24,-104.71 488.65,-104.3 490.71,-110.99"/> <g id="node6" class="node">
</g> <title>:core:network</title>
<!-- :core:datastore --> <ellipse fill="none" stroke="black" cx="80.95" cy="-90" rx="64.66" ry="18"/>
<g id="node5" class="node"> <text text-anchor="middle" x="80.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<title>:core:datastore</title> </g>
<ellipse fill="none" stroke="black" cx="396.89" cy="-90" rx="65.17" ry="18"/> <g id="edge5" class="edge">
<text text-anchor="middle" x="396.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <title>:core:data-&gt;:core:network</title>
</g> <path fill="none" stroke="black" d="M289.9,-150.22C248.69,-138.53 182.56,-119.8 135.75,-106.53"/>
<!-- :core:data&#45;&gt;:core:datastore --> <polygon fill="black" stroke="black" points="136.92,-103.22 126.35,-103.86 135.01,-109.96 136.92,-103.22"/>
<g id="edge4" class="edge"> </g>
<title>:core:data&#45;&gt;:core:datastore</title> <g id="node7" class="node">
<path fill="none" stroke="black" d="M334.27,-145.12C344.61,-136.18 357.73,-124.85 369.28,-114.86"/> <title>:core:analytics</title>
<polygon fill="black" stroke="black" points="371.31,-117.73 376.59,-108.54 366.74,-112.43 371.31,-117.73"/> <ellipse fill="none" stroke="black" cx="715.95" cy="-90" rx="67.34" ry="18"/>
</g> <text text-anchor="middle" x="715.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<!-- :core:network --> </g>
<g id="node6" class="node"> <g id="edge6" class="edge">
<title>:core:network</title> <title>:core:data-&gt;:core:analytics</title>
<ellipse fill="none" stroke="black" cx="77.89" cy="-90" rx="62.1" ry="18"/> <path fill="none" stroke="black" d="M372.63,-154.09C433.15,-144.56 544.48,-126.47 638.95,-108 644.14,-106.99 649.51,-105.89 654.9,-104.76"/>
<text text-anchor="middle" x="77.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <polygon fill="black" stroke="black" points="655.38,-108.24 664.43,-102.73 653.92,-101.39 655.38,-108.24"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:network --> <g id="node8" class="node">
<g id="edge5" class="edge"> <title>:core:notifications</title>
<title>:core:data&#45;&gt;:core:network</title> <ellipse fill="none" stroke="black" cx="244.95" cy="-90" rx="81.29" ry="18"/>
<path fill="none" stroke="black" d="M279.22,-150.22C239.68,-138.58 176.33,-119.95 131.26,-106.7"/> <text text-anchor="middle" x="244.95" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<polygon fill="black" stroke="black" points="132.26,-103.34 121.68,-103.88 130.28,-110.06 132.26,-103.34"/> </g>
</g> <g id="edge7" class="edge">
<!-- :core:analytics --> <title>:core:data-&gt;:core:notifications</title>
<g id="node7" class="node"> <path fill="none" stroke="black" d="M309.12,-145.12C298.6,-136.24 285.28,-125.01 273.5,-115.08"/>
<title>:core:analytics</title> <polygon fill="black" stroke="black" points="275.93,-112.54 266.03,-108.77 271.42,-117.9 275.93,-112.54"/>
<ellipse fill="none" stroke="black" cx="689.89" cy="-90" rx="64.66" ry="18"/> </g>
<text text-anchor="middle" x="689.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <g id="node9" class="node">
</g> <title>:core:model</title>
<!-- :core:data&#45;&gt;:core:analytics --> <ellipse fill="none" stroke="black" cx="244.95" cy="-18" rx="57.16" ry="18"/>
<g id="edge6" class="edge"> <text text-anchor="middle" x="244.95" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<title>:core:data&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="black" d="M358.9,-154.18C417.44,-144.73 525.39,-126.69 616.89,-108 621.48,-107.06 626.22,-106.05 630.98,-105.01"/> <g id="edge8" class="edge">
<polygon fill="black" stroke="black" points="631.59,-108.46 640.59,-102.86 630.07,-101.63 631.59,-108.46"/> <title>:core:database-&gt;:core:model</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M514.77,-77.69C506.17,-75.76 497.31,-73.8 488.95,-72 410.47,-55.13 390.22,-53.88 311.95,-36 307.67,-35.02 303.24,-33.97 298.79,-32.9"/>
<!-- :core:notifications --> <polygon fill="red" stroke="red" stroke-width="2" points="301.26,-29.9 290.71,-30.91 299.59,-36.7 301.26,-29.9"/>
<g id="node8" class="node"> </g>
<title>:core:notifications</title> <g id="edge11" class="edge">
<ellipse fill="none" stroke="black" cx="235.89" cy="-90" rx="77.97" ry="18"/> <title>:core:datastore-&gt;:core:common</title>
<text text-anchor="middle" x="235.89" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <path fill="none" stroke="black" d="M361.01,-77.73C352.32,-75.82 343.38,-73.85 334.95,-72 273.33,-58.48 202.89,-43.12 153.77,-32.44"/>
</g> <polygon fill="black" stroke="black" points="154.69,-29.05 144.17,-30.35 153.2,-35.89 154.69,-29.05"/>
<!-- :core:data&#45;&gt;:core:notifications --> </g>
<g id="edge7" class="edge"> <g id="edge10" class="edge">
<title>:core:data&#45;&gt;:core:notifications</title> <title>:core:datastore-&gt;:core:model</title>
<path fill="none" stroke="black" d="M297.74,-145.12C287.7,-136.33 275.01,-125.23 263.74,-115.37"/> <path fill="none" stroke="black" d="M376.95,-74.33C351.28,-63.57 316.25,-48.89 288.73,-37.35"/>
<polygon fill="black" stroke="black" points="266.06,-112.75 256.23,-108.79 261.45,-118.01 266.06,-112.75"/> <polygon fill="black" stroke="black" points="290.18,-34.16 279.61,-33.52 287.48,-40.62 290.18,-34.16"/>
</g> </g>
<!-- :core:model --> <g id="node10" class="node">
<g id="node9" class="node"> <title>:core:datastore-proto</title>
<title>:core:model</title> <ellipse fill="none" stroke="black" cx="411.95" cy="-18" rx="91.47" ry="18"/>
<ellipse fill="none" stroke="black" cx="235.89" cy="-18" rx="55.45" ry="18"/> <text text-anchor="middle" x="411.95" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<text text-anchor="middle" x="235.89" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> </g>
</g> <g id="edge9" class="edge">
<!-- :core:database&#45;&gt;:core:model --> <title>:core:datastore-&gt;:core:datastore-proto</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M411.95,-71.7C411.95,-64.41 411.95,-55.73 411.95,-47.54"/>
<title>:core:database&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="415.45,-47.62 411.95,-37.62 408.45,-47.62 415.45,-47.62"/>
<path fill="none" stroke="red" stroke-width="2" d="M496.02,-77.7C487.65,-75.77 479.02,-73.8 470.89,-72 395.06,-55.19 375.45,-53.98 299.89,-36 296.08,-35.09 292.16,-34.13 288.21,-33.14"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="290.61,-30.14 280.06,-31.04 288.87,-36.92 290.61,-30.14"/> <g id="edge12" class="edge">
</g> <title>:core:network-&gt;:core:common</title>
<!-- :core:datastore&#45;&gt;:core:common --> <path fill="none" stroke="black" d="M83.67,-71.7C84.83,-64.32 86.22,-55.52 87.52,-47.25"/>
<g id="edge11" class="edge"> <polygon fill="black" stroke="black" points="90.94,-48.02 89.03,-37.6 84.02,-46.93 90.94,-48.02"/>
<title>:core:datastore&#45;&gt;:core:common</title> </g>
<path fill="none" stroke="black" d="M347.94,-77.72C339.58,-75.81 330.99,-73.84 322.89,-72 263.62,-58.51 195.9,-43.25 148.43,-32.58"/> <g id="edge13" class="edge">
<polygon fill="black" stroke="black" points="149.42,-29.22 138.89,-30.44 147.88,-36.05 149.42,-29.22"/> <title>:core:network-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M115.33,-74.33C140.46,-63.6 174.71,-48.98 201.7,-37.46"/>
<!-- :core:datastore&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="202.8,-40.8 210.63,-33.65 200.06,-34.36 202.8,-40.8"/>
<g id="edge10" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:model</title> <g id="edge15" class="edge">
<path fill="none" stroke="black" d="M363.14,-74.33C338.58,-63.65 305.15,-49.11 278.71,-37.62"/> <title>:core:notifications-&gt;:core:common</title>
<polygon fill="black" stroke="black" points="280.18,-34.44 269.61,-33.66 277.39,-40.86 280.18,-34.44"/> <path fill="none" stroke="black" d="M210.62,-73.29C188.29,-63.07 158.98,-49.66 135.08,-38.73"/>
</g> <polygon fill="black" stroke="black" points="136.79,-35.66 126.24,-34.69 133.88,-42.03 136.79,-35.66"/>
<!-- :core:datastore&#45;proto --> </g>
<g id="node10" class="node"> <g id="edge14" class="edge">
<title>:core:datastore&#45;proto</title> <title>:core:notifications-&gt;:core:model</title>
<ellipse fill="none" stroke="black" cx="396.89" cy="-18" rx="87.69" ry="18"/> <path fill="none" stroke="black" d="M244.95,-71.7C244.95,-64.41 244.95,-55.73 244.95,-47.54"/>
<text text-anchor="middle" x="396.89" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> <polygon fill="black" stroke="black" points="248.45,-47.62 244.95,-37.62 241.45,-47.62 248.45,-47.62"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto --> </g>
<g id="edge9" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M396.89,-71.7C396.89,-64.41 396.89,-55.73 396.89,-47.54"/>
<polygon fill="black" stroke="black" points="400.39,-47.62 396.89,-37.62 393.39,-47.62 400.39,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge12" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M80.36,-71.7C81.42,-64.32 82.67,-55.52 83.85,-47.25"/>
<polygon fill="black" stroke="black" points="87.28,-48 85.23,-37.6 80.35,-47.01 87.28,-48"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge13" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M111.01,-74.33C135.11,-63.65 167.92,-49.11 193.87,-37.62"/>
<polygon fill="black" stroke="black" points="195.05,-40.92 202.78,-33.67 192.21,-34.52 195.05,-40.92"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge15" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M202.68,-73.29C181.17,-63.12 152.98,-49.79 129.92,-38.88"/>
<polygon fill="black" stroke="black" points="131.63,-35.82 121.09,-34.7 128.64,-42.14 131.63,-35.82"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge14" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M235.89,-71.7C235.89,-64.41 235.89,-55.73 235.89,-47.54"/>
<polygon fill="black" stroke="black" points="239.39,-47.62 235.89,-37.62 232.39,-47.62 239.39,-47.62"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

@ -1,31 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="141pt" height="116pt" viewBox="0.00 0.00 140.52 116.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-112 136.52,-112 136.52,4 -4,4"/>
<svg width="135pt" height="116pt" <g id="node1" class="node">
viewBox="0.00 0.00 135.27 116.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:database</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)"> <ellipse fill="none" stroke="black" cx="66.26" cy="-90" rx="66.26" ry="18"/>
<title>G</title> <text text-anchor="middle" x="66.26" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-112 131.27,-112 131.27,4 -4,4"/> </g>
<!-- :core:database --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:model</title>
<title>:core:database</title> <ellipse fill="none" stroke="black" cx="66.26" cy="-18" rx="57.16" ry="18"/>
<ellipse fill="none" stroke="black" cx="63.63" cy="-90" rx="63.63" ry="18"/> <text text-anchor="middle" x="66.26" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<text text-anchor="middle" x="63.63" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:model --> <title>:core:database-&gt;:core:model</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M66.26,-71.7C66.26,-64.41 66.26,-55.73 66.26,-47.54"/>
<title>:core:model</title> <polygon fill="red" stroke="red" stroke-width="2" points="69.76,-49.13 66.26,-39.13 62.76,-49.13 69.76,-49.13"/>
<ellipse fill="none" stroke="black" cx="63.63" cy="-18" rx="55.45" ry="18"/> </g>
<text text-anchor="middle" x="63.63" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> </g>
</g>
<!-- :core:database&#45;&gt;:core:model -->
<g id="edge1" class="edge">
<title>:core:database&#45;&gt;:core:model</title>
<path fill="none" stroke="red" stroke-width="2" d="M63.63,-71.7C63.63,-64.41 63.63,-55.73 63.63,-47.54"/>
<polygon fill="red" stroke="red" stroke-width="2" points="67.13,-49.13 63.63,-39.13 60.13,-49.13 67.13,-49.13"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -1,55 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="475pt" height="116pt" viewBox="0.00 0.00 475.29 116.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-112 471.29,-112 471.29,4 -4,4"/>
<svg width="461pt" height="116pt" <g id="node1" class="node">
viewBox="0.00 0.00 460.86 116.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:datastore</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)"> <ellipse fill="none" stroke="black" cx="258.47" cy="-90" rx="67.87" ry="18"/>
<title>G</title> <text text-anchor="middle" x="258.47" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-112 456.86,-112 456.86,4 -4,4"/> </g>
<!-- :core:datastore --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:datastore-proto</title>
<title>:core:datastore</title> <ellipse fill="none" stroke="black" cx="91.47" cy="-18" rx="91.47" ry="18"/>
<ellipse fill="none" stroke="black" cx="248.69" cy="-90" rx="65.17" ry="18"/> <text text-anchor="middle" x="91.47" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<text text-anchor="middle" x="248.69" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:datastore&#45;proto --> <title>:core:datastore-&gt;:core:datastore-proto</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M223.47,-74.33C199.06,-64.1 166.21,-50.32 139.38,-39.08"/>
<title>:core:datastore&#45;proto</title> <polygon fill="red" stroke="red" stroke-width="2" points="142.42,-36.56 131.84,-35.92 139.71,-43.01 142.42,-36.56"/>
<ellipse fill="none" stroke="black" cx="87.69" cy="-18" rx="87.69" ry="18"/> </g>
<text text-anchor="middle" x="87.69" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> <g id="node3" class="node">
</g> <title>:core:model</title>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto --> <ellipse fill="none" stroke="black" cx="258.47" cy="-18" rx="57.16" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="258.47" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M214.94,-74.33C191.52,-64.14 160.02,-50.45 134.22,-39.23"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="137.26,-36.73 126.69,-35.96 134.47,-43.15 137.26,-36.73"/> <title>:core:datastore-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M258.47,-71.7C258.47,-64.41 258.47,-55.73 258.47,-47.54"/>
<!-- :core:model --> <polygon fill="black" stroke="black" points="261.97,-47.62 258.47,-37.62 254.97,-47.62 261.97,-47.62"/>
<g id="node3" class="node"> </g>
<title>:core:model</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="248.69" cy="-18" rx="55.45" ry="18"/> <title>:core:common</title>
<text text-anchor="middle" x="248.69" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <ellipse fill="none" stroke="black" cx="400.47" cy="-18" rx="66.81" ry="18"/>
</g> <text text-anchor="middle" x="400.47" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<!-- :core:datastore&#45;&gt;:core:model --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:datastore-&gt;:core:common</title>
<path fill="none" stroke="black" d="M248.69,-71.7C248.69,-64.41 248.69,-55.73 248.69,-47.54"/> <path fill="none" stroke="black" d="M289.64,-73.64C310.08,-63.56 337.03,-50.28 359.24,-39.33"/>
<polygon fill="black" stroke="black" points="252.19,-47.62 248.69,-37.62 245.19,-47.62 252.19,-47.62"/> <polygon fill="black" stroke="black" points="360.61,-42.56 368.03,-35 357.51,-36.28 360.61,-42.56"/>
</g> </g>
<!-- :core:common --> </g>
<g id="node4" class="node">
<title>:core:common</title>
<ellipse fill="none" stroke="black" cx="387.69" cy="-18" rx="65.17" ry="18"/>
<text text-anchor="middle" x="387.69" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text>
</g>
<!-- :core:datastore&#45;&gt;:core:common -->
<g id="edge3" class="edge">
<title>:core:datastore&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M279.19,-73.64C299.11,-63.61 325.34,-50.4 347.03,-39.48"/>
<polygon fill="black" stroke="black" points="348.55,-42.63 355.91,-35.01 345.4,-36.38 348.55,-42.63"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -1,19 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="191pt" height="44pt" viewBox="0.00 0.00 190.95 44.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-40 186.95,-40 186.95,4 -4,4"/>
<svg width="183pt" height="44pt" <g id="node1" class="node">
viewBox="0.00 0.00 183.38 44.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:datastore-proto</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)"> <ellipse fill="none" stroke="black" cx="91.47" cy="-18" rx="91.47" ry="18"/>
<title>G</title> <text text-anchor="middle" x="91.47" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-40 179.38,-40 179.38,4 -4,4"/> </g>
<!-- :core:datastore&#45;proto --> </g>
<g id="node1" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="87.69" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="87.69" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 893 B

After

Width:  |  Height:  |  Size: 796 B

@ -1,73 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="475pt" height="188pt" viewBox="0.00 0.00 474.97 188.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-184 470.97,-184 470.97,4 -4,4"/>
<svg width="461pt" height="188pt" <g id="node1" class="node">
viewBox="0.00 0.00 460.62 188.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:datastore-test</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)"> <ellipse fill="none" stroke="black" cx="154.81" cy="-162" rx="84.5" ry="18"/>
<title>G</title> <text text-anchor="middle" x="154.81" y="-157.8" font-family="Times,serif" font-size="14.00">:core:datastore-test</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-184 456.62,-184 456.62,4 -4,4"/> </g>
<!-- :core:datastore&#45;test --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:common</title>
<title>:core:datastore&#45;test</title> <ellipse fill="none" stroke="black" cx="66.81" cy="-18" rx="66.81" ry="18"/>
<ellipse fill="none" stroke="black" cx="150.17" cy="-162" rx="81.04" ry="18"/> <text text-anchor="middle" x="66.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<text text-anchor="middle" x="150.17" y="-156.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;test</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:common --> <title>:core:datastore-test-&gt;:core:common</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M144.2,-143.87C129.07,-119.46 101.16,-74.43 83.32,-45.64"/>
<title>:core:common</title> <polygon fill="black" stroke="black" points="86.51,-44.13 78.26,-37.48 80.56,-47.82 86.51,-44.13"/>
<ellipse fill="none" stroke="black" cx="65.17" cy="-18" rx="65.17" ry="18"/> </g>
<text text-anchor="middle" x="65.17" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <g id="node3" class="node">
</g> <title>:core:datastore</title>
<!-- :core:datastore&#45;test&#45;&gt;:core:common --> <ellipse fill="none" stroke="black" cx="222.81" cy="-90" rx="67.87" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="222.81" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<title>:core:datastore&#45;test&#45;&gt;:core:common</title> </g>
<path fill="none" stroke="black" d="M139.92,-143.87C125.37,-119.56 98.58,-74.82 81.34,-46.01"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="84.38,-44.27 76.24,-37.49 78.37,-47.87 84.38,-44.27"/> <title>:core:datastore-test-&gt;:core:datastore</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M171.27,-144.05C179.46,-135.63 189.51,-125.28 198.56,-115.97"/>
<!-- :core:datastore --> <polygon fill="red" stroke="red" stroke-width="2" points="199.94,-119.57 204.4,-109.96 194.92,-114.69 199.94,-119.57"/>
<g id="node3" class="node"> </g>
<title>:core:datastore</title> <g id="edge5" class="edge">
<ellipse fill="none" stroke="black" cx="216.17" cy="-90" rx="65.17" ry="18"/> <title>:core:datastore-&gt;:core:common</title>
<text text-anchor="middle" x="216.17" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <path fill="none" stroke="black" d="M189.35,-73.98C166.32,-63.65 135.5,-49.82 110.53,-38.61"/>
</g> <polygon fill="black" stroke="black" points="112.16,-35.51 101.61,-34.61 109.3,-41.9 112.16,-35.51"/>
<!-- :core:datastore&#45;test&#45;&gt;:core:datastore --> </g>
<g id="edge2" class="edge"> <g id="node4" class="node">
<title>:core:datastore&#45;test&#45;&gt;:core:datastore</title> <title>:core:datastore-proto</title>
<path fill="none" stroke="red" stroke-width="2" d="M166.15,-144.05C174.09,-135.63 183.85,-125.28 192.63,-115.97"/> <ellipse fill="none" stroke="black" cx="242.81" cy="-18" rx="91.47" ry="18"/>
<polygon fill="red" stroke="red" stroke-width="2" points="193.95,-119.67 198.26,-109.99 188.86,-114.87 193.95,-119.67"/> <text text-anchor="middle" x="242.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:common --> <g id="edge3" class="edge">
<g id="edge5" class="edge"> <title>:core:datastore-&gt;:core:datastore-proto</title>
<title>:core:datastore&#45;&gt;:core:common</title> <path fill="none" stroke="red" stroke-width="2" d="M227.76,-71.7C229.89,-64.24 232.44,-55.32 234.82,-46.97"/>
<path fill="none" stroke="black" d="M183.78,-73.98C161.58,-63.7 131.92,-49.94 107.81,-38.77"/> <polygon fill="red" stroke="red" stroke-width="2" points="237.71,-49.59 237.1,-39.01 230.98,-47.67 237.71,-49.59"/>
<polygon fill="black" stroke="black" points="109.43,-35.66 98.88,-34.63 106.48,-42.01 109.43,-35.66"/> </g>
</g> <g id="node5" class="node">
<!-- :core:datastore&#45;proto --> <title>:core:model</title>
<g id="node4" class="node"> <ellipse fill="none" stroke="black" cx="409.81" cy="-18" rx="57.16" ry="18"/>
<title>:core:datastore&#45;proto</title> <text text-anchor="middle" x="409.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<ellipse fill="none" stroke="black" cx="236.17" cy="-18" rx="87.69" ry="18"/> </g>
<text text-anchor="middle" x="236.17" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> <g id="edge4" class="edge">
</g> <title>:core:datastore-&gt;:core:model</title>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto --> <path fill="none" stroke="black" d="M260.66,-74.83C290.25,-63.76 331.54,-48.3 363.18,-36.46"/>
<g id="edge3" class="edge"> <polygon fill="black" stroke="black" points="364.38,-39.75 372.51,-32.96 361.92,-33.19 364.38,-39.75"/>
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M221.11,-71.7C223.25,-64.24 225.79,-55.32 228.18,-46.97"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="231.07,-49.59 230.45,-39.01 224.34,-47.67 231.07,-49.59"/>
</g>
<!-- :core:model -->
<g id="node5" class="node">
<title>:core:model</title>
<ellipse fill="none" stroke="black" cx="397.17" cy="-18" rx="55.45" ry="18"/>
<text text-anchor="middle" x="397.17" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text>
</g>
<!-- :core:datastore&#45;&gt;:core:model -->
<g id="edge4" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M252.8,-74.83C281.44,-63.76 321.41,-48.3 352.03,-36.46"/>
<polygon fill="black" stroke="black" points="352.96,-39.85 361.03,-32.98 350.44,-33.32 352.96,-39.85"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -1,19 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="178pt" height="44pt" viewBox="0.00 0.00 178.11 44.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-40 174.11,-40 174.11,4 -4,4"/>
<svg width="172pt" height="44pt" <g id="node1" class="node">
viewBox="0.00 0.00 172.12 44.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:designsystem</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)"> <ellipse fill="none" stroke="black" cx="85.06" cy="-18" rx="85.06" ry="18"/>
<title>G</title> <text text-anchor="middle" x="85.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-40 168.12,-40 168.12,4 -4,4"/> </g>
<!-- :core:designsystem --> </g>
<g id="node1" class="node">
<title>:core:designsystem</title>
<ellipse fill="none" stroke="black" cx="82.06" cy="-18" rx="82.06" ry="18"/>
<text text-anchor="middle" x="82.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 872 B

After

Width:  |  Height:  |  Size: 790 B

@ -1,169 +1,138 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="857pt" height="260pt" viewBox="0.00 0.00 857.47 260.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-256 853.47,-256 853.47,4 -4,4"/>
<svg width="829pt" height="260pt" <g id="node1" class="node">
viewBox="0.00 0.00 829.46 260.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:domain</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)"> <ellipse fill="none" stroke="black" cx="644.47" cy="-234" rx="61.99" ry="18"/>
<title>G</title> <text text-anchor="middle" x="644.47" y="-229.8" font-family="Times,serif" font-size="14.00">:core:domain</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-256 825.46,-256 825.46,4 -4,4"/> </g>
<!-- :core:domain --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:data</title>
<title>:core:domain</title> <ellipse fill="none" stroke="black" cx="432.47" cy="-162" rx="49.1" ry="18"/>
<ellipse fill="none" stroke="black" cx="623.69" cy="-234" rx="60.05" ry="18"/> <text text-anchor="middle" x="432.47" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<text text-anchor="middle" x="623.69" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:data --> <title>:core:domain-&gt;:core:data</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M604.6,-219.83C568.79,-208.01 516.22,-190.65 478.61,-178.23"/>
<title>:core:data</title> <polygon fill="red" stroke="red" stroke-width="2" points="481.41,-175.47 470.82,-175.66 479.22,-182.12 481.41,-175.47"/>
<ellipse fill="none" stroke="black" cx="418.69" cy="-162" rx="47.26" ry="18"/> </g>
<text text-anchor="middle" x="418.69" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> <g id="node3" class="node">
</g> <title>:core:model</title>
<!-- :core:domain&#45;&gt;:core:data --> <ellipse fill="none" stroke="black" cx="596.47" cy="-18" rx="57.16" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="596.47" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<title>:core:domain&#45;&gt;:core:data</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M585.13,-219.83C550.65,-208.06 500.11,-190.8 463.77,-178.39"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="466.45,-175.61 455.85,-175.69 464.18,-182.23 466.45,-175.61"/> <title>:core:domain-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M684.75,-219.99C755.51,-195.06 889.9,-137.21 837.47,-72 815.89,-45.15 726.29,-31.12 662.67,-24.39"/>
<!-- :core:model --> <polygon fill="black" stroke="black" points="663.32,-20.94 653.01,-23.41 662.61,-27.91 663.32,-20.94"/>
<g id="node3" class="node"> </g>
<title>:core:model</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="576.69" cy="-18" rx="55.45" ry="18"/> <title>:core:common</title>
<text text-anchor="middle" x="576.69" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <ellipse fill="none" stroke="black" cx="350.47" cy="-18" rx="66.81" ry="18"/>
</g> <text text-anchor="middle" x="350.47" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<!-- :core:domain&#45;&gt;:core:model --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:core:domain&#45;&gt;:core:model</title> <title>:core:data-&gt;:core:common</title>
<path fill="none" stroke="black" d="M662.34,-219.86C730.64,-194.61 860.84,-136.09 809.69,-72 788.92,-45.98 702.6,-31.75 641.09,-24.76"/> <path fill="none" stroke="black" d="M384.98,-156.68C325.39,-150.17 228.32,-135.56 206.47,-108 196.54,-95.46 197.32,-85.12 206.47,-72 222.88,-48.48 250.96,-35.36 277.99,-28.07"/>
<polygon fill="black" stroke="black" points="641.74,-21.31 631.42,-23.7 640.98,-28.27 641.74,-21.31"/> <polygon fill="black" stroke="black" points="278.71,-31.49 287.6,-25.73 277.05,-24.69 278.71,-31.49"/>
</g> </g>
<!-- :core:common --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:database</title>
<title>:core:common</title> <ellipse fill="none" stroke="black" cx="762.47" cy="-90" rx="66.26" ry="18"/>
<ellipse fill="none" stroke="black" cx="338.69" cy="-18" rx="65.17" ry="18"/> <text text-anchor="middle" x="762.47" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<text text-anchor="middle" x="338.69" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> </g>
</g> <g id="edge4" class="edge">
<!-- :core:data&#45;&gt;:core:common --> <title>:core:data-&gt;:core:database</title>
<g id="edge3" class="edge"> <path fill="none" stroke="red" stroke-width="2" d="M474.76,-152.37C525.2,-142.03 612.06,-124.08 686.47,-108 691.36,-106.94 696.43,-105.84 701.51,-104.72"/>
<title>:core:data&#45;&gt;:core:common</title> <polygon fill="red" stroke="red" stroke-width="2" points="700.66,-108.49 709.67,-102.91 699.15,-101.66 700.66,-108.49"/>
<path fill="none" stroke="black" d="M373.15,-156.52C315.42,-149.79 220.86,-134.9 199.69,-108 189.8,-95.43 190.61,-85.18 199.69,-72 215.46,-49.11 242.54,-36.1 268.63,-28.71"/> </g>
<polygon fill="black" stroke="black" points="269.43,-32.11 278.25,-26.24 267.69,-25.33 269.43,-32.11"/> <g id="node6" class="node">
</g> <title>:core:datastore</title>
<!-- :core:database --> <ellipse fill="none" stroke="black" cx="91.47" cy="-90" rx="67.87" ry="18"/>
<g id="node5" class="node"> <text text-anchor="middle" x="91.47" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<title>:core:database</title> </g>
<ellipse fill="none" stroke="black" cx="736.69" cy="-90" rx="63.63" ry="18"/> <g id="edge5" class="edge">
<text text-anchor="middle" x="736.69" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <title>:core:data-&gt;:core:datastore</title>
</g> <path fill="none" stroke="black" d="M390.3,-152.4C339.03,-141.95 249.9,-123.74 173.47,-108 167.27,-106.72 160.81,-105.39 154.34,-104.05"/>
<!-- :core:data&#45;&gt;:core:database --> <polygon fill="black" stroke="black" points="155.51,-100.72 145.01,-102.12 154.09,-107.57 155.51,-100.72"/>
<g id="edge4" class="edge"> </g>
<title>:core:data&#45;&gt;:core:database</title> <g id="node7" class="node">
<path fill="none" stroke="red" stroke-width="2" d="M459.48,-152.38C508.14,-142.05 591.93,-124.12 663.69,-108 668.26,-106.97 672.99,-105.9 677.74,-104.81"/> <title>:core:network</title>
<polygon fill="red" stroke="red" stroke-width="2" points="676.9,-108.6 685.86,-102.94 675.33,-101.78 676.9,-108.6"/> <ellipse fill="none" stroke="black" cx="432.47" cy="-90" rx="64.66" ry="18"/>
</g> <text text-anchor="middle" x="432.47" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<!-- :core:datastore --> </g>
<g id="node6" class="node"> <g id="edge6" class="edge">
<title>:core:datastore</title> <title>:core:data-&gt;:core:network</title>
<ellipse fill="none" stroke="black" cx="87.69" cy="-90" rx="65.17" ry="18"/> <path fill="none" stroke="black" d="M432.47,-143.7C432.47,-136.41 432.47,-127.73 432.47,-119.54"/>
<text text-anchor="middle" x="87.69" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <polygon fill="black" stroke="black" points="435.97,-119.62 432.47,-109.62 428.97,-119.62 435.97,-119.62"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:datastore --> <g id="node8" class="node">
<g id="edge5" class="edge"> <title>:core:analytics</title>
<title>:core:data&#45;&gt;:core:datastore</title> <ellipse fill="none" stroke="black" cx="282.47" cy="-90" rx="67.34" ry="18"/>
<path fill="none" stroke="black" d="M378.09,-152.52C328.27,-142.11 241.25,-123.86 166.69,-108 160.86,-106.76 154.79,-105.46 148.71,-104.16"/> <text text-anchor="middle" x="282.47" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<polygon fill="black" stroke="black" points="149.82,-100.82 139.31,-102.14 148.36,-107.66 149.82,-100.82"/> </g>
</g> <g id="edge7" class="edge">
<!-- :core:network --> <title>:core:data-&gt;:core:analytics</title>
<g id="node7" class="node"> <path fill="none" stroke="black" d="M402.84,-147.17C380.65,-136.82 349.98,-122.5 325.15,-110.91"/>
<title>:core:network</title> <polygon fill="black" stroke="black" points="326.82,-107.83 316.28,-106.78 323.86,-114.18 326.82,-107.83"/>
<ellipse fill="none" stroke="black" cx="418.69" cy="-90" rx="62.1" ry="18"/> </g>
<text text-anchor="middle" x="418.69" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <g id="node9" class="node">
</g> <title>:core:notifications</title>
<!-- :core:data&#45;&gt;:core:network --> <ellipse fill="none" stroke="black" cx="596.47" cy="-90" rx="81.29" ry="18"/>
<g id="edge6" class="edge"> <text text-anchor="middle" x="596.47" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<title>:core:data&#45;&gt;:core:network</title> </g>
<path fill="none" stroke="black" d="M418.69,-143.7C418.69,-136.41 418.69,-127.73 418.69,-119.54"/> <g id="edge8" class="edge">
<polygon fill="black" stroke="black" points="422.19,-119.62 418.69,-109.62 415.19,-119.62 422.19,-119.62"/> <title>:core:data-&gt;:core:notifications</title>
</g> <path fill="none" stroke="black" d="M463.71,-147.67C487.99,-137.3 522.07,-122.76 549.62,-111"/>
<!-- :core:analytics --> <polygon fill="black" stroke="black" points="551,-114.22 558.82,-107.07 548.25,-107.78 551,-114.22"/>
<g id="node8" class="node"> </g>
<title>:core:analytics</title> <g id="edge9" class="edge">
<ellipse fill="none" stroke="black" cx="273.69" cy="-90" rx="64.66" ry="18"/> <title>:core:database-&gt;:core:model</title>
<text text-anchor="middle" x="273.69" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <path fill="none" stroke="red" stroke-width="2" d="M727.68,-74.33C702.25,-63.6 667.58,-48.98 640.26,-37.46"/>
</g> <polygon fill="red" stroke="red" stroke-width="2" points="643.18,-34.89 632.6,-34.23 640.46,-41.34 643.18,-34.89"/>
<!-- :core:data&#45;&gt;:core:analytics --> </g>
<g id="edge7" class="edge"> <g id="edge11" class="edge">
<title>:core:data&#45;&gt;:core:analytics</title> <title>:core:datastore-&gt;:core:model</title>
<path fill="none" stroke="black" d="M390.39,-147.34C368.99,-137.01 339.3,-122.67 315.21,-111.05"/> <path fill="none" stroke="black" d="M149.37,-80.31C167.63,-77.6 187.89,-74.64 206.47,-72 321.74,-55.65 456.32,-37.59 533.45,-27.33"/>
<polygon fill="black" stroke="black" points="316.83,-107.94 306.3,-106.74 313.78,-114.24 316.83,-107.94"/> <polygon fill="black" stroke="black" points="533.45,-30.86 542.9,-26.08 532.53,-23.93 533.45,-30.86"/>
</g> </g>
<!-- :core:notifications --> <g id="edge12" class="edge">
<g id="node9" class="node"> <title>:core:datastore-&gt;:core:common</title>
<title>:core:notifications</title> <path fill="none" stroke="black" d="M137.78,-76.49C181.42,-64.69 246.93,-46.99 293.7,-34.34"/>
<ellipse fill="none" stroke="black" cx="576.69" cy="-90" rx="77.97" ry="18"/> <polygon fill="black" stroke="black" points="294.37,-37.79 303.11,-31.8 292.54,-31.03 294.37,-37.79"/>
<text text-anchor="middle" x="576.69" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> </g>
</g> <g id="node10" class="node">
<!-- :core:data&#45;&gt;:core:notifications --> <title>:core:datastore-proto</title>
<g id="edge8" class="edge"> <ellipse fill="none" stroke="black" cx="91.47" cy="-18" rx="91.47" ry="18"/>
<title>:core:data&#45;&gt;:core:notifications</title> <text text-anchor="middle" x="91.47" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<path fill="none" stroke="black" d="M448.78,-147.67C472.18,-137.3 505.01,-122.76 531.55,-111"/> </g>
<polygon fill="black" stroke="black" points="532.64,-114.34 540.37,-107.09 529.81,-107.94 532.64,-114.34"/> <g id="edge10" class="edge">
</g> <title>:core:datastore-&gt;:core:datastore-proto</title>
<!-- :core:database&#45;&gt;:core:model --> <path fill="none" stroke="black" d="M91.47,-71.7C91.47,-64.41 91.47,-55.73 91.47,-47.54"/>
<g id="edge9" class="edge"> <polygon fill="black" stroke="black" points="94.97,-47.62 91.47,-37.62 87.97,-47.62 94.97,-47.62"/>
<title>:core:database&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M703.15,-74.33C678.75,-63.65 645.52,-49.11 619.24,-37.62"/> <g id="edge14" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="622.16,-35.07 611.6,-34.27 619.35,-41.49 622.16,-35.07"/> <title>:core:network-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M466.85,-74.33C491.98,-63.6 526.23,-48.98 553.22,-37.46"/>
<!-- :core:datastore&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="554.32,-40.8 562.15,-33.65 551.58,-34.36 554.32,-40.8"/>
<g id="edge11" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:model</title> <g id="edge13" class="edge">
<path fill="none" stroke="black" d="M143.5,-80.41C161.44,-77.68 181.4,-74.67 199.69,-72 310.88,-55.75 440.67,-37.7 515.31,-27.42"/> <title>:core:network-&gt;:core:common</title>
<polygon fill="black" stroke="black" points="515.43,-30.94 524.86,-26.1 514.47,-24 515.43,-30.94"/> <path fill="none" stroke="black" d="M413.04,-72.41C402.73,-63.61 389.87,-52.63 378.49,-42.92"/>
</g> <polygon fill="black" stroke="black" points="380.8,-40.28 370.92,-36.45 376.25,-45.61 380.8,-40.28"/>
<!-- :core:datastore&#45;&gt;:core:common --> </g>
<g id="edge12" class="edge"> <g id="edge15" class="edge">
<title>:core:datastore&#45;&gt;:core:common</title> <title>:core:notifications-&gt;:core:model</title>
<path fill="none" stroke="black" d="M132.27,-76.57C174.44,-64.81 237.85,-47.12 283.26,-34.46"/> <path fill="none" stroke="black" d="M596.47,-71.7C596.47,-64.41 596.47,-55.73 596.47,-47.54"/>
<polygon fill="black" stroke="black" points="283.95,-37.9 292.64,-31.84 282.07,-31.16 283.95,-37.9"/> <polygon fill="black" stroke="black" points="599.97,-47.62 596.47,-37.62 592.97,-47.62 599.97,-47.62"/>
</g> </g>
<!-- :core:datastore&#45;proto --> <g id="edge16" class="edge">
<g id="node10" class="node"> <title>:core:notifications-&gt;:core:common</title>
<title>:core:datastore&#45;proto</title> <path fill="none" stroke="black" d="M547.87,-75.17C507.13,-63.58 448.93,-47.02 406.29,-34.88"/>
<ellipse fill="none" stroke="black" cx="87.69" cy="-18" rx="87.69" ry="18"/> <polygon fill="black" stroke="black" points="407.28,-31.53 396.7,-32.15 405.36,-38.26 407.28,-31.53"/>
<text text-anchor="middle" x="87.69" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> </g>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge10" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M87.69,-71.7C87.69,-64.41 87.69,-55.73 87.69,-47.54"/>
<polygon fill="black" stroke="black" points="91.19,-47.62 87.69,-37.62 84.19,-47.62 91.19,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge14" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M451.81,-74.33C475.91,-63.65 508.72,-49.11 534.67,-37.62"/>
<polygon fill="black" stroke="black" points="535.85,-40.92 543.58,-33.67 533.01,-34.52 535.85,-40.92"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge13" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M399.73,-72.41C389.67,-63.61 377.12,-52.63 366.03,-42.92"/>
<polygon fill="black" stroke="black" points="368.48,-40.42 358.65,-36.47 363.87,-45.69 368.48,-40.42"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge15" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M576.69,-71.7C576.69,-64.41 576.69,-55.73 576.69,-47.54"/>
<polygon fill="black" stroke="black" points="580.19,-47.62 576.69,-37.62 573.19,-47.62 580.19,-47.62"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge16" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M529.95,-75.25C490.64,-63.69 434.4,-47.15 393.08,-35"/>
<polygon fill="black" stroke="black" points="394.15,-31.66 383.56,-32.2 392.17,-38.38 394.15,-31.66"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

@ -1,19 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="122pt" height="44pt" viewBox="0.00 0.00 122.31 44.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-40 118.31,-40 118.31,4 -4,4"/>
<svg width="119pt" height="44pt" <g id="node1" class="node">
viewBox="0.00 0.00 118.89 44.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:model</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 40)"> <ellipse fill="none" stroke="black" cx="57.16" cy="-18" rx="57.16" ry="18"/>
<title>G</title> <text text-anchor="middle" x="57.16" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-40 114.89,-40 114.89,4 -4,4"/> </g>
<!-- :core:model --> </g>
<g id="node1" class="node">
<title>:core:model</title>
<ellipse fill="none" stroke="black" cx="55.45" cy="-18" rx="55.45" ry="18"/>
<text text-anchor="middle" x="55.45" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 776 B

@ -1,43 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="274pt" height="116pt" viewBox="0.00 0.00 273.97 116.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-112 269.97,-112 269.97,4 -4,4"/>
<svg width="268pt" height="116pt" <g id="node1" class="node">
viewBox="0.00 0.00 267.62 116.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:network</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)"> <ellipse fill="none" stroke="black" cx="137.81" cy="-90" rx="64.66" ry="18"/>
<title>G</title> <text text-anchor="middle" x="137.81" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-112 263.62,-112 263.62,4 -4,4"/> </g>
<!-- :core:network --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:common</title>
<title>:core:network</title> <ellipse fill="none" stroke="black" cx="66.81" cy="-18" rx="66.81" ry="18"/>
<ellipse fill="none" stroke="black" cx="134.17" cy="-90" rx="62.1" ry="18"/> <text text-anchor="middle" x="66.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<text text-anchor="middle" x="134.17" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:common --> <title>:core:network-&gt;:core:common</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M120.99,-72.41C112.23,-63.78 101.36,-53.06 91.66,-43.5"/>
<title>:core:common</title> <polygon fill="red" stroke="red" stroke-width="2" points="95.25,-42.12 85.67,-37.6 90.34,-47.11 95.25,-42.12"/>
<ellipse fill="none" stroke="black" cx="65.17" cy="-18" rx="65.17" ry="18"/> </g>
<text text-anchor="middle" x="65.17" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <g id="node3" class="node">
</g> <title>:core:model</title>
<!-- :core:network&#45;&gt;:core:common --> <ellipse fill="none" stroke="black" cx="208.81" cy="-18" rx="57.16" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="208.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<title>:core:network&#45;&gt;:core:common</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M117.82,-72.41C109.31,-63.78 98.75,-53.06 89.32,-43.5"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="93.04,-42.29 83.53,-37.63 88.06,-47.2 93.04,-42.29"/> <title>:core:network-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M154.64,-72.41C163.39,-63.78 174.27,-53.06 183.97,-43.5"/>
<!-- :core:model --> <polygon fill="black" stroke="black" points="186.37,-46.05 191.03,-36.53 181.45,-41.06 186.37,-46.05"/>
<g id="node3" class="node"> </g>
<title>:core:model</title> </g>
<ellipse fill="none" stroke="black" cx="204.17" cy="-18" rx="55.45" ry="18"/>
<text text-anchor="middle" x="204.17" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge2" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M150.76,-72.41C159.39,-63.78 170.11,-53.06 179.67,-43.5"/>
<polygon fill="black" stroke="black" points="182.03,-46.09 186.63,-36.54 177.08,-41.14 182.03,-46.09"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -1,43 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="274pt" height="116pt" viewBox="0.00 0.00 273.97 116.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-112 269.97,-112 269.97,4 -4,4"/>
<svg width="268pt" height="116pt" <g id="node1" class="node">
viewBox="0.00 0.00 267.62 116.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:notifications</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)"> <ellipse fill="none" stroke="black" cx="128.16" cy="-90" rx="81.29" ry="18"/>
<title>G</title> <text text-anchor="middle" x="128.16" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-112 263.62,-112 263.62,4 -4,4"/> </g>
<!-- :core:notifications --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:model</title>
<title>:core:notifications</title> <ellipse fill="none" stroke="black" cx="57.16" cy="-18" rx="57.16" ry="18"/>
<ellipse fill="none" stroke="black" cx="124.45" cy="-90" rx="77.97" ry="18"/> <text text-anchor="middle" x="57.16" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<text text-anchor="middle" x="124.45" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:model --> <title>:core:notifications-&gt;:core:model</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M110.97,-72.05C102.21,-63.42 91.4,-52.76 81.77,-43.27"/>
<title>:core:model</title> <polygon fill="red" stroke="red" stroke-width="2" points="85.43,-41.96 75.85,-37.43 80.52,-46.95 85.43,-41.96"/>
<ellipse fill="none" stroke="black" cx="55.45" cy="-18" rx="55.45" ry="18"/> </g>
<text text-anchor="middle" x="55.45" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <g id="node3" class="node">
</g> <title>:core:common</title>
<!-- :core:notifications&#45;&gt;:core:model --> <ellipse fill="none" stroke="black" cx="199.16" cy="-18" rx="66.81" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="199.16" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<title>:core:notifications&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M107.74,-72.05C99.23,-63.42 88.72,-52.76 79.37,-43.27"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="83.16,-42.13 73.64,-37.46 78.17,-47.04 83.16,-42.13"/> <title>:core:notifications-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M145.34,-72.05C153.98,-63.54 164.6,-53.07 174.12,-43.68"/>
<!-- :core:common --> <polygon fill="black" stroke="black" points="176.39,-46.36 181.05,-36.85 171.47,-41.38 176.39,-46.36"/>
<g id="node3" class="node"> </g>
<title>:core:common</title> </g>
<ellipse fill="none" stroke="black" cx="194.45" cy="-18" rx="65.17" ry="18"/>
<text text-anchor="middle" x="194.45" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge2" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M141.39,-72.05C149.9,-63.54 160.38,-53.07 169.76,-43.68"/>
<polygon fill="black" stroke="black" points="171.99,-46.41 176.59,-36.86 167.04,-41.46 171.99,-46.41"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -1,31 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="330pt" height="116pt" viewBox="0.00 0.00 329.87 116.00">
<!-- Generated by graphviz version 10.0.1 (20240210.2158) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-112 325.87,-112 325.87,4 -4,4"/>
<svg width="205pt" height="116pt" <g id="node1" class="node">
viewBox="0.00 0.00 204.88 116.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:screenshot-testing</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)"> <ellipse fill="none" stroke="black" cx="151.81" cy="-90" rx="102.74" ry="18"/>
<title>G</title> <text text-anchor="middle" x="151.81" y="-85.8" font-family="Times,serif" font-size="14.00">:core:screenshot-testing</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-112 200.88,-112 200.88,4 -4,4"/> </g>
<!-- :core:screenshot&#45;testing --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:common</title>
<title>:core:screenshot&#45;testing</title> <ellipse fill="none" stroke="black" cx="66.81" cy="-18" rx="66.81" ry="18"/>
<ellipse fill="none" stroke="black" cx="98.44" cy="-90" rx="98.44" ry="18"/> <text text-anchor="middle" x="66.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<text text-anchor="middle" x="98.44" y="-84.95" font-family="Times,serif" font-size="14.00">:core:screenshot&#45;testing</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:designsystem --> <title>:core:screenshot-testing-&gt;:core:common</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M131.24,-72.05C120.51,-63.22 107.22,-52.27 95.49,-42.62"/>
<title>:core:designsystem</title> <polygon fill="red" stroke="red" stroke-width="2" points="99.19,-41.13 89.24,-37.47 94.74,-46.53 99.19,-41.13"/>
<ellipse fill="none" stroke="black" cx="98.44" cy="-18" rx="82.06" ry="18"/> </g>
<text text-anchor="middle" x="98.44" y="-12.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :core:screenshot&#45;testing&#45;&gt;:core:designsystem --> <ellipse fill="none" stroke="black" cx="236.81" cy="-18" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="236.81" y="-13.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:core:screenshot&#45;testing&#45;&gt;:core:designsystem</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M98.44,-71.7C98.44,-64.41 98.44,-55.73 98.44,-47.54"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="101.94,-49.13 98.44,-39.13 94.94,-49.13 101.94,-49.13"/> <title>:core:screenshot-testing-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M172.39,-72.05C183.04,-63.28 196.22,-52.43 207.88,-42.83"/>
</g> <polygon fill="black" stroke="black" points="209.76,-45.81 215.26,-36.75 205.31,-40.41 209.76,-45.81"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -1,187 +1,163 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1056pt" height="260pt" viewBox="0.00 0.00 1055.83 260.00">
<!-- Generated by graphviz version 10.0.1 (20240210.2158) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-256 1051.83,-256 1051.83,4 -4,4"/>
<svg width="832pt" height="260pt" <g id="node1" class="node">
viewBox="0.00 0.00 831.76 260.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:testing</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)"> <ellipse fill="none" stroke="black" cx="639.77" cy="-234" rx="58.77" ry="18"/>
<title>G</title> <text text-anchor="middle" x="639.77" y="-229.8" font-family="Times,serif" font-size="14.00">:core:testing</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-256 827.76,-256 827.76,4 -4,4"/> </g>
<!-- :core:testing --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:analytics</title>
<title>:core:testing</title> <ellipse fill="none" stroke="black" cx="83.77" cy="-90" rx="67.34" ry="18"/>
<ellipse fill="none" stroke="black" cx="349.29" cy="-234" rx="56.47" ry="18"/> <text text-anchor="middle" x="83.77" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<text text-anchor="middle" x="349.29" y="-228.95" font-family="Times,serif" font-size="14.00">:core:testing</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:analytics --> <title>:core:testing-&gt;:core:analytics</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M595.68,-221.74C496.23,-196.34 254.43,-134.58 142.46,-105.99"/>
<title>:core:analytics</title> <polygon fill="black" stroke="black" points="143.41,-102.62 132.86,-103.54 141.68,-109.4 143.41,-102.62"/>
<ellipse fill="none" stroke="black" cx="91.29" cy="-90" rx="64.66" ry="18"/> </g>
<text text-anchor="middle" x="91.29" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <g id="node3" class="node">
</g> <title>:core:data</title>
<!-- :core:testing&#45;&gt;:core:analytics --> <ellipse fill="none" stroke="black" cx="538.77" cy="-162" rx="49.1" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="538.77" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<title>:core:testing&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="black" d="M322.17,-218.07C276.08,-192.7 182.35,-141.12 129.6,-112.08"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="131.39,-109.07 120.94,-107.32 128.02,-115.21 131.39,-109.07"/> <title>:core:testing-&gt;:core:data</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M616.85,-217.12C603.1,-207.59 585.42,-195.33 570.35,-184.89"/>
<!-- :core:common --> <polygon fill="red" stroke="red" stroke-width="2" points="573.6,-182.88 563.39,-180.06 569.62,-188.64 573.6,-182.88"/>
<g id="node3" class="node"> </g>
<title>:core:common</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="349.29" cy="-18" rx="65.17" ry="18"/> <title>:core:model</title>
<text text-anchor="middle" x="349.29" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <ellipse fill="none" stroke="black" cx="438.77" cy="-18" rx="57.16" ry="18"/>
</g> <text text-anchor="middle" x="438.77" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<!-- :core:testing&#45;&gt;:core:common --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:core:testing&#45;&gt;:core:common</title> <title>:core:testing-&gt;:core:model</title>
<path fill="none" stroke="black" d="M296.51,-227.13C183.14,-212.55 -66.81,-168.65 17.29,-72 55.29,-28.33 218.36,-46.49 275.29,-36 280.24,-35.09 285.36,-34.07 290.48,-33"/> <path fill="none" stroke="black" d="M581.6,-230.81C438.88,-224.05 77.96,-198.2 7.77,-108 -2.06,-95.37 -2.97,-83.86 7.77,-72 62.34,-11.76 291.71,-50.03 371.77,-36 376.36,-35.2 381.09,-34.24 385.83,-33.21"/>
<polygon fill="black" stroke="black" points="291.14,-36.44 300.17,-30.91 289.66,-29.6 291.14,-36.44"/> <polygon fill="black" stroke="black" points="386.38,-36.68 395.33,-31.01 384.8,-29.86 386.38,-36.68"/>
</g> </g>
<!-- :core:data --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:notifications</title>
<title>:core:data</title> <ellipse fill="none" stroke="black" cx="740.77" cy="-90" rx="81.29" ry="18"/>
<ellipse fill="none" stroke="black" cx="349.29" cy="-162" rx="47.26" ry="18"/> <text text-anchor="middle" x="740.77" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<text text-anchor="middle" x="349.29" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="edge4" class="edge">
<!-- :core:testing&#45;&gt;:core:data --> <title>:core:testing-&gt;:core:notifications</title>
<g id="edge3" class="edge"> <path fill="none" stroke="black" d="M651.75,-216.15C669.12,-191.73 701.46,-146.26 722.01,-117.38"/>
<title>:core:testing&#45;&gt;:core:data</title> <polygon fill="black" stroke="black" points="724.67,-119.68 727.61,-109.5 718.96,-115.62 724.67,-119.68"/>
<path fill="none" stroke="red" stroke-width="2" d="M349.29,-215.7C349.29,-208.41 349.29,-199.73 349.29,-191.54"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="352.8,-193.13 349.29,-183.13 345.8,-193.13 352.8,-193.13"/> <g id="node6" class="node">
</g> <title>:core:common</title>
<!-- :core:model --> <ellipse fill="none" stroke="black" cx="631.77" cy="-18" rx="66.81" ry="18"/>
<g id="node5" class="node"> <text text-anchor="middle" x="631.77" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<title>:core:model</title> </g>
<ellipse fill="none" stroke="black" cx="566.29" cy="-18" rx="55.45" ry="18"/> <g id="edge5" class="edge">
<text text-anchor="middle" x="566.29" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <title>:core:testing-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M679.13,-220.22C748.7,-195.57 881.51,-138.02 830.77,-72 814.92,-51.38 752.81,-37.08 702.14,-28.57"/>
<!-- :core:testing&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="702.79,-25.13 692.36,-26.99 701.67,-32.04 702.79,-25.13"/>
<g id="edge4" class="edge"> </g>
<title>:core:testing&#45;&gt;:core:model</title> <g id="node7" class="node">
<path fill="none" stroke="black" d="M401.41,-226.88C511.79,-212.75 763.13,-173.88 813.29,-108 862.77,-43.03 722.04,-25.41 633.09,-20.68"/> <title>:core:designsystem</title>
<polygon fill="black" stroke="black" points="633.38,-17.19 623.22,-20.21 633.04,-24.18 633.38,-17.19"/> <ellipse fill="none" stroke="black" cx="962.77" cy="-162" rx="85.06" ry="18"/>
</g> <text text-anchor="middle" x="962.77" y="-157.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<!-- :core:notifications --> </g>
<g id="node6" class="node"> <g id="edge6" class="edge">
<title>:core:notifications</title> <title>:core:testing-&gt;:core:designsystem</title>
<ellipse fill="none" stroke="black" cx="726.29" cy="-90" rx="77.97" ry="18"/> <path fill="none" stroke="black" d="M686.74,-222.82C741.21,-211.02 831.49,-191.45 893.89,-177.93"/>
<text text-anchor="middle" x="726.29" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <polygon fill="black" stroke="black" points="894.31,-181.42 903.34,-175.88 892.82,-174.58 894.31,-181.42"/>
</g> </g>
<!-- :core:testing&#45;&gt;:core:notifications --> <g id="edge11" class="edge">
<g id="edge5" class="edge"> <title>:core:data-&gt;:core:analytics</title>
<title>:core:testing&#45;&gt;:core:notifications</title> <path fill="none" stroke="black" d="M492.32,-155.67C420.83,-147.2 279.63,-129.42 160.77,-108 155.49,-107.05 150.02,-105.99 144.55,-104.88"/>
<path fill="none" stroke="black" d="M384.76,-219.64C452.16,-194.25 598.91,-138.98 676.27,-109.84"/> <polygon fill="black" stroke="black" points="145.35,-101.47 134.84,-102.85 143.92,-108.32 145.35,-101.47"/>
<polygon fill="black" stroke="black" points="677.16,-113.25 685.29,-106.45 674.7,-106.69 677.16,-113.25"/> </g>
</g> <g id="edge12" class="edge">
<!-- :core:data&#45;&gt;:core:analytics --> <title>:core:data-&gt;:core:notifications</title>
<g id="edge10" class="edge"> <path fill="none" stroke="black" d="M573.5,-148.97C604.88,-138.09 651.55,-121.92 687.62,-109.42"/>
<title>:core:data&#45;&gt;:core:analytics</title> <polygon fill="black" stroke="black" points="688.72,-112.74 697.02,-106.16 686.43,-106.13 688.72,-112.74"/>
<path fill="none" stroke="black" d="M311.5,-150.75C268.3,-139.03 197.16,-119.72 147.46,-106.24"/> </g>
<polygon fill="black" stroke="black" points="148.61,-102.92 138.04,-103.68 146.77,-109.68 148.61,-102.92"/> <g id="edge7" class="edge">
</g> <title>:core:data-&gt;:core:common</title>
<!-- :core:data&#45;&gt;:core:common --> <path fill="none" stroke="black" d="M567.46,-147.19C583.19,-138.17 601.69,-124.92 612.77,-108 624.49,-90.11 629.12,-66.26 630.89,-47.75"/>
<g id="edge6" class="edge"> <polygon fill="black" stroke="black" points="634.37,-48.21 631.58,-37.99 627.39,-47.71 634.37,-48.21"/>
<title>:core:data&#45;&gt;:core:common</title> </g>
<path fill="none" stroke="black" d="M303.06,-157.76C269.29,-152.68 225.66,-139.91 203.29,-108 194.11,-94.9 194.11,-85.1 203.29,-72 213.78,-57.04 254.06,-43.07 289.66,-33.23"/> <g id="node8" class="node">
<polygon fill="black" stroke="black" points="290.31,-36.68 299.06,-30.71 288.49,-29.92 290.31,-36.68"/> <title>:core:database</title>
</g> <ellipse fill="none" stroke="black" cx="235.77" cy="-90" rx="66.26" ry="18"/>
<!-- :core:data&#45;&gt;:core:notifications --> <text text-anchor="middle" x="235.77" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<g id="edge11" class="edge"> </g>
<title>:core:data&#45;&gt;:core:notifications</title> <g id="edge8" class="edge">
<path fill="none" stroke="black" d="M391.59,-153.44C448.09,-143.3 551.29,-124.64 639.29,-108 645.15,-106.89 651.23,-105.73 657.33,-104.56"/> <title>:core:data-&gt;:core:database</title>
<polygon fill="black" stroke="black" points="657.65,-108.06 666.8,-102.72 656.32,-101.19 657.65,-108.06"/> <path fill="none" stroke="red" stroke-width="2" d="M497.91,-151.56C446.01,-139.57 356.02,-118.78 296.18,-104.96"/>
</g> <polygon fill="red" stroke="red" stroke-width="2" points="298.49,-101.9 287.95,-103.06 296.91,-108.72 298.49,-101.9"/>
<!-- :core:database --> </g>
<g id="node7" class="node"> <g id="node9" class="node">
<title>:core:database</title> <title>:core:datastore</title>
<ellipse fill="none" stroke="black" cx="566.29" cy="-90" rx="63.63" ry="18"/> <ellipse fill="none" stroke="black" cx="387.77" cy="-90" rx="67.87" ry="18"/>
<text text-anchor="middle" x="566.29" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <text text-anchor="middle" x="387.77" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:database --> <g id="edge9" class="edge">
<g id="edge7" class="edge"> <title>:core:data-&gt;:core:datastore</title>
<title>:core:data&#45;&gt;:core:database</title> <path fill="none" stroke="black" d="M509.3,-147.34C486.99,-137 456.02,-122.64 430.93,-111.01"/>
<path fill="none" stroke="red" stroke-width="2" d="M384.64,-149.6C419.88,-138.23 474.39,-120.65 514.51,-107.71"/> <polygon fill="black" stroke="black" points="432.49,-107.88 421.95,-106.84 429.55,-114.23 432.49,-107.88"/>
<polygon fill="red" stroke="red" stroke-width="2" points="514.09,-111.52 522.53,-105.12 511.94,-104.86 514.09,-111.52"/> </g>
</g> <g id="node10" class="node">
<!-- :core:datastore --> <title>:core:network</title>
<g id="node8" class="node"> <ellipse fill="none" stroke="black" cx="538.77" cy="-90" rx="64.66" ry="18"/>
<title>:core:datastore</title> <text text-anchor="middle" x="538.77" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<ellipse fill="none" stroke="black" cx="277.29" cy="-90" rx="65.17" ry="18"/> </g>
<text text-anchor="middle" x="277.29" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <g id="edge10" class="edge">
</g> <title>:core:data-&gt;:core:network</title>
<!-- :core:data&#45;&gt;:core:datastore --> <path fill="none" stroke="black" d="M538.77,-143.7C538.77,-136.41 538.77,-127.73 538.77,-119.54"/>
<g id="edge8" class="edge"> <polygon fill="black" stroke="black" points="542.27,-119.62 538.77,-109.62 535.27,-119.62 542.27,-119.62"/>
<title>:core:data&#45;&gt;:core:datastore</title> </g>
<path fill="none" stroke="black" d="M332.6,-144.76C323.64,-136.06 312.42,-125.15 302.43,-115.43"/> <g id="edge19" class="edge">
<polygon fill="black" stroke="black" points="305.1,-113.15 295.49,-108.69 300.22,-118.17 305.1,-113.15"/> <title>:core:notifications-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M686.08,-76.32C631.97,-63.78 549.53,-44.67 494.92,-32.01"/>
<!-- :core:network --> <polygon fill="black" stroke="black" points="495.71,-28.61 485.18,-29.76 494.13,-35.43 495.71,-28.61"/>
<g id="node9" class="node"> </g>
<title>:core:network</title> <g id="edge20" class="edge">
<ellipse fill="none" stroke="black" cx="422.29" cy="-90" rx="62.1" ry="18"/> <title>:core:notifications-&gt;:core:common</title>
<text text-anchor="middle" x="422.29" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <path fill="none" stroke="black" d="M715.21,-72.59C700.62,-63.22 682.13,-51.34 666.27,-41.16"/>
</g> <polygon fill="black" stroke="black" points="668.37,-38.34 658.06,-35.89 664.59,-44.23 668.37,-38.34"/>
<!-- :core:data&#45;&gt;:core:network --> </g>
<g id="edge9" class="edge"> <g id="edge13" class="edge">
<title>:core:data&#45;&gt;:core:network</title> <title>:core:database-&gt;:core:model</title>
<path fill="none" stroke="black" d="M366.23,-144.76C375.31,-136.06 386.68,-125.15 396.81,-115.43"/> <path fill="none" stroke="red" stroke-width="2" d="M275.39,-75.34C308.44,-63.94 355.63,-47.67 390.8,-35.54"/>
<polygon fill="black" stroke="black" points="399.06,-118.13 403.86,-108.68 394.22,-113.08 399.06,-118.13"/> <polygon fill="red" stroke="red" stroke-width="2" points="390.13,-39.47 398.44,-32.91 387.85,-32.86 390.13,-39.47"/>
</g> </g>
<!-- :core:notifications&#45;&gt;:core:common --> <g id="edge15" class="edge">
<g id="edge19" class="edge"> <title>:core:datastore-&gt;:core:model</title>
<title>:core:notifications&#45;&gt;:core:common</title> <path fill="none" stroke="black" d="M400.12,-72.05C406.07,-63.89 413.33,-53.91 419.96,-44.82"/>
<path fill="none" stroke="black" d="M668.28,-77.56C658.61,-75.68 648.67,-73.77 639.29,-72 561.93,-57.37 472.83,-41.19 414.03,-30.6"/> <polygon fill="black" stroke="black" points="422.59,-47.16 425.65,-37.01 416.93,-43.03 422.59,-47.16"/>
<polygon fill="black" stroke="black" points="415,-27.22 404.54,-28.89 413.76,-34.1 415,-27.22"/> </g>
</g> <g id="edge16" class="edge">
<!-- :core:notifications&#45;&gt;:core:model --> <title>:core:datastore-&gt;:core:common</title>
<g id="edge18" class="edge"> <path fill="none" stroke="black" d="M432.52,-76.16C473.02,-64.54 532.82,-47.39 576.33,-34.9"/>
<title>:core:notifications&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="577.2,-38.3 585.85,-32.18 575.27,-31.57 577.2,-38.3"/>
<path fill="none" stroke="black" d="M691.18,-73.64C666.85,-62.99 634.32,-48.76 608.56,-37.49"/> </g>
<polygon fill="black" stroke="black" points="610.29,-34.43 599.72,-33.62 607.48,-40.84 610.29,-34.43"/> <g id="node11" class="node">
</g> <title>:core:datastore-proto</title>
<!-- :core:database&#45;&gt;:core:model --> <ellipse fill="none" stroke="black" cx="271.77" cy="-18" rx="91.47" ry="18"/>
<g id="edge12" class="edge"> <text text-anchor="middle" x="271.77" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<title>:core:database&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M566.29,-71.7C566.29,-64.41 566.29,-55.73 566.29,-47.54"/> <g id="edge14" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="569.8,-49.13 566.29,-39.13 562.8,-49.13 569.8,-49.13"/> <title>:core:datastore-&gt;:core:datastore-proto</title>
</g> <path fill="none" stroke="black" d="M361.45,-73.12C345.91,-63.74 326.01,-51.73 308.9,-41.4"/>
<!-- :core:datastore&#45;&gt;:core:common --> <polygon fill="black" stroke="black" points="310.86,-38.5 300.49,-36.33 307.25,-44.5 310.86,-38.5"/>
<g id="edge15" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:common</title> <g id="edge18" class="edge">
<path fill="none" stroke="black" d="M294.36,-72.41C303.32,-63.69 314.48,-52.85 324.4,-43.21"/> <title>:core:network-&gt;:core:model</title>
<polygon fill="black" stroke="black" points="326.54,-46.01 331.27,-36.53 321.66,-40.99 326.54,-46.01"/> <path fill="none" stroke="black" d="M515.58,-72.76C502.23,-63.42 485.26,-51.55 470.68,-41.33"/>
</g> <polygon fill="black" stroke="black" points="472.93,-38.64 462.73,-35.77 468.92,-44.38 472.93,-38.64"/>
<!-- :core:datastore&#45;&gt;:core:model --> </g>
<g id="edge14" class="edge"> <g id="edge17" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:network-&gt;:core:common</title>
<path fill="none" stroke="black" d="M325.02,-77.44C376.36,-65.01 457.86,-45.27 511.71,-32.22"/> <path fill="none" stroke="black" d="M560.34,-72.76C572.46,-63.64 587.79,-52.1 601.14,-42.06"/>
<polygon fill="black" stroke="black" points="512.39,-35.66 521.29,-29.9 510.75,-28.85 512.39,-35.66"/> <polygon fill="black" stroke="black" points="602.9,-45.11 608.79,-36.3 598.69,-39.52 602.9,-45.11"/>
</g> </g>
<!-- :core:datastore&#45;proto --> </g>
<g id="node10" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="178.29" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="178.29" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge13" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M254.33,-72.76C241.52,-63.71 225.35,-52.27 211.21,-42.28"/>
<polygon fill="black" stroke="black" points="213.24,-39.42 203.06,-36.51 209.2,-45.14 213.24,-39.42"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge16" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M404.99,-72.41C395.97,-63.76 384.75,-53 374.76,-43.42"/>
<polygon fill="black" stroke="black" points="377.46,-41.16 367.82,-36.76 372.61,-46.21 377.46,-41.16"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge17" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M453.19,-73.98C474.54,-63.6 503.16,-49.69 526.26,-38.46"/>
<polygon fill="black" stroke="black" points="527.62,-41.69 535.08,-34.17 524.56,-35.4 527.62,-41.69"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

@ -1,55 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="462pt" height="116pt" viewBox="0.00 0.00 462.50 116.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-112 458.5,-112 458.5,4 -4,4"/>
<svg width="449pt" height="116pt" <g id="node1" class="node">
viewBox="0.00 0.00 449.10 116.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:core:ui</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 112)"> <ellipse fill="none" stroke="black" cx="237.34" cy="-90" rx="40.53" ry="18"/>
<title>G</title> <text text-anchor="middle" x="237.34" y="-85.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-112 445.1,-112 445.1,4 -4,4"/> </g>
<!-- :core:ui --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:analytics</title>
<title>:core:ui</title> <ellipse fill="none" stroke="black" cx="67.34" cy="-18" rx="67.34" ry="18"/>
<ellipse fill="none" stroke="black" cx="229.66" cy="-90" rx="39.07" ry="18"/> <text text-anchor="middle" x="67.34" y="-13.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<text text-anchor="middle" x="229.66" y="-84.95" font-family="Times,serif" font-size="14.00">:core:ui</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:analytics --> <title>:core:ui-&gt;:core:analytics</title>
<g id="node2" class="node"> <path fill="none" stroke="red" stroke-width="2" d="M208.5,-77.13C182.4,-66.38 143.52,-50.37 113.16,-37.87"/>
<title>:core:analytics</title> <polygon fill="red" stroke="red" stroke-width="2" points="116.2,-35.33 105.62,-34.76 113.53,-41.8 116.2,-35.33"/>
<ellipse fill="none" stroke="black" cx="64.66" cy="-18" rx="64.66" ry="18"/> </g>
<text text-anchor="middle" x="64.66" y="-12.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :core:ui&#45;&gt;:core:analytics --> <ellipse fill="none" stroke="black" cx="237.34" cy="-18" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="237.34" y="-13.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:core:ui&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M201.67,-77.13C176.45,-66.43 138.92,-50.51 109.52,-38.03"/> <g id="edge2" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="112.45,-35.47 101.88,-34.79 109.72,-41.92 112.45,-35.47"/> <title>:core:ui-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M237.34,-71.7C237.34,-64.41 237.34,-55.73 237.34,-47.54"/>
<!-- :core:designsystem --> <polygon fill="black" stroke="black" points="240.84,-47.62 237.34,-37.62 233.84,-47.62 240.84,-47.62"/>
<g id="node3" class="node"> </g>
<title>:core:designsystem</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="229.66" cy="-18" rx="82.06" ry="18"/> <title>:core:model</title>
<text text-anchor="middle" x="229.66" y="-12.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <ellipse fill="none" stroke="black" cx="397.34" cy="-18" rx="57.16" ry="18"/>
</g> <text text-anchor="middle" x="397.34" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<!-- :core:ui&#45;&gt;:core:designsystem --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:core:ui&#45;&gt;:core:designsystem</title> <title>:core:ui-&gt;:core:model</title>
<path fill="none" stroke="black" d="M229.66,-71.7C229.66,-64.41 229.66,-55.73 229.66,-47.54"/> <path fill="none" stroke="black" d="M265.58,-76.65C290.24,-65.86 326.4,-50.04 354.6,-37.7"/>
<polygon fill="black" stroke="black" points="233.16,-47.62 229.66,-37.62 226.16,-47.62 233.16,-47.62"/> <polygon fill="black" stroke="black" points="355.84,-40.98 363.6,-33.76 353.03,-34.57 355.84,-40.98"/>
</g> </g>
<!-- :core:model --> </g>
<g id="node4" class="node">
<title>:core:model</title>
<ellipse fill="none" stroke="black" cx="385.66" cy="-18" rx="55.45" ry="18"/>
<text text-anchor="middle" x="385.66" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text>
</g>
<!-- :core:ui&#45;&gt;:core:model -->
<g id="edge3" class="edge">
<title>:core:ui&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M256.83,-76.81C280.83,-66.04 316.19,-50.17 343.8,-37.78"/>
<polygon fill="black" stroke="black" points="344.89,-41.13 352.58,-33.84 342.02,-34.74 344.89,-41.13"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -1,205 +1,168 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1064pt" height="260pt" viewBox="0.00 0.00 1063.53 260.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-256 1059.53,-256 1059.53,4 -4,4"/>
<svg width="1028pt" height="260pt" <g id="node1" class="node">
viewBox="0.00 0.00 1027.75 260.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:feature:bookmarks</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)"> <ellipse fill="none" stroke="black" cx="198.06" cy="-234" rx="86.12" ry="18"/>
<title>G</title> <text text-anchor="middle" x="198.06" y="-229.8" font-family="Times,serif" font-size="14.00">:feature:bookmarks</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-256 1023.75,-256 1023.75,4 -4,4"/> </g>
<!-- :feature:bookmarks --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:ui</title>
<title>:feature:bookmarks</title> <ellipse fill="none" stroke="black" cx="198.06" cy="-162" rx="40.53" ry="18"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-234" rx="83.08" ry="18"/> <text text-anchor="middle" x="198.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<text text-anchor="middle" x="192.06" y="-228.95" font-family="Times,serif" font-size="14.00">:feature:bookmarks</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:ui --> <title>:feature:bookmarks-&gt;:core:ui</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M198.06,-215.7C198.06,-208.41 198.06,-199.73 198.06,-191.54"/>
<title>:core:ui</title> <polygon fill="black" stroke="black" points="201.56,-191.62 198.06,-181.62 194.56,-191.62 201.56,-191.62"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-162" rx="39.07" ry="18"/> </g>
<text text-anchor="middle" x="192.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :feature:bookmarks&#45;&gt;:core:ui --> <ellipse fill="none" stroke="black" cx="85.06" cy="-90" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="85.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:feature:bookmarks&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M192.06,-215.7C192.06,-208.41 192.06,-199.73 192.06,-191.54"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="195.56,-191.62 192.06,-181.62 188.56,-191.62 195.56,-191.62"/> <title>:feature:bookmarks-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M180.75,-215.9C170.82,-205.78 158.32,-192.53 148.06,-180 131.56,-159.86 114.61,-135.67 102.45,-117.6"/>
<!-- :core:designsystem --> <polygon fill="black" stroke="black" points="105.52,-115.89 97.06,-109.51 99.69,-119.77 105.52,-115.89"/>
<g id="node3" class="node"> </g>
<title>:core:designsystem</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="82.06" cy="-90" rx="82.06" ry="18"/> <title>:core:data</title>
<text text-anchor="middle" x="82.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <ellipse fill="none" stroke="black" cx="611.06" cy="-162" rx="49.1" ry="18"/>
</g> <text text-anchor="middle" x="611.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<!-- :feature:bookmarks&#45;&gt;:core:designsystem --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:feature:bookmarks&#45;&gt;:core:designsystem</title> <title>:feature:bookmarks-&gt;:core:data</title>
<path fill="none" stroke="black" d="M175.93,-216.3C166.33,-206.1 154.11,-192.63 144.06,-180 128.01,-159.83 111.39,-135.78 99.41,-117.77"/> <path fill="none" stroke="red" stroke-width="2" d="M263.5,-221.91C344.3,-208.21 480.31,-185.16 556,-172.33"/>
<polygon fill="black" stroke="black" points="102.35,-115.88 93.93,-109.46 96.51,-119.73 102.35,-115.88"/> <polygon fill="red" stroke="red" stroke-width="2" points="554.91,-176.07 564.18,-170.94 553.74,-169.17 554.91,-176.07"/>
</g> </g>
<!-- :core:data --> <g id="edge5" class="edge">
<g id="node4" class="node"> <title>:core:ui-&gt;:core:designsystem</title>
<title>:core:data</title> <path fill="none" stroke="black" d="M175.19,-146.83C159.63,-137.19 138.71,-124.24 120.95,-113.23"/>
<ellipse fill="none" stroke="black" cx="591.06" cy="-162" rx="47.26" ry="18"/> <polygon fill="black" stroke="black" points="123.09,-110.44 112.74,-108.15 119.4,-116.39 123.09,-110.44"/>
<text text-anchor="middle" x="591.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="node5" class="node">
<!-- :feature:bookmarks&#45;&gt;:core:data --> <title>:core:analytics</title>
<g id="edge3" class="edge"> <ellipse fill="none" stroke="black" cx="293.06" cy="-90" rx="67.34" ry="18"/>
<title>:feature:bookmarks&#45;&gt;:core:data</title> <text text-anchor="middle" x="293.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<path fill="none" stroke="red" stroke-width="2" d="M255.28,-221.91C333.19,-208.24 464.2,-185.26 537.42,-172.41"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="536.43,-176.14 545.68,-170.96 535.22,-169.24 536.43,-176.14"/> <g id="edge4" class="edge">
</g> <title>:core:ui-&gt;:core:analytics</title>
<!-- :core:ui&#45;&gt;:core:designsystem --> <path fill="none" stroke="black" d="M218.2,-146.15C230.89,-136.81 247.53,-124.54 261.9,-113.96"/>
<g id="edge5" class="edge"> <polygon fill="black" stroke="black" points="263.76,-116.94 269.73,-108.19 259.6,-111.3 263.76,-116.94"/>
<title>:core:ui&#45;&gt;:core:designsystem</title> </g>
<path fill="none" stroke="black" d="M169.8,-146.83C154.65,-137.19 134.29,-124.24 117,-113.23"/> <g id="node6" class="node">
<polygon fill="black" stroke="black" points="119.35,-110.58 109.04,-108.17 115.59,-116.49 119.35,-110.58"/> <title>:core:model</title>
</g> <ellipse fill="none" stroke="black" cx="611.06" cy="-18" rx="57.16" ry="18"/>
<!-- :core:analytics --> <text text-anchor="middle" x="611.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<g id="node5" class="node"> </g>
<title>:core:analytics</title> <g id="edge6" class="edge">
<ellipse fill="none" stroke="black" cx="285.06" cy="-90" rx="64.66" ry="18"/> <title>:core:ui-&gt;:core:model</title>
<text text-anchor="middle" x="285.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <path fill="none" stroke="black" d="M196.38,-143.8C195.44,-123.51 197.35,-90.25 217.06,-72 263.07,-29.38 442.34,-20.56 542.46,-19.03"/>
</g> <polygon fill="black" stroke="black" points="542.2,-22.54 552.15,-18.91 542.11,-15.54 542.2,-22.54"/>
<!-- :core:ui&#45;&gt;:core:analytics --> </g>
<g id="edge4" class="edge"> <g id="edge11" class="edge">
<title>:core:ui&#45;&gt;:core:analytics</title> <title>:core:data-&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M211.78,-146.15C224.2,-136.81 240.49,-124.54 254.56,-113.96"/> <path fill="none" stroke="black" d="M569.69,-151.91C521.68,-141.37 440.13,-123.44 370.06,-108 364.98,-106.88 359.71,-105.72 354.42,-104.55"/>
<polygon fill="black" stroke="black" points="256.32,-117.01 262.21,-108.2 252.11,-111.42 256.32,-117.01"/> <polygon fill="black" stroke="black" points="355.58,-101.23 345.07,-102.49 354.08,-108.06 355.58,-101.23"/>
</g> </g>
<!-- :core:model --> <g id="node7" class="node">
<g id="node6" class="node"> <title>:core:common</title>
<title>:core:model</title> <ellipse fill="none" stroke="black" cx="781.06" cy="-18" rx="66.81" ry="18"/>
<ellipse fill="none" stroke="black" cx="591.06" cy="-18" rx="55.45" ry="18"/> <text text-anchor="middle" x="781.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<text text-anchor="middle" x="591.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> </g>
</g> <g id="edge7" class="edge">
<!-- :core:ui&#45;&gt;:core:model --> <title>:core:data-&gt;:core:common</title>
<g id="edge6" class="edge"> <path fill="none" stroke="black" d="M658.9,-157.27C721.41,-151.3 825.69,-137.15 849.06,-108 859.07,-95.52 856.08,-86.38 849.06,-72 842.9,-59.39 832.13,-48.91 820.96,-40.69"/>
<title>:core:ui&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="823.06,-37.88 812.82,-35.17 819.13,-43.68 823.06,-37.88"/>
<path fill="none" stroke="black" d="M190.4,-143.81C189.47,-123.54 191.4,-90.3 211.06,-72 255.22,-30.9 427.13,-21.43 523.91,-19.4"/> </g>
<polygon fill="black" stroke="black" points="523.87,-22.9 533.81,-19.22 523.74,-15.9 523.87,-22.9"/> <g id="node8" class="node">
</g> <title>:core:database</title>
<!-- :core:data&#45;&gt;:core:analytics --> <ellipse fill="none" stroke="black" cx="445.06" cy="-90" rx="66.26" ry="18"/>
<g id="edge11" class="edge"> <text text-anchor="middle" x="445.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<title>:core:data&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="black" d="M551.05,-151.97C504.63,-141.47 425.78,-123.59 358.06,-108 353.57,-106.97 348.92,-105.89 344.24,-104.81"/> <g id="edge8" class="edge">
<polygon fill="black" stroke="black" points="345.36,-101.48 334.82,-102.62 343.78,-108.29 345.36,-101.48"/> <title>:core:data-&gt;:core:database</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M579.83,-147.83C554.6,-137.19 518.74,-122.07 490.35,-110.1"/>
<!-- :core:common --> <polygon fill="red" stroke="red" stroke-width="2" points="493.23,-107.52 482.66,-106.86 490.51,-113.97 493.23,-107.52"/>
<g id="node7" class="node"> </g>
<title>:core:common</title> <g id="node9" class="node">
<ellipse fill="none" stroke="black" cx="755.06" cy="-18" rx="65.17" ry="18"/> <title>:core:datastore</title>
<text text-anchor="middle" x="755.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <ellipse fill="none" stroke="black" cx="964.06" cy="-90" rx="67.87" ry="18"/>
</g> <text text-anchor="middle" x="964.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<!-- :core:data&#45;&gt;:core:common --> </g>
<g id="edge7" class="edge"> <g id="edge9" class="edge">
<title>:core:data&#45;&gt;:core:common</title> <title>:core:data-&gt;:core:datastore</title>
<path fill="none" stroke="black" d="M636.86,-157.02C697,-150.74 797.62,-136.23 820.06,-108 830.02,-95.48 826.92,-86.45 820.06,-72 814.21,-59.69 803.96,-49.3 793.29,-41.07"/> <path fill="none" stroke="black" d="M653.8,-152.8C707.23,-142.5 801.46,-124.24 882.06,-108 888.27,-106.75 894.74,-105.43 901.2,-104.11"/>
<polygon fill="black" stroke="black" points="795.33,-38.22 785.15,-35.27 791.27,-43.92 795.33,-38.22"/> <polygon fill="black" stroke="black" points="901.45,-107.63 910.54,-102.19 900.04,-100.77 901.45,-107.63"/>
</g> </g>
<!-- :core:database --> <g id="node10" class="node">
<g id="node8" class="node"> <title>:core:network</title>
<title>:core:database</title> <ellipse fill="none" stroke="black" cx="775.06" cy="-90" rx="64.66" ry="18"/>
<ellipse fill="none" stroke="black" cx="431.06" cy="-90" rx="63.63" ry="18"/> <text text-anchor="middle" x="775.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<text text-anchor="middle" x="431.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> </g>
</g> <g id="edge10" class="edge">
<!-- :core:data&#45;&gt;:core:database --> <title>:core:data-&gt;:core:network</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M642.29,-147.67C667.26,-137.01 702.58,-121.93 730.52,-110.01"/>
<title>:core:data&#45;&gt;:core:database</title> <polygon fill="black" stroke="black" points="731.61,-113.35 739.43,-106.2 728.86,-106.91 731.61,-113.35"/>
<path fill="none" stroke="red" stroke-width="2" d="M560.97,-147.83C536.75,-137.24 502.38,-122.2 475.07,-110.26"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="477.95,-107.7 467.39,-106.89 475.15,-114.11 477.95,-107.7"/> <g id="node11" class="node">
</g> <title>:core:notifications</title>
<!-- :core:datastore --> <ellipse fill="none" stroke="black" cx="611.06" cy="-90" rx="81.29" ry="18"/>
<g id="node9" class="node"> <text text-anchor="middle" x="611.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<title>:core:datastore</title> </g>
<ellipse fill="none" stroke="black" cx="932.06" cy="-90" rx="65.17" ry="18"/> <g id="edge12" class="edge">
<text text-anchor="middle" x="932.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <title>:core:data-&gt;:core:notifications</title>
</g> <path fill="none" stroke="black" d="M611.06,-143.7C611.06,-136.41 611.06,-127.73 611.06,-119.54"/>
<!-- :core:data&#45;&gt;:core:datastore --> <polygon fill="black" stroke="black" points="614.56,-119.62 611.06,-109.62 607.56,-119.62 614.56,-119.62"/>
<g id="edge9" class="edge"> </g>
<title>:core:data&#45;&gt;:core:datastore</title> <g id="edge13" class="edge">
<path fill="none" stroke="black" d="M632.39,-152.8C684.04,-142.52 775.15,-124.26 853.06,-108 858.9,-106.78 864.97,-105.5 871.05,-104.21"/> <title>:core:database-&gt;:core:model</title>
<polygon fill="black" stroke="black" points="871.4,-107.71 880.45,-102.2 869.94,-100.87 871.4,-107.71"/> <path fill="none" stroke="red" stroke-width="2" d="M479.86,-74.33C505.29,-63.6 539.96,-48.98 567.27,-37.46"/>
</g> <polygon fill="red" stroke="red" stroke-width="2" points="567.08,-41.34 574.93,-34.23 564.36,-34.89 567.08,-41.34"/>
<!-- :core:network --> </g>
<g id="node10" class="node"> <g id="edge15" class="edge">
<title>:core:network</title> <title>:core:datastore-&gt;:core:model</title>
<ellipse fill="none" stroke="black" cx="749.06" cy="-90" rx="62.1" ry="18"/> <path fill="none" stroke="black" d="M910.83,-78.44C846.01,-65.59 736.89,-43.95 669.71,-30.63"/>
<text text-anchor="middle" x="749.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <polygon fill="black" stroke="black" points="670.46,-27.21 659.97,-28.7 669.1,-34.08 670.46,-27.21"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:network --> <g id="edge16" class="edge">
<g id="edge10" class="edge"> <title>:core:datastore-&gt;:core:common</title>
<title>:core:data&#45;&gt;:core:network</title> <path fill="none" stroke="black" d="M926.58,-74.67C898.33,-63.86 859.38,-48.96 828.88,-37.29"/>
<path fill="none" stroke="black" d="M621.15,-147.67C645.1,-137.06 678.94,-122.07 705.79,-110.17"/> <polygon fill="black" stroke="black" points="830.49,-34.16 819.9,-33.86 827.98,-40.7 830.49,-34.16"/>
<polygon fill="black" stroke="black" points="706.97,-113.47 714.7,-106.22 704.14,-107.07 706.97,-113.47"/> </g>
</g> <g id="node12" class="node">
<!-- :core:notifications --> <title>:core:datastore-proto</title>
<g id="node11" class="node"> <ellipse fill="none" stroke="black" cx="964.06" cy="-18" rx="91.47" ry="18"/>
<title>:core:notifications</title> <text text-anchor="middle" x="964.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<ellipse fill="none" stroke="black" cx="591.06" cy="-90" rx="77.97" ry="18"/> </g>
<text text-anchor="middle" x="591.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <g id="edge14" class="edge">
</g> <title>:core:datastore-&gt;:core:datastore-proto</title>
<!-- :core:data&#45;&gt;:core:notifications --> <path fill="none" stroke="black" d="M964.06,-71.7C964.06,-64.41 964.06,-55.73 964.06,-47.54"/>
<g id="edge12" class="edge"> <polygon fill="black" stroke="black" points="967.56,-47.62 964.06,-37.62 960.56,-47.62 967.56,-47.62"/>
<title>:core:data&#45;&gt;:core:notifications</title> </g>
<path fill="none" stroke="black" d="M591.06,-143.7C591.06,-136.41 591.06,-127.73 591.06,-119.54"/> <g id="edge18" class="edge">
<polygon fill="black" stroke="black" points="594.56,-119.62 591.06,-109.62 587.56,-119.62 594.56,-119.62"/> <title>:core:network-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M740.68,-74.33C715.55,-63.6 681.3,-48.98 654.32,-37.46"/>
<!-- :core:database&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="655.96,-34.36 645.39,-33.65 653.21,-40.8 655.96,-34.36"/>
<g id="edge13" class="edge"> </g>
<title>:core:database&#45;&gt;:core:model</title> <g id="edge17" class="edge">
<path fill="none" stroke="red" stroke-width="2" d="M464.6,-74.33C489,-63.65 522.23,-49.11 548.51,-37.62"/> <title>:core:network-&gt;:core:common</title>
<polygon fill="red" stroke="red" stroke-width="2" points="548.4,-41.49 556.15,-34.27 545.59,-35.07 548.4,-41.49"/> <path fill="none" stroke="black" d="M776.54,-71.7C777.17,-64.41 777.91,-55.73 778.61,-47.54"/>
</g> <polygon fill="black" stroke="black" points="782.1,-47.87 779.46,-37.61 775.12,-47.28 782.1,-47.87"/>
<!-- :core:datastore&#45;&gt;:core:model --> </g>
<g id="edge15" class="edge"> <g id="edge19" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:notifications-&gt;:core:model</title>
<path fill="none" stroke="black" d="M881.01,-78.52C818.61,-65.71 713.32,-44.1 648.25,-30.74"/> <path fill="none" stroke="black" d="M611.06,-71.7C611.06,-64.41 611.06,-55.73 611.06,-47.54"/>
<polygon fill="black" stroke="black" points="648.97,-27.31 638.47,-28.73 647.56,-34.17 648.97,-27.31"/> <polygon fill="black" stroke="black" points="614.56,-47.62 611.06,-37.62 607.56,-47.62 614.56,-47.62"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:common --> <g id="edge20" class="edge">
<g id="edge16" class="edge"> <title>:core:notifications-&gt;:core:common</title>
<title>:core:datastore&#45;&gt;:core:common</title> <path fill="none" stroke="black" d="M648.36,-73.64C673.9,-63.12 707.94,-49.11 735.14,-37.91"/>
<path fill="none" stroke="black" d="M895.81,-74.67C868.61,-63.91 831.14,-49.09 801.71,-37.45"/> <polygon fill="black" stroke="black" points="736.27,-41.23 744.18,-34.18 733.6,-34.76 736.27,-41.23"/>
<polygon fill="black" stroke="black" points="803.25,-34.29 792.66,-33.87 800.68,-40.8 803.25,-34.29"/> </g>
</g> </g>
<!-- :core:datastore&#45;proto -->
<g id="node12" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="932.06" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="932.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge14" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M932.06,-71.7C932.06,-64.41 932.06,-55.73 932.06,-47.54"/>
<polygon fill="black" stroke="black" points="935.56,-47.62 932.06,-37.62 928.56,-47.62 935.56,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge18" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M715.94,-74.33C691.84,-63.65 659.03,-49.11 633.08,-37.62"/>
<polygon fill="black" stroke="black" points="634.74,-34.52 624.17,-33.67 631.9,-40.92 634.74,-34.52"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge17" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M750.54,-71.7C751.17,-64.41 751.91,-55.73 752.61,-47.54"/>
<polygon fill="black" stroke="black" points="756.1,-47.87 753.46,-37.61 749.12,-47.28 756.1,-47.87"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge19" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M591.06,-71.7C591.06,-64.41 591.06,-55.73 591.06,-47.54"/>
<polygon fill="black" stroke="black" points="594.56,-47.62 591.06,-37.62 587.56,-47.62 594.56,-47.62"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge20" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M627.05,-73.64C651.5,-63.2 684.01,-49.33 710.15,-38.17"/>
<polygon fill="black" stroke="black" points="711.34,-41.47 719.17,-34.32 708.59,-35.03 711.34,-41.47"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

@ -1,229 +1,188 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1108pt" height="332pt" viewBox="0.00 0.00 1107.53 332.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-328 1103.53,-328 1103.53,4 -4,4"/>
<svg width="1073pt" height="332pt" <g id="node1" class="node">
viewBox="0.00 0.00 1072.75 332.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:feature:foryou</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)"> <ellipse fill="none" stroke="black" cx="258.06" cy="-306" rx="68.95" ry="18"/>
<title>G</title> <text text-anchor="middle" x="258.06" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:foryou</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-328 1068.75,-328 1068.75,4 -4,4"/> </g>
<!-- :feature:foryou --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:ui</title>
<title>:feature:foryou</title> <ellipse fill="none" stroke="black" cx="198.06" cy="-234" rx="40.53" ry="18"/>
<ellipse fill="none" stroke="black" cx="250.06" cy="-306" rx="66.19" ry="18"/> <text text-anchor="middle" x="198.06" y="-229.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<text text-anchor="middle" x="250.06" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:foryou</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:ui --> <title>:feature:foryou-&gt;:core:ui</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M243.53,-288.05C236.28,-279.59 227.36,-269.19 219.35,-259.84"/>
<title>:core:ui</title> <polygon fill="black" stroke="black" points="222.19,-257.77 213.02,-252.46 216.87,-262.33 222.19,-257.77"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-234" rx="39.07" ry="18"/> </g>
<text text-anchor="middle" x="192.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :feature:foryou&#45;&gt;:core:ui --> <ellipse fill="none" stroke="black" cx="85.06" cy="-162" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="85.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:feature:foryou&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M236.02,-288.05C229.08,-279.68 220.57,-269.4 212.89,-260.13"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="215.61,-257.94 206.54,-252.47 210.22,-262.41 215.61,-257.94"/> <title>:feature:foryou-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M217.28,-291.11C195.21,-282.25 168.37,-269.18 148.06,-252 127.69,-234.78 110.66,-209.55 99.46,-190.35"/>
<!-- :core:designsystem --> <polygon fill="black" stroke="black" points="102.55,-188.71 94.6,-181.71 96.45,-192.14 102.55,-188.71"/>
<g id="node3" class="node"> </g>
<title>:core:designsystem</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="82.06" cy="-162" rx="82.06" ry="18"/> <title>:core:data</title>
<text text-anchor="middle" x="82.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <ellipse fill="none" stroke="black" cx="585.06" cy="-162" rx="49.1" ry="18"/>
</g> <text text-anchor="middle" x="585.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<!-- :feature:foryou&#45;&gt;:core:designsystem --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:feature:foryou&#45;&gt;:core:designsystem</title> <title>:feature:foryou-&gt;:core:data</title>
<path fill="none" stroke="black" d="M211.24,-291.1C189.86,-282.17 163.75,-269.02 144.06,-252 123.99,-234.64 107.23,-209.43 96.22,-190.27"/> <path fill="none" stroke="black" d="M295.52,-290.49C322.04,-280.09 358.39,-265.57 390.06,-252 444.42,-228.7 506.44,-200.03 545.66,-181.63"/>
<polygon fill="black" stroke="black" points="99.35,-188.7 91.44,-181.66 93.23,-192.1 99.35,-188.7"/> <polygon fill="black" stroke="black" points="546.91,-184.91 554.47,-177.49 543.94,-178.57 546.91,-184.91"/>
</g> </g>
<!-- :core:data --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:domain</title>
<title>:core:data</title> <ellipse fill="none" stroke="black" cx="319.06" cy="-234" rx="61.99" ry="18"/>
<ellipse fill="none" stroke="black" cx="568.06" cy="-162" rx="47.26" ry="18"/> <text text-anchor="middle" x="319.06" y="-229.8" font-family="Times,serif" font-size="14.00">:core:domain</text>
<text text-anchor="middle" x="568.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="edge4" class="edge">
<!-- :feature:foryou&#45;&gt;:core:data --> <title>:feature:foryou-&gt;:core:domain</title>
<g id="edge3" class="edge"> <path fill="none" stroke="red" stroke-width="2" d="M272.82,-288.05C280.09,-279.71 289,-269.49 297.05,-260.25"/>
<title>:feature:foryou&#45;&gt;:core:data</title> <polygon fill="red" stroke="red" stroke-width="2" points="298.51,-263.91 302.44,-254.07 293.23,-259.31 298.51,-263.91"/>
<path fill="none" stroke="black" d="M286.11,-290.58C311.86,-280.16 347.25,-265.59 378.06,-252 430.92,-228.69 491.2,-200.11 529.43,-181.73"/> </g>
<polygon fill="black" stroke="black" points="530.74,-184.98 538.23,-177.48 527.71,-178.67 530.74,-184.98"/> <g id="edge6" class="edge">
</g> <title>:core:ui-&gt;:core:designsystem</title>
<!-- :core:domain --> <path fill="none" stroke="black" d="M175.19,-218.83C159.63,-209.19 138.71,-196.24 120.95,-185.23"/>
<g id="node5" class="node"> <polygon fill="black" stroke="black" points="123.09,-182.44 112.74,-180.15 119.4,-188.39 123.09,-182.44"/>
<title>:core:domain</title> </g>
<ellipse fill="none" stroke="black" cx="309.06" cy="-234" rx="60.05" ry="18"/> <g id="node6" class="node">
<text text-anchor="middle" x="309.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text> <title>:core:analytics</title>
</g> <ellipse fill="none" stroke="black" cx="350.06" cy="-90" rx="67.34" ry="18"/>
<!-- :feature:foryou&#45;&gt;:core:domain --> <text text-anchor="middle" x="350.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<g id="edge4" class="edge"> </g>
<title>:feature:foryou&#45;&gt;:core:domain</title> <g id="edge5" class="edge">
<path fill="none" stroke="red" stroke-width="2" d="M264.34,-288.05C271.3,-279.8 279.81,-269.7 287.54,-260.54"/> <title>:core:ui-&gt;:core:analytics</title>
<polygon fill="red" stroke="red" stroke-width="2" points="289.19,-264.01 292.96,-254.1 283.84,-259.49 289.19,-264.01"/> <path fill="none" stroke="black" d="M214.9,-217.26C241.33,-192.58 292.72,-144.57 323.96,-115.38"/>
</g> <polygon fill="black" stroke="black" points="326.17,-118.1 331.09,-108.72 321.39,-112.99 326.17,-118.1"/>
<!-- :core:ui&#45;&gt;:core:designsystem --> </g>
<g id="edge6" class="edge"> <g id="node7" class="node">
<title>:core:ui&#45;&gt;:core:designsystem</title> <title>:core:model</title>
<path fill="none" stroke="black" d="M169.8,-218.83C154.65,-209.19 134.29,-196.24 117,-185.23"/> <ellipse fill="none" stroke="black" cx="585.06" cy="-18" rx="57.16" ry="18"/>
<polygon fill="black" stroke="black" points="119.35,-182.58 109.04,-180.17 115.59,-188.49 119.35,-182.58"/> <text text-anchor="middle" x="585.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
</g> </g>
<!-- :core:analytics --> <g id="edge7" class="edge">
<g id="node6" class="node"> <title>:core:ui-&gt;:core:model</title>
<title>:core:analytics</title> <path fill="none" stroke="black" d="M198.92,-215.71C201.6,-182.26 212.51,-108.76 257.06,-72 295.71,-40.1 433.01,-27.09 517.23,-22.02"/>
<ellipse fill="none" stroke="black" cx="342.06" cy="-90" rx="64.66" ry="18"/> <polygon fill="black" stroke="black" points="517.2,-25.53 526.98,-21.46 516.79,-18.54 517.2,-25.53"/>
<text text-anchor="middle" x="342.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> </g>
</g> <g id="edge12" class="edge">
<!-- :core:ui&#45;&gt;:core:analytics --> <title>:core:data-&gt;:core:analytics</title>
<g id="edge5" class="edge"> <path fill="none" stroke="black" d="M547.82,-149.91C509.28,-138.43 448.68,-120.38 404.71,-107.28"/>
<title>:core:ui&#45;&gt;:core:analytics</title> <polygon fill="black" stroke="black" points="405.95,-104 395.37,-104.5 403.95,-110.71 405.95,-104"/>
<path fill="none" stroke="black" d="M208.69,-217.26C234.76,-192.58 285.48,-144.57 316.3,-115.38"/> </g>
<polygon fill="black" stroke="black" points="318.48,-118.14 323.33,-108.73 313.67,-113.06 318.48,-118.14"/> <g id="node8" class="node">
</g> <title>:core:common</title>
<!-- :core:model --> <ellipse fill="none" stroke="black" cx="832.06" cy="-18" rx="66.81" ry="18"/>
<g id="node7" class="node"> <text text-anchor="middle" x="832.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<title>:core:model</title> </g>
<ellipse fill="none" stroke="black" cx="568.06" cy="-18" rx="55.45" ry="18"/> <g id="edge8" class="edge">
<text text-anchor="middle" x="568.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <title>:core:data-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M633.67,-159.18C749.06,-154.36 1031.95,-139.42 1060.06,-108 1070.73,-96.08 1070.01,-84.53 1060.06,-72 1058.73,-70.32 960.24,-47.86 893.16,-32.72"/>
<!-- :core:ui&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="894.27,-29.39 883.74,-30.6 892.73,-36.22 894.27,-29.39"/>
<g id="edge7" class="edge"> </g>
<title>:core:ui&#45;&gt;:core:model</title> <g id="node9" class="node">
<path fill="none" stroke="black" d="M192.94,-215.73C195.65,-182.32 206.61,-108.88 251.06,-72 288.33,-41.08 420.81,-27.72 502.24,-22.33"/> <title>:core:database</title>
<polygon fill="black" stroke="black" points="502.11,-25.84 511.87,-21.71 501.66,-18.86 502.11,-25.84"/> <ellipse fill="none" stroke="black" cx="502.06" cy="-90" rx="66.26" ry="18"/>
</g> <text text-anchor="middle" x="502.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<!-- :core:data&#45;&gt;:core:analytics --> </g>
<g id="edge12" class="edge"> <g id="edge9" class="edge">
<title>:core:data&#45;&gt;:core:analytics</title> <title>:core:data-&gt;:core:database</title>
<path fill="none" stroke="black" d="M532.25,-149.91C495.35,-138.48 437.4,-120.53 395.16,-107.45"/> <path fill="none" stroke="red" stroke-width="2" d="M566.22,-145.12C555.63,-136.18 542.19,-124.85 530.35,-114.86"/>
<polygon fill="black" stroke="black" points="396.27,-104.13 385.69,-104.51 394.2,-110.81 396.27,-104.13"/> <polygon fill="red" stroke="red" stroke-width="2" points="533.9,-113.27 524,-109.5 529.38,-118.63 533.9,-113.27"/>
</g> </g>
<!-- :core:common --> <g id="node10" class="node">
<g id="node8" class="node"> <title>:core:datastore</title>
<title>:core:common</title> <ellipse fill="none" stroke="black" cx="983.06" cy="-90" rx="67.87" ry="18"/>
<ellipse fill="none" stroke="black" cx="806.06" cy="-18" rx="65.17" ry="18"/> <text text-anchor="middle" x="983.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<text text-anchor="middle" x="806.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> </g>
</g> <g id="edge10" class="edge">
<!-- :core:data&#45;&gt;:core:common --> <title>:core:data-&gt;:core:datastore</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M630.12,-154.34C692.34,-144.97 808.03,-126.9 906.06,-108 911.25,-107 916.62,-105.91 922,-104.79"/>
<title>:core:data&#45;&gt;:core:common</title> <polygon fill="black" stroke="black" points="922.48,-108.27 931.54,-102.77 921.03,-101.42 922.48,-108.27"/>
<path fill="none" stroke="black" d="M614.84,-159.04C725.87,-153.9 998.07,-138.31 1025.06,-108 1035.7,-96.05 1034.95,-84.57 1025.06,-72 1023.79,-70.39 929.84,-48.06 865.42,-32.9"/> </g>
<polygon fill="black" stroke="black" points="866.57,-29.58 856.03,-30.7 864.97,-36.39 866.57,-29.58"/> <g id="node11" class="node">
</g> <title>:core:network</title>
<!-- :core:database --> <ellipse fill="none" stroke="black" cx="832.06" cy="-90" rx="64.66" ry="18"/>
<g id="node9" class="node"> <text text-anchor="middle" x="832.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<title>:core:database</title> </g>
<ellipse fill="none" stroke="black" cx="488.06" cy="-90" rx="63.63" ry="18"/> <g id="edge11" class="edge">
<text text-anchor="middle" x="488.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <title>:core:data-&gt;:core:network</title>
</g> <path fill="none" stroke="black" d="M623.11,-150.22C664.33,-138.53 730.45,-119.8 777.26,-106.53"/>
<!-- :core:data&#45;&gt;:core:database --> <polygon fill="black" stroke="black" points="778,-109.96 786.67,-103.86 776.09,-103.22 778,-109.96"/>
<g id="edge9" class="edge"> </g>
<title>:core:data&#45;&gt;:core:database</title> <g id="node12" class="node">
<path fill="none" stroke="red" stroke-width="2" d="M549.91,-145.12C539.69,-136.18 526.74,-124.85 515.33,-114.86"/> <title>:core:notifications</title>
<polygon fill="red" stroke="red" stroke-width="2" points="519.08,-113.5 509.25,-109.54 514.48,-118.76 519.08,-113.5"/> <ellipse fill="none" stroke="black" cx="668.06" cy="-90" rx="81.29" ry="18"/>
</g> <text text-anchor="middle" x="668.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<!-- :core:datastore --> </g>
<g id="node10" class="node"> <g id="edge13" class="edge">
<title>:core:datastore</title> <title>:core:data-&gt;:core:notifications</title>
<ellipse fill="none" stroke="black" cx="951.06" cy="-90" rx="65.17" ry="18"/> <path fill="none" stroke="black" d="M603.89,-145.12C614.41,-136.24 627.73,-125.01 639.51,-115.08"/>
<text text-anchor="middle" x="951.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <polygon fill="black" stroke="black" points="641.6,-117.9 646.98,-108.77 637.08,-112.54 641.6,-117.9"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:datastore --> <g id="edge22" class="edge">
<g id="edge10" class="edge"> <title>:core:domain-&gt;:core:data</title>
<title>:core:data&#45;&gt;:core:datastore</title> <path fill="none" stroke="red" stroke-width="2" d="M363.88,-221.2C411.27,-208.73 485.84,-189.11 535.1,-176.15"/>
<path fill="none" stroke="black" d="M611.44,-154.34C671.36,-144.97 782.73,-126.91 877.06,-108 881.92,-107.03 886.94,-105.97 891.98,-104.88"/> <polygon fill="red" stroke="red" stroke-width="2" points="534.41,-179.95 543.19,-174.02 532.63,-173.18 534.41,-179.95"/>
<polygon fill="black" stroke="black" points="892.49,-108.35 901.5,-102.78 890.98,-101.52 892.49,-108.35"/> </g>
</g> <g id="edge23" class="edge">
<!-- :core:network --> <title>:core:domain-&gt;:core:model</title>
<g id="node11" class="node"> <path fill="none" stroke="black" d="M305.66,-216.32C281.85,-184.58 237.93,-114.81 274.06,-72 304.43,-36.01 434.35,-24.46 516.36,-20.75"/>
<title>:core:network</title> <polygon fill="black" stroke="black" points="516.49,-24.25 526.33,-20.33 516.19,-17.25 516.49,-24.25"/>
<ellipse fill="none" stroke="black" cx="806.06" cy="-90" rx="62.1" ry="18"/> </g>
<text text-anchor="middle" x="806.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <g id="edge14" class="edge">
</g> <title>:core:database-&gt;:core:model</title>
<!-- :core:data&#45;&gt;:core:network --> <path fill="none" stroke="red" stroke-width="2" d="M521.73,-72.41C532.35,-63.45 545.63,-52.25 557.29,-42.42"/>
<g id="edge11" class="edge"> <polygon fill="red" stroke="red" stroke-width="2" points="558.11,-46.3 563.5,-37.18 553.6,-40.95 558.11,-46.3"/>
<title>:core:data&#45;&gt;:core:network</title> </g>
<path fill="none" stroke="black" d="M604.73,-150.22C644.27,-138.58 707.62,-119.95 752.69,-106.7"/> <g id="edge16" class="edge">
<polygon fill="black" stroke="black" points="753.67,-110.06 762.27,-103.88 751.69,-103.34 753.67,-110.06"/> <title>:core:datastore-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M933.02,-77.54C924.06,-75.61 914.79,-73.68 906.06,-72 816.46,-54.73 712.11,-38.15 647.31,-28.27"/>
<!-- :core:notifications --> <polygon fill="black" stroke="black" points="647.99,-24.83 637.57,-26.79 646.94,-31.75 647.99,-24.83"/>
<g id="node12" class="node"> </g>
<title>:core:notifications</title> <g id="edge17" class="edge">
<ellipse fill="none" stroke="black" cx="648.06" cy="-90" rx="77.97" ry="18"/> <title>:core:datastore-&gt;:core:common</title>
<text text-anchor="middle" x="648.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <path fill="none" stroke="black" d="M950.29,-73.81C928.23,-63.58 898.91,-49.99 874.98,-38.9"/>
</g> <polygon fill="black" stroke="black" points="876.68,-35.83 866.13,-34.8 873.73,-42.18 876.68,-35.83"/>
<!-- :core:data&#45;&gt;:core:notifications --> </g>
<g id="edge13" class="edge"> <g id="node13" class="node">
<title>:core:data&#45;&gt;:core:notifications</title> <title>:core:datastore-proto</title>
<path fill="none" stroke="black" d="M586.21,-145.12C596.25,-136.33 608.94,-125.23 620.21,-115.37"/> <ellipse fill="none" stroke="black" cx="1008.06" cy="-18" rx="91.47" ry="18"/>
<polygon fill="black" stroke="black" points="622.5,-118.01 627.72,-108.79 617.89,-112.75 622.5,-118.01"/> <text text-anchor="middle" x="1008.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
</g> </g>
<!-- :core:domain&#45;&gt;:core:data --> <g id="edge15" class="edge">
<g id="edge22" class="edge"> <title>:core:datastore-&gt;:core:datastore-proto</title>
<title>:core:domain&#45;&gt;:core:data</title> <path fill="none" stroke="black" d="M989.24,-71.7C991.93,-64.15 995.16,-55.12 998.17,-46.68"/>
<path fill="none" stroke="red" stroke-width="2" d="M352.7,-221.2C398.75,-208.76 471.15,-189.19 519.11,-176.23"/> <polygon fill="black" stroke="black" points="1001.37,-48.12 1001.44,-37.53 994.78,-45.77 1001.37,-48.12"/>
<polygon fill="red" stroke="red" stroke-width="2" points="518.48,-180.02 527.22,-174.04 516.66,-173.27 518.48,-180.02"/> </g>
</g> <g id="edge19" class="edge">
<!-- :core:domain&#45;&gt;:core:model --> <title>:core:network-&gt;:core:model</title>
<g id="edge23" class="edge"> <path fill="none" stroke="black" d="M787.9,-76.49C745.68,-64.52 682.02,-46.48 637.31,-33.81"/>
<title>:core:domain&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="638.4,-30.48 627.83,-31.12 636.49,-37.21 638.4,-30.48"/>
<path fill="none" stroke="black" d="M296.33,-216.3C273.75,-184.5 232.28,-114.65 268.06,-72 297.26,-37.19 422.38,-25.23 501.52,-21.13"/> </g>
<polygon fill="black" stroke="black" points="501.52,-24.64 511.34,-20.66 501.18,-17.64 501.52,-24.64"/> <g id="edge18" class="edge">
</g> <title>:core:network-&gt;:core:common</title>
<!-- :core:database&#45;&gt;:core:model --> <path fill="none" stroke="black" d="M832.06,-71.7C832.06,-64.41 832.06,-55.73 832.06,-47.54"/>
<g id="edge14" class="edge"> <polygon fill="black" stroke="black" points="835.56,-47.62 832.06,-37.62 828.56,-47.62 835.56,-47.62"/>
<title>:core:database&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M507.02,-72.41C517.15,-63.54 529.81,-52.47 540.96,-42.71"/> <g id="edge20" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="542.01,-46.44 547.23,-37.22 537.4,-41.17 542.01,-46.44"/> <title>:core:notifications-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M648.39,-72.41C637.77,-63.45 624.48,-52.25 612.83,-42.42"/>
<!-- :core:datastore&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="615.36,-39.98 605.46,-36.2 610.84,-45.33 615.36,-39.98"/>
<g id="edge16" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:model</title> <g id="edge21" class="edge">
<path fill="none" stroke="black" d="M902.98,-77.54C894.37,-75.61 885.46,-73.68 877.06,-72 791.15,-54.78 691.1,-38.26 628.66,-28.37"/> <title>:core:notifications-&gt;:core:common</title>
<polygon fill="black" stroke="black" points="629.37,-24.94 618.95,-26.83 628.28,-31.85 629.37,-24.94"/> <path fill="none" stroke="black" d="M704.45,-73.46C728.84,-63.06 761.11,-49.28 787.1,-38.19"/>
</g> <polygon fill="black" stroke="black" points="788.23,-41.51 796.05,-34.37 785.48,-35.07 788.23,-41.51"/>
<!-- :core:datastore&#45;&gt;:core:common --> </g>
<g id="edge17" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M919.6,-73.81C898.51,-63.63 870.51,-50.11 847.59,-39.05"/>
<polygon fill="black" stroke="black" points="849.35,-36.01 838.82,-34.82 846.31,-42.32 849.35,-36.01"/>
</g>
<!-- :core:datastore&#45;proto -->
<g id="node13" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="977.06" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="977.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge15" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M957.49,-71.7C960.29,-64.15 963.64,-55.12 966.78,-46.68"/>
<polygon fill="black" stroke="black" points="969.98,-48.12 970.18,-37.52 963.42,-45.68 969.98,-48.12"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge19" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M763.51,-76.49C723.04,-64.58 662.12,-46.67 619.07,-34"/>
<polygon fill="black" stroke="black" points="620.29,-30.71 609.71,-31.25 618.32,-37.43 620.29,-30.71"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge18" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M806.06,-71.7C806.06,-64.41 806.06,-55.73 806.06,-47.54"/>
<polygon fill="black" stroke="black" points="809.56,-47.62 806.06,-37.62 802.56,-47.62 809.56,-47.62"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge20" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M629.1,-72.41C618.97,-63.54 606.31,-52.47 595.15,-42.71"/>
<polygon fill="black" stroke="black" points="597.58,-40.18 587.75,-36.23 592.97,-45.44 597.58,-40.18"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge21" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M683.13,-73.46C706.43,-63.14 737.22,-49.5 762.16,-38.45"/>
<polygon fill="black" stroke="black" points="763.34,-41.76 771.06,-34.51 760.5,-35.36 763.34,-41.76"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@ -1,229 +1,188 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1108pt" height="332pt" viewBox="0.00 0.00 1107.53 332.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-328 1103.53,-328 1103.53,4 -4,4"/>
<svg width="1073pt" height="332pt" <g id="node1" class="node">
viewBox="0.00 0.00 1072.75 332.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:feature:interests</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)"> <ellipse fill="none" stroke="black" cx="258.06" cy="-306" rx="75.39" ry="18"/>
<title>G</title> <text text-anchor="middle" x="258.06" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:interests</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-328 1068.75,-328 1068.75,4 -4,4"/> </g>
<!-- :feature:interests --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:ui</title>
<title>:feature:interests</title> <ellipse fill="none" stroke="black" cx="198.06" cy="-234" rx="40.53" ry="18"/>
<ellipse fill="none" stroke="black" cx="250.06" cy="-306" rx="72.34" ry="18"/> <text text-anchor="middle" x="198.06" y="-229.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<text text-anchor="middle" x="250.06" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:interests</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:ui --> <title>:feature:interests-&gt;:core:ui</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M243.53,-288.05C236.28,-279.59 227.36,-269.19 219.35,-259.84"/>
<title>:core:ui</title> <polygon fill="black" stroke="black" points="222.19,-257.77 213.02,-252.46 216.87,-262.33 222.19,-257.77"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-234" rx="39.07" ry="18"/> </g>
<text text-anchor="middle" x="192.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :feature:interests&#45;&gt;:core:ui --> <ellipse fill="none" stroke="black" cx="85.06" cy="-162" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="85.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:feature:interests&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M236.02,-288.05C229.08,-279.68 220.57,-269.4 212.89,-260.13"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="215.61,-257.94 206.54,-252.47 210.22,-262.41 215.61,-257.94"/> <title>:feature:interests-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M216.22,-290.69C194.35,-281.83 168.05,-268.9 148.06,-252 127.69,-234.78 110.66,-209.55 99.46,-190.35"/>
<!-- :core:designsystem --> <polygon fill="black" stroke="black" points="102.55,-188.71 94.6,-181.71 96.45,-192.14 102.55,-188.71"/>
<g id="node3" class="node"> </g>
<title>:core:designsystem</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="82.06" cy="-162" rx="82.06" ry="18"/> <title>:core:data</title>
<text text-anchor="middle" x="82.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <ellipse fill="none" stroke="black" cx="585.06" cy="-162" rx="49.1" ry="18"/>
</g> <text text-anchor="middle" x="585.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<!-- :feature:interests&#45;&gt;:core:designsystem --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:feature:interests&#45;&gt;:core:designsystem</title> <title>:feature:interests-&gt;:core:data</title>
<path fill="none" stroke="black" d="M209.97,-290.57C188.83,-281.64 163.36,-268.69 144.06,-252 123.99,-234.64 107.23,-209.43 96.22,-190.27"/> <path fill="none" stroke="black" d="M296.37,-290.16C322.82,-279.78 358.74,-265.43 390.06,-252 444.42,-228.7 506.44,-200.03 545.66,-181.63"/>
<polygon fill="black" stroke="black" points="99.35,-188.7 91.44,-181.66 93.23,-192.1 99.35,-188.7"/> <polygon fill="black" stroke="black" points="546.91,-184.91 554.47,-177.49 543.94,-178.57 546.91,-184.91"/>
</g> </g>
<!-- :core:data --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:domain</title>
<title>:core:data</title> <ellipse fill="none" stroke="black" cx="319.06" cy="-234" rx="61.99" ry="18"/>
<ellipse fill="none" stroke="black" cx="568.06" cy="-162" rx="47.26" ry="18"/> <text text-anchor="middle" x="319.06" y="-229.8" font-family="Times,serif" font-size="14.00">:core:domain</text>
<text text-anchor="middle" x="568.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="edge4" class="edge">
<!-- :feature:interests&#45;&gt;:core:data --> <title>:feature:interests-&gt;:core:domain</title>
<g id="edge3" class="edge"> <path fill="none" stroke="red" stroke-width="2" d="M272.82,-288.05C280.09,-279.71 289,-269.49 297.05,-260.25"/>
<title>:feature:interests&#45;&gt;:core:data</title> <polygon fill="red" stroke="red" stroke-width="2" points="298.51,-263.91 302.44,-254.07 293.23,-259.31 298.51,-263.91"/>
<path fill="none" stroke="black" d="M287.22,-290.14C312.87,-279.75 347.69,-265.39 378.06,-252 430.92,-228.69 491.2,-200.11 529.43,-181.73"/> </g>
<polygon fill="black" stroke="black" points="530.74,-184.98 538.23,-177.48 527.71,-178.67 530.74,-184.98"/> <g id="edge6" class="edge">
</g> <title>:core:ui-&gt;:core:designsystem</title>
<!-- :core:domain --> <path fill="none" stroke="black" d="M175.19,-218.83C159.63,-209.19 138.71,-196.24 120.95,-185.23"/>
<g id="node5" class="node"> <polygon fill="black" stroke="black" points="123.09,-182.44 112.74,-180.15 119.4,-188.39 123.09,-182.44"/>
<title>:core:domain</title> </g>
<ellipse fill="none" stroke="black" cx="309.06" cy="-234" rx="60.05" ry="18"/> <g id="node6" class="node">
<text text-anchor="middle" x="309.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text> <title>:core:analytics</title>
</g> <ellipse fill="none" stroke="black" cx="350.06" cy="-90" rx="67.34" ry="18"/>
<!-- :feature:interests&#45;&gt;:core:domain --> <text text-anchor="middle" x="350.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<g id="edge4" class="edge"> </g>
<title>:feature:interests&#45;&gt;:core:domain</title> <g id="edge5" class="edge">
<path fill="none" stroke="red" stroke-width="2" d="M264.34,-288.05C271.3,-279.8 279.81,-269.7 287.54,-260.54"/> <title>:core:ui-&gt;:core:analytics</title>
<polygon fill="red" stroke="red" stroke-width="2" points="289.19,-264.01 292.96,-254.1 283.84,-259.49 289.19,-264.01"/> <path fill="none" stroke="black" d="M214.9,-217.26C241.33,-192.58 292.72,-144.57 323.96,-115.38"/>
</g> <polygon fill="black" stroke="black" points="326.17,-118.1 331.09,-108.72 321.39,-112.99 326.17,-118.1"/>
<!-- :core:ui&#45;&gt;:core:designsystem --> </g>
<g id="edge6" class="edge"> <g id="node7" class="node">
<title>:core:ui&#45;&gt;:core:designsystem</title> <title>:core:model</title>
<path fill="none" stroke="black" d="M169.8,-218.83C154.65,-209.19 134.29,-196.24 117,-185.23"/> <ellipse fill="none" stroke="black" cx="585.06" cy="-18" rx="57.16" ry="18"/>
<polygon fill="black" stroke="black" points="119.35,-182.58 109.04,-180.17 115.59,-188.49 119.35,-182.58"/> <text text-anchor="middle" x="585.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
</g> </g>
<!-- :core:analytics --> <g id="edge7" class="edge">
<g id="node6" class="node"> <title>:core:ui-&gt;:core:model</title>
<title>:core:analytics</title> <path fill="none" stroke="black" d="M198.92,-215.71C201.6,-182.26 212.51,-108.76 257.06,-72 295.71,-40.1 433.01,-27.09 517.23,-22.02"/>
<ellipse fill="none" stroke="black" cx="342.06" cy="-90" rx="64.66" ry="18"/> <polygon fill="black" stroke="black" points="517.2,-25.53 526.98,-21.46 516.79,-18.54 517.2,-25.53"/>
<text text-anchor="middle" x="342.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> </g>
</g> <g id="edge12" class="edge">
<!-- :core:ui&#45;&gt;:core:analytics --> <title>:core:data-&gt;:core:analytics</title>
<g id="edge5" class="edge"> <path fill="none" stroke="black" d="M547.82,-149.91C509.28,-138.43 448.68,-120.38 404.71,-107.28"/>
<title>:core:ui&#45;&gt;:core:analytics</title> <polygon fill="black" stroke="black" points="405.95,-104 395.37,-104.5 403.95,-110.71 405.95,-104"/>
<path fill="none" stroke="black" d="M208.69,-217.26C234.76,-192.58 285.48,-144.57 316.3,-115.38"/> </g>
<polygon fill="black" stroke="black" points="318.48,-118.14 323.33,-108.73 313.67,-113.06 318.48,-118.14"/> <g id="node8" class="node">
</g> <title>:core:common</title>
<!-- :core:model --> <ellipse fill="none" stroke="black" cx="832.06" cy="-18" rx="66.81" ry="18"/>
<g id="node7" class="node"> <text text-anchor="middle" x="832.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<title>:core:model</title> </g>
<ellipse fill="none" stroke="black" cx="568.06" cy="-18" rx="55.45" ry="18"/> <g id="edge8" class="edge">
<text text-anchor="middle" x="568.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <title>:core:data-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M633.67,-159.18C749.06,-154.36 1031.95,-139.42 1060.06,-108 1070.73,-96.08 1070.01,-84.53 1060.06,-72 1058.73,-70.32 960.24,-47.86 893.16,-32.72"/>
<!-- :core:ui&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="894.27,-29.39 883.74,-30.6 892.73,-36.22 894.27,-29.39"/>
<g id="edge7" class="edge"> </g>
<title>:core:ui&#45;&gt;:core:model</title> <g id="node9" class="node">
<path fill="none" stroke="black" d="M192.94,-215.73C195.65,-182.32 206.61,-108.88 251.06,-72 288.33,-41.08 420.81,-27.72 502.24,-22.33"/> <title>:core:database</title>
<polygon fill="black" stroke="black" points="502.11,-25.84 511.87,-21.71 501.66,-18.86 502.11,-25.84"/> <ellipse fill="none" stroke="black" cx="502.06" cy="-90" rx="66.26" ry="18"/>
</g> <text text-anchor="middle" x="502.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<!-- :core:data&#45;&gt;:core:analytics --> </g>
<g id="edge12" class="edge"> <g id="edge9" class="edge">
<title>:core:data&#45;&gt;:core:analytics</title> <title>:core:data-&gt;:core:database</title>
<path fill="none" stroke="black" d="M532.25,-149.91C495.35,-138.48 437.4,-120.53 395.16,-107.45"/> <path fill="none" stroke="red" stroke-width="2" d="M566.22,-145.12C555.63,-136.18 542.19,-124.85 530.35,-114.86"/>
<polygon fill="black" stroke="black" points="396.27,-104.13 385.69,-104.51 394.2,-110.81 396.27,-104.13"/> <polygon fill="red" stroke="red" stroke-width="2" points="533.9,-113.27 524,-109.5 529.38,-118.63 533.9,-113.27"/>
</g> </g>
<!-- :core:common --> <g id="node10" class="node">
<g id="node8" class="node"> <title>:core:datastore</title>
<title>:core:common</title> <ellipse fill="none" stroke="black" cx="983.06" cy="-90" rx="67.87" ry="18"/>
<ellipse fill="none" stroke="black" cx="806.06" cy="-18" rx="65.17" ry="18"/> <text text-anchor="middle" x="983.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<text text-anchor="middle" x="806.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> </g>
</g> <g id="edge10" class="edge">
<!-- :core:data&#45;&gt;:core:common --> <title>:core:data-&gt;:core:datastore</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M630.12,-154.34C692.34,-144.97 808.03,-126.9 906.06,-108 911.25,-107 916.62,-105.91 922,-104.79"/>
<title>:core:data&#45;&gt;:core:common</title> <polygon fill="black" stroke="black" points="922.48,-108.27 931.54,-102.77 921.03,-101.42 922.48,-108.27"/>
<path fill="none" stroke="black" d="M614.84,-159.04C725.87,-153.9 998.07,-138.31 1025.06,-108 1035.7,-96.05 1034.95,-84.57 1025.06,-72 1023.79,-70.39 929.84,-48.06 865.42,-32.9"/> </g>
<polygon fill="black" stroke="black" points="866.57,-29.58 856.03,-30.7 864.97,-36.39 866.57,-29.58"/> <g id="node11" class="node">
</g> <title>:core:network</title>
<!-- :core:database --> <ellipse fill="none" stroke="black" cx="832.06" cy="-90" rx="64.66" ry="18"/>
<g id="node9" class="node"> <text text-anchor="middle" x="832.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<title>:core:database</title> </g>
<ellipse fill="none" stroke="black" cx="488.06" cy="-90" rx="63.63" ry="18"/> <g id="edge11" class="edge">
<text text-anchor="middle" x="488.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <title>:core:data-&gt;:core:network</title>
</g> <path fill="none" stroke="black" d="M623.11,-150.22C664.33,-138.53 730.45,-119.8 777.26,-106.53"/>
<!-- :core:data&#45;&gt;:core:database --> <polygon fill="black" stroke="black" points="778,-109.96 786.67,-103.86 776.09,-103.22 778,-109.96"/>
<g id="edge9" class="edge"> </g>
<title>:core:data&#45;&gt;:core:database</title> <g id="node12" class="node">
<path fill="none" stroke="red" stroke-width="2" d="M549.91,-145.12C539.69,-136.18 526.74,-124.85 515.33,-114.86"/> <title>:core:notifications</title>
<polygon fill="red" stroke="red" stroke-width="2" points="519.08,-113.5 509.25,-109.54 514.48,-118.76 519.08,-113.5"/> <ellipse fill="none" stroke="black" cx="668.06" cy="-90" rx="81.29" ry="18"/>
</g> <text text-anchor="middle" x="668.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<!-- :core:datastore --> </g>
<g id="node10" class="node"> <g id="edge13" class="edge">
<title>:core:datastore</title> <title>:core:data-&gt;:core:notifications</title>
<ellipse fill="none" stroke="black" cx="951.06" cy="-90" rx="65.17" ry="18"/> <path fill="none" stroke="black" d="M603.89,-145.12C614.41,-136.24 627.73,-125.01 639.51,-115.08"/>
<text text-anchor="middle" x="951.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <polygon fill="black" stroke="black" points="641.6,-117.9 646.98,-108.77 637.08,-112.54 641.6,-117.9"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:datastore --> <g id="edge22" class="edge">
<g id="edge10" class="edge"> <title>:core:domain-&gt;:core:data</title>
<title>:core:data&#45;&gt;:core:datastore</title> <path fill="none" stroke="red" stroke-width="2" d="M363.88,-221.2C411.27,-208.73 485.84,-189.11 535.1,-176.15"/>
<path fill="none" stroke="black" d="M611.44,-154.34C671.36,-144.97 782.73,-126.91 877.06,-108 881.92,-107.03 886.94,-105.97 891.98,-104.88"/> <polygon fill="red" stroke="red" stroke-width="2" points="534.41,-179.95 543.19,-174.02 532.63,-173.18 534.41,-179.95"/>
<polygon fill="black" stroke="black" points="892.49,-108.35 901.5,-102.78 890.98,-101.52 892.49,-108.35"/> </g>
</g> <g id="edge23" class="edge">
<!-- :core:network --> <title>:core:domain-&gt;:core:model</title>
<g id="node11" class="node"> <path fill="none" stroke="black" d="M305.66,-216.32C281.85,-184.58 237.93,-114.81 274.06,-72 304.43,-36.01 434.35,-24.46 516.36,-20.75"/>
<title>:core:network</title> <polygon fill="black" stroke="black" points="516.49,-24.25 526.33,-20.33 516.19,-17.25 516.49,-24.25"/>
<ellipse fill="none" stroke="black" cx="806.06" cy="-90" rx="62.1" ry="18"/> </g>
<text text-anchor="middle" x="806.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <g id="edge14" class="edge">
</g> <title>:core:database-&gt;:core:model</title>
<!-- :core:data&#45;&gt;:core:network --> <path fill="none" stroke="red" stroke-width="2" d="M521.73,-72.41C532.35,-63.45 545.63,-52.25 557.29,-42.42"/>
<g id="edge11" class="edge"> <polygon fill="red" stroke="red" stroke-width="2" points="558.11,-46.3 563.5,-37.18 553.6,-40.95 558.11,-46.3"/>
<title>:core:data&#45;&gt;:core:network</title> </g>
<path fill="none" stroke="black" d="M604.73,-150.22C644.27,-138.58 707.62,-119.95 752.69,-106.7"/> <g id="edge16" class="edge">
<polygon fill="black" stroke="black" points="753.67,-110.06 762.27,-103.88 751.69,-103.34 753.67,-110.06"/> <title>:core:datastore-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M933.02,-77.54C924.06,-75.61 914.79,-73.68 906.06,-72 816.46,-54.73 712.11,-38.15 647.31,-28.27"/>
<!-- :core:notifications --> <polygon fill="black" stroke="black" points="647.99,-24.83 637.57,-26.79 646.94,-31.75 647.99,-24.83"/>
<g id="node12" class="node"> </g>
<title>:core:notifications</title> <g id="edge17" class="edge">
<ellipse fill="none" stroke="black" cx="648.06" cy="-90" rx="77.97" ry="18"/> <title>:core:datastore-&gt;:core:common</title>
<text text-anchor="middle" x="648.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <path fill="none" stroke="black" d="M950.29,-73.81C928.23,-63.58 898.91,-49.99 874.98,-38.9"/>
</g> <polygon fill="black" stroke="black" points="876.68,-35.83 866.13,-34.8 873.73,-42.18 876.68,-35.83"/>
<!-- :core:data&#45;&gt;:core:notifications --> </g>
<g id="edge13" class="edge"> <g id="node13" class="node">
<title>:core:data&#45;&gt;:core:notifications</title> <title>:core:datastore-proto</title>
<path fill="none" stroke="black" d="M586.21,-145.12C596.25,-136.33 608.94,-125.23 620.21,-115.37"/> <ellipse fill="none" stroke="black" cx="1008.06" cy="-18" rx="91.47" ry="18"/>
<polygon fill="black" stroke="black" points="622.5,-118.01 627.72,-108.79 617.89,-112.75 622.5,-118.01"/> <text text-anchor="middle" x="1008.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
</g> </g>
<!-- :core:domain&#45;&gt;:core:data --> <g id="edge15" class="edge">
<g id="edge22" class="edge"> <title>:core:datastore-&gt;:core:datastore-proto</title>
<title>:core:domain&#45;&gt;:core:data</title> <path fill="none" stroke="black" d="M989.24,-71.7C991.93,-64.15 995.16,-55.12 998.17,-46.68"/>
<path fill="none" stroke="red" stroke-width="2" d="M352.7,-221.2C398.75,-208.76 471.15,-189.19 519.11,-176.23"/> <polygon fill="black" stroke="black" points="1001.37,-48.12 1001.44,-37.53 994.78,-45.77 1001.37,-48.12"/>
<polygon fill="red" stroke="red" stroke-width="2" points="518.48,-180.02 527.22,-174.04 516.66,-173.27 518.48,-180.02"/> </g>
</g> <g id="edge19" class="edge">
<!-- :core:domain&#45;&gt;:core:model --> <title>:core:network-&gt;:core:model</title>
<g id="edge23" class="edge"> <path fill="none" stroke="black" d="M787.9,-76.49C745.68,-64.52 682.02,-46.48 637.31,-33.81"/>
<title>:core:domain&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="638.4,-30.48 627.83,-31.12 636.49,-37.21 638.4,-30.48"/>
<path fill="none" stroke="black" d="M296.33,-216.3C273.75,-184.5 232.28,-114.65 268.06,-72 297.26,-37.19 422.38,-25.23 501.52,-21.13"/> </g>
<polygon fill="black" stroke="black" points="501.52,-24.64 511.34,-20.66 501.18,-17.64 501.52,-24.64"/> <g id="edge18" class="edge">
</g> <title>:core:network-&gt;:core:common</title>
<!-- :core:database&#45;&gt;:core:model --> <path fill="none" stroke="black" d="M832.06,-71.7C832.06,-64.41 832.06,-55.73 832.06,-47.54"/>
<g id="edge14" class="edge"> <polygon fill="black" stroke="black" points="835.56,-47.62 832.06,-37.62 828.56,-47.62 835.56,-47.62"/>
<title>:core:database&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M507.02,-72.41C517.15,-63.54 529.81,-52.47 540.96,-42.71"/> <g id="edge20" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="542.01,-46.44 547.23,-37.22 537.4,-41.17 542.01,-46.44"/> <title>:core:notifications-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M648.39,-72.41C637.77,-63.45 624.48,-52.25 612.83,-42.42"/>
<!-- :core:datastore&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="615.36,-39.98 605.46,-36.2 610.84,-45.33 615.36,-39.98"/>
<g id="edge16" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:model</title> <g id="edge21" class="edge">
<path fill="none" stroke="black" d="M902.98,-77.54C894.37,-75.61 885.46,-73.68 877.06,-72 791.15,-54.78 691.1,-38.26 628.66,-28.37"/> <title>:core:notifications-&gt;:core:common</title>
<polygon fill="black" stroke="black" points="629.37,-24.94 618.95,-26.83 628.28,-31.85 629.37,-24.94"/> <path fill="none" stroke="black" d="M704.45,-73.46C728.84,-63.06 761.11,-49.28 787.1,-38.19"/>
</g> <polygon fill="black" stroke="black" points="788.23,-41.51 796.05,-34.37 785.48,-35.07 788.23,-41.51"/>
<!-- :core:datastore&#45;&gt;:core:common --> </g>
<g id="edge17" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M919.6,-73.81C898.51,-63.63 870.51,-50.11 847.59,-39.05"/>
<polygon fill="black" stroke="black" points="849.35,-36.01 838.82,-34.82 846.31,-42.32 849.35,-36.01"/>
</g>
<!-- :core:datastore&#45;proto -->
<g id="node13" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="977.06" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="977.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge15" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M957.49,-71.7C960.29,-64.15 963.64,-55.12 966.78,-46.68"/>
<polygon fill="black" stroke="black" points="969.98,-48.12 970.18,-37.52 963.42,-45.68 969.98,-48.12"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge19" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M763.51,-76.49C723.04,-64.58 662.12,-46.67 619.07,-34"/>
<polygon fill="black" stroke="black" points="620.29,-30.71 609.71,-31.25 618.32,-37.43 620.29,-30.71"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge18" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M806.06,-71.7C806.06,-64.41 806.06,-55.73 806.06,-47.54"/>
<polygon fill="black" stroke="black" points="809.56,-47.62 806.06,-37.62 802.56,-47.62 809.56,-47.62"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge20" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M629.1,-72.41C618.97,-63.54 606.31,-52.47 595.15,-42.71"/>
<polygon fill="black" stroke="black" points="597.58,-40.18 587.75,-36.23 592.97,-45.44 597.58,-40.18"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge21" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M683.13,-73.46C706.43,-63.14 737.22,-49.5 762.16,-38.45"/>
<polygon fill="black" stroke="black" points="763.34,-41.76 771.06,-34.51 760.5,-35.36 763.34,-41.76"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@ -1,229 +1,188 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1108pt" height="332pt" viewBox="0.00 0.00 1107.53 332.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-328 1103.53,-328 1103.53,4 -4,4"/>
<svg width="1073pt" height="332pt" <g id="node1" class="node">
viewBox="0.00 0.00 1072.75 332.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:feature:search</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)"> <ellipse fill="none" stroke="black" cx="258.06" cy="-306" rx="67.87" ry="18"/>
<title>G</title> <text text-anchor="middle" x="258.06" y="-301.8" font-family="Times,serif" font-size="14.00">:feature:search</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-328 1068.75,-328 1068.75,4 -4,4"/> </g>
<!-- :feature:search --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:ui</title>
<title>:feature:search</title> <ellipse fill="none" stroke="black" cx="198.06" cy="-234" rx="40.53" ry="18"/>
<ellipse fill="none" stroke="black" cx="250.06" cy="-306" rx="65.17" ry="18"/> <text text-anchor="middle" x="198.06" y="-229.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<text text-anchor="middle" x="250.06" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:search</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:ui --> <title>:feature:search-&gt;:core:ui</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M243.53,-288.05C236.28,-279.59 227.36,-269.19 219.35,-259.84"/>
<title>:core:ui</title> <polygon fill="black" stroke="black" points="222.19,-257.77 213.02,-252.46 216.87,-262.33 222.19,-257.77"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-234" rx="39.07" ry="18"/> </g>
<text text-anchor="middle" x="192.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :feature:search&#45;&gt;:core:ui --> <ellipse fill="none" stroke="black" cx="85.06" cy="-162" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="85.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:feature:search&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M236.02,-288.05C229.08,-279.68 220.57,-269.4 212.89,-260.13"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="215.61,-257.94 206.54,-252.47 210.22,-262.41 215.61,-257.94"/> <title>:feature:search-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M217.55,-291.22C195.42,-282.35 168.45,-269.25 148.06,-252 127.69,-234.78 110.66,-209.55 99.46,-190.35"/>
<!-- :core:designsystem --> <polygon fill="black" stroke="black" points="102.55,-188.71 94.6,-181.71 96.45,-192.14 102.55,-188.71"/>
<g id="node3" class="node"> </g>
<title>:core:designsystem</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="82.06" cy="-162" rx="82.06" ry="18"/> <title>:core:data</title>
<text text-anchor="middle" x="82.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <ellipse fill="none" stroke="black" cx="585.06" cy="-162" rx="49.1" ry="18"/>
</g> <text text-anchor="middle" x="585.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<!-- :feature:search&#45;&gt;:core:designsystem --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:feature:search&#45;&gt;:core:designsystem</title> <title>:feature:search-&gt;:core:data</title>
<path fill="none" stroke="black" d="M211.24,-291.1C189.86,-282.17 163.75,-269.02 144.06,-252 123.99,-234.64 107.23,-209.43 96.22,-190.27"/> <path fill="none" stroke="black" d="M295.23,-290.61C321.78,-280.2 358.28,-265.62 390.06,-252 444.42,-228.7 506.44,-200.03 545.66,-181.63"/>
<polygon fill="black" stroke="black" points="99.35,-188.7 91.44,-181.66 93.23,-192.1 99.35,-188.7"/> <polygon fill="black" stroke="black" points="546.91,-184.91 554.47,-177.49 543.94,-178.57 546.91,-184.91"/>
</g> </g>
<!-- :core:data --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:domain</title>
<title>:core:data</title> <ellipse fill="none" stroke="black" cx="319.06" cy="-234" rx="61.99" ry="18"/>
<ellipse fill="none" stroke="black" cx="568.06" cy="-162" rx="47.26" ry="18"/> <text text-anchor="middle" x="319.06" y="-229.8" font-family="Times,serif" font-size="14.00">:core:domain</text>
<text text-anchor="middle" x="568.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="edge4" class="edge">
<!-- :feature:search&#45;&gt;:core:data --> <title>:feature:search-&gt;:core:domain</title>
<g id="edge3" class="edge"> <path fill="none" stroke="red" stroke-width="2" d="M272.82,-288.05C280.09,-279.71 289,-269.49 297.05,-260.25"/>
<title>:feature:search&#45;&gt;:core:data</title> <polygon fill="red" stroke="red" stroke-width="2" points="298.51,-263.91 302.44,-254.07 293.23,-259.31 298.51,-263.91"/>
<path fill="none" stroke="black" d="M286.11,-290.58C311.86,-280.16 347.25,-265.59 378.06,-252 430.92,-228.69 491.2,-200.11 529.43,-181.73"/> </g>
<polygon fill="black" stroke="black" points="530.74,-184.98 538.23,-177.48 527.71,-178.67 530.74,-184.98"/> <g id="edge6" class="edge">
</g> <title>:core:ui-&gt;:core:designsystem</title>
<!-- :core:domain --> <path fill="none" stroke="black" d="M175.19,-218.83C159.63,-209.19 138.71,-196.24 120.95,-185.23"/>
<g id="node5" class="node"> <polygon fill="black" stroke="black" points="123.09,-182.44 112.74,-180.15 119.4,-188.39 123.09,-182.44"/>
<title>:core:domain</title> </g>
<ellipse fill="none" stroke="black" cx="309.06" cy="-234" rx="60.05" ry="18"/> <g id="node6" class="node">
<text text-anchor="middle" x="309.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text> <title>:core:analytics</title>
</g> <ellipse fill="none" stroke="black" cx="350.06" cy="-90" rx="67.34" ry="18"/>
<!-- :feature:search&#45;&gt;:core:domain --> <text text-anchor="middle" x="350.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<g id="edge4" class="edge"> </g>
<title>:feature:search&#45;&gt;:core:domain</title> <g id="edge5" class="edge">
<path fill="none" stroke="red" stroke-width="2" d="M264.34,-288.05C271.3,-279.8 279.81,-269.7 287.54,-260.54"/> <title>:core:ui-&gt;:core:analytics</title>
<polygon fill="red" stroke="red" stroke-width="2" points="289.19,-264.01 292.96,-254.1 283.84,-259.49 289.19,-264.01"/> <path fill="none" stroke="black" d="M214.9,-217.26C241.33,-192.58 292.72,-144.57 323.96,-115.38"/>
</g> <polygon fill="black" stroke="black" points="326.17,-118.1 331.09,-108.72 321.39,-112.99 326.17,-118.1"/>
<!-- :core:ui&#45;&gt;:core:designsystem --> </g>
<g id="edge6" class="edge"> <g id="node7" class="node">
<title>:core:ui&#45;&gt;:core:designsystem</title> <title>:core:model</title>
<path fill="none" stroke="black" d="M169.8,-218.83C154.65,-209.19 134.29,-196.24 117,-185.23"/> <ellipse fill="none" stroke="black" cx="585.06" cy="-18" rx="57.16" ry="18"/>
<polygon fill="black" stroke="black" points="119.35,-182.58 109.04,-180.17 115.59,-188.49 119.35,-182.58"/> <text text-anchor="middle" x="585.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
</g> </g>
<!-- :core:analytics --> <g id="edge7" class="edge">
<g id="node6" class="node"> <title>:core:ui-&gt;:core:model</title>
<title>:core:analytics</title> <path fill="none" stroke="black" d="M198.92,-215.71C201.6,-182.26 212.51,-108.76 257.06,-72 295.71,-40.1 433.01,-27.09 517.23,-22.02"/>
<ellipse fill="none" stroke="black" cx="342.06" cy="-90" rx="64.66" ry="18"/> <polygon fill="black" stroke="black" points="517.2,-25.53 526.98,-21.46 516.79,-18.54 517.2,-25.53"/>
<text text-anchor="middle" x="342.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> </g>
</g> <g id="edge12" class="edge">
<!-- :core:ui&#45;&gt;:core:analytics --> <title>:core:data-&gt;:core:analytics</title>
<g id="edge5" class="edge"> <path fill="none" stroke="black" d="M547.82,-149.91C509.28,-138.43 448.68,-120.38 404.71,-107.28"/>
<title>:core:ui&#45;&gt;:core:analytics</title> <polygon fill="black" stroke="black" points="405.95,-104 395.37,-104.5 403.95,-110.71 405.95,-104"/>
<path fill="none" stroke="black" d="M208.69,-217.26C234.76,-192.58 285.48,-144.57 316.3,-115.38"/> </g>
<polygon fill="black" stroke="black" points="318.48,-118.14 323.33,-108.73 313.67,-113.06 318.48,-118.14"/> <g id="node8" class="node">
</g> <title>:core:common</title>
<!-- :core:model --> <ellipse fill="none" stroke="black" cx="832.06" cy="-18" rx="66.81" ry="18"/>
<g id="node7" class="node"> <text text-anchor="middle" x="832.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<title>:core:model</title> </g>
<ellipse fill="none" stroke="black" cx="568.06" cy="-18" rx="55.45" ry="18"/> <g id="edge8" class="edge">
<text text-anchor="middle" x="568.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <title>:core:data-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M633.67,-159.18C749.06,-154.36 1031.95,-139.42 1060.06,-108 1070.73,-96.08 1070.01,-84.53 1060.06,-72 1058.73,-70.32 960.24,-47.86 893.16,-32.72"/>
<!-- :core:ui&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="894.27,-29.39 883.74,-30.6 892.73,-36.22 894.27,-29.39"/>
<g id="edge7" class="edge"> </g>
<title>:core:ui&#45;&gt;:core:model</title> <g id="node9" class="node">
<path fill="none" stroke="black" d="M192.94,-215.73C195.65,-182.32 206.61,-108.88 251.06,-72 288.33,-41.08 420.81,-27.72 502.24,-22.33"/> <title>:core:database</title>
<polygon fill="black" stroke="black" points="502.11,-25.84 511.87,-21.71 501.66,-18.86 502.11,-25.84"/> <ellipse fill="none" stroke="black" cx="502.06" cy="-90" rx="66.26" ry="18"/>
</g> <text text-anchor="middle" x="502.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<!-- :core:data&#45;&gt;:core:analytics --> </g>
<g id="edge12" class="edge"> <g id="edge9" class="edge">
<title>:core:data&#45;&gt;:core:analytics</title> <title>:core:data-&gt;:core:database</title>
<path fill="none" stroke="black" d="M532.25,-149.91C495.35,-138.48 437.4,-120.53 395.16,-107.45"/> <path fill="none" stroke="red" stroke-width="2" d="M566.22,-145.12C555.63,-136.18 542.19,-124.85 530.35,-114.86"/>
<polygon fill="black" stroke="black" points="396.27,-104.13 385.69,-104.51 394.2,-110.81 396.27,-104.13"/> <polygon fill="red" stroke="red" stroke-width="2" points="533.9,-113.27 524,-109.5 529.38,-118.63 533.9,-113.27"/>
</g> </g>
<!-- :core:common --> <g id="node10" class="node">
<g id="node8" class="node"> <title>:core:datastore</title>
<title>:core:common</title> <ellipse fill="none" stroke="black" cx="983.06" cy="-90" rx="67.87" ry="18"/>
<ellipse fill="none" stroke="black" cx="806.06" cy="-18" rx="65.17" ry="18"/> <text text-anchor="middle" x="983.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<text text-anchor="middle" x="806.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> </g>
</g> <g id="edge10" class="edge">
<!-- :core:data&#45;&gt;:core:common --> <title>:core:data-&gt;:core:datastore</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M630.12,-154.34C692.34,-144.97 808.03,-126.9 906.06,-108 911.25,-107 916.62,-105.91 922,-104.79"/>
<title>:core:data&#45;&gt;:core:common</title> <polygon fill="black" stroke="black" points="922.48,-108.27 931.54,-102.77 921.03,-101.42 922.48,-108.27"/>
<path fill="none" stroke="black" d="M614.84,-159.04C725.87,-153.9 998.07,-138.31 1025.06,-108 1035.7,-96.05 1034.95,-84.57 1025.06,-72 1023.79,-70.39 929.84,-48.06 865.42,-32.9"/> </g>
<polygon fill="black" stroke="black" points="866.57,-29.58 856.03,-30.7 864.97,-36.39 866.57,-29.58"/> <g id="node11" class="node">
</g> <title>:core:network</title>
<!-- :core:database --> <ellipse fill="none" stroke="black" cx="832.06" cy="-90" rx="64.66" ry="18"/>
<g id="node9" class="node"> <text text-anchor="middle" x="832.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<title>:core:database</title> </g>
<ellipse fill="none" stroke="black" cx="488.06" cy="-90" rx="63.63" ry="18"/> <g id="edge11" class="edge">
<text text-anchor="middle" x="488.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <title>:core:data-&gt;:core:network</title>
</g> <path fill="none" stroke="black" d="M623.11,-150.22C664.33,-138.53 730.45,-119.8 777.26,-106.53"/>
<!-- :core:data&#45;&gt;:core:database --> <polygon fill="black" stroke="black" points="778,-109.96 786.67,-103.86 776.09,-103.22 778,-109.96"/>
<g id="edge9" class="edge"> </g>
<title>:core:data&#45;&gt;:core:database</title> <g id="node12" class="node">
<path fill="none" stroke="red" stroke-width="2" d="M549.91,-145.12C539.69,-136.18 526.74,-124.85 515.33,-114.86"/> <title>:core:notifications</title>
<polygon fill="red" stroke="red" stroke-width="2" points="519.08,-113.5 509.25,-109.54 514.48,-118.76 519.08,-113.5"/> <ellipse fill="none" stroke="black" cx="668.06" cy="-90" rx="81.29" ry="18"/>
</g> <text text-anchor="middle" x="668.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<!-- :core:datastore --> </g>
<g id="node10" class="node"> <g id="edge13" class="edge">
<title>:core:datastore</title> <title>:core:data-&gt;:core:notifications</title>
<ellipse fill="none" stroke="black" cx="951.06" cy="-90" rx="65.17" ry="18"/> <path fill="none" stroke="black" d="M603.89,-145.12C614.41,-136.24 627.73,-125.01 639.51,-115.08"/>
<text text-anchor="middle" x="951.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <polygon fill="black" stroke="black" points="641.6,-117.9 646.98,-108.77 637.08,-112.54 641.6,-117.9"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:datastore --> <g id="edge22" class="edge">
<g id="edge10" class="edge"> <title>:core:domain-&gt;:core:data</title>
<title>:core:data&#45;&gt;:core:datastore</title> <path fill="none" stroke="red" stroke-width="2" d="M363.88,-221.2C411.27,-208.73 485.84,-189.11 535.1,-176.15"/>
<path fill="none" stroke="black" d="M611.44,-154.34C671.36,-144.97 782.73,-126.91 877.06,-108 881.92,-107.03 886.94,-105.97 891.98,-104.88"/> <polygon fill="red" stroke="red" stroke-width="2" points="534.41,-179.95 543.19,-174.02 532.63,-173.18 534.41,-179.95"/>
<polygon fill="black" stroke="black" points="892.49,-108.35 901.5,-102.78 890.98,-101.52 892.49,-108.35"/> </g>
</g> <g id="edge23" class="edge">
<!-- :core:network --> <title>:core:domain-&gt;:core:model</title>
<g id="node11" class="node"> <path fill="none" stroke="black" d="M305.66,-216.32C281.85,-184.58 237.93,-114.81 274.06,-72 304.43,-36.01 434.35,-24.46 516.36,-20.75"/>
<title>:core:network</title> <polygon fill="black" stroke="black" points="516.49,-24.25 526.33,-20.33 516.19,-17.25 516.49,-24.25"/>
<ellipse fill="none" stroke="black" cx="806.06" cy="-90" rx="62.1" ry="18"/> </g>
<text text-anchor="middle" x="806.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <g id="edge14" class="edge">
</g> <title>:core:database-&gt;:core:model</title>
<!-- :core:data&#45;&gt;:core:network --> <path fill="none" stroke="red" stroke-width="2" d="M521.73,-72.41C532.35,-63.45 545.63,-52.25 557.29,-42.42"/>
<g id="edge11" class="edge"> <polygon fill="red" stroke="red" stroke-width="2" points="558.11,-46.3 563.5,-37.18 553.6,-40.95 558.11,-46.3"/>
<title>:core:data&#45;&gt;:core:network</title> </g>
<path fill="none" stroke="black" d="M604.73,-150.22C644.27,-138.58 707.62,-119.95 752.69,-106.7"/> <g id="edge16" class="edge">
<polygon fill="black" stroke="black" points="753.67,-110.06 762.27,-103.88 751.69,-103.34 753.67,-110.06"/> <title>:core:datastore-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M933.02,-77.54C924.06,-75.61 914.79,-73.68 906.06,-72 816.46,-54.73 712.11,-38.15 647.31,-28.27"/>
<!-- :core:notifications --> <polygon fill="black" stroke="black" points="647.99,-24.83 637.57,-26.79 646.94,-31.75 647.99,-24.83"/>
<g id="node12" class="node"> </g>
<title>:core:notifications</title> <g id="edge17" class="edge">
<ellipse fill="none" stroke="black" cx="648.06" cy="-90" rx="77.97" ry="18"/> <title>:core:datastore-&gt;:core:common</title>
<text text-anchor="middle" x="648.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <path fill="none" stroke="black" d="M950.29,-73.81C928.23,-63.58 898.91,-49.99 874.98,-38.9"/>
</g> <polygon fill="black" stroke="black" points="876.68,-35.83 866.13,-34.8 873.73,-42.18 876.68,-35.83"/>
<!-- :core:data&#45;&gt;:core:notifications --> </g>
<g id="edge13" class="edge"> <g id="node13" class="node">
<title>:core:data&#45;&gt;:core:notifications</title> <title>:core:datastore-proto</title>
<path fill="none" stroke="black" d="M586.21,-145.12C596.25,-136.33 608.94,-125.23 620.21,-115.37"/> <ellipse fill="none" stroke="black" cx="1008.06" cy="-18" rx="91.47" ry="18"/>
<polygon fill="black" stroke="black" points="622.5,-118.01 627.72,-108.79 617.89,-112.75 622.5,-118.01"/> <text text-anchor="middle" x="1008.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
</g> </g>
<!-- :core:domain&#45;&gt;:core:data --> <g id="edge15" class="edge">
<g id="edge22" class="edge"> <title>:core:datastore-&gt;:core:datastore-proto</title>
<title>:core:domain&#45;&gt;:core:data</title> <path fill="none" stroke="black" d="M989.24,-71.7C991.93,-64.15 995.16,-55.12 998.17,-46.68"/>
<path fill="none" stroke="red" stroke-width="2" d="M352.7,-221.2C398.75,-208.76 471.15,-189.19 519.11,-176.23"/> <polygon fill="black" stroke="black" points="1001.37,-48.12 1001.44,-37.53 994.78,-45.77 1001.37,-48.12"/>
<polygon fill="red" stroke="red" stroke-width="2" points="518.48,-180.02 527.22,-174.04 516.66,-173.27 518.48,-180.02"/> </g>
</g> <g id="edge19" class="edge">
<!-- :core:domain&#45;&gt;:core:model --> <title>:core:network-&gt;:core:model</title>
<g id="edge23" class="edge"> <path fill="none" stroke="black" d="M787.9,-76.49C745.68,-64.52 682.02,-46.48 637.31,-33.81"/>
<title>:core:domain&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="638.4,-30.48 627.83,-31.12 636.49,-37.21 638.4,-30.48"/>
<path fill="none" stroke="black" d="M296.33,-216.3C273.75,-184.5 232.28,-114.65 268.06,-72 297.26,-37.19 422.38,-25.23 501.52,-21.13"/> </g>
<polygon fill="black" stroke="black" points="501.52,-24.64 511.34,-20.66 501.18,-17.64 501.52,-24.64"/> <g id="edge18" class="edge">
</g> <title>:core:network-&gt;:core:common</title>
<!-- :core:database&#45;&gt;:core:model --> <path fill="none" stroke="black" d="M832.06,-71.7C832.06,-64.41 832.06,-55.73 832.06,-47.54"/>
<g id="edge14" class="edge"> <polygon fill="black" stroke="black" points="835.56,-47.62 832.06,-37.62 828.56,-47.62 835.56,-47.62"/>
<title>:core:database&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M507.02,-72.41C517.15,-63.54 529.81,-52.47 540.96,-42.71"/> <g id="edge20" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="542.01,-46.44 547.23,-37.22 537.4,-41.17 542.01,-46.44"/> <title>:core:notifications-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M648.39,-72.41C637.77,-63.45 624.48,-52.25 612.83,-42.42"/>
<!-- :core:datastore&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="615.36,-39.98 605.46,-36.2 610.84,-45.33 615.36,-39.98"/>
<g id="edge16" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:model</title> <g id="edge21" class="edge">
<path fill="none" stroke="black" d="M902.98,-77.54C894.37,-75.61 885.46,-73.68 877.06,-72 791.15,-54.78 691.1,-38.26 628.66,-28.37"/> <title>:core:notifications-&gt;:core:common</title>
<polygon fill="black" stroke="black" points="629.37,-24.94 618.95,-26.83 628.28,-31.85 629.37,-24.94"/> <path fill="none" stroke="black" d="M704.45,-73.46C728.84,-63.06 761.11,-49.28 787.1,-38.19"/>
</g> <polygon fill="black" stroke="black" points="788.23,-41.51 796.05,-34.37 785.48,-35.07 788.23,-41.51"/>
<!-- :core:datastore&#45;&gt;:core:common --> </g>
<g id="edge17" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M919.6,-73.81C898.51,-63.63 870.51,-50.11 847.59,-39.05"/>
<polygon fill="black" stroke="black" points="849.35,-36.01 838.82,-34.82 846.31,-42.32 849.35,-36.01"/>
</g>
<!-- :core:datastore&#45;proto -->
<g id="node13" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="977.06" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="977.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge15" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M957.49,-71.7C960.29,-64.15 963.64,-55.12 966.78,-46.68"/>
<polygon fill="black" stroke="black" points="969.98,-48.12 970.18,-37.52 963.42,-45.68 969.98,-48.12"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge19" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M763.51,-76.49C723.04,-64.58 662.12,-46.67 619.07,-34"/>
<polygon fill="black" stroke="black" points="620.29,-30.71 609.71,-31.25 618.32,-37.43 620.29,-30.71"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge18" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M806.06,-71.7C806.06,-64.41 806.06,-55.73 806.06,-47.54"/>
<polygon fill="black" stroke="black" points="809.56,-47.62 806.06,-37.62 802.56,-47.62 809.56,-47.62"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge20" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M629.1,-72.41C618.97,-63.54 606.31,-52.47 595.15,-42.71"/>
<polygon fill="black" stroke="black" points="597.58,-40.18 587.75,-36.23 592.97,-45.44 597.58,-40.18"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge21" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M683.13,-73.46C706.43,-63.14 737.22,-49.5 762.16,-38.45"/>
<polygon fill="black" stroke="black" points="763.34,-41.76 771.06,-34.51 760.5,-35.36 763.34,-41.76"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@ -1,205 +1,168 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1064pt" height="260pt" viewBox="0.00 0.00 1063.53 260.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-256 1059.53,-256 1059.53,4 -4,4"/>
<svg width="1028pt" height="260pt" <g id="node1" class="node">
viewBox="0.00 0.00 1027.75 260.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:feature:settings</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)"> <ellipse fill="none" stroke="black" cx="198.06" cy="-234" rx="72.71" ry="18"/>
<title>G</title> <text text-anchor="middle" x="198.06" y="-229.8" font-family="Times,serif" font-size="14.00">:feature:settings</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-256 1023.75,-256 1023.75,4 -4,4"/> </g>
<!-- :feature:settings --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:ui</title>
<title>:feature:settings</title> <ellipse fill="none" stroke="black" cx="198.06" cy="-162" rx="40.53" ry="18"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-234" rx="69.78" ry="18"/> <text text-anchor="middle" x="198.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<text text-anchor="middle" x="192.06" y="-228.95" font-family="Times,serif" font-size="14.00">:feature:settings</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:ui --> <title>:feature:settings-&gt;:core:ui</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M198.06,-215.7C198.06,-208.41 198.06,-199.73 198.06,-191.54"/>
<title>:core:ui</title> <polygon fill="black" stroke="black" points="201.56,-191.62 198.06,-181.62 194.56,-191.62 201.56,-191.62"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-162" rx="39.07" ry="18"/> </g>
<text text-anchor="middle" x="192.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :feature:settings&#45;&gt;:core:ui --> <ellipse fill="none" stroke="black" cx="85.06" cy="-90" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="85.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:feature:settings&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M192.06,-215.7C192.06,-208.41 192.06,-199.73 192.06,-191.54"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="195.56,-191.62 192.06,-181.62 188.56,-191.62 195.56,-191.62"/> <title>:feature:settings-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M181.21,-216.37C171.21,-206.19 158.48,-192.72 148.06,-180 131.56,-159.86 114.61,-135.67 102.45,-117.6"/>
<!-- :core:designsystem --> <polygon fill="black" stroke="black" points="105.52,-115.89 97.06,-109.51 99.69,-119.77 105.52,-115.89"/>
<g id="node3" class="node"> </g>
<title>:core:designsystem</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="82.06" cy="-90" rx="82.06" ry="18"/> <title>:core:data</title>
<text text-anchor="middle" x="82.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <ellipse fill="none" stroke="black" cx="611.06" cy="-162" rx="49.1" ry="18"/>
</g> <text text-anchor="middle" x="611.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<!-- :feature:settings&#45;&gt;:core:designsystem --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:feature:settings&#45;&gt;:core:designsystem</title> <title>:feature:settings-&gt;:core:data</title>
<path fill="none" stroke="black" d="M175.93,-216.3C166.33,-206.1 154.11,-192.63 144.06,-180 128.01,-159.83 111.39,-135.78 99.41,-117.77"/> <path fill="none" stroke="red" stroke-width="2" d="M256.79,-223.05C336.6,-209.52 478.25,-185.51 556.07,-172.32"/>
<polygon fill="black" stroke="black" points="102.35,-115.88 93.93,-109.46 96.51,-119.73 102.35,-115.88"/> <polygon fill="red" stroke="red" stroke-width="2" points="554.81,-176.08 564.09,-170.96 553.64,-169.18 554.81,-176.08"/>
</g> </g>
<!-- :core:data --> <g id="edge5" class="edge">
<g id="node4" class="node"> <title>:core:ui-&gt;:core:designsystem</title>
<title>:core:data</title> <path fill="none" stroke="black" d="M175.19,-146.83C159.63,-137.19 138.71,-124.24 120.95,-113.23"/>
<ellipse fill="none" stroke="black" cx="591.06" cy="-162" rx="47.26" ry="18"/> <polygon fill="black" stroke="black" points="123.09,-110.44 112.74,-108.15 119.4,-116.39 123.09,-110.44"/>
<text text-anchor="middle" x="591.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="node5" class="node">
<!-- :feature:settings&#45;&gt;:core:data --> <title>:core:analytics</title>
<g id="edge3" class="edge"> <ellipse fill="none" stroke="black" cx="293.06" cy="-90" rx="67.34" ry="18"/>
<title>:feature:settings&#45;&gt;:core:data</title> <text text-anchor="middle" x="293.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<path fill="none" stroke="red" stroke-width="2" d="M248.38,-223.12C325.31,-209.62 462.27,-185.59 537.65,-172.37"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="536.53,-176.12 545.77,-170.95 535.32,-169.23 536.53,-176.12"/> <g id="edge4" class="edge">
</g> <title>:core:ui-&gt;:core:analytics</title>
<!-- :core:ui&#45;&gt;:core:designsystem --> <path fill="none" stroke="black" d="M218.2,-146.15C230.89,-136.81 247.53,-124.54 261.9,-113.96"/>
<g id="edge5" class="edge"> <polygon fill="black" stroke="black" points="263.76,-116.94 269.73,-108.19 259.6,-111.3 263.76,-116.94"/>
<title>:core:ui&#45;&gt;:core:designsystem</title> </g>
<path fill="none" stroke="black" d="M169.8,-146.83C154.65,-137.19 134.29,-124.24 117,-113.23"/> <g id="node6" class="node">
<polygon fill="black" stroke="black" points="119.35,-110.58 109.04,-108.17 115.59,-116.49 119.35,-110.58"/> <title>:core:model</title>
</g> <ellipse fill="none" stroke="black" cx="611.06" cy="-18" rx="57.16" ry="18"/>
<!-- :core:analytics --> <text text-anchor="middle" x="611.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<g id="node5" class="node"> </g>
<title>:core:analytics</title> <g id="edge6" class="edge">
<ellipse fill="none" stroke="black" cx="285.06" cy="-90" rx="64.66" ry="18"/> <title>:core:ui-&gt;:core:model</title>
<text text-anchor="middle" x="285.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <path fill="none" stroke="black" d="M196.38,-143.8C195.44,-123.51 197.35,-90.25 217.06,-72 263.07,-29.38 442.34,-20.56 542.46,-19.03"/>
</g> <polygon fill="black" stroke="black" points="542.2,-22.54 552.15,-18.91 542.11,-15.54 542.2,-22.54"/>
<!-- :core:ui&#45;&gt;:core:analytics --> </g>
<g id="edge4" class="edge"> <g id="edge11" class="edge">
<title>:core:ui&#45;&gt;:core:analytics</title> <title>:core:data-&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M211.78,-146.15C224.2,-136.81 240.49,-124.54 254.56,-113.96"/> <path fill="none" stroke="black" d="M569.69,-151.91C521.68,-141.37 440.13,-123.44 370.06,-108 364.98,-106.88 359.71,-105.72 354.42,-104.55"/>
<polygon fill="black" stroke="black" points="256.32,-117.01 262.21,-108.2 252.11,-111.42 256.32,-117.01"/> <polygon fill="black" stroke="black" points="355.58,-101.23 345.07,-102.49 354.08,-108.06 355.58,-101.23"/>
</g> </g>
<!-- :core:model --> <g id="node7" class="node">
<g id="node6" class="node"> <title>:core:common</title>
<title>:core:model</title> <ellipse fill="none" stroke="black" cx="781.06" cy="-18" rx="66.81" ry="18"/>
<ellipse fill="none" stroke="black" cx="591.06" cy="-18" rx="55.45" ry="18"/> <text text-anchor="middle" x="781.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<text text-anchor="middle" x="591.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> </g>
</g> <g id="edge7" class="edge">
<!-- :core:ui&#45;&gt;:core:model --> <title>:core:data-&gt;:core:common</title>
<g id="edge6" class="edge"> <path fill="none" stroke="black" d="M658.9,-157.27C721.41,-151.3 825.69,-137.15 849.06,-108 859.07,-95.52 856.08,-86.38 849.06,-72 842.9,-59.39 832.13,-48.91 820.96,-40.69"/>
<title>:core:ui&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="823.06,-37.88 812.82,-35.17 819.13,-43.68 823.06,-37.88"/>
<path fill="none" stroke="black" d="M190.4,-143.81C189.47,-123.54 191.4,-90.3 211.06,-72 255.22,-30.9 427.13,-21.43 523.91,-19.4"/> </g>
<polygon fill="black" stroke="black" points="523.87,-22.9 533.81,-19.22 523.74,-15.9 523.87,-22.9"/> <g id="node8" class="node">
</g> <title>:core:database</title>
<!-- :core:data&#45;&gt;:core:analytics --> <ellipse fill="none" stroke="black" cx="445.06" cy="-90" rx="66.26" ry="18"/>
<g id="edge11" class="edge"> <text text-anchor="middle" x="445.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<title>:core:data&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="black" d="M551.05,-151.97C504.63,-141.47 425.78,-123.59 358.06,-108 353.57,-106.97 348.92,-105.89 344.24,-104.81"/> <g id="edge8" class="edge">
<polygon fill="black" stroke="black" points="345.36,-101.48 334.82,-102.62 343.78,-108.29 345.36,-101.48"/> <title>:core:data-&gt;:core:database</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M579.83,-147.83C554.6,-137.19 518.74,-122.07 490.35,-110.1"/>
<!-- :core:common --> <polygon fill="red" stroke="red" stroke-width="2" points="493.23,-107.52 482.66,-106.86 490.51,-113.97 493.23,-107.52"/>
<g id="node7" class="node"> </g>
<title>:core:common</title> <g id="node9" class="node">
<ellipse fill="none" stroke="black" cx="755.06" cy="-18" rx="65.17" ry="18"/> <title>:core:datastore</title>
<text text-anchor="middle" x="755.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <ellipse fill="none" stroke="black" cx="964.06" cy="-90" rx="67.87" ry="18"/>
</g> <text text-anchor="middle" x="964.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<!-- :core:data&#45;&gt;:core:common --> </g>
<g id="edge7" class="edge"> <g id="edge9" class="edge">
<title>:core:data&#45;&gt;:core:common</title> <title>:core:data-&gt;:core:datastore</title>
<path fill="none" stroke="black" d="M636.86,-157.02C697,-150.74 797.62,-136.23 820.06,-108 830.02,-95.48 826.92,-86.45 820.06,-72 814.21,-59.69 803.96,-49.3 793.29,-41.07"/> <path fill="none" stroke="black" d="M653.8,-152.8C707.23,-142.5 801.46,-124.24 882.06,-108 888.27,-106.75 894.74,-105.43 901.2,-104.11"/>
<polygon fill="black" stroke="black" points="795.33,-38.22 785.15,-35.27 791.27,-43.92 795.33,-38.22"/> <polygon fill="black" stroke="black" points="901.45,-107.63 910.54,-102.19 900.04,-100.77 901.45,-107.63"/>
</g> </g>
<!-- :core:database --> <g id="node10" class="node">
<g id="node8" class="node"> <title>:core:network</title>
<title>:core:database</title> <ellipse fill="none" stroke="black" cx="775.06" cy="-90" rx="64.66" ry="18"/>
<ellipse fill="none" stroke="black" cx="431.06" cy="-90" rx="63.63" ry="18"/> <text text-anchor="middle" x="775.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<text text-anchor="middle" x="431.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> </g>
</g> <g id="edge10" class="edge">
<!-- :core:data&#45;&gt;:core:database --> <title>:core:data-&gt;:core:network</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M642.29,-147.67C667.26,-137.01 702.58,-121.93 730.52,-110.01"/>
<title>:core:data&#45;&gt;:core:database</title> <polygon fill="black" stroke="black" points="731.61,-113.35 739.43,-106.2 728.86,-106.91 731.61,-113.35"/>
<path fill="none" stroke="red" stroke-width="2" d="M560.97,-147.83C536.75,-137.24 502.38,-122.2 475.07,-110.26"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="477.95,-107.7 467.39,-106.89 475.15,-114.11 477.95,-107.7"/> <g id="node11" class="node">
</g> <title>:core:notifications</title>
<!-- :core:datastore --> <ellipse fill="none" stroke="black" cx="611.06" cy="-90" rx="81.29" ry="18"/>
<g id="node9" class="node"> <text text-anchor="middle" x="611.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<title>:core:datastore</title> </g>
<ellipse fill="none" stroke="black" cx="932.06" cy="-90" rx="65.17" ry="18"/> <g id="edge12" class="edge">
<text text-anchor="middle" x="932.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <title>:core:data-&gt;:core:notifications</title>
</g> <path fill="none" stroke="black" d="M611.06,-143.7C611.06,-136.41 611.06,-127.73 611.06,-119.54"/>
<!-- :core:data&#45;&gt;:core:datastore --> <polygon fill="black" stroke="black" points="614.56,-119.62 611.06,-109.62 607.56,-119.62 614.56,-119.62"/>
<g id="edge9" class="edge"> </g>
<title>:core:data&#45;&gt;:core:datastore</title> <g id="edge13" class="edge">
<path fill="none" stroke="black" d="M632.39,-152.8C684.04,-142.52 775.15,-124.26 853.06,-108 858.9,-106.78 864.97,-105.5 871.05,-104.21"/> <title>:core:database-&gt;:core:model</title>
<polygon fill="black" stroke="black" points="871.4,-107.71 880.45,-102.2 869.94,-100.87 871.4,-107.71"/> <path fill="none" stroke="red" stroke-width="2" d="M479.86,-74.33C505.29,-63.6 539.96,-48.98 567.27,-37.46"/>
</g> <polygon fill="red" stroke="red" stroke-width="2" points="567.08,-41.34 574.93,-34.23 564.36,-34.89 567.08,-41.34"/>
<!-- :core:network --> </g>
<g id="node10" class="node"> <g id="edge15" class="edge">
<title>:core:network</title> <title>:core:datastore-&gt;:core:model</title>
<ellipse fill="none" stroke="black" cx="749.06" cy="-90" rx="62.1" ry="18"/> <path fill="none" stroke="black" d="M910.83,-78.44C846.01,-65.59 736.89,-43.95 669.71,-30.63"/>
<text text-anchor="middle" x="749.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <polygon fill="black" stroke="black" points="670.46,-27.21 659.97,-28.7 669.1,-34.08 670.46,-27.21"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:network --> <g id="edge16" class="edge">
<g id="edge10" class="edge"> <title>:core:datastore-&gt;:core:common</title>
<title>:core:data&#45;&gt;:core:network</title> <path fill="none" stroke="black" d="M926.58,-74.67C898.33,-63.86 859.38,-48.96 828.88,-37.29"/>
<path fill="none" stroke="black" d="M621.15,-147.67C645.1,-137.06 678.94,-122.07 705.79,-110.17"/> <polygon fill="black" stroke="black" points="830.49,-34.16 819.9,-33.86 827.98,-40.7 830.49,-34.16"/>
<polygon fill="black" stroke="black" points="706.97,-113.47 714.7,-106.22 704.14,-107.07 706.97,-113.47"/> </g>
</g> <g id="node12" class="node">
<!-- :core:notifications --> <title>:core:datastore-proto</title>
<g id="node11" class="node"> <ellipse fill="none" stroke="black" cx="964.06" cy="-18" rx="91.47" ry="18"/>
<title>:core:notifications</title> <text text-anchor="middle" x="964.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<ellipse fill="none" stroke="black" cx="591.06" cy="-90" rx="77.97" ry="18"/> </g>
<text text-anchor="middle" x="591.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <g id="edge14" class="edge">
</g> <title>:core:datastore-&gt;:core:datastore-proto</title>
<!-- :core:data&#45;&gt;:core:notifications --> <path fill="none" stroke="black" d="M964.06,-71.7C964.06,-64.41 964.06,-55.73 964.06,-47.54"/>
<g id="edge12" class="edge"> <polygon fill="black" stroke="black" points="967.56,-47.62 964.06,-37.62 960.56,-47.62 967.56,-47.62"/>
<title>:core:data&#45;&gt;:core:notifications</title> </g>
<path fill="none" stroke="black" d="M591.06,-143.7C591.06,-136.41 591.06,-127.73 591.06,-119.54"/> <g id="edge18" class="edge">
<polygon fill="black" stroke="black" points="594.56,-119.62 591.06,-109.62 587.56,-119.62 594.56,-119.62"/> <title>:core:network-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M740.68,-74.33C715.55,-63.6 681.3,-48.98 654.32,-37.46"/>
<!-- :core:database&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="655.96,-34.36 645.39,-33.65 653.21,-40.8 655.96,-34.36"/>
<g id="edge13" class="edge"> </g>
<title>:core:database&#45;&gt;:core:model</title> <g id="edge17" class="edge">
<path fill="none" stroke="red" stroke-width="2" d="M464.6,-74.33C489,-63.65 522.23,-49.11 548.51,-37.62"/> <title>:core:network-&gt;:core:common</title>
<polygon fill="red" stroke="red" stroke-width="2" points="548.4,-41.49 556.15,-34.27 545.59,-35.07 548.4,-41.49"/> <path fill="none" stroke="black" d="M776.54,-71.7C777.17,-64.41 777.91,-55.73 778.61,-47.54"/>
</g> <polygon fill="black" stroke="black" points="782.1,-47.87 779.46,-37.61 775.12,-47.28 782.1,-47.87"/>
<!-- :core:datastore&#45;&gt;:core:model --> </g>
<g id="edge15" class="edge"> <g id="edge19" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:notifications-&gt;:core:model</title>
<path fill="none" stroke="black" d="M881.01,-78.52C818.61,-65.71 713.32,-44.1 648.25,-30.74"/> <path fill="none" stroke="black" d="M611.06,-71.7C611.06,-64.41 611.06,-55.73 611.06,-47.54"/>
<polygon fill="black" stroke="black" points="648.97,-27.31 638.47,-28.73 647.56,-34.17 648.97,-27.31"/> <polygon fill="black" stroke="black" points="614.56,-47.62 611.06,-37.62 607.56,-47.62 614.56,-47.62"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:common --> <g id="edge20" class="edge">
<g id="edge16" class="edge"> <title>:core:notifications-&gt;:core:common</title>
<title>:core:datastore&#45;&gt;:core:common</title> <path fill="none" stroke="black" d="M648.36,-73.64C673.9,-63.12 707.94,-49.11 735.14,-37.91"/>
<path fill="none" stroke="black" d="M895.81,-74.67C868.61,-63.91 831.14,-49.09 801.71,-37.45"/> <polygon fill="black" stroke="black" points="736.27,-41.23 744.18,-34.18 733.6,-34.76 736.27,-41.23"/>
<polygon fill="black" stroke="black" points="803.25,-34.29 792.66,-33.87 800.68,-40.8 803.25,-34.29"/> </g>
</g> </g>
<!-- :core:datastore&#45;proto -->
<g id="node12" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="932.06" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="932.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge14" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M932.06,-71.7C932.06,-64.41 932.06,-55.73 932.06,-47.54"/>
<polygon fill="black" stroke="black" points="935.56,-47.62 932.06,-37.62 928.56,-47.62 935.56,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge18" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M715.94,-74.33C691.84,-63.65 659.03,-49.11 633.08,-37.62"/>
<polygon fill="black" stroke="black" points="634.74,-34.52 624.17,-33.67 631.9,-40.92 634.74,-34.52"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge17" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M750.54,-71.7C751.17,-64.41 751.91,-55.73 752.61,-47.54"/>
<polygon fill="black" stroke="black" points="756.1,-47.87 753.46,-37.61 749.12,-47.28 756.1,-47.87"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge19" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M591.06,-71.7C591.06,-64.41 591.06,-55.73 591.06,-47.54"/>
<polygon fill="black" stroke="black" points="594.56,-47.62 591.06,-37.62 587.56,-47.62 594.56,-47.62"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge20" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M627.05,-73.64C651.5,-63.2 684.01,-49.33 710.15,-38.17"/>
<polygon fill="black" stroke="black" points="711.34,-41.47 719.17,-34.32 708.59,-35.03 711.34,-41.47"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

@ -1,205 +1,168 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1064pt" height="260pt" viewBox="0.00 0.00 1063.53 260.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-256 1059.53,-256 1059.53,4 -4,4"/>
<svg width="1028pt" height="260pt" <g id="node1" class="node">
viewBox="0.00 0.00 1027.75 260.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:feature:topic</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)"> <ellipse fill="none" stroke="black" cx="198.06" cy="-234" rx="62.51" ry="18"/>
<title>G</title> <text text-anchor="middle" x="198.06" y="-229.8" font-family="Times,serif" font-size="14.00">:feature:topic</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-256 1023.75,-256 1023.75,4 -4,4"/> </g>
<!-- :feature:topic --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:ui</title>
<title>:feature:topic</title> <ellipse fill="none" stroke="black" cx="198.06" cy="-162" rx="40.53" ry="18"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-234" rx="60.05" ry="18"/> <text text-anchor="middle" x="198.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:ui</text>
<text text-anchor="middle" x="192.06" y="-228.95" font-family="Times,serif" font-size="14.00">:feature:topic</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:ui --> <title>:feature:topic-&gt;:core:ui</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M198.06,-215.7C198.06,-208.41 198.06,-199.73 198.06,-191.54"/>
<title>:core:ui</title> <polygon fill="black" stroke="black" points="201.56,-191.62 198.06,-181.62 194.56,-191.62 201.56,-191.62"/>
<ellipse fill="none" stroke="black" cx="192.06" cy="-162" rx="39.07" ry="18"/> </g>
<text text-anchor="middle" x="192.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <g id="node3" class="node">
</g> <title>:core:designsystem</title>
<!-- :feature:topic&#45;&gt;:core:ui --> <ellipse fill="none" stroke="black" cx="85.06" cy="-90" rx="85.06" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="85.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
<title>:feature:topic&#45;&gt;:core:ui</title> </g>
<path fill="none" stroke="black" d="M192.06,-215.7C192.06,-208.41 192.06,-199.73 192.06,-191.54"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="195.56,-191.62 192.06,-181.62 188.56,-191.62 195.56,-191.62"/> <title>:feature:topic-&gt;:core:designsystem</title>
</g> <path fill="none" stroke="black" d="M181.21,-216.37C171.21,-206.19 158.48,-192.72 148.06,-180 131.56,-159.86 114.61,-135.67 102.45,-117.6"/>
<!-- :core:designsystem --> <polygon fill="black" stroke="black" points="105.52,-115.89 97.06,-109.51 99.69,-119.77 105.52,-115.89"/>
<g id="node3" class="node"> </g>
<title>:core:designsystem</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="82.06" cy="-90" rx="82.06" ry="18"/> <title>:core:data</title>
<text text-anchor="middle" x="82.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <ellipse fill="none" stroke="black" cx="611.06" cy="-162" rx="49.1" ry="18"/>
</g> <text text-anchor="middle" x="611.06" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<!-- :feature:topic&#45;&gt;:core:designsystem --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:feature:topic&#45;&gt;:core:designsystem</title> <title>:feature:topic-&gt;:core:data</title>
<path fill="none" stroke="black" d="M175.93,-216.3C166.33,-206.1 154.11,-192.63 144.06,-180 128.01,-159.83 111.39,-135.78 99.41,-117.77"/> <path fill="none" stroke="red" stroke-width="2" d="M250.78,-224.06C329.23,-210.77 476,-185.89 555.86,-172.36"/>
<polygon fill="black" stroke="black" points="102.35,-115.88 93.93,-109.46 96.51,-119.73 102.35,-115.88"/> <polygon fill="red" stroke="red" stroke-width="2" points="554.88,-176.07 564.15,-170.95 553.71,-169.17 554.88,-176.07"/>
</g> </g>
<!-- :core:data --> <g id="edge5" class="edge">
<g id="node4" class="node"> <title>:core:ui-&gt;:core:designsystem</title>
<title>:core:data</title> <path fill="none" stroke="black" d="M175.19,-146.83C159.63,-137.19 138.71,-124.24 120.95,-113.23"/>
<ellipse fill="none" stroke="black" cx="591.06" cy="-162" rx="47.26" ry="18"/> <polygon fill="black" stroke="black" points="123.09,-110.44 112.74,-108.15 119.4,-116.39 123.09,-110.44"/>
<text text-anchor="middle" x="591.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> </g>
</g> <g id="node5" class="node">
<!-- :feature:topic&#45;&gt;:core:data --> <title>:core:analytics</title>
<g id="edge3" class="edge"> <ellipse fill="none" stroke="black" cx="293.06" cy="-90" rx="67.34" ry="18"/>
<title>:feature:topic&#45;&gt;:core:data</title> <text text-anchor="middle" x="293.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<path fill="none" stroke="red" stroke-width="2" d="M243,-224.06C318.79,-210.77 460.58,-185.89 537.73,-172.36"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="536.4,-176.14 545.65,-170.97 535.19,-169.25 536.4,-176.14"/> <g id="edge4" class="edge">
</g> <title>:core:ui-&gt;:core:analytics</title>
<!-- :core:ui&#45;&gt;:core:designsystem --> <path fill="none" stroke="black" d="M218.2,-146.15C230.89,-136.81 247.53,-124.54 261.9,-113.96"/>
<g id="edge5" class="edge"> <polygon fill="black" stroke="black" points="263.76,-116.94 269.73,-108.19 259.6,-111.3 263.76,-116.94"/>
<title>:core:ui&#45;&gt;:core:designsystem</title> </g>
<path fill="none" stroke="black" d="M169.8,-146.83C154.65,-137.19 134.29,-124.24 117,-113.23"/> <g id="node6" class="node">
<polygon fill="black" stroke="black" points="119.35,-110.58 109.04,-108.17 115.59,-116.49 119.35,-110.58"/> <title>:core:model</title>
</g> <ellipse fill="none" stroke="black" cx="611.06" cy="-18" rx="57.16" ry="18"/>
<!-- :core:analytics --> <text text-anchor="middle" x="611.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<g id="node5" class="node"> </g>
<title>:core:analytics</title> <g id="edge6" class="edge">
<ellipse fill="none" stroke="black" cx="285.06" cy="-90" rx="64.66" ry="18"/> <title>:core:ui-&gt;:core:model</title>
<text text-anchor="middle" x="285.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <path fill="none" stroke="black" d="M196.38,-143.8C195.44,-123.51 197.35,-90.25 217.06,-72 263.07,-29.38 442.34,-20.56 542.46,-19.03"/>
</g> <polygon fill="black" stroke="black" points="542.2,-22.54 552.15,-18.91 542.11,-15.54 542.2,-22.54"/>
<!-- :core:ui&#45;&gt;:core:analytics --> </g>
<g id="edge4" class="edge"> <g id="edge11" class="edge">
<title>:core:ui&#45;&gt;:core:analytics</title> <title>:core:data-&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M211.78,-146.15C224.2,-136.81 240.49,-124.54 254.56,-113.96"/> <path fill="none" stroke="black" d="M569.69,-151.91C521.68,-141.37 440.13,-123.44 370.06,-108 364.98,-106.88 359.71,-105.72 354.42,-104.55"/>
<polygon fill="black" stroke="black" points="256.32,-117.01 262.21,-108.2 252.11,-111.42 256.32,-117.01"/> <polygon fill="black" stroke="black" points="355.58,-101.23 345.07,-102.49 354.08,-108.06 355.58,-101.23"/>
</g> </g>
<!-- :core:model --> <g id="node7" class="node">
<g id="node6" class="node"> <title>:core:common</title>
<title>:core:model</title> <ellipse fill="none" stroke="black" cx="781.06" cy="-18" rx="66.81" ry="18"/>
<ellipse fill="none" stroke="black" cx="591.06" cy="-18" rx="55.45" ry="18"/> <text text-anchor="middle" x="781.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<text text-anchor="middle" x="591.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> </g>
</g> <g id="edge7" class="edge">
<!-- :core:ui&#45;&gt;:core:model --> <title>:core:data-&gt;:core:common</title>
<g id="edge6" class="edge"> <path fill="none" stroke="black" d="M658.9,-157.27C721.41,-151.3 825.69,-137.15 849.06,-108 859.07,-95.52 856.08,-86.38 849.06,-72 842.9,-59.39 832.13,-48.91 820.96,-40.69"/>
<title>:core:ui&#45;&gt;:core:model</title> <polygon fill="black" stroke="black" points="823.06,-37.88 812.82,-35.17 819.13,-43.68 823.06,-37.88"/>
<path fill="none" stroke="black" d="M190.4,-143.81C189.47,-123.54 191.4,-90.3 211.06,-72 255.22,-30.9 427.13,-21.43 523.91,-19.4"/> </g>
<polygon fill="black" stroke="black" points="523.87,-22.9 533.81,-19.22 523.74,-15.9 523.87,-22.9"/> <g id="node8" class="node">
</g> <title>:core:database</title>
<!-- :core:data&#45;&gt;:core:analytics --> <ellipse fill="none" stroke="black" cx="445.06" cy="-90" rx="66.26" ry="18"/>
<g id="edge11" class="edge"> <text text-anchor="middle" x="445.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<title>:core:data&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="black" d="M551.05,-151.97C504.63,-141.47 425.78,-123.59 358.06,-108 353.57,-106.97 348.92,-105.89 344.24,-104.81"/> <g id="edge8" class="edge">
<polygon fill="black" stroke="black" points="345.36,-101.48 334.82,-102.62 343.78,-108.29 345.36,-101.48"/> <title>:core:data-&gt;:core:database</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M579.83,-147.83C554.6,-137.19 518.74,-122.07 490.35,-110.1"/>
<!-- :core:common --> <polygon fill="red" stroke="red" stroke-width="2" points="493.23,-107.52 482.66,-106.86 490.51,-113.97 493.23,-107.52"/>
<g id="node7" class="node"> </g>
<title>:core:common</title> <g id="node9" class="node">
<ellipse fill="none" stroke="black" cx="755.06" cy="-18" rx="65.17" ry="18"/> <title>:core:datastore</title>
<text text-anchor="middle" x="755.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <ellipse fill="none" stroke="black" cx="964.06" cy="-90" rx="67.87" ry="18"/>
</g> <text text-anchor="middle" x="964.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<!-- :core:data&#45;&gt;:core:common --> </g>
<g id="edge7" class="edge"> <g id="edge9" class="edge">
<title>:core:data&#45;&gt;:core:common</title> <title>:core:data-&gt;:core:datastore</title>
<path fill="none" stroke="black" d="M636.86,-157.02C697,-150.74 797.62,-136.23 820.06,-108 830.02,-95.48 826.92,-86.45 820.06,-72 814.21,-59.69 803.96,-49.3 793.29,-41.07"/> <path fill="none" stroke="black" d="M653.8,-152.8C707.23,-142.5 801.46,-124.24 882.06,-108 888.27,-106.75 894.74,-105.43 901.2,-104.11"/>
<polygon fill="black" stroke="black" points="795.33,-38.22 785.15,-35.27 791.27,-43.92 795.33,-38.22"/> <polygon fill="black" stroke="black" points="901.45,-107.63 910.54,-102.19 900.04,-100.77 901.45,-107.63"/>
</g> </g>
<!-- :core:database --> <g id="node10" class="node">
<g id="node8" class="node"> <title>:core:network</title>
<title>:core:database</title> <ellipse fill="none" stroke="black" cx="775.06" cy="-90" rx="64.66" ry="18"/>
<ellipse fill="none" stroke="black" cx="431.06" cy="-90" rx="63.63" ry="18"/> <text text-anchor="middle" x="775.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<text text-anchor="middle" x="431.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> </g>
</g> <g id="edge10" class="edge">
<!-- :core:data&#45;&gt;:core:database --> <title>:core:data-&gt;:core:network</title>
<g id="edge8" class="edge"> <path fill="none" stroke="black" d="M642.29,-147.67C667.26,-137.01 702.58,-121.93 730.52,-110.01"/>
<title>:core:data&#45;&gt;:core:database</title> <polygon fill="black" stroke="black" points="731.61,-113.35 739.43,-106.2 728.86,-106.91 731.61,-113.35"/>
<path fill="none" stroke="red" stroke-width="2" d="M560.97,-147.83C536.75,-137.24 502.38,-122.2 475.07,-110.26"/> </g>
<polygon fill="red" stroke="red" stroke-width="2" points="477.95,-107.7 467.39,-106.89 475.15,-114.11 477.95,-107.7"/> <g id="node11" class="node">
</g> <title>:core:notifications</title>
<!-- :core:datastore --> <ellipse fill="none" stroke="black" cx="611.06" cy="-90" rx="81.29" ry="18"/>
<g id="node9" class="node"> <text text-anchor="middle" x="611.06" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<title>:core:datastore</title> </g>
<ellipse fill="none" stroke="black" cx="932.06" cy="-90" rx="65.17" ry="18"/> <g id="edge12" class="edge">
<text text-anchor="middle" x="932.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <title>:core:data-&gt;:core:notifications</title>
</g> <path fill="none" stroke="black" d="M611.06,-143.7C611.06,-136.41 611.06,-127.73 611.06,-119.54"/>
<!-- :core:data&#45;&gt;:core:datastore --> <polygon fill="black" stroke="black" points="614.56,-119.62 611.06,-109.62 607.56,-119.62 614.56,-119.62"/>
<g id="edge9" class="edge"> </g>
<title>:core:data&#45;&gt;:core:datastore</title> <g id="edge13" class="edge">
<path fill="none" stroke="black" d="M632.39,-152.8C684.04,-142.52 775.15,-124.26 853.06,-108 858.9,-106.78 864.97,-105.5 871.05,-104.21"/> <title>:core:database-&gt;:core:model</title>
<polygon fill="black" stroke="black" points="871.4,-107.71 880.45,-102.2 869.94,-100.87 871.4,-107.71"/> <path fill="none" stroke="red" stroke-width="2" d="M479.86,-74.33C505.29,-63.6 539.96,-48.98 567.27,-37.46"/>
</g> <polygon fill="red" stroke="red" stroke-width="2" points="567.08,-41.34 574.93,-34.23 564.36,-34.89 567.08,-41.34"/>
<!-- :core:network --> </g>
<g id="node10" class="node"> <g id="edge15" class="edge">
<title>:core:network</title> <title>:core:datastore-&gt;:core:model</title>
<ellipse fill="none" stroke="black" cx="749.06" cy="-90" rx="62.1" ry="18"/> <path fill="none" stroke="black" d="M910.83,-78.44C846.01,-65.59 736.89,-43.95 669.71,-30.63"/>
<text text-anchor="middle" x="749.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <polygon fill="black" stroke="black" points="670.46,-27.21 659.97,-28.7 669.1,-34.08 670.46,-27.21"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:network --> <g id="edge16" class="edge">
<g id="edge10" class="edge"> <title>:core:datastore-&gt;:core:common</title>
<title>:core:data&#45;&gt;:core:network</title> <path fill="none" stroke="black" d="M926.58,-74.67C898.33,-63.86 859.38,-48.96 828.88,-37.29"/>
<path fill="none" stroke="black" d="M621.15,-147.67C645.1,-137.06 678.94,-122.07 705.79,-110.17"/> <polygon fill="black" stroke="black" points="830.49,-34.16 819.9,-33.86 827.98,-40.7 830.49,-34.16"/>
<polygon fill="black" stroke="black" points="706.97,-113.47 714.7,-106.22 704.14,-107.07 706.97,-113.47"/> </g>
</g> <g id="node12" class="node">
<!-- :core:notifications --> <title>:core:datastore-proto</title>
<g id="node11" class="node"> <ellipse fill="none" stroke="black" cx="964.06" cy="-18" rx="91.47" ry="18"/>
<title>:core:notifications</title> <text text-anchor="middle" x="964.06" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<ellipse fill="none" stroke="black" cx="591.06" cy="-90" rx="77.97" ry="18"/> </g>
<text text-anchor="middle" x="591.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <g id="edge14" class="edge">
</g> <title>:core:datastore-&gt;:core:datastore-proto</title>
<!-- :core:data&#45;&gt;:core:notifications --> <path fill="none" stroke="black" d="M964.06,-71.7C964.06,-64.41 964.06,-55.73 964.06,-47.54"/>
<g id="edge12" class="edge"> <polygon fill="black" stroke="black" points="967.56,-47.62 964.06,-37.62 960.56,-47.62 967.56,-47.62"/>
<title>:core:data&#45;&gt;:core:notifications</title> </g>
<path fill="none" stroke="black" d="M591.06,-143.7C591.06,-136.41 591.06,-127.73 591.06,-119.54"/> <g id="edge18" class="edge">
<polygon fill="black" stroke="black" points="594.56,-119.62 591.06,-109.62 587.56,-119.62 594.56,-119.62"/> <title>:core:network-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M740.68,-74.33C715.55,-63.6 681.3,-48.98 654.32,-37.46"/>
<!-- :core:database&#45;&gt;:core:model --> <polygon fill="black" stroke="black" points="655.96,-34.36 645.39,-33.65 653.21,-40.8 655.96,-34.36"/>
<g id="edge13" class="edge"> </g>
<title>:core:database&#45;&gt;:core:model</title> <g id="edge17" class="edge">
<path fill="none" stroke="red" stroke-width="2" d="M464.6,-74.33C489,-63.65 522.23,-49.11 548.51,-37.62"/> <title>:core:network-&gt;:core:common</title>
<polygon fill="red" stroke="red" stroke-width="2" points="548.4,-41.49 556.15,-34.27 545.59,-35.07 548.4,-41.49"/> <path fill="none" stroke="black" d="M776.54,-71.7C777.17,-64.41 777.91,-55.73 778.61,-47.54"/>
</g> <polygon fill="black" stroke="black" points="782.1,-47.87 779.46,-37.61 775.12,-47.28 782.1,-47.87"/>
<!-- :core:datastore&#45;&gt;:core:model --> </g>
<g id="edge15" class="edge"> <g id="edge19" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:notifications-&gt;:core:model</title>
<path fill="none" stroke="black" d="M881.01,-78.52C818.61,-65.71 713.32,-44.1 648.25,-30.74"/> <path fill="none" stroke="black" d="M611.06,-71.7C611.06,-64.41 611.06,-55.73 611.06,-47.54"/>
<polygon fill="black" stroke="black" points="648.97,-27.31 638.47,-28.73 647.56,-34.17 648.97,-27.31"/> <polygon fill="black" stroke="black" points="614.56,-47.62 611.06,-37.62 607.56,-47.62 614.56,-47.62"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:common --> <g id="edge20" class="edge">
<g id="edge16" class="edge"> <title>:core:notifications-&gt;:core:common</title>
<title>:core:datastore&#45;&gt;:core:common</title> <path fill="none" stroke="black" d="M648.36,-73.64C673.9,-63.12 707.94,-49.11 735.14,-37.91"/>
<path fill="none" stroke="black" d="M895.81,-74.67C868.61,-63.91 831.14,-49.09 801.71,-37.45"/> <polygon fill="black" stroke="black" points="736.27,-41.23 744.18,-34.18 733.6,-34.76 736.27,-41.23"/>
<polygon fill="black" stroke="black" points="803.25,-34.29 792.66,-33.87 800.68,-40.8 803.25,-34.29"/> </g>
</g> </g>
<!-- :core:datastore&#45;proto -->
<g id="node12" class="node">
<title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="932.06" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="932.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge14" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M932.06,-71.7C932.06,-64.41 932.06,-55.73 932.06,-47.54"/>
<polygon fill="black" stroke="black" points="935.56,-47.62 932.06,-37.62 928.56,-47.62 935.56,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge18" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M715.94,-74.33C691.84,-63.65 659.03,-49.11 633.08,-37.62"/>
<polygon fill="black" stroke="black" points="634.74,-34.52 624.17,-33.67 631.9,-40.92 634.74,-34.52"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge17" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M750.54,-71.7C751.17,-64.41 751.91,-55.73 752.61,-47.54"/>
<polygon fill="black" stroke="black" points="756.1,-47.87 753.46,-37.61 749.12,-47.28 756.1,-47.87"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge19" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M591.06,-71.7C591.06,-64.41 591.06,-55.73 591.06,-47.54"/>
<polygon fill="black" stroke="black" points="594.56,-47.62 591.06,-37.62 587.56,-47.62 594.56,-47.62"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge20" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M627.05,-73.64C651.5,-63.2 684.01,-49.33 710.15,-38.17"/>
<polygon fill="black" stroke="black" points="711.34,-41.47 719.17,-34.32 708.59,-35.03 711.34,-41.47"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

@ -1,187 +1,153 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="791pt" height="332pt" viewBox="0.00 0.00 791.39 332.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-328 787.39,-328 787.39,4 -4,4"/>
<svg width="763pt" height="332pt" <g id="node1" class="node">
viewBox="0.00 0.00 762.64 332.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:sync:sync-test</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)"> <ellipse fill="none" stroke="black" cx="453.04" cy="-306" rx="68.43" ry="18"/>
<title>G</title> <text text-anchor="middle" x="453.04" y="-301.8" font-family="Times,serif" font-size="14.00">:sync:sync-test</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-328 758.64,-328 758.64,4 -4,4"/> </g>
<!-- :sync:sync&#45;test --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:data</title>
<title>:sync:sync&#45;test</title> <ellipse fill="none" stroke="black" cx="412.04" cy="-162" rx="49.1" ry="18"/>
<ellipse fill="none" stroke="black" cx="436.98" cy="-306" rx="65.68" ry="18"/> <text text-anchor="middle" x="412.04" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<text text-anchor="middle" x="436.98" y="-300.95" font-family="Times,serif" font-size="14.00">:sync:sync&#45;test</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:data --> <title>:sync:sync-test-&gt;:core:data</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M444.89,-287.63C440.34,-277.43 434.84,-264.18 431.04,-252 424.86,-232.14 420.01,-209.18 416.76,-191.55"/>
<title>:core:data</title> <polygon fill="black" stroke="black" points="420.22,-191.03 415.03,-181.79 413.33,-192.25 420.22,-191.03"/>
<ellipse fill="none" stroke="black" cx="396.98" cy="-162" rx="47.26" ry="18"/> </g>
<text text-anchor="middle" x="396.98" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> <g id="node3" class="node">
</g> <title>:sync:work</title>
<!-- :sync:sync&#45;test&#45;&gt;:core:data --> <ellipse fill="none" stroke="black" cx="494.04" cy="-234" rx="53.95" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="494.04" y="-229.8" font-family="Times,serif" font-size="14.00">:sync:work</text>
<title>:sync:sync&#45;test&#45;&gt;:core:data</title> </g>
<path fill="none" stroke="black" d="M429.44,-288.07C425.07,-277.79 419.71,-264.32 415.98,-252 409.96,-232.09 405.11,-209.13 401.81,-191.51"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="405.28,-190.99 400.06,-181.77 398.39,-192.23 405.28,-190.99"/> <title>:sync:sync-test-&gt;:sync:work</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M462.97,-288.05C467.6,-280.14 473.23,-270.54 478.41,-261.69"/>
<!-- :sync:work --> <polygon fill="red" stroke="red" stroke-width="2" points="480.65,-264.8 482.68,-254.4 474.61,-261.26 480.65,-264.8"/>
<g id="node3" class="node"> </g>
<title>:sync:work</title> <g id="node4" class="node">
<ellipse fill="none" stroke="black" cx="476.98" cy="-234" rx="51.86" ry="18"/> <title>:core:common</title>
<text text-anchor="middle" x="476.98" y="-228.95" font-family="Times,serif" font-size="14.00">:sync:work</text> <ellipse fill="none" stroke="black" cx="92.04" cy="-18" rx="66.81" ry="18"/>
</g> <text text-anchor="middle" x="92.04" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
<!-- :sync:sync&#45;test&#45;&gt;:sync:work --> </g>
<g id="edge2" class="edge"> <g id="edge3" class="edge">
<title>:sync:sync&#45;test&#45;&gt;:sync:work</title> <title>:core:data-&gt;:core:common</title>
<path fill="none" stroke="red" stroke-width="2" d="M446.67,-288.05C451.19,-280.14 456.67,-270.54 461.73,-261.69"/> <path fill="none" stroke="black" d="M363.83,-158.21C261.55,-151.79 30.29,-134.48 7.04,-108 -3.51,-95.97 -0.72,-85.99 7.04,-72 15.13,-57.42 29.09,-46.33 43.38,-38.16"/>
<polygon fill="red" stroke="red" stroke-width="2" points="463.96,-264.84 465.89,-254.42 457.89,-261.36 463.96,-264.84"/> <polygon fill="black" stroke="black" points="44.7,-41.42 51.91,-33.66 41.44,-35.22 44.7,-41.42"/>
</g> </g>
<!-- :core:common --> <g id="node5" class="node">
<g id="node4" class="node"> <title>:core:database</title>
<title>:core:common</title> <ellipse fill="none" stroke="black" cx="564.04" cy="-90" rx="66.26" ry="18"/>
<ellipse fill="none" stroke="black" cx="87.98" cy="-18" rx="65.17" ry="18"/> <text text-anchor="middle" x="564.04" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<text text-anchor="middle" x="87.98" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> </g>
</g> <g id="edge4" class="edge">
<!-- :core:data&#45;&gt;:core:common --> <title>:core:data-&gt;:core:database</title>
<g id="edge3" class="edge"> <path fill="none" stroke="red" stroke-width="2" d="M441.71,-147.34C464.24,-136.96 495.55,-122.54 520.85,-110.89"/>
<title>:core:data&#45;&gt;:core:common</title> <polygon fill="red" stroke="red" stroke-width="2" points="520.92,-114.71 528.54,-107.35 517.99,-108.35 520.92,-114.71"/>
<path fill="none" stroke="black" d="M350.54,-158.07C252.04,-151.38 29.32,-133.57 6.98,-108 -3.54,-95.95 -0.63,-86.07 6.98,-72 14.64,-57.84 27.9,-46.86 41.5,-38.66"/> </g>
<polygon fill="black" stroke="black" points="43.02,-41.82 50.07,-33.91 39.62,-35.7 43.02,-41.82"/> <g id="node6" class="node">
</g> <title>:core:datastore</title>
<!-- :core:database --> <ellipse fill="none" stroke="black" cx="412.04" cy="-90" rx="67.87" ry="18"/>
<g id="node5" class="node"> <text text-anchor="middle" x="412.04" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<title>:core:database</title> </g>
<ellipse fill="none" stroke="black" cx="543.98" cy="-90" rx="63.63" ry="18"/> <g id="edge5" class="edge">
<text text-anchor="middle" x="543.98" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <title>:core:data-&gt;:core:datastore</title>
</g> <path fill="none" stroke="black" d="M412.04,-143.7C412.04,-136.41 412.04,-127.73 412.04,-119.54"/>
<!-- :core:data&#45;&gt;:core:database --> <polygon fill="black" stroke="black" points="415.54,-119.62 412.04,-109.62 408.54,-119.62 415.54,-119.62"/>
<g id="edge4" class="edge"> </g>
<title>:core:data&#45;&gt;:core:database</title> <g id="node7" class="node">
<path fill="none" stroke="red" stroke-width="2" d="M425.67,-147.34C447.46,-136.96 477.74,-122.54 502.21,-110.89"/> <title>:core:network</title>
<polygon fill="red" stroke="red" stroke-width="2" points="502.05,-114.85 509.57,-107.39 499.04,-108.53 502.05,-114.85"/> <ellipse fill="none" stroke="black" cx="81.04" cy="-90" rx="64.66" ry="18"/>
</g> <text text-anchor="middle" x="81.04" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
<!-- :core:datastore --> </g>
<g id="node6" class="node"> <g id="edge6" class="edge">
<title>:core:datastore</title> <title>:core:data-&gt;:core:network</title>
<ellipse fill="none" stroke="black" cx="396.98" cy="-90" rx="65.17" ry="18"/> <path fill="none" stroke="black" d="M369.69,-152.57C318.7,-142.35 230.49,-124.44 155.04,-108 150.41,-106.99 145.61,-105.93 140.79,-104.85"/>
<text text-anchor="middle" x="396.98" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <polygon fill="black" stroke="black" points="141.57,-101.44 131.05,-102.65 140.03,-108.26 141.57,-101.44"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:datastore --> <g id="node8" class="node">
<g id="edge5" class="edge"> <title>:core:analytics</title>
<title>:core:data&#45;&gt;:core:datastore</title> <ellipse fill="none" stroke="black" cx="716.04" cy="-90" rx="67.34" ry="18"/>
<path fill="none" stroke="black" d="M396.98,-143.7C396.98,-136.41 396.98,-127.73 396.98,-119.54"/> <text text-anchor="middle" x="716.04" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<polygon fill="black" stroke="black" points="400.48,-119.62 396.98,-109.62 393.48,-119.62 400.48,-119.62"/> </g>
</g> <g id="edge7" class="edge">
<!-- :core:network --> <title>:core:data-&gt;:core:analytics</title>
<g id="node7" class="node"> <path fill="none" stroke="black" d="M452.73,-151.63C504.74,-139.66 595.25,-118.81 655.41,-104.96"/>
<title>:core:network</title> <polygon fill="black" stroke="black" points="655.84,-108.45 664.8,-102.8 654.27,-101.63 655.84,-108.45"/>
<ellipse fill="none" stroke="black" cx="77.98" cy="-90" rx="62.1" ry="18"/> </g>
<text text-anchor="middle" x="77.98" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <g id="node9" class="node">
</g> <title>:core:notifications</title>
<!-- :core:data&#45;&gt;:core:network --> <ellipse fill="none" stroke="black" cx="245.04" cy="-90" rx="81.29" ry="18"/>
<g id="edge6" class="edge"> <text text-anchor="middle" x="245.04" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<title>:core:data&#45;&gt;:core:network</title> </g>
<path fill="none" stroke="black" d="M356.1,-152.58C306.89,-142.38 221.77,-124.49 148.98,-108 144.66,-107.02 140.19,-105.99 135.69,-104.94"/> <g id="edge8" class="edge">
<polygon fill="black" stroke="black" points="136.55,-101.55 126.01,-102.67 134.94,-108.36 136.55,-101.55"/> <title>:core:data-&gt;:core:notifications</title>
</g> <path fill="none" stroke="black" d="M380.63,-147.83C355.75,-137.4 320.59,-122.67 292.31,-110.81"/>
<!-- :core:analytics --> <polygon fill="black" stroke="black" points="293.82,-107.65 283.24,-107.01 291.11,-114.1 293.82,-107.65"/>
<g id="node8" class="node"> </g>
<title>:core:analytics</title> <g id="edge18" class="edge">
<ellipse fill="none" stroke="black" cx="689.98" cy="-90" rx="64.66" ry="18"/> <title>:sync:work-&gt;:core:data</title>
<text text-anchor="middle" x="689.98" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <path fill="none" stroke="red" stroke-width="2" d="M475.03,-216.76C464.39,-207.69 450.96,-196.22 439.24,-186.21"/>
</g> <polygon fill="red" stroke="red" stroke-width="2" points="442.86,-184.7 432.98,-180.87 438.31,-190.03 442.86,-184.7"/>
<!-- :core:data&#45;&gt;:core:analytics --> </g>
<g id="edge7" class="edge"> <g id="edge17" class="edge">
<title>:core:data&#45;&gt;:core:analytics</title> <title>:sync:work-&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M436.19,-151.63C486.12,-139.7 572.84,-118.99 630.82,-105.13"/> <path fill="none" stroke="black" d="M518.22,-217.53C557.69,-192.29 636.1,-142.13 681.45,-113.13"/>
<polygon fill="black" stroke="black" points="631.63,-108.54 640.54,-102.81 630,-101.73 631.63,-108.54"/> <polygon fill="black" stroke="black" points="683.06,-116.25 689.6,-107.92 679.29,-110.36 683.06,-116.25"/>
</g> </g>
<!-- :core:notifications --> <g id="node10" class="node">
<g id="node9" class="node"> <title>:core:model</title>
<title>:core:notifications</title> <ellipse fill="none" stroke="black" cx="245.04" cy="-18" rx="57.16" ry="18"/>
<ellipse fill="none" stroke="black" cx="235.98" cy="-90" rx="77.97" ry="18"/> <text text-anchor="middle" x="245.04" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<text text-anchor="middle" x="235.98" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> </g>
</g> <g id="edge9" class="edge">
<!-- :core:data&#45;&gt;:core:notifications --> <title>:core:database-&gt;:core:model</title>
<g id="edge8" class="edge"> <path fill="none" stroke="red" stroke-width="2" d="M514.86,-77.69C506.26,-75.76 497.4,-73.8 489.04,-72 410.56,-55.13 390.31,-53.88 312.04,-36 307.76,-35.02 303.32,-33.97 298.88,-32.9"/>
<title>:core:data&#45;&gt;:core:notifications</title> <polygon fill="red" stroke="red" stroke-width="2" points="301.35,-29.9 290.8,-30.91 299.67,-36.7 301.35,-29.9"/>
<path fill="none" stroke="black" d="M366.7,-147.83C342.82,-137.45 309.11,-122.8 281.91,-110.97"/> </g>
<polygon fill="black" stroke="black" points="283.42,-107.81 272.85,-107.03 280.63,-114.23 283.42,-107.81"/> <g id="edge12" class="edge">
</g> <title>:core:datastore-&gt;:core:common</title>
<!-- :sync:work&#45;&gt;:core:data --> <path fill="none" stroke="black" d="M361.1,-77.73C352.41,-75.82 343.47,-73.85 335.04,-72 273.42,-58.48 202.98,-43.12 153.86,-32.44"/>
<g id="edge18" class="edge"> <polygon fill="black" stroke="black" points="154.78,-29.05 144.26,-30.35 153.29,-35.89 154.78,-29.05"/>
<title>:sync:work&#45;&gt;:core:data</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M458.43,-216.76C448.06,-207.69 434.95,-196.22 423.51,-186.21"/> <g id="edge11" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="427.27,-184.85 417.44,-180.9 422.66,-190.12 427.27,-184.85"/> <title>:core:datastore-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M377.03,-74.33C351.37,-63.57 316.34,-48.89 288.82,-37.35"/>
<!-- :sync:work&#45;&gt;:core:analytics --> <polygon fill="black" stroke="black" points="290.27,-34.16 279.7,-33.52 287.57,-40.62 290.27,-34.16"/>
<g id="edge17" class="edge"> </g>
<title>:sync:work&#45;&gt;:core:analytics</title> <g id="node11" class="node">
<path fill="none" stroke="black" d="M500.18,-217.53C537.97,-192.34 612.97,-142.34 656.52,-113.31"/> <title>:core:datastore-proto</title>
<polygon fill="black" stroke="black" points="658.19,-116.4 664.57,-107.94 654.31,-110.57 658.19,-116.4"/> <ellipse fill="none" stroke="black" cx="412.04" cy="-18" rx="91.47" ry="18"/>
</g> <text text-anchor="middle" x="412.04" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<!-- :core:model --> </g>
<g id="node10" class="node"> <g id="edge10" class="edge">
<title>:core:model</title> <title>:core:datastore-&gt;:core:datastore-proto</title>
<ellipse fill="none" stroke="black" cx="235.98" cy="-18" rx="55.45" ry="18"/> <path fill="none" stroke="black" d="M412.04,-71.7C412.04,-64.41 412.04,-55.73 412.04,-47.54"/>
<text text-anchor="middle" x="235.98" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <polygon fill="black" stroke="black" points="415.54,-47.62 412.04,-37.62 408.54,-47.62 415.54,-47.62"/>
</g> </g>
<!-- :core:database&#45;&gt;:core:model --> <g id="edge13" class="edge">
<g id="edge9" class="edge"> <title>:core:network-&gt;:core:common</title>
<title>:core:database&#45;&gt;:core:model</title> <path fill="none" stroke="black" d="M83.76,-71.7C84.92,-64.32 86.3,-55.52 87.6,-47.25"/>
<path fill="none" stroke="red" stroke-width="2" d="M496.11,-77.7C487.74,-75.77 479.11,-73.8 470.98,-72 395.16,-55.19 375.54,-53.98 299.98,-36 296.18,-35.09 292.25,-34.13 288.31,-33.14"/> <polygon fill="black" stroke="black" points="91.03,-48.02 89.12,-37.6 84.11,-46.93 91.03,-48.02"/>
<polygon fill="red" stroke="red" stroke-width="2" points="290.7,-30.14 280.15,-31.04 288.96,-36.92 290.7,-30.14"/> </g>
</g> <g id="edge14" class="edge">
<!-- :core:datastore&#45;&gt;:core:common --> <title>:core:network-&gt;:core:model</title>
<g id="edge12" class="edge"> <path fill="none" stroke="black" d="M115.42,-74.33C140.55,-63.6 174.8,-48.98 201.78,-37.46"/>
<title>:core:datastore&#45;&gt;:core:common</title> <polygon fill="black" stroke="black" points="202.89,-40.8 210.72,-33.65 200.14,-34.36 202.89,-40.8"/>
<path fill="none" stroke="black" d="M348.03,-77.72C339.67,-75.81 331.08,-73.84 322.98,-72 263.71,-58.51 195.99,-43.25 148.52,-32.58"/> </g>
<polygon fill="black" stroke="black" points="149.51,-29.22 138.99,-30.44 147.98,-36.05 149.51,-29.22"/> <g id="edge16" class="edge">
</g> <title>:core:notifications-&gt;:core:common</title>
<!-- :core:datastore&#45;&gt;:core:model --> <path fill="none" stroke="black" d="M210.71,-73.29C188.37,-63.07 159.07,-49.66 135.17,-38.73"/>
<g id="edge11" class="edge"> <polygon fill="black" stroke="black" points="136.88,-35.66 126.33,-34.69 133.97,-42.03 136.88,-35.66"/>
<title>:core:datastore&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="black" d="M363.23,-74.33C338.68,-63.65 305.24,-49.11 278.8,-37.62"/> <g id="edge15" class="edge">
<polygon fill="black" stroke="black" points="280.27,-34.44 269.7,-33.66 277.48,-40.86 280.27,-34.44"/> <title>:core:notifications-&gt;:core:model</title>
</g> <path fill="none" stroke="black" d="M245.04,-71.7C245.04,-64.41 245.04,-55.73 245.04,-47.54"/>
<!-- :core:datastore&#45;proto --> <polygon fill="black" stroke="black" points="248.54,-47.62 245.04,-37.62 241.54,-47.62 248.54,-47.62"/>
<g id="node11" class="node"> </g>
<title>:core:datastore&#45;proto</title> </g>
<ellipse fill="none" stroke="black" cx="396.98" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="396.98" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge10" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M396.98,-71.7C396.98,-64.41 396.98,-55.73 396.98,-47.54"/>
<polygon fill="black" stroke="black" points="400.48,-47.62 396.98,-37.62 393.48,-47.62 400.48,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge13" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M80.45,-71.7C81.51,-64.32 82.76,-55.52 83.95,-47.25"/>
<polygon fill="black" stroke="black" points="87.38,-48 85.33,-37.6 80.45,-47.01 87.38,-48"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge14" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M111.1,-74.33C135.2,-63.65 168.02,-49.11 193.96,-37.62"/>
<polygon fill="black" stroke="black" points="195.14,-40.92 202.87,-33.67 192.31,-34.52 195.14,-40.92"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge16" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M202.77,-73.29C181.26,-63.12 153.07,-49.79 130.01,-38.88"/>
<polygon fill="black" stroke="black" points="131.72,-35.82 121.19,-34.7 128.73,-42.14 131.72,-35.82"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge15" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M235.98,-71.7C235.98,-64.41 235.98,-55.73 235.98,-47.54"/>
<polygon fill="black" stroke="black" points="239.48,-47.62 235.98,-37.62 232.48,-47.62 239.48,-47.62"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

@ -1,169 +1,138 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="813pt" height="260pt" viewBox="0.00 0.00 812.60 260.00">
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
--> <title>G</title>
<!-- Title: G Pages: 1 --> <polygon fill="white" stroke="none" points="-4,4 -4,-256 808.6,-256 808.6,4 -4,4"/>
<svg width="785pt" height="260pt" <g id="node1" class="node">
viewBox="0.00 0.00 785.29 260.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>:sync:work</title>
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)"> <ellipse fill="none" stroke="black" cx="161.34" cy="-234" rx="53.95" ry="18"/>
<title>G</title> <text text-anchor="middle" x="161.34" y="-229.8" font-family="Times,serif" font-size="14.00">:sync:work</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-256 781.29,-256 781.29,4 -4,4"/> </g>
<!-- :sync:work --> <g id="node2" class="node">
<g id="node1" class="node"> <title>:core:analytics</title>
<title>:sync:work</title> <ellipse fill="none" stroke="black" cx="67.34" cy="-90" rx="67.34" ry="18"/>
<ellipse fill="none" stroke="black" cx="155.66" cy="-234" rx="51.86" ry="18"/> <text text-anchor="middle" x="67.34" y="-85.8" font-family="Times,serif" font-size="14.00">:core:analytics</text>
<text text-anchor="middle" x="155.66" y="-228.95" font-family="Times,serif" font-size="14.00">:sync:work</text> </g>
</g> <g id="edge1" class="edge">
<!-- :core:analytics --> <title>:sync:work-&gt;:core:analytics</title>
<g id="node2" class="node"> <path fill="none" stroke="black" d="M150.19,-216.15C134.01,-191.71 103.86,-146.17 84.74,-117.29"/>
<title>:core:analytics</title> <polygon fill="black" stroke="black" points="87.75,-115.49 79.32,-109.09 81.92,-119.36 87.75,-115.49"/>
<ellipse fill="none" stroke="black" cx="64.66" cy="-90" rx="64.66" ry="18"/> </g>
<text text-anchor="middle" x="64.66" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <g id="node3" class="node">
</g> <title>:core:data</title>
<!-- :sync:work&#45;&gt;:core:analytics --> <ellipse fill="none" stroke="black" cx="255.34" cy="-162" rx="49.1" ry="18"/>
<g id="edge1" class="edge"> <text text-anchor="middle" x="255.34" y="-157.8" font-family="Times,serif" font-size="14.00">:core:data</text>
<title>:sync:work&#45;&gt;:core:analytics</title> </g>
<path fill="none" stroke="black" d="M144.86,-216.15C129.2,-191.71 100.01,-146.17 81.5,-117.29"/> <g id="edge2" class="edge">
<polygon fill="black" stroke="black" points="84.6,-115.63 76.26,-109.1 78.71,-119.41 84.6,-115.63"/> <title>:sync:work-&gt;:core:data</title>
</g> <path fill="none" stroke="red" stroke-width="2" d="M182.67,-217.12C195.26,-207.74 211.39,-195.73 225.25,-185.41"/>
<!-- :core:data --> <polygon fill="red" stroke="red" stroke-width="2" points="226.06,-189.17 231.99,-180.39 221.88,-183.55 226.06,-189.17"/>
<g id="node3" class="node"> </g>
<title>:core:data</title> <g id="edge7" class="edge">
<ellipse fill="none" stroke="black" cx="247.66" cy="-162" rx="47.26" ry="18"/> <title>:core:data-&gt;:core:analytics</title>
<text text-anchor="middle" x="247.66" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> <path fill="none" stroke="black" d="M221.73,-148.49C192.28,-137.52 149.12,-121.45 115.92,-109.09"/>
</g> <polygon fill="black" stroke="black" points="117.53,-105.95 106.93,-105.74 115.08,-112.51 117.53,-105.95"/>
<!-- :sync:work&#45;&gt;:core:data --> </g>
<g id="edge2" class="edge"> <g id="node4" class="node">
<title>:sync:work&#45;&gt;:core:data</title> <title>:core:common</title>
<path fill="none" stroke="red" stroke-width="2" d="M176.53,-217.12C188.85,-207.74 204.64,-195.73 218.21,-185.41"/> <ellipse fill="none" stroke="black" cx="266.34" cy="-18" rx="66.81" ry="18"/>
<polygon fill="red" stroke="red" stroke-width="2" points="218.93,-189.25 224.77,-180.41 214.7,-183.68 218.93,-189.25"/> <text text-anchor="middle" x="266.34" y="-13.8" font-family="Times,serif" font-size="14.00">:core:common</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:analytics --> <g id="edge3" class="edge">
<g id="edge7" class="edge"> <title>:core:data-&gt;:core:common</title>
<title>:core:data&#45;&gt;:core:analytics</title> <path fill="none" stroke="black" d="M224.51,-147.58C208.51,-138.83 190.44,-125.71 181.34,-108 174.03,-93.77 173.58,-85.99 181.34,-72 189.43,-57.42 203.38,-46.33 217.67,-38.16"/>
<path fill="none" stroke="black" d="M215.36,-148.65C186.78,-137.72 144.7,-121.62 112.27,-109.21"/> <polygon fill="black" stroke="black" points="218.99,-41.42 226.21,-33.66 215.73,-35.22 218.99,-41.42"/>
<polygon fill="black" stroke="black" points="113.67,-106 103.08,-105.7 111.17,-112.54 113.67,-106"/> </g>
</g> <g id="node5" class="node">
<!-- :core:common --> <title>:core:database</title>
<g id="node4" class="node"> <ellipse fill="none" stroke="black" cx="738.34" cy="-90" rx="66.26" ry="18"/>
<title>:core:common</title> <text text-anchor="middle" x="738.34" y="-85.8" font-family="Times,serif" font-size="14.00">:core:database</text>
<ellipse fill="none" stroke="black" cx="257.66" cy="-18" rx="65.17" ry="18"/> </g>
<text text-anchor="middle" x="257.66" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <g id="edge4" class="edge">
</g> <title>:core:data-&gt;:core:database</title>
<!-- :core:data&#45;&gt;:core:common --> <path fill="none" stroke="red" stroke-width="2" d="M302.37,-156.34C378.53,-148.47 533.42,-131.11 663.34,-108 668.49,-107.08 673.82,-106.05 679.16,-104.96"/>
<g id="edge3" class="edge"> <polygon fill="red" stroke="red" stroke-width="2" points="678.05,-108.77 687.1,-103.27 676.59,-101.92 678.05,-108.77"/>
<title>:core:data&#45;&gt;:core:common</title> </g>
<path fill="none" stroke="black" d="M218.41,-147.49C202.96,-138.64 185.41,-125.46 176.66,-108 169.49,-93.7 169.05,-86.07 176.66,-72 184.31,-57.84 197.57,-46.86 211.18,-38.66"/> <g id="node6" class="node">
<polygon fill="black" stroke="black" points="212.7,-41.82 219.74,-33.91 209.3,-35.7 212.7,-41.82"/> <title>:core:datastore</title>
</g> <ellipse fill="none" stroke="black" cx="586.34" cy="-90" rx="67.87" ry="18"/>
<!-- :core:database --> <text text-anchor="middle" x="586.34" y="-85.8" font-family="Times,serif" font-size="14.00">:core:datastore</text>
<g id="node5" class="node"> </g>
<title>:core:database</title> <g id="edge5" class="edge">
<ellipse fill="none" stroke="black" cx="713.66" cy="-90" rx="63.63" ry="18"/> <title>:core:data-&gt;:core:datastore</title>
<text text-anchor="middle" x="713.66" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <path fill="none" stroke="black" d="M297.62,-152.33C348.06,-141.96 434.91,-123.98 509.34,-108 514.22,-106.95 519.26,-105.86 524.33,-104.76"/>
</g> <polygon fill="black" stroke="black" points="524.92,-108.21 533.94,-102.65 523.42,-101.37 524.92,-108.21"/>
<!-- :core:data&#45;&gt;:core:database --> </g>
<g id="edge4" class="edge"> <g id="node7" class="node">
<title>:core:data&#45;&gt;:core:database</title> <title>:core:network</title>
<path fill="none" stroke="red" stroke-width="2" d="M292.97,-156.3C366.34,-148.38 515.55,-130.95 640.66,-108 645.62,-107.09 650.74,-106.07 655.88,-104.99"/> <ellipse fill="none" stroke="black" cx="255.34" cy="-90" rx="64.66" ry="18"/>
<polygon fill="red" stroke="red" stroke-width="2" points="655.08,-108.74 664.11,-103.19 653.59,-101.9 655.08,-108.74"/> <text text-anchor="middle" x="255.34" y="-85.8" font-family="Times,serif" font-size="14.00">:core:network</text>
</g> </g>
<!-- :core:datastore --> <g id="edge6" class="edge">
<g id="node6" class="node"> <title>:core:data-&gt;:core:network</title>
<title>:core:datastore</title> <path fill="none" stroke="black" d="M255.34,-143.7C255.34,-136.41 255.34,-127.73 255.34,-119.54"/>
<ellipse fill="none" stroke="black" cx="566.66" cy="-90" rx="65.17" ry="18"/> <polygon fill="black" stroke="black" points="258.84,-119.62 255.34,-109.62 251.84,-119.62 258.84,-119.62"/>
<text text-anchor="middle" x="566.66" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> </g>
</g> <g id="node8" class="node">
<!-- :core:data&#45;&gt;:core:datastore --> <title>:core:notifications</title>
<g id="edge5" class="edge"> <ellipse fill="none" stroke="black" cx="419.34" cy="-90" rx="81.29" ry="18"/>
<title>:core:data&#45;&gt;:core:datastore</title> <text text-anchor="middle" x="419.34" y="-85.8" font-family="Times,serif" font-size="14.00">:core:notifications</text>
<path fill="none" stroke="black" d="M288.01,-152.44C336.6,-142.09 420.66,-124.06 492.66,-108 497.29,-106.97 502.08,-105.89 506.9,-104.8"/> </g>
<polygon fill="black" stroke="black" points="507.67,-108.21 516.64,-102.58 506.11,-101.39 507.67,-108.21"/> <g id="edge8" class="edge">
</g> <title>:core:data-&gt;:core:notifications</title>
<!-- :core:network --> <path fill="none" stroke="black" d="M286.58,-147.67C310.86,-137.3 344.94,-122.76 372.49,-111"/>
<g id="node7" class="node"> <polygon fill="black" stroke="black" points="373.86,-114.22 381.69,-107.07 371.12,-107.78 373.86,-114.22"/>
<title>:core:network</title> </g>
<ellipse fill="none" stroke="black" cx="247.66" cy="-90" rx="62.1" ry="18"/> <g id="node9" class="node">
<text text-anchor="middle" x="247.66" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <title>:core:model</title>
</g> <ellipse fill="none" stroke="black" cx="419.34" cy="-18" rx="57.16" ry="18"/>
<!-- :core:data&#45;&gt;:core:network --> <text text-anchor="middle" x="419.34" y="-13.8" font-family="Times,serif" font-size="14.00">:core:model</text>
<g id="edge6" class="edge"> </g>
<title>:core:data&#45;&gt;:core:network</title> <g id="edge9" class="edge">
<path fill="none" stroke="black" d="M247.66,-143.7C247.66,-136.41 247.66,-127.73 247.66,-119.54"/> <title>:core:database-&gt;:core:model</title>
<polygon fill="black" stroke="black" points="251.16,-119.62 247.66,-109.62 244.16,-119.62 251.16,-119.62"/> <path fill="none" stroke="red" stroke-width="2" d="M689.16,-77.69C680.56,-75.76 671.7,-73.8 663.34,-72 584.86,-55.13 564.6,-53.88 486.34,-36 482.06,-35.02 477.62,-33.97 473.18,-32.9"/>
</g> <polygon fill="red" stroke="red" stroke-width="2" points="475.65,-29.9 465.1,-30.91 473.97,-36.7 475.65,-29.9"/>
<!-- :core:notifications --> </g>
<g id="node8" class="node"> <g id="edge12" class="edge">
<title>:core:notifications</title> <title>:core:datastore-&gt;:core:common</title>
<ellipse fill="none" stroke="black" cx="405.66" cy="-90" rx="77.97" ry="18"/> <path fill="none" stroke="black" d="M535.4,-77.73C526.71,-75.82 517.77,-73.85 509.34,-72 447.72,-58.48 377.27,-43.12 328.16,-32.44"/>
<text text-anchor="middle" x="405.66" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <polygon fill="black" stroke="black" points="329.07,-29.05 318.56,-30.35 327.59,-35.89 329.07,-29.05"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:notifications --> <g id="edge11" class="edge">
<g id="edge8" class="edge"> <title>:core:datastore-&gt;:core:model</title>
<title>:core:data&#45;&gt;:core:notifications</title> <path fill="none" stroke="black" d="M551.33,-74.33C525.66,-63.57 490.64,-48.89 463.12,-37.35"/>
<path fill="none" stroke="black" d="M277.75,-147.67C301.15,-137.3 333.98,-122.76 360.52,-111"/> <polygon fill="black" stroke="black" points="464.57,-34.16 453.99,-33.52 461.86,-40.62 464.57,-34.16"/>
<polygon fill="black" stroke="black" points="361.61,-114.34 369.34,-107.09 358.78,-107.94 361.61,-114.34"/> </g>
</g> <g id="node10" class="node">
<!-- :core:model --> <title>:core:datastore-proto</title>
<g id="node9" class="node"> <ellipse fill="none" stroke="black" cx="586.34" cy="-18" rx="91.47" ry="18"/>
<title>:core:model</title> <text text-anchor="middle" x="586.34" y="-13.8" font-family="Times,serif" font-size="14.00">:core:datastore-proto</text>
<ellipse fill="none" stroke="black" cx="405.66" cy="-18" rx="55.45" ry="18"/> </g>
<text text-anchor="middle" x="405.66" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <g id="edge10" class="edge">
</g> <title>:core:datastore-&gt;:core:datastore-proto</title>
<!-- :core:database&#45;&gt;:core:model --> <path fill="none" stroke="black" d="M586.34,-71.7C586.34,-64.41 586.34,-55.73 586.34,-47.54"/>
<g id="edge9" class="edge"> <polygon fill="black" stroke="black" points="589.84,-47.62 586.34,-37.62 582.84,-47.62 589.84,-47.62"/>
<title>:core:database&#45;&gt;:core:model</title> </g>
<path fill="none" stroke="red" stroke-width="2" d="M665.79,-77.7C657.42,-75.77 648.79,-73.8 640.66,-72 564.83,-55.19 545.22,-53.98 469.66,-36 465.85,-35.09 461.93,-34.13 457.98,-33.14"/> <g id="edge13" class="edge">
<polygon fill="red" stroke="red" stroke-width="2" points="460.38,-30.14 449.82,-31.04 458.64,-36.92 460.38,-30.14"/> <title>:core:network-&gt;:core:common</title>
</g> <path fill="none" stroke="black" d="M258.06,-71.7C259.22,-64.32 260.6,-55.52 261.9,-47.25"/>
<!-- :core:datastore&#45;&gt;:core:common --> <polygon fill="black" stroke="black" points="265.32,-48.02 263.42,-37.6 258.41,-46.93 265.32,-48.02"/>
<g id="edge12" class="edge"> </g>
<title>:core:datastore&#45;&gt;:core:common</title> <g id="edge14" class="edge">
<path fill="none" stroke="black" d="M517.7,-77.72C509.35,-75.81 500.76,-73.84 492.66,-72 433.39,-58.51 365.66,-43.25 318.2,-32.58"/> <title>:core:network-&gt;:core:model</title>
<polygon fill="black" stroke="black" points="319.19,-29.22 308.66,-30.44 317.65,-36.05 319.19,-29.22"/> <path fill="none" stroke="black" d="M289.72,-74.33C314.85,-63.6 349.1,-48.98 376.08,-37.46"/>
</g> <polygon fill="black" stroke="black" points="377.19,-40.8 385.01,-33.65 374.44,-34.36 377.19,-40.8"/>
<!-- :core:datastore&#45;&gt;:core:model --> </g>
<g id="edge11" class="edge"> <g id="edge16" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:notifications-&gt;:core:common</title>
<path fill="none" stroke="black" d="M532.91,-74.33C508.35,-63.65 474.91,-49.11 448.48,-37.62"/> <path fill="none" stroke="black" d="M385.01,-73.29C362.67,-63.07 333.37,-49.66 309.47,-38.73"/>
<polygon fill="black" stroke="black" points="449.95,-34.44 439.38,-33.66 447.16,-40.86 449.95,-34.44"/> <polygon fill="black" stroke="black" points="311.18,-35.66 300.63,-34.69 308.27,-42.03 311.18,-35.66"/>
</g> </g>
<!-- :core:datastore&#45;proto --> <g id="edge15" class="edge">
<g id="node10" class="node"> <title>:core:notifications-&gt;:core:model</title>
<title>:core:datastore&#45;proto</title> <path fill="none" stroke="black" d="M419.34,-71.7C419.34,-64.41 419.34,-55.73 419.34,-47.54"/>
<ellipse fill="none" stroke="black" cx="566.66" cy="-18" rx="87.69" ry="18"/> <polygon fill="black" stroke="black" points="422.84,-47.62 419.34,-37.62 415.84,-47.62 422.84,-47.62"/>
<text text-anchor="middle" x="566.66" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> </g>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge10" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M566.66,-71.7C566.66,-64.41 566.66,-55.73 566.66,-47.54"/>
<polygon fill="black" stroke="black" points="570.16,-47.62 566.66,-37.62 563.16,-47.62 570.16,-47.62"/>
</g>
<!-- :core:network&#45;&gt;:core:common -->
<g id="edge13" class="edge">
<title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M250.13,-71.7C251.18,-64.32 252.44,-55.52 253.62,-47.25"/>
<polygon fill="black" stroke="black" points="257.05,-48 255,-37.6 250.12,-47.01 257.05,-48"/>
</g>
<!-- :core:network&#45;&gt;:core:model -->
<g id="edge14" class="edge">
<title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M280.78,-74.33C304.88,-63.65 337.69,-49.11 363.64,-37.62"/>
<polygon fill="black" stroke="black" points="364.82,-40.92 372.54,-33.67 361.98,-34.52 364.82,-40.92"/>
</g>
<!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge16" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M372.44,-73.29C350.94,-63.12 322.75,-49.79 299.69,-38.88"/>
<polygon fill="black" stroke="black" points="301.4,-35.82 290.86,-34.7 298.4,-42.14 301.4,-35.82"/>
</g>
<!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge15" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M405.66,-71.7C405.66,-64.41 405.66,-55.73 405.66,-47.54"/>
<polygon fill="black" stroke="black" points="409.16,-47.62 405.66,-37.62 402.16,-47.62 409.16,-47.62"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

@ -23,9 +23,9 @@ import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRepository import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRepository
import com.google.samples.apps.nowinandroid.core.data.repository.SearchContentsRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsCountUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase
import com.google.samples.apps.nowinandroid.core.model.data.UserSearchResult import com.google.samples.apps.nowinandroid.core.model.data.UserSearchResult
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
@ -42,8 +42,8 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class SearchViewModel @Inject constructor( class SearchViewModel @Inject constructor(
getSearchContentsUseCase: GetSearchContentsUseCase, getSearchContentsUseCase: GetSearchContentsUseCase,
getSearchContentsCountUseCase: GetSearchContentsCountUseCase,
recentSearchQueriesUseCase: GetRecentSearchQueriesUseCase, recentSearchQueriesUseCase: GetRecentSearchQueriesUseCase,
private val searchContentsRepository: SearchContentsRepository,
private val recentSearchRepository: RecentSearchRepository, private val recentSearchRepository: RecentSearchRepository,
private val userDataRepository: UserDataRepository, private val userDataRepository: UserDataRepository,
private val savedStateHandle: SavedStateHandle, private val savedStateHandle: SavedStateHandle,
@ -53,7 +53,7 @@ class SearchViewModel @Inject constructor(
val searchQuery = savedStateHandle.getStateFlow(key = SEARCH_QUERY, initialValue = "") val searchQuery = savedStateHandle.getStateFlow(key = SEARCH_QUERY, initialValue = "")
val searchResultUiState: StateFlow<SearchResultUiState> = val searchResultUiState: StateFlow<SearchResultUiState> =
getSearchContentsCountUseCase() searchContentsRepository.getSearchContentsCount()
.flatMapLatest { totalCount -> .flatMapLatest { totalCount ->
if (totalCount < SEARCH_MIN_FTS_ENTITY_COUNT) { if (totalCount < SEARCH_MIN_FTS_ENTITY_COUNT) {
flowOf(SearchResultUiState.SearchNotReady) flowOf(SearchResultUiState.SearchNotReady)

@ -19,7 +19,6 @@ package com.google.samples.apps.nowinandroid.feature.search
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import com.google.samples.apps.nowinandroid.core.analytics.NoOpAnalyticsHelper import com.google.samples.apps.nowinandroid.core.analytics.NoOpAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsCountUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase
import com.google.samples.apps.nowinandroid.core.testing.data.newsResourcesTestData import com.google.samples.apps.nowinandroid.core.testing.data.newsResourcesTestData
import com.google.samples.apps.nowinandroid.core.testing.data.topicsTestData import com.google.samples.apps.nowinandroid.core.testing.data.topicsTestData
@ -60,7 +59,6 @@ class SearchViewModelTest {
) )
private val recentSearchRepository = TestRecentSearchRepository() private val recentSearchRepository = TestRecentSearchRepository()
private val getRecentQueryUseCase = GetRecentSearchQueriesUseCase(recentSearchRepository) private val getRecentQueryUseCase = GetRecentSearchQueriesUseCase(recentSearchRepository)
private val getSearchContentsCountUseCase = GetSearchContentsCountUseCase(searchContentsRepository)
private lateinit var viewModel: SearchViewModel private lateinit var viewModel: SearchViewModel
@ -68,8 +66,8 @@ class SearchViewModelTest {
fun setup() { fun setup() {
viewModel = SearchViewModel( viewModel = SearchViewModel(
getSearchContentsUseCase = getSearchContentsUseCase, getSearchContentsUseCase = getSearchContentsUseCase,
getSearchContentsCountUseCase = getSearchContentsCountUseCase,
recentSearchQueriesUseCase = getRecentQueryUseCase, recentSearchQueriesUseCase = getRecentQueryUseCase,
searchContentsRepository = searchContentsRepository,
savedStateHandle = SavedStateHandle(), savedStateHandle = SavedStateHandle(),
recentSearchRepository = recentSearchRepository, recentSearchRepository = recentSearchRepository,
userDataRepository = userDataRepository, userDataRepository = userDataRepository,
@ -87,7 +85,8 @@ class SearchViewModelTest {
fun stateIsEmptyQuery_withEmptySearchQuery() = runTest { fun stateIsEmptyQuery_withEmptySearchQuery() = runTest {
searchContentsRepository.addNewsResources(newsResourcesTestData) searchContentsRepository.addNewsResources(newsResourcesTestData)
searchContentsRepository.addTopics(topicsTestData) searchContentsRepository.addTopics(topicsTestData)
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
viewModel.onSearchQueryChanged("") viewModel.onSearchQueryChanged("")
@ -98,7 +97,8 @@ class SearchViewModelTest {
@Test @Test
fun emptyResultIsReturned_withNotMatchingQuery() = runTest { fun emptyResultIsReturned_withNotMatchingQuery() = runTest {
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
viewModel.onSearchQueryChanged("XXX") viewModel.onSearchQueryChanged("XXX")
searchContentsRepository.addNewsResources(newsResourcesTestData) searchContentsRepository.addNewsResources(newsResourcesTestData)
@ -112,7 +112,8 @@ class SearchViewModelTest {
@Test @Test
fun recentSearches_verifyUiStateIsSuccess() = runTest { fun recentSearches_verifyUiStateIsSuccess() = runTest {
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.recentSearchQueriesUiState.collect() } val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.recentSearchQueriesUiState.collect() }
viewModel.onSearchTriggered("kotlin") viewModel.onSearchTriggered("kotlin")
val result = viewModel.recentSearchQueriesUiState.value val result = viewModel.recentSearchQueriesUiState.value
@ -123,7 +124,8 @@ class SearchViewModelTest {
@Test @Test
fun searchNotReady_withNoFtsTableEntity() = runTest { fun searchNotReady_withNoFtsTableEntity() = runTest {
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
viewModel.onSearchQueryChanged("") viewModel.onSearchQueryChanged("")

@ -41,13 +41,16 @@ internal class TopicArgs(val topicId: String) {
} }
fun NavController.navigateToTopic(topicId: String, navOptions: NavOptionsBuilder.() -> Unit = {}) { fun NavController.navigateToTopic(topicId: String, navOptions: NavOptionsBuilder.() -> Unit = {}) {
val encodedId = URLEncoder.encode(topicId, URL_CHARACTER_ENCODING) navigate(createTopicRoute(topicId)) {
val newRoute = "$TOPIC_ROUTE/$encodedId"
navigate(newRoute) {
navOptions() navOptions()
} }
} }
fun createTopicRoute(topicId: String): String {
val encodedId = URLEncoder.encode(topicId, URL_CHARACTER_ENCODING)
return "$TOPIC_ROUTE/$encodedId"
}
fun NavGraphBuilder.topicScreen( fun NavGraphBuilder.topicScreen(
showBackButton: Boolean, showBackButton: Boolean,
onBackClick: () -> Unit, onBackClick: () -> Unit,

@ -100,8 +100,11 @@ echo "$module_paths" | while read -r module_path; do
-Pmodules.graph.output.gv="/tmp/${file_name}.gv" \ -Pmodules.graph.output.gv="/tmp/${file_name}.gv" \
-Pmodules.graph.of.module="${module_path}" </dev/null -Pmodules.graph.of.module="${module_path}" </dev/null
# Convert to SVG using dot # Convert to SVG using dot, remove unnecessary comments, and reformat
dot -Tsvg "/tmp/${file_name}.gv" > "docs/images/graphs/${file_name}.svg" dot -Tsvg "/tmp/${file_name}.gv" |
sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' | grep -zv '^<!--' | tr -d '\0' |
xmllint --format - \
> "docs/images/graphs/${file_name}.svg"
# Remove the temporary .gv file # Remove the temporary .gv file
rm "/tmp/${file_name}.gv" rm "/tmp/${file_name}.gv"
fi fi

@ -39,3 +39,6 @@ kotlin.code.style=official
# https://developer.android.com/build/releases/gradle-plugin#default-changes # https://developer.android.com/build/releases/gradle-plugin#default-changes
android.defaults.buildfeatures.resvalues=false android.defaults.buildfeatures.resvalues=false
android.defaults.buildfeatures.shaders=false android.defaults.buildfeatures.shaders=false
# Run Roborazzi screenshot tests with the local tests
roborazzi.test.verify=true

@ -2,14 +2,15 @@
accompanist = "0.34.0" accompanist = "0.34.0"
androidDesugarJdkLibs = "2.0.4" androidDesugarJdkLibs = "2.0.4"
# AGP and tools should be updated together # AGP and tools should be updated together
androidGradlePlugin = "8.3.0" androidGradlePlugin = "8.4.0"
androidTools = "31.3.0" androidTools = "31.4.0"
androidxActivity = "1.8.0" androidxActivity = "1.8.2"
androidxAppCompat = "1.6.1" androidxAppCompat = "1.6.1"
androidxBrowser = "1.8.0" androidxBrowser = "1.8.0"
androidxComposeBom = "2024.02.02" androidxComposeBom = "2024.02.02"
androidxComposeCompiler = "1.5.8" androidxComposeCompiler = "1.5.8"
androidxComposeMaterial3Adaptive = "1.0.0-alpha08" androidxComposeUiTest = "1.7.0-alpha06"
androidxComposeMaterial3Adaptive = "1.0.0-alpha10"
androidxComposeRuntimeTracing = "1.0.0-beta01" androidxComposeRuntimeTracing = "1.0.0-beta01"
androidxCore = "1.12.0" androidxCore = "1.12.0"
androidxCoreSplashscreen = "1.0.1" androidxCoreSplashscreen = "1.0.1"
@ -17,9 +18,9 @@ androidxDataStore = "1.0.0"
androidxEspresso = "3.5.1" androidxEspresso = "3.5.1"
androidxHiltNavigationCompose = "1.2.0" androidxHiltNavigationCompose = "1.2.0"
androidxLifecycle = "2.7.0" androidxLifecycle = "2.7.0"
androidxMacroBenchmark = "1.2.2" androidxMacroBenchmark = "1.2.4"
androidxMetrics = "1.0.0-alpha04" androidxMetrics = "1.0.0-alpha04"
androidxNavigation = "2.7.4" androidxNavigation = "2.8.0-alpha06"
androidxProfileinstaller = "1.3.1" androidxProfileinstaller = "1.3.1"
androidxTestCore = "1.5.0" androidxTestCore = "1.5.0"
androidxTestExt = "1.1.5" androidxTestExt = "1.1.5"
@ -27,10 +28,10 @@ androidxTestRules = "1.5.0"
androidxTestRunner = "1.5.2" androidxTestRunner = "1.5.2"
androidxTracing = "1.3.0-alpha02" androidxTracing = "1.3.0-alpha02"
androidxUiAutomator = "2.2.0" androidxUiAutomator = "2.2.0"
androidxWindowManager = "1.2.0" androidxWindowManager = "1.3.0-alpha03"
androidxWork = "2.9.0" androidxWork = "2.9.0"
coil = "2.6.0" coil = "2.6.0"
dependencyGuard = "0.4.3" dependencyGuard = "0.5.0"
firebaseBom = "32.4.0" firebaseBom = "32.4.0"
firebaseCrashlyticsPlugin = "2.9.9" firebaseCrashlyticsPlugin = "2.9.9"
firebasePerfPlugin = "1.4.2" firebasePerfPlugin = "1.4.2"
@ -48,7 +49,7 @@ kotlinxSerializationJson = "1.6.3"
ksp = "1.9.22-1.0.18" ksp = "1.9.22-1.0.18"
moduleGraph = "2.5.0" moduleGraph = "2.5.0"
okhttp = "4.12.0" okhttp = "4.12.0"
protobuf = "3.25.2" protobuf = "4.26.0"
protobufPlugin = "0.9.4" protobufPlugin = "0.9.4"
retrofit = "2.9.0" retrofit = "2.9.0"
retrofitKotlinxSerializationJson = "1.0.0" retrofitKotlinxSerializationJson = "1.0.0"
@ -57,14 +58,13 @@ roborazzi = "1.7.0"
room = "2.6.1" room = "2.6.1"
secrets = "2.0.1" secrets = "2.0.1"
truth = "1.4.2" truth = "1.4.2"
turbine = "1.0.0" turbine = "1.1.0"
[bundles] [bundles]
androidx-compose-ui-test = ["androidx-compose-ui-test", "androidx-compose-ui-testManifest"] androidx-compose-ui-test = ["androidx-compose-ui-test", "androidx-compose-ui-testManifest"]
[libraries] [libraries]
accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanist" } accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanist" }
accompanist-testharness = { group = "com.google.accompanist", name = "accompanist-testharness", version.ref = "accompanist" }
android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidxAppCompat" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidxAppCompat" }
@ -81,7 +81,7 @@ androidx-compose-material3-adaptive-navigation = { group = "androidx.compose.mat
androidx-compose-material3-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class" } androidx-compose-material3-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class" }
androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" } androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
androidx-compose-runtime-tracing = { group = "androidx.compose.runtime", name = "runtime-tracing", version.ref = "androidxComposeRuntimeTracing" } androidx-compose-runtime-tracing = { group = "androidx.compose.runtime", name = "runtime-tracing", version.ref = "androidxComposeRuntimeTracing" }
androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4", version.ref = "androidxComposeUiTest" }
androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
@ -104,6 +104,7 @@ androidx-test-rules = { group = "androidx.test", name = "rules", version.ref = "
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" } androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" }
androidx-test-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "androidxUiAutomator" } androidx-test-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "androidxUiAutomator" }
androidx-tracing-ktx = { group = "androidx.tracing", name = "tracing-ktx", version.ref = "androidxTracing" } androidx-tracing-ktx = { group = "androidx.tracing", name = "tracing-ktx", version.ref = "androidxTracing" }
androidx-window-core = { group = "androidx.window", name = "window-core", version.ref = "androidxWindowManager" }
androidx-work-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "androidxWork" } androidx-work-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "androidxWork" }
androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "androidxWork" } androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "androidxWork" }
coil-kt = { group = "io.coil-kt", name = "coil", version.ref = "coil" } coil-kt = { group = "io.coil-kt", name = "coil", version.ref = "coil" }
@ -151,7 +152,6 @@ firebase-performance-gradlePlugin = { group = "com.google.firebase", name = "per
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
room-gradlePlugin = { group = "androidx.room", name = "room-gradle-plugin", version.ref = "room" } room-gradlePlugin = { group = "androidx.room", name = "room-gradle-plugin", version.ref = "room" }
work-testing = { group = "androidx.work", name = "work-testing", version = "2.9.0" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }

Binary file not shown.

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

20
gradlew.bat vendored

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

@ -18,6 +18,8 @@ package com.google.samples.apps.nowinandroid.core.sync.test
import com.google.samples.apps.nowinandroid.core.data.util.SyncManager import com.google.samples.apps.nowinandroid.core.data.util.SyncManager
import com.google.samples.apps.nowinandroid.sync.di.SyncModule import com.google.samples.apps.nowinandroid.sync.di.SyncModule
import com.google.samples.apps.nowinandroid.sync.status.StubSyncSubscriber
import com.google.samples.apps.nowinandroid.sync.status.SyncSubscriber
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
@ -33,4 +35,9 @@ internal interface TestSyncModule {
fun bindsSyncStatusMonitor( fun bindsSyncStatusMonitor(
syncStatusMonitor: NeverSyncingSyncManager, syncStatusMonitor: NeverSyncingSyncManager,
): SyncManager ): SyncManager
@Binds
fun bindsSyncSubscriber(
syncSubscriber: StubSyncSubscriber,
): SyncSubscriber
} }

@ -40,5 +40,6 @@ dependencies {
androidTestImplementation(libs.androidx.work.testing) androidTestImplementation(libs.androidx.work.testing)
androidTestImplementation(libs.hilt.android.testing) androidTestImplementation(libs.hilt.android.testing)
androidTestImplementation(libs.kotlinx.coroutines.guava)
androidTestImplementation(projects.core.testing) androidTestImplementation(projects.core.testing)
} }

@ -24,7 +24,7 @@ private const val TAG = "StubSyncSubscriber"
/** /**
* Stub implementation of [SyncSubscriber] * Stub implementation of [SyncSubscriber]
*/ */
internal class StubSyncSubscriber @Inject constructor() : SyncSubscriber { class StubSyncSubscriber @Inject constructor() : SyncSubscriber {
override suspend fun subscribe() { override suspend fun subscribe() {
Log.d(TAG, "Subscribing to sync") Log.d(TAG, "Subscribing to sync")
} }

Loading…
Cancel
Save