diff --git a/.gitignore b/.gitignore index b9beab33be..5a92170dbc 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ local.properties *.iml .idea/ captures/ + +# Kotlin Metadata +.kotlin/ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 85cc6f751f..530df49c74 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,6 +39,8 @@ androidx-viewbinding = "8.1.2" detekt = "1.19.0" dokka = "2.0.0" dependencyGuard = "0.5.0" +# Any version above 0.10.0-beta03 requires Compose 1.8.0 or higher, beta03 is 1.7.3 or higher. +filekit-dialogs-compose = "0.10.0-beta03" google-accompanist = "0.18.0" google-dagger = "2.40.5" @@ -78,6 +80,7 @@ squareup-curtains = "1.2.5" squareup-cycler = "0.1.9" squareup-leakcanary = "3.0-alpha-8" squareup-moshi = "1.15.0" +squareup-moshi-kotlin = "1.15.2" squareup-okhttp = "4.9.1" squareup-okio = "3.3.0" squareup-radiography = "2.4.1" @@ -185,6 +188,7 @@ dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", vers dropbox-dependencyGuard = { module = "com.dropbox.dependency-guard:dependency-guard", version.ref = "dependencyGuard" } +filekit-dialogs-compose = { module = "io.github.vinceglb:filekit-dialogs-compose", version.ref = "filekit-dialogs-compose" } google-android-material = { module = "com.google.android.material:material", version.ref = "material" } google-ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "google-ksp" } @@ -250,6 +254,7 @@ squareup-leakcanary-objectwatcher-android = { module = "com.squareup.leakcanary: squareup-moshi = { module = "com.squareup.moshi:moshi", version.ref = "squareup-moshi" } squareup-moshi-adapters = { module = "com.squareup.moshi:moshi-adapters", version.ref = "squareup-moshi" } squareup-moshi-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "squareup-moshi" } +squareup-moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "squareup-moshi-kotlin" } squareup-okio = { module = "com.squareup.okio:okio", version.ref = "squareup-okio" } diff --git a/workflow-trace-viewer/README.md b/workflow-trace-viewer/README.md index 98b5e424ca..9f989983a8 100644 --- a/workflow-trace-viewer/README.md +++ b/workflow-trace-viewer/README.md @@ -9,3 +9,7 @@ It can be run via Gradle using: ```shell ./gradlew :workflow-trace-viewer:run ``` + +### External Libraries + +[FileKit](https://github.com/vinceglb/FileKit) is an external library made to apply file operations on Kotlin and KMP projects. It's purpose in this app is to allow developers to upload their own json trace files. The motivation for its use is to quickly implement a file picker. diff --git a/workflow-trace-viewer/api/workflow-trace-viewer.api b/workflow-trace-viewer/api/workflow-trace-viewer.api index 783954eb63..dbddaaaa5d 100644 --- a/workflow-trace-viewer/api/workflow-trace-viewer.api +++ b/workflow-trace-viewer/api/workflow-trace-viewer.api @@ -1,5 +1,5 @@ public final class com/squareup/workflow1/traceviewer/AppKt { - public static final fun App (Landroidx/compose/runtime/Composer;I)V + public static final fun App (Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V } public final class com/squareup/workflow1/traceviewer/ComposableSingletons$MainKt { @@ -9,8 +9,47 @@ public final class com/squareup/workflow1/traceviewer/ComposableSingletons$MainK public final fun getLambda-1$wf1_workflow_trace_viewer ()Lkotlin/jvm/functions/Function3; } +public final class com/squareup/workflow1/traceviewer/ComposableSingletons$UploadFileKt { + public static final field INSTANCE Lcom/squareup/workflow1/traceviewer/ComposableSingletons$UploadFileKt; + public static field lambda-1 Lkotlin/jvm/functions/Function3; + public fun ()V + public final fun getLambda-1$wf1_workflow_trace_viewer ()Lkotlin/jvm/functions/Function3; +} + public final class com/squareup/workflow1/traceviewer/MainKt { public static final fun main ()V public static synthetic fun main ([Ljava/lang/String;)V } +public final class com/squareup/workflow1/traceviewer/SandboxBackgroundKt { + public static final fun SandboxBackground (Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/squareup/workflow1/traceviewer/UploadFileKt { + public static final fun UploadFile (Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/squareup/workflow1/traceviewer/WorkflowJsonParserKt { + public static final fun parseTrace (Ljava/lang/String;)Lcom/squareup/workflow1/traceviewer/WorkflowNode; +} + +public final class com/squareup/workflow1/traceviewer/WorkflowNode { + public static final field $stable I + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/util/List; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)Lcom/squareup/workflow1/traceviewer/WorkflowNode; + public static synthetic fun copy$default (Lcom/squareup/workflow1/traceviewer/WorkflowNode;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)Lcom/squareup/workflow1/traceviewer/WorkflowNode; + public fun equals (Ljava/lang/Object;)Z + public final fun getChildren ()Ljava/util/List; + public final fun getId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/squareup/workflow1/traceviewer/WorkflowTreeKt { + public static final fun DrawWorkflowTree (Lcom/squareup/workflow1/traceviewer/WorkflowNode;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V +} + diff --git a/workflow-trace-viewer/build.gradle.kts b/workflow-trace-viewer/build.gradle.kts index 61e4fb13df..c0a63cc870 100644 --- a/workflow-trace-viewer/build.gradle.kts +++ b/workflow-trace-viewer/build.gradle.kts @@ -23,6 +23,8 @@ kotlin { implementation(compose.desktop.currentOs) implementation(libs.kotlinx.coroutines.swing) implementation(compose.materialIconsExtended) + implementation(libs.squareup.moshi.kotlin) + implementation(libs.filekit.dialogs.compose) } } } diff --git a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/App.kt b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/App.kt index 8a82d46090..667e0bdd32 100644 --- a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/App.kt +++ b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/App.kt @@ -1,9 +1,46 @@ package com.squareup.workflow1.traceviewer +import androidx.compose.foundation.layout.Box import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import io.github.vinceglb.filekit.PlatformFile +import io.github.vinceglb.filekit.readString +/** + * Main composable that provides the different layers of UI. + */ @Composable -fun App() { - Text("Hello world!") +public fun App( + modifier: Modifier = Modifier +) { + Box { + var selectedFile by remember { mutableStateOf(null) } + + if (selectedFile != null) { + SandboxBackground { WorkflowContent(selectedFile!!) } + } + + UploadFile(onFileSelect = { selectedFile = it }) + } +} + +@Composable +private fun WorkflowContent(file: PlatformFile) { + var jsonString by remember { mutableStateOf(null) } + LaunchedEffect(file) { + jsonString = file.readString() + } + val root = jsonString?.let { parseTrace(it) } + + if (root != null) { + DrawWorkflowTree(root) + } else { + Text("Empty data or failed to parse data") // TODO: proper handling of error + } } diff --git a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/Main.kt b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/Main.kt index 63ebd1cc3b..b455d04354 100644 --- a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/Main.kt +++ b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/Main.kt @@ -2,6 +2,9 @@ package com.squareup.workflow1.traceviewer import androidx.compose.ui.window.singleWindowApplication +/** + * Main entry point for the desktop application, see [README.md] for more details. + */ fun main() { singleWindowApplication(title = "Workflow Trace Viewer") { App() diff --git a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/SandboxBackground.kt b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/SandboxBackground.kt new file mode 100644 index 0000000000..cbbdb1255c --- /dev/null +++ b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/SandboxBackground.kt @@ -0,0 +1,72 @@ +package com.squareup.workflow1.traceviewer + +import androidx.compose.foundation.gestures.awaitEachGesture +import androidx.compose.foundation.gestures.detectDragGestures +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.input.pointer.pointerInput + +/** + * This is the backdrop for the whole app. Since there can be hundreds of modules at a time, there + * is not realistic way to fit everything on the screen at once. Having the liberty to pan across + * the whole tree as well as zoom into specific subtrees means there's a lot more control when + * analyzing the traces. + * + */ +@Composable +public fun SandboxBackground( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + var scale by remember { mutableFloatStateOf(1f) } + var offset by remember { mutableStateOf(Offset.Zero) } + + Box( + modifier + .fillMaxSize() + .pointerInput(Unit) { + // Panning capabilities: watches for drag gestures and applies the translation + detectDragGestures { _, translation-> + offset += translation + } + } + .pointerInput(Unit) { + // Zooming capabilities: watches for any scroll events and immediately consumes changes. + // - This is AI generated. + awaitEachGesture { + val event = awaitPointerEvent() + if (event.type == PointerEventType.Scroll) { + val scrollDelta = event.changes.first().scrollDelta.y + scale *= if (scrollDelta < 0) 1.1f else 0.9f + scale = scale.coerceIn(0.1f, 10f) + event.changes.forEach { it.consume() } + } + } + } + ) { + Box( + modifier = Modifier + .wrapContentSize(unbounded = true, align = Alignment.Center) + .graphicsLayer { + translationX = offset.x + translationY = offset.y + scaleX = scale + scaleY = scale + } + ) { + content() + } + } +} diff --git a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/UploadFile.kt b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/UploadFile.kt new file mode 100644 index 0000000000..5cfd1d308d --- /dev/null +++ b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/UploadFile.kt @@ -0,0 +1,55 @@ +package com.squareup.workflow1.traceviewer + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Button +import androidx.compose.material.ButtonDefaults.buttonColors +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.github.vinceglb.filekit.PlatformFile +import io.github.vinceglb.filekit.dialogs.FileKitType +import io.github.vinceglb.filekit.dialogs.compose.rememberFilePickerLauncher + +/** + * Provides functionality for user to upload a JSON or .txt file from their local devices, which + * contains information pulled from workflow traces + */ +@Composable +public fun UploadFile( + onFileSelect: (PlatformFile?) -> Unit, + modifier: Modifier = Modifier, +) { + Box( + modifier + .padding(16.dp) + .fillMaxSize() + ) { + val launcher = rememberFilePickerLauncher( + type = FileKitType.File(listOf("json", "txt")), + title = "Select Workflow Trace File" + ) { + onFileSelect(it) + } + Button( + onClick = { launcher.launch() }, + modifier = Modifier + .align(Alignment.BottomEnd), + shape = CircleShape, + colors = buttonColors(Color.Black) + ) { + Text( + text = "+", + color = Color.White, + fontSize = 24.sp, + fontWeight = androidx.compose.ui.text.font.FontWeight.Bold + ) + } + } +} diff --git a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/WorkflowJsonParser.kt b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/WorkflowJsonParser.kt new file mode 100644 index 0000000000..73dbe90735 --- /dev/null +++ b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/WorkflowJsonParser.kt @@ -0,0 +1,29 @@ +package com.squareup.workflow1.traceviewer + +import com.squareup.moshi.JsonDataException +import com.squareup.moshi.Moshi +import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory +import java.io.IOException + +/** + * Parses a JSON string into [WorkflowNode] with Moshi adapters. + * + * All the caught exceptions should be handled by the caller, and appropriate UI feedback should be + * provided to user. + */ +public fun parseTrace( + json: String +): WorkflowNode? { + return try { + val moshi = Moshi.Builder() + .add(KotlinJsonAdapterFactory()) + .build() + val workflowAdapter = moshi.adapter(WorkflowNode::class.java) + val root = workflowAdapter.fromJson(json) + root + } catch (e: JsonDataException) { + throw JsonDataException("Failed to parse JSON: ${e.message}", e) + } catch (e: IOException) { + throw IOException("Malformed JSON: ${e.message}", e) + } +} diff --git a/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/WorkflowTree.kt b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/WorkflowTree.kt new file mode 100644 index 0000000000..536d72f9a6 --- /dev/null +++ b/workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/WorkflowTree.kt @@ -0,0 +1,87 @@ +package com.squareup.workflow1.traceviewer + +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp + +/** + * Since the logic of Workflow is hierarchical (where each workflow may have parent workflows and/or + * children workflows, a tree structure is most appropriate for representing the data rather than + * using flat data structures like an array. + * + * TBD what more metadata should be involved with each node, e.g. (props, states, # of render passes) + */ +public data class WorkflowNode( + val id: String, + val name: String, + val children: List +) + +/** + * Since the workflow nodes present a tree structure, we utilize a recursive function to draw the tree. + * The Column holds a subtree of nodes, and the Row holds all the children of the current node. + */ +@Composable +public fun DrawWorkflowTree( + node: WorkflowNode, + modifier: Modifier = Modifier, +) { + Column( + modifier + .padding(5.dp) + .border(1.dp, Color.Black) + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + // draws itself + DrawNode(node) + + // draws children recursively + Row( + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.Top + ) { + node.children.forEach { childNode -> + DrawWorkflowTree(childNode) + } + } + } +} + +/** + * A basic box that represents a workflow node. + */ +@Composable +private fun DrawNode( + node: WorkflowNode, +) { + var open by remember { mutableStateOf(false) } + Box( + modifier = Modifier + .clickable { open = !open } + .padding(10.dp) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text(text = node.name) + Text(text = "ID: ${node.id}") + if (open) { + Text("node is opened") + } + } + } +} diff --git a/workflow-trace-viewer/src/jvmMain/resources/workflow-20.json b/workflow-trace-viewer/src/jvmMain/resources/workflow-20.json new file mode 100644 index 0000000000..08ad530c63 --- /dev/null +++ b/workflow-trace-viewer/src/jvmMain/resources/workflow-20.json @@ -0,0 +1,105 @@ +{ + "id": 1, + "name": "root", + "children": [ + { + "id": 2, + "name": "auth-flow", + "children": [ + { + "id": 3, + "name": "login-screen", + "children": [ + { + "id": 4, + "name": "login-form", + "children": [] + }, + { + "id": 5, + "name": "social-login", + "children": [] + } + ] + } + ] + }, + { + "id": 6, + "name": "main-flow", + "children": [ + { + "id": 7, + "name": "dashboard", + "children": [ + { + "id": 8, + "name": "stats-widget", + "children": [] + }, + { + "id": 9, + "name": "recent-activity", + "children": [] + } + ] + } + ] + }, + { + "id": 10, + "name": "background-tasks", + "children": [ + { + "id": 11, + "name": "sync-service", + "children": [ + { + "id": 12, + "name": "profile-sync", + "children": [] + }, + { + "id": 13, + "name": "preferences-sync", + "children": [] + } + ] + }, + { + "id": 14, + "name": "notification-service", + "children": [ + { + "id": 15, + "name": "push-handler", + "children": [] + } + ] + } + ] + }, + { + "id": 16, + "name": "settings-flow", + "children": [ + { + "id": 17, + "name": "settings-screen", + "children": [ + { + "id": 18, + "name": "profile-settings", + "children": [] + }, + { + "id": 19, + "name": "notification-settings", + "children": [] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/workflow-trace-viewer/src/jvmMain/resources/workflow-300.json b/workflow-trace-viewer/src/jvmMain/resources/workflow-300.json new file mode 100644 index 0000000000..9733c6e233 --- /dev/null +++ b/workflow-trace-viewer/src/jvmMain/resources/workflow-300.json @@ -0,0 +1,2598 @@ +{ + "id": 1, + "name": "root", + "children": [ + { + "id": 2, + "name": "comment-proxy", + "children": [ + { + "id": 11, + "name": "transformer-collector", + "children": [ + { + "id": 14, + "name": "backup-tracker", + "children": [ + { + "id": 32, + "name": "schedule-form", + "children": [ + { + "id": 66, + "name": "download-aggregator", + "children": [] + }, + { + "id": 67, + "name": "search-handler", + "children": [] + }, + { + "id": 68, + "name": "share-dispatcher", + "children": [] + }, + { + "id": 69, + "name": "profile-factory", + "children": [ + { + "id": 71, + "name": "schedule-tracker", + "children": [] + }, + { + "id": 72, + "name": "data-adapter", + "children": [] + }, + { + "id": 73, + "name": "export-server", + "children": [] + }, + { + "id": 74, + "name": "processor-builder", + "children": [] + } + ] + }, + { + "id": 70, + "name": "signup-controller", + "children": [] + } + ] + }, + { + "id": 33, + "name": "schedule-transformer", + "children": [ + { + "id": 113, + "name": "cart-dispatcher", + "children": [] + }, + { + "id": 114, + "name": "cache-validator", + "children": [] + }, + { + "id": 115, + "name": "admin-server", + "children": [] + }, + { + "id": 116, + "name": "notification-client", + "children": [] + }, + { + "id": 117, + "name": "document-formatter", + "children": [] + } + ] + }, + { + "id": 109, + "name": "utils", + "children": [ + { + "id": 186, + "name": "migration-dispatcher", + "children": [] + }, + { + "id": 187, + "name": "audio-gateway", + "children": [] + }, + { + "id": 335, + "name": "export-form", + "children": [] + }, + { + "id": 336, + "name": "schedule-reporter", + "children": [] + }, + { + "id": 337, + "name": "image-collector", + "children": [] + } + ] + }, + { + "id": 110, + "name": "admin-manager", + "children": [ + { + "id": 124, + "name": "video-sorter", + "children": [] + }, + { + "id": 125, + "name": "config", + "children": [] + }, + { + "id": 156, + "name": "search-encoder", + "children": [ + { + "id": 159, + "name": "storage-logger", + "children": [] + }, + { + "id": 160, + "name": "video-manager", + "children": [] + } + ] + }, + { + "id": 157, + "name": "share-formatter", + "children": [] + }, + { + "id": 175, + "name": "import-reporter", + "children": [ + { + "id": 181, + "name": "api-screen", + "children": [] + }, + { + "id": 182, + "name": "task-client", + "children": [] + }, + { + "id": 183, + "name": "storage-transformer", + "children": [] + }, + { + "id": 184, + "name": "order-service", + "children": [] + }, + { + "id": 185, + "name": "service-component", + "children": [] + } + ] + } + ] + }, + { + "id": 197, + "name": "processor-reporter", + "children": [] + } + ] + }, + { + "id": 15, + "name": "user-client", + "children": [ + { + "id": 47, + "name": "download-parser", + "children": [] + }, + { + "id": 48, + "name": "migration-handler", + "children": [] + }, + { + "id": 49, + "name": "filter-sorter", + "children": [] + }, + { + "id": 198, + "name": "notification-sorter", + "children": [] + }, + { + "id": 256, + "name": "message-formatter", + "children": [] + }, + { + "id": 257, + "name": "message-client", + "children": [] + }, + { + "id": 258, + "name": "storage-gateway", + "children": [] + }, + { + "id": 259, + "name": "schedule-client", + "children": [] + } + ] + }, + { + "id": 16, + "name": "processor-optimizer", + "children": [ + { + "id": 19, + "name": "message-reporter", + "children": [ + { + "id": 283, + "name": "schedule-collector", + "children": [] + }, + { + "id": 284, + "name": "review-scheduler", + "children": [] + }, + { + "id": 285, + "name": "sync-filter", + "children": [] + }, + { + "id": 286, + "name": "workspace-validator", + "children": [] + }, + { + "id": 338, + "name": "signup-logger", + "children": [ + { + "id": 482, + "name": "admin-monitor", + "children": [] + }, + { + "id": 483, + "name": "storage-collector", + "children": [] + } + ] + }, + { + "id": 339, + "name": "download-flow", + "children": [ + { + "id": 355, + "name": "order-processor", + "children": [] + }, + { + "id": 356, + "name": "import-client", + "children": [] + }, + { + "id": 357, + "name": "report-collector", + "children": [] + }, + { + "id": 358, + "name": "storage-client", + "children": [] + } + ] + } + ] + }, + { + "id": 20, + "name": "comment-service", + "children": [ + { + "id": 34, + "name": "report-monitor", + "children": [ + { + "id": 84, + "name": "worker-widget", + "children": [ + { + "id": 384, + "name": "migration-service", + "children": [] + }, + { + "id": 385, + "name": "validator-reporter", + "children": [] + }, + { + "id": 386, + "name": "api-server", + "children": [] + }, + { + "id": 387, + "name": "data-logger", + "children": [] + }, + { + "id": 388, + "name": "document-screen", + "children": [] + } + ] + }, + { + "id": 85, + "name": "constants", + "children": [ + { + "id": 131, + "name": "sync-controller", + "children": [] + }, + { + "id": 174, + "name": "message-flow", + "children": [] + }, + { + "id": 214, + "name": "image-tracker", + "children": [ + { + "id": 289, + "name": "project-server", + "children": [ + { + "id": 321, + "name": "filter-manager", + "children": [] + }, + { + "id": 322, + "name": "refresh", + "children": [] + }, + { + "id": 323, + "name": "service-controller", + "children": [ + { + "id": 334, + "name": "audio-scheduler", + "children": [] + } + ] + }, + { + "id": 324, + "name": "upload-controller", + "children": [] + }, + { + "id": 325, + "name": "login-analyzer", + "children": [] + } + ] + }, + { + "id": 366, + "name": "user-parser", + "children": [] + }, + { + "id": 367, + "name": "settings-handler", + "children": [] + }, + { + "id": 368, + "name": "database-component", + "children": [] + }, + { + "id": 369, + "name": "login-filter", + "children": [] + }, + { + "id": 370, + "name": "workspace-dispatcher", + "children": [] + } + ] + }, + { + "id": 215, + "name": "worker-scheduler", + "children": [ + { + "id": 265, + "name": "task-gateway", + "children": [] + }, + { + "id": 266, + "name": "schedule-processor", + "children": [ + { + "id": 290, + "name": "upload-server", + "children": [ + { + "id": 307, + "name": "database-validator", + "children": [] + }, + { + "id": 308, + "name": "signup-aggregator", + "children": [] + }, + { + "id": 309, + "name": "share-optimizer", + "children": [] + }, + { + "id": 315, + "name": "order-reporter", + "children": [] + }, + { + "id": 316, + "name": "auth-service", + "children": [ + { + "id": 390, + "name": "document-factory", + "children": [ + { + "id": 494, + "name": "admin-aggregator", + "children": [] + }, + { + "id": 495, + "name": "task-scheduler", + "children": [] + } + ] + }, + { + "id": 391, + "name": "team-screen", + "children": [ + { + "id": 418, + "name": "backup-sorter", + "children": [ + { + "id": 449, + "name": "share-form", + "children": [] + }, + { + "id": 450, + "name": "user-monitor", + "children": [] + }, + { + "id": 488, + "name": "share-scheduler", + "children": [] + } + ] + }, + { + "id": 419, + "name": "backup-factory", + "children": [] + }, + { + "id": 420, + "name": "sync-optimizer", + "children": [] + }, + { + "id": 421, + "name": "video-server", + "children": [] + }, + { + "id": 422, + "name": "signup-validator", + "children": [] + } + ] + }, + { + "id": 392, + "name": "signup-transformer", + "children": [] + }, + { + "id": 393, + "name": "share-controller", + "children": [] + }, + { + "id": 433, + "name": "settings-client", + "children": [] + }, + { + "id": 434, + "name": "notification-controller", + "children": [] + }, + { + "id": 435, + "name": "workspace-collector", + "children": [] + }, + { + "id": 436, + "name": "processor-server", + "children": [] + }, + { + "id": 437, + "name": "report-transformer", + "children": [] + } + ] + } + ] + }, + { + "id": 291, + "name": "worker-client", + "children": [ + { + "id": 310, + "name": "analytics-adapter", + "children": [] + }, + { + "id": 311, + "name": "settings-tracker", + "children": [] + }, + { + "id": 312, + "name": "migration-processor", + "children": [] + }, + { + "id": 451, + "name": "validator-analyzer", + "children": [] + }, + { + "id": 452, + "name": "filter-collector", + "children": [] + }, + { + "id": 453, + "name": "export-collector", + "children": [] + }, + { + "id": 454, + "name": "team-adapter", + "children": [] + }, + { + "id": 455, + "name": "workspace-service", + "children": [] + } + ] + }, + { + "id": 410, + "name": "video-service", + "children": [] + }, + { + "id": 411, + "name": "analytics-builder", + "children": [] + }, + { + "id": 412, + "name": "workspace-proxy", + "children": [] + }, + { + "id": 413, + "name": "service-reporter", + "children": [] + } + ] + }, + { + "id": 267, + "name": "rating-parser", + "children": [] + }, + { + "id": 268, + "name": "cart-manager", + "children": [ + { + "id": 273, + "name": "team-component", + "children": [] + }, + { + "id": 274, + "name": "signup-tracker", + "children": [] + }, + { + "id": 275, + "name": "sync-dispatcher", + "children": [] + }, + { + "id": 276, + "name": "worker-processor", + "children": [] + }, + { + "id": 277, + "name": "auth-server", + "children": [] + } + ] + }, + { + "id": 269, + "name": "backup-service", + "children": [] + } + ] + }, + { + "id": 216, + "name": "login-builder", + "children": [] + }, + { + "id": 217, + "name": "login-formatter", + "children": [] + } + ] + }, + { + "id": 313, + "name": "import-dispatcher", + "children": [ + { + "id": 317, + "name": "transformer-monitor", + "children": [] + }, + { + "id": 318, + "name": "message-dispatcher", + "children": [] + }, + { + "id": 319, + "name": "dashboard-collector", + "children": [] + }, + { + "id": 320, + "name": "cache-processor", + "children": [] + } + ] + }, + { + "id": 314, + "name": "filter-widget", + "children": [ + { + "id": 428, + "name": "notification-optimizer", + "children": [] + }, + { + "id": 429, + "name": "migration-analyzer", + "children": [] + }, + { + "id": 430, + "name": "download-gateway", + "children": [] + }, + { + "id": 431, + "name": "workspace-widget", + "children": [] + }, + { + "id": 432, + "name": "image-parser", + "children": [] + } + ] + }, + { + "id": 461, + "name": "analytics-flow", + "children": [] + }, + { + "id": 462, + "name": "order-filter", + "children": [] + }, + { + "id": 463, + "name": "image-builder", + "children": [] + }, + { + "id": 464, + "name": "rating-proxy", + "children": [] + }, + { + "id": 465, + "name": "auth-gateway", + "children": [] + } + ] + }, + { + "id": 35, + "name": "comment-widget", + "children": [] + }, + { + "id": 36, + "name": "user-factory", + "children": [] + }, + { + "id": 86, + "name": "backup-screen", + "children": [ + { + "id": 234, + "name": "document-service", + "children": [] + }, + { + "id": 235, + "name": "cart-builder", + "children": [] + }, + { + "id": 236, + "name": "restore-gateway", + "children": [] + }, + { + "id": 237, + "name": "upload-analyzer", + "children": [] + }, + { + "id": 251, + "name": "analytics-analyzer", + "children": [] + }, + { + "id": 252, + "name": "comment-reporter", + "children": [] + }, + { + "id": 253, + "name": "storage-dispatcher", + "children": [] + }, + { + "id": 254, + "name": "report-client", + "children": [] + }, + { + "id": 255, + "name": "restore-factory", + "children": [] + } + ] + }, + { + "id": 87, + "name": "audio-client", + "children": [ + { + "id": 147, + "name": "restore-client", + "children": [] + }, + { + "id": 148, + "name": "auth-aggregator", + "children": [] + }, + { + "id": 149, + "name": "filter-parser", + "children": [] + }, + { + "id": 150, + "name": "migration-adapter", + "children": [] + }, + { + "id": 151, + "name": "team-scheduler", + "children": [ + { + "id": 152, + "name": "restore-builder", + "children": [] + }, + { + "id": 153, + "name": "filter-scheduler", + "children": [] + }, + { + "id": 154, + "name": "message-adapter", + "children": [] + }, + { + "id": 155, + "name": "storage-handler", + "children": [] + } + ] + } + ] + }, + { + "id": 88, + "name": "login-client", + "children": [] + }, + { + "id": 89, + "name": "payment-transformer", + "children": [] + } + ] + }, + { + "id": 21, + "name": "service-sorter", + "children": [ + { + "id": 118, + "name": "video-transformer", + "children": [] + }, + { + "id": 270, + "name": "comment-parser", + "children": [] + }, + { + "id": 271, + "name": "restore-form", + "children": [] + }, + { + "id": 272, + "name": "signup-manager", + "children": [] + }, + { + "id": 340, + "name": "schedule-component", + "children": [] + }, + { + "id": 341, + "name": "processor-formatter", + "children": [] + }, + { + "id": 342, + "name": "image-form", + "children": [ + { + "id": 346, + "name": "worker-sorter", + "children": [ + { + "id": 359, + "name": "share-flow", + "children": [] + }, + { + "id": 360, + "name": "admin-flow", + "children": [] + }, + { + "id": 361, + "name": "worker-validator", + "children": [] + } + ] + }, + { + "id": 347, + "name": "download-optimizer", + "children": [] + }, + { + "id": 348, + "name": "login-adapter", + "children": [] + }, + { + "id": 349, + "name": "audio-transformer", + "children": [] + } + ] + }, + { + "id": 343, + "name": "processor-factory", + "children": [] + }, + { + "id": 344, + "name": "dashboard-component", + "children": [ + { + "id": 350, + "name": "restore-scheduler", + "children": [] + }, + { + "id": 351, + "name": "data-aggregator", + "children": [] + }, + { + "id": 352, + "name": "user-service", + "children": [] + }, + { + "id": 353, + "name": "image-dispatcher", + "children": [] + }, + { + "id": 354, + "name": "dashboard-formatter", + "children": [] + } + ] + } + ] + }, + { + "id": 96, + "name": "login-optimizer", + "children": [] + }, + { + "id": 97, + "name": "api-sorter", + "children": [] + }, + { + "id": 98, + "name": "user-filter", + "children": [] + }, + { + "id": 99, + "name": "login-dispatcher", + "children": [] + } + ] + }, + { + "id": 17, + "name": "rating-controller", + "children": [ + { + "id": 30, + "name": "workspace-flow", + "children": [ + { + "id": 466, + "name": "api-formatter", + "children": [] + }, + { + "id": 467, + "name": "auth-tracker", + "children": [] + }, + { + "id": 468, + "name": "message-decoder", + "children": [] + }, + { + "id": 469, + "name": "audio-collector", + "children": [] + }, + { + "id": 470, + "name": "project-service", + "children": [] + } + ] + }, + { + "id": 31, + "name": "team-proxy", + "children": [ + { + "id": 80, + "name": "chat-component", + "children": [] + }, + { + "id": 81, + "name": "project-validator", + "children": [] + }, + { + "id": 82, + "name": "search-dispatcher", + "children": [] + }, + { + "id": 83, + "name": "signup-factory", + "children": [] + }, + { + "id": 239, + "name": "chat-client", + "children": [] + }, + { + "id": 240, + "name": "import-proxy", + "children": [] + } + ] + }, + { + "id": 61, + "name": "schedule-dispatcher", + "children": [] + }, + { + "id": 62, + "name": "document-filter", + "children": [] + }, + { + "id": 139, + "name": "login-handler", + "children": [ + { + "id": 158, + "name": "review-adapter", + "children": [] + } + ] + }, + { + "id": 140, + "name": "restore-adapter", + "children": [] + }, + { + "id": 141, + "name": "migration-tracker", + "children": [] + } + ] + }, + { + "id": 18, + "name": "validator-flow", + "children": [ + { + "id": 22, + "name": "login-reporter", + "children": [ + { + "id": 28, + "name": "api-controller", + "children": [ + { + "id": 104, + "name": "project-flow", + "children": [] + }, + { + "id": 105, + "name": "worker-filter", + "children": [] + }, + { + "id": 106, + "name": "comment-client", + "children": [] + }, + { + "id": 107, + "name": "download-widget", + "children": [] + }, + { + "id": 108, + "name": "login-decoder", + "children": [] + } + ] + }, + { + "id": 29, + "name": "transformer-server", + "children": [ + { + "id": 50, + "name": "cache-component", + "children": [] + }, + { + "id": 51, + "name": "worker-decoder", + "children": [] + }, + { + "id": 52, + "name": "video-component", + "children": [] + }, + { + "id": 53, + "name": "backup-transformer", + "children": [] + }, + { + "id": 111, + "name": "setup", + "children": [ + { + "id": 126, + "name": "project-handler", + "children": [] + }, + { + "id": 127, + "name": "admin-tracker", + "children": [] + }, + { + "id": 128, + "name": "validator-encoder", + "children": [] + }, + { + "id": 129, + "name": "task-builder", + "children": [] + }, + { + "id": 130, + "name": "project-sorter", + "children": [] + } + ] + }, + { + "id": 112, + "name": "backup-server", + "children": [ + { + "id": 219, + "name": "notification-parser", + "children": [] + }, + { + "id": 220, + "name": "profile-reporter", + "children": [] + }, + { + "id": 221, + "name": "storage-factory", + "children": [] + }, + { + "id": 222, + "name": "video-adapter", + "children": [] + }, + { + "id": 389, + "name": "workspace-factory", + "children": [ + { + "id": 423, + "name": "api-service", + "children": [] + } + ] + } + ] + } + ] + }, + { + "id": 91, + "name": "auth-encoder", + "children": [] + }, + { + "id": 119, + "name": "backup-handler", + "children": [] + }, + { + "id": 120, + "name": "dashboard-dispatcher", + "children": [] + } + ] + }, + { + "id": 23, + "name": "cart-client", + "children": [ + { + "id": 207, + "name": "search-sorter", + "children": [] + }, + { + "id": 208, + "name": "schedule-aggregator", + "children": [] + }, + { + "id": 209, + "name": "document-adapter", + "children": [] + } + ] + }, + { + "id": 24, + "name": "upload-tracker", + "children": [ + { + "id": 161, + "name": "message-component", + "children": [ + { + "id": 498, + "name": "api-manager", + "children": [] + }, + { + "id": 499, + "name": "auth-client", + "children": [] + }, + { + "id": 500, + "name": "storage-parser", + "children": [] + } + ] + }, + { + "id": 162, + "name": "cache-factory", + "children": [] + }, + { + "id": 163, + "name": "user-logger", + "children": [ + { + "id": 165, + "name": "search-monitor", + "children": [] + }, + { + "id": 166, + "name": "validator-screen", + "children": [] + }, + { + "id": 167, + "name": "comment-logger", + "children": [] + }, + { + "id": 190, + "name": "report-server", + "children": [ + { + "id": 247, + "name": "analytics-widget", + "children": [] + }, + { + "id": 248, + "name": "cache-flow", + "children": [] + }, + { + "id": 249, + "name": "analytics-optimizer", + "children": [] + }, + { + "id": 250, + "name": "report-service", + "children": [] + }, + { + "id": 362, + "name": "workspace-formatter", + "children": [ + { + "id": 403, + "name": "filter-validator", + "children": [] + }, + { + "id": 404, + "name": "cart-adapter", + "children": [] + }, + { + "id": 405, + "name": "api-reporter", + "children": [] + }, + { + "id": 406, + "name": "migration-scheduler", + "children": [] + }, + { + "id": 407, + "name": "review-flow", + "children": [] + } + ] + }, + { + "id": 363, + "name": "document-validator", + "children": [ + { + "id": 440, + "name": "storage-filter", + "children": [ + { + "id": 445, + "name": "cart-factory", + "children": [] + }, + { + "id": 446, + "name": "task-filter", + "children": [] + }, + { + "id": 447, + "name": "team-validator", + "children": [] + }, + { + "id": 448, + "name": "report-parser", + "children": [] + }, + { + "id": 476, + "name": "filter-form", + "children": [] + }, + { + "id": 477, + "name": "video-encoder", + "children": [] + } + ] + }, + { + "id": 441, + "name": "analytics-scheduler", + "children": [] + }, + { + "id": 442, + "name": "chat-optimizer", + "children": [] + }, + { + "id": 443, + "name": "validator-form", + "children": [ + { + "id": 496, + "name": "processor-component", + "children": [] + }, + { + "id": 497, + "name": "migration-reporter", + "children": [] + } + ] + }, + { + "id": 444, + "name": "dashboard-decoder", + "children": [] + } + ] + }, + { + "id": 364, + "name": "notification-form", + "children": [ + { + "id": 408, + "name": "order-controller", + "children": [] + }, + { + "id": 409, + "name": "backup-reporter", + "children": [] + } + ] + }, + { + "id": 365, + "name": "sync-monitor", + "children": [] + } + ] + }, + { + "id": 191, + "name": "share-sorter", + "children": [ + { + "id": 228, + "name": "migration-client", + "children": [] + }, + { + "id": 229, + "name": "profile-monitor", + "children": [] + }, + { + "id": 260, + "name": "payment-factory", + "children": [] + }, + { + "id": 471, + "name": "schedule-flow", + "children": [ + { + "id": 472, + "name": "upload-widget", + "children": [] + }, + { + "id": 473, + "name": "download-client", + "children": [] + }, + { + "id": 474, + "name": "payment-analyzer", + "children": [] + } + ] + } + ] + }, + { + "id": 192, + "name": "search-service", + "children": [ + { + "id": 295, + "name": "validator-component", + "children": [] + }, + { + "id": 296, + "name": "team-transformer", + "children": [] + }, + { + "id": 297, + "name": "database-aggregator", + "children": [] + }, + { + "id": 298, + "name": "profile-sorter", + "children": [] + }, + { + "id": 398, + "name": "report-manager", + "children": [] + }, + { + "id": 399, + "name": "review-widget", + "children": [] + }, + { + "id": 400, + "name": "message-widget", + "children": [] + }, + { + "id": 401, + "name": "user-encoder", + "children": [] + }, + { + "id": 402, + "name": "auth-formatter", + "children": [] + } + ] + }, + { + "id": 193, + "name": "worker-monitor", + "children": [] + } + ] + }, + { + "id": 164, + "name": "database-parser", + "children": [ + { + "id": 394, + "name": "worker-server", + "children": [] + }, + { + "id": 395, + "name": "transformer-decoder", + "children": [] + }, + { + "id": 396, + "name": "settings-processor", + "children": [] + }, + { + "id": 397, + "name": "document-controller", + "children": [] + } + ] + }, + { + "id": 168, + "name": "audio-validator", + "children": [] + }, + { + "id": 169, + "name": "transformer-client", + "children": [] + } + ] + }, + { + "id": 25, + "name": "export-aggregator", + "children": [ + { + "id": 218, + "name": "project-client", + "children": [] + } + ] + }, + { + "id": 26, + "name": "auth-handler", + "children": [ + { + "id": 223, + "name": "chat-decoder", + "children": [] + }, + { + "id": 224, + "name": "filter-decoder", + "children": [] + }, + { + "id": 225, + "name": "document-collector", + "children": [] + }, + { + "id": 226, + "name": "backup-proxy", + "children": [] + }, + { + "id": 227, + "name": "api-factory", + "children": [] + } + ] + }, + { + "id": 27, + "name": "migration-optimizer", + "children": [ + { + "id": 54, + "name": "signup-screen", + "children": [] + }, + { + "id": 55, + "name": "settings-flow", + "children": [] + }, + { + "id": 56, + "name": "task-service", + "children": [] + }, + { + "id": 57, + "name": "backup-component", + "children": [] + }, + { + "id": 58, + "name": "order-builder", + "children": [] + } + ] + } + ] + } + ] + }, + { + "id": 60, + "name": "cart-component", + "children": [ + { + "id": 75, + "name": "backup-processor", + "children": [] + }, + { + "id": 76, + "name": "import-filter", + "children": [] + }, + { + "id": 77, + "name": "database-proxy", + "children": [] + }, + { + "id": 78, + "name": "share-service", + "children": [] + }, + { + "id": 79, + "name": "dashboard-screen", + "children": [] + } + ] + }, + { + "id": 241, + "name": "dashboard-manager", + "children": [ + { + "id": 305, + "name": "database-client", + "children": [] + }, + { + "id": 306, + "name": "signup-proxy", + "children": [] + }, + { + "id": 371, + "name": "signup-sorter", + "children": [] + }, + { + "id": 372, + "name": "review-dispatcher", + "children": [] + }, + { + "id": 377, + "name": "api-adapter", + "children": [] + }, + { + "id": 378, + "name": "message-tracker", + "children": [] + }, + { + "id": 379, + "name": "upload-gateway", + "children": [] + }, + { + "id": 380, + "name": "login-validator", + "children": [] + }, + { + "id": 381, + "name": "sync-form", + "children": [] + } + ] + }, + { + "id": 242, + "name": "signup-builder", + "children": [ + { + "id": 326, + "name": "share-reporter", + "children": [] + }, + { + "id": 327, + "name": "filter-client", + "children": [ + { + "id": 331, + "name": "cache-proxy", + "children": [] + }, + { + "id": 332, + "name": "export-screen", + "children": [] + }, + { + "id": 333, + "name": "processor-widget", + "children": [] + } + ] + }, + { + "id": 328, + "name": "backup-formatter", + "children": [] + }, + { + "id": 329, + "name": "admin-builder", + "children": [] + }, + { + "id": 330, + "name": "payment-collector", + "children": [] + } + ] + }, + { + "id": 243, + "name": "calendar-manager", + "children": [ + { + "id": 478, + "name": "review-gateway", + "children": [] + }, + { + "id": 479, + "name": "import-tracker", + "children": [] + }, + { + "id": 480, + "name": "rating-builder", + "children": [] + }, + { + "id": 481, + "name": "sync-screen", + "children": [] + } + ] + } + ] + }, + { + "id": 3, + "name": "user-collector", + "children": [ + { + "id": 44, + "name": "cart-formatter", + "children": [] + }, + { + "id": 45, + "name": "user-manager", + "children": [] + }, + { + "id": 46, + "name": "database-reporter", + "children": [] + }, + { + "id": 90, + "name": "document-gateway", + "children": [] + }, + { + "id": 292, + "name": "auth-collector", + "children": [] + }, + { + "id": 293, + "name": "image-handler", + "children": [] + }, + { + "id": 294, + "name": "export-optimizer", + "children": [] + } + ] + }, + { + "id": 4, + "name": "filter-logger", + "children": [ + { + "id": 12, + "name": "notification-decoder", + "children": [ + { + "id": 63, + "name": "download-controller", + "children": [] + }, + { + "id": 64, + "name": "database-widget", + "children": [] + }, + { + "id": 205, + "name": "auth-transformer", + "children": [] + }, + { + "id": 206, + "name": "task-logger", + "children": [] + }, + { + "id": 261, + "name": "database-filter", + "children": [] + }, + { + "id": 262, + "name": "review-filter", + "children": [] + }, + { + "id": 263, + "name": "audio-server", + "children": [] + }, + { + "id": 264, + "name": "notification-factory", + "children": [] + } + ] + }, + { + "id": 13, + "name": "service-monitor", + "children": [ + { + "id": 37, + "name": "schedule-monitor", + "children": [] + }, + { + "id": 38, + "name": "download-monitor", + "children": [] + }, + { + "id": 39, + "name": "message-manager", + "children": [] + }, + { + "id": 40, + "name": "rating-filter", + "children": [] + }, + { + "id": 194, + "name": "search-analyzer", + "children": [] + }, + { + "id": 195, + "name": "message-filter", + "children": [] + }, + { + "id": 196, + "name": "order-monitor", + "children": [] + } + ] + }, + { + "id": 202, + "name": "video-client", + "children": [] + }, + { + "id": 203, + "name": "chat-transformer", + "children": [] + }, + { + "id": 204, + "name": "search-gateway", + "children": [] + } + ] + }, + { + "id": 5, + "name": "filter-monitor", + "children": [ + { + "id": 41, + "name": "api-optimizer", + "children": [] + }, + { + "id": 42, + "name": "settings-formatter", + "children": [] + }, + { + "id": 43, + "name": "import-logger", + "children": [] + }, + { + "id": 65, + "name": "team-logger", + "children": [] + }, + { + "id": 373, + "name": "stop", + "children": [] + }, + { + "id": 374, + "name": "worker-formatter", + "children": [ + { + "id": 382, + "name": "document-builder", + "children": [] + }, + { + "id": 383, + "name": "share-monitor", + "children": [] + } + ] + }, + { + "id": 375, + "name": "order-decoder", + "children": [] + }, + { + "id": 376, + "name": "download-transformer", + "children": [] + } + ] + }, + { + "id": 6, + "name": "transformer-dispatcher", + "children": [ + { + "id": 132, + "name": "export-dispatcher", + "children": [] + }, + { + "id": 133, + "name": "task-monitor", + "children": [] + }, + { + "id": 134, + "name": "profile-server", + "children": [] + }, + { + "id": 136, + "name": "cart-widget", + "children": [ + { + "id": 170, + "name": "upload-manager", + "children": [] + }, + { + "id": 171, + "name": "payment-validator", + "children": [] + }, + { + "id": 244, + "name": "filter-gateway", + "children": [] + }, + { + "id": 245, + "name": "task-component", + "children": [] + }, + { + "id": 246, + "name": "api-proxy", + "children": [] + } + ] + }, + { + "id": 137, + "name": "review-component", + "children": [ + { + "id": 230, + "name": "restore-collector", + "children": [] + }, + { + "id": 231, + "name": "cache-analyzer", + "children": [] + }, + { + "id": 232, + "name": "worker-parser", + "children": [] + }, + { + "id": 233, + "name": "import-monitor", + "children": [] + }, + { + "id": 438, + "name": "cart-service", + "children": [] + }, + { + "id": 439, + "name": "order-transformer", + "children": [] + } + ] + } + ] + }, + { + "id": 7, + "name": "dashboard-encoder", + "children": [ + { + "id": 8, + "name": "validator-validator", + "children": [ + { + "id": 138, + "name": "signup-optimizer", + "children": [ + { + "id": 142, + "name": "notification-manager", + "children": [] + }, + { + "id": 143, + "name": "profile-collector", + "children": [] + }, + { + "id": 144, + "name": "project-encoder", + "children": [] + }, + { + "id": 145, + "name": "admin-client", + "children": [] + }, + { + "id": 146, + "name": "validator-controller", + "children": [] + } + ] + }, + { + "id": 176, + "name": "admin-filter", + "children": [] + }, + { + "id": 177, + "name": "service-tracker", + "children": [] + }, + { + "id": 178, + "name": "order-parser", + "children": [] + }, + { + "id": 179, + "name": "cache-service", + "children": [] + }, + { + "id": 180, + "name": "auth-dispatcher", + "children": [] + } + ] + }, + { + "id": 9, + "name": "export-proxy", + "children": [ + { + "id": 135, + "name": "database-screen", + "children": [ + { + "id": 210, + "name": "migration-server", + "children": [] + }, + { + "id": 211, + "name": "video-handler", + "children": [] + }, + { + "id": 212, + "name": "data-manager", + "children": [] + }, + { + "id": 213, + "name": "analytics-processor", + "children": [] + }, + { + "id": 303, + "name": "search-formatter", + "children": [] + }, + { + "id": 304, + "name": "analytics-encoder", + "children": [] + } + ] + }, + { + "id": 188, + "name": "user-validator", + "children": [ + { + "id": 345, + "name": "service-manager", + "children": [] + }, + { + "id": 414, + "name": "sync-formatter", + "children": [ + { + "id": 484, + "name": "payment-proxy", + "children": [] + }, + { + "id": 485, + "name": "profile-adapter", + "children": [] + }, + { + "id": 486, + "name": "team-formatter", + "children": [] + }, + { + "id": 487, + "name": "upload-logger", + "children": [] + } + ] + }, + { + "id": 415, + "name": "calendar-builder", + "children": [] + }, + { + "id": 416, + "name": "api-handler", + "children": [ + { + "id": 489, + "name": "task-formatter", + "children": [] + }, + { + "id": 490, + "name": "signup-gateway", + "children": [] + }, + { + "id": 491, + "name": "validator-optimizer", + "children": [] + }, + { + "id": 492, + "name": "admin-dispatcher", + "children": [] + }, + { + "id": 493, + "name": "restore-filter", + "children": [] + } + ] + }, + { + "id": 417, + "name": "task-decoder", + "children": [ + { + "id": 424, + "name": "pause", + "children": [] + }, + { + "id": 425, + "name": "search-form", + "children": [ + { + "id": 427, + "name": "document-widget", + "children": [] + } + ] + }, + { + "id": 426, + "name": "signup-decoder", + "children": [] + }, + { + "id": 475, + "name": "worker-analyzer", + "children": [] + } + ] + } + ] + }, + { + "id": 189, + "name": "download-handler", + "children": [ + { + "id": 456, + "name": "data-dispatcher", + "children": [] + }, + { + "id": 457, + "name": "profile-encoder", + "children": [] + }, + { + "id": 458, + "name": "document-processor", + "children": [] + }, + { + "id": 459, + "name": "search-collector", + "children": [] + }, + { + "id": 460, + "name": "data-collector", + "children": [] + } + ] + }, + { + "id": 238, + "name": "team-widget", + "children": [ + { + "id": 278, + "name": "download-collector", + "children": [] + }, + { + "id": 279, + "name": "task-screen", + "children": [] + }, + { + "id": 280, + "name": "notification-builder", + "children": [ + { + "id": 287, + "name": "upload-flow", + "children": [] + }, + { + "id": 288, + "name": "common", + "children": [] + } + ] + }, + { + "id": 281, + "name": "database-encoder", + "children": [] + }, + { + "id": 282, + "name": "signup-analyzer", + "children": [] + } + ] + }, + { + "id": 299, + "name": "message-scheduler", + "children": [] + }, + { + "id": 300, + "name": "payment-optimizer", + "children": [] + }, + { + "id": 301, + "name": "calendar-aggregator", + "children": [] + }, + { + "id": 302, + "name": "export-encoder", + "children": [] + } + ] + }, + { + "id": 10, + "name": "database-dispatcher", + "children": [ + { + "id": 121, + "name": "export-manager", + "children": [] + }, + { + "id": 122, + "name": "database-manager", + "children": [] + }, + { + "id": 123, + "name": "report-logger", + "children": [] + }, + { + "id": 172, + "name": "report-decoder", + "children": [] + }, + { + "id": 173, + "name": "user-gateway", + "children": [] + } + ] + }, + { + "id": 59, + "name": "api-monitor", + "children": [ + { + "id": 100, + "name": "dashboard-builder", + "children": [] + }, + { + "id": 101, + "name": "chat-server", + "children": [] + }, + { + "id": 102, + "name": "settings-aggregator", + "children": [] + }, + { + "id": 103, + "name": "review-decoder", + "children": [] + }, + { + "id": 199, + "name": "cart-screen", + "children": [] + }, + { + "id": 200, + "name": "comment-handler", + "children": [] + }, + { + "id": 201, + "name": "project-widget", + "children": [] + } + ] + }, + { + "id": 92, + "name": "audio-aggregator", + "children": [] + }, + { + "id": 93, + "name": "backup-analyzer", + "children": [] + }, + { + "id": 94, + "name": "cache-client", + "children": [] + }, + { + "id": 95, + "name": "audio-service", + "children": [] + } + ] + } + ] +} \ No newline at end of file