# ReaderCanvas

- File ID: file:3sb16d:readercanvas-razor
- Path: NexusReader.UI.Shared/Components/Organisms/ReaderCanvas.razor
- Role: ui-component
- Layer: frontend

## Purpose

Razor UI component that renders an ebook reader canvas, manages chapter loading, selection/highlight UX, JS observers/selection interop, and synchronizes reading progress across devices.

## Key Details

Component heavily coordinates between JS observer modules, a KnowledgeCoordinator, SyncService and navigation; it guards against missing ebook selection, handles JS initialization failures with logged warnings, and temporarily highlights blocks with a timed clear.

## Symbols

- ReaderCanvas: Razor UI component that renders an ebook reader canvas, manages chapter loading, selection/highlight UX, JS observers/selection interop, and synchronizes reading progress across devices.
- OnInitializedAsync(): Component initialization: clears coordinator and subscribes to theme, navigation, interaction and sync events.
- OnParametersSetAsync(): Triggered when component parameters are set; loads the chapter for the current navigation index.
- OnNavigationChanged(): Handles navigation changes by resetting selection/JS state and reloading the chapter.
- OnAfterRenderAsync(): After render hook: initializes sync, processes full page with coordinator on first render, and initializes JS observers/listeners when needed.
- InitializeSelectionListenerAsync(): Loads a JS module and registers a DOM selection listener via JS interop; logs warning on failure.
- InitializeObserverAsync(): Loads JS observer module and initializes scroll/visibility observer; logs warning on failure.
- HandleBlockReached(): Invoked from JS when a block becomes visible; notifies coordinator and updates sync progress if ViewModel present.
- HandleSyncProgressReceived(): Receives progress from other devices, logs it, scrolls to the corresponding node and requests UI update.
- HandleTextSelected(): JS-invokable handler that records selected text, block id and coordinates and triggers UI update.
- HandleSelectionCleared(): Clears current text selection state and requests UI update.
- HandleScrollRequested(): Handler that triggers a scroll to a specific block node.
- HandleHighlightRequested(): Highlights a block temporarily by setting a highlighted id, triggers UI updates and clears it after a delay.
- GetFullPageContent(): Builds a plain-text representation of all text blocks (IDs + content) for coordinator processing or full-page use.
- LoadChapterAsync(): Loads a reader page (chapter) via Mediator, updates view model and navigation metadata, handles errors and UI loading state, and triggers coordinator/process sync when interactive.
- ScrollToNodeAsync(): Uses JS interop to scroll a DOM element into view by id with smooth behavior and logs warnings on failure.
- HandleUpdate(): Lightweight helper that requests a StateHasChanged invocation asynchronously.
- Dispose(): Unsubscribes all previously registered event handlers to avoid leaks when component is disposed.

## Dependencies

- No resolved dependencies.

## Calls

- No resolved calls.

## Unresolved References

- dependency-target: NexusReader.Application.Queries.Reader (GetReaderPageQuery)
- dependency-target: NexusReader.UI.Shared.Services (Coordinator, NavigationService, InteractionService, SyncService, ThemeService, FocusMode, IReaderInteractionService, IReaderNavigationService, IThemeService)
- dependency-target: MediatR (Mediator.Send)
- dependency-target: JS modules: ./_content/NexusReader.UI.Shared/js/selectionHandler.js
- dependency-target: JS modules: ./_content/NexusReader.UI.Shared/js/readerObserver.js
- call-target: unknown
- call-target: self
- call-target: self
- call-target: unknown
- call-target: unknown
- call-target: self
- call-target: self
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: self
- call-target: self
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- interaction-target: var userId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
- interaction-target: StatusMessage = $"Błąd: {result.Errors.FirstOrDefault()?.Message ?? "Nie udało się wczytać treści"}";
- interaction-target: JS.InvokeAsync('import', './_content/.../selectionHandler.js')
- interaction-target: JS.InvokeAsync('import', './_content/.../readerObserver.js')
- interaction-target: JS.InvokeVoidAsync('eval', script)

## Coverage

- Symbols: 18
- Executable symbols: 17
- Executable symbols with control flow: 17
- Grounded edges: 18
- Unresolved references: 31
- Control-flow fragments: 17
- Unresolved jumps: 15
- Unsupported constructs: 0
- Control-flow coverage: 100%
- Required diagrams: 2
- Generated diagrams: 11

## Control Flow Fragments

- OnInitializedAsync: 8 nodes, 7 edges, 1 jumps, 0 unsupported constructs
- OnParametersSetAsync: 5 nodes, 4 edges, 1 jumps, 0 unsupported constructs
- OnNavigationChanged: 6 nodes, 5 edges, 1 jumps, 0 unsupported constructs
- OnAfterRenderAsync: 31 nodes, 35 edges, 4 jumps, 0 unsupported constructs
- InitializeSelectionListenerAsync: 11 nodes, 10 edges, 2 jumps, 0 unsupported constructs
- InitializeObserverAsync: 11 nodes, 10 edges, 2 jumps, 0 unsupported constructs
- HandleBlockReached: 16 nodes, 17 edges, 2 jumps, 0 unsupported constructs
- HandleSyncProgressReceived: 8 nodes, 7 edges, 1 jumps, 0 unsupported constructs
- HandleTextSelected: 7 nodes, 6 edges, 0 jumps, 0 unsupported constructs
- HandleSelectionCleared: 5 nodes, 4 edges, 0 jumps, 0 unsupported constructs
- HandleScrollRequested: 5 nodes, 4 edges, 1 jumps, 0 unsupported constructs
- HandleHighlightRequested: 12 nodes, 12 edges, 1 jumps, 0 unsupported constructs
- GetFullPageContent: 13 nodes, 14 edges, 0 jumps, 0 unsupported constructs
- LoadChapterAsync: 40 nodes, 44 edges, 4 jumps, 0 unsupported constructs
- ScrollToNodeAsync: 9 nodes, 8 edges, 1 jumps, 0 unsupported constructs
- HandleUpdate: 3 nodes, 2 edges, 0 jumps, 0 unsupported constructs
- Dispose: 6 nodes, 5 edges, 0 jumps, 0 unsupported constructs

## Diagrams

### ReaderCanvas Neighborhood

_Warnings: diagram file_3sb16d_readercanvas_razor_neighborhood_view exceeds preferred complexity thresholds (19 nodes, 0 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart LR
    class_scmh0y_readercanvas("ReaderCanvas")
    file_3sb16d_readercanvas_razor("ReaderCanvas")
    method_105vz8s_scrolltonodeasync[["ScrollToNodeAsync()"]]
    method_16xot65_handletextselected[["HandleTextSelected()"]]
    method_1ejbaxq_handlescrollrequested[["HandleScrollRequested()"]]
    method_1h2dsti_dispose[["Dispose()"]]
    method_1i9kqly_getfullpagecontent[["GetFullPageContent()"]]
    method_1k0kfjg_onnavigationchanged[["OnNavigationChanged()"]]
    method_1l7jj8x_initializeobserverasync[["InitializeObserverAsync()"]]
    method_1nqcmix_handlehighlightrequested[["HandleHighlightRequested()"]]
    method_1p3f1im_handleblockreached[["HandleBlockReached()"]]
    method_1pp2oro_oninitializedasync[["OnInitializedAsync()"]]
    method_1qikoos_handleupdate[["HandleUpdate()"]]
    method_1rioxzo_handleselectioncleared[["HandleSelectionCleared()"]]
    method_ero6bp_loadchapterasync[["LoadChapterAsync()"]]
    method_etczkb_onparameterssetasync[["OnParametersSetAsync()"]]
    method_o7fqko_handlesyncprogressreceived[["HandleSyncProgressReceived()"]]
    method_qspmus_onafterrenderasync[["OnAfterRenderAsync()"]]
    method_w4053o_initializeselectionlistenerasync[["InitializeSelectionListenerAsync()"]]
```

### ReaderCanvas Execution Overview

_Warnings: diagram file_3sb16d_readercanvas_razor_execution_view exceeds preferred complexity thresholds (44 nodes, 43 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    class_scmh0y_readercanvas("ReaderCanvas")
    method_105vz8s_scrolltonodeasync[["ScrollToNodeAsync()"]]
    method_16xot65_handletextselected[["HandleTextSelected()"]]
    method_1ejbaxq_handlescrollrequested[["HandleScrollRequested()"]]
    method_1h2dsti_dispose[["Dispose()"]]
    method_1i9kqly_getfullpagecontent[["GetFullPageContent()"]]
    method_1k0kfjg_onnavigationchanged[["OnNavigationChanged()"]]
    method_1l7jj8x_initializeobserverasync[["InitializeObserverAsync()"]]
    method_1nqcmix_handlehighlightrequested[["HandleHighlightRequested()"]]
    method_1p3f1im_handleblockreached[["HandleBlockReached()"]]
    method_1pp2oro_oninitializedasync[["OnInitializedAsync()"]]
    method_1qikoos_handleupdate[["HandleUpdate()"]]
    method_1rioxzo_handleselectioncleared[["HandleSelectionCleared()"]]
    method_ero6bp_loadchapterasync[["LoadChapterAsync()"]]
    method_etczkb_onparameterssetasync[["OnParametersSetAsync()"]]
    method_o7fqko_handlesyncprogressreceived[["HandleSyncProgressReceived()"]]
    method_qspmus_onafterrenderasync[["OnAfterRenderAsync()"]]
    method_w4053o_initializeselectionlistenerasync[["InitializeSelectionListenerAsync()"]]
    unresolved_unresolved_10oitcb_call_target{"Unresolved: LoadChapterAsync"}
    unresolved_unresolved_1290kf4_interaction_target{"Unresolved: var userId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;"}
    unresolved_unresolved_14tu9s8_call_target{"Unresolved: UpdateProgressAsync"}
    unresolved_unresolved_1bfvgf7_interaction_target{"Unresolved: JS.InvokeAsync('import', './_content/.../selectionHandler.js')"}
    unresolved_unresolved_1clpv1o_call_target{"Unresolved: ScrollToNodeAsync"}
    unresolved_unresolved_1ecszuf_call_target{"Unresolved: ScrollToNodeAsync"}
    unresolved_unresolved_1nywp45_interaction_target{"Unresolved: JS.InvokeVoidAsync('eval', script)"}
    unresolved_unresolved_1o4rxvq_call_target{"Unresolved: ProcessFullPageAsync"}
    unresolved_unresolved_1ojxmgq_call_target{"Unresolved: GetAuthenticationStateAsync"}
    unresolved_unresolved_1pzrppn_call_target{"Unresolved: ClearAsync"}
    unresolved_unresolved_1tl9hd6_call_target{"Unresolved: InitializeAsync"}
    unresolved_unresolved_1xmlex9_call_target{"Unresolved: UpdateMetadataAsync"}
    unresolved_unresolved_1ykg7qx_call_target{"Unresolved: Send"}
    unresolved_unresolved_49c7i_call_target{"Unresolved: InvokeVoidAsync"}
    unresolved_unresolved_4b0xv6_call_target{"Unresolved: LoadChapterAsync"}
    unresolved_unresolved_cztvzm_call_target{"Unresolved: OnBlockReachedAsync"}
    unresolved_unresolved_dmm0s1_call_target{"Unresolved: ProcessFullPageAsync"}
    unresolved_unresolved_er2dng_call_target{"Unresolved: InitializeSelectionListenerAsync"}
    unresolved_unresolved_ihgsmk_call_target{"Unresolved: InitializeObserverAsync"}
    unresolved_unresolved_ovldpq_call_target{"Unresolved: InvokeVoidAsync"}
    unresolved_unresolved_oww71w_call_target{"Unresolved: InvokeAsync"}
    unresolved_unresolved_raqq7q_interaction_target{"Unresolved: JS.InvokeAsync('import', './_content/.../readerObserver.js')"}
    unresolved_unresolved_rtadvy_call_target{"Unresolved: Delay"}
    unresolved_unresolved_wp86mw_interaction_target{"Unresolved: StatusMessage = $\\"Błąd: {result.Errors.FirstOrDefault()?.Message ?? \\"Nie udało się wczytać treści\\"}\\";"}
    unresolved_unresolved_y0aono_call_target{"Unresolved: InvokeAsync"}
    unresolved_unresolved_z4tu8x_call_target{"Unresolved: InvokeVoidAsync"}
    class_scmh0y_readercanvas -->|contains| method_105vz8s_scrolltonodeasync
    class_scmh0y_readercanvas -->|contains| method_16xot65_handletextselected
    class_scmh0y_readercanvas -->|contains| method_1ejbaxq_handlescrollrequested
    class_scmh0y_readercanvas -->|contains| method_1h2dsti_dispose
    class_scmh0y_readercanvas -->|contains| method_1i9kqly_getfullpagecontent
    class_scmh0y_readercanvas -->|contains| method_1k0kfjg_onnavigationchanged
    class_scmh0y_readercanvas -->|contains| method_1l7jj8x_initializeobserverasync
    class_scmh0y_readercanvas -->|contains| method_1nqcmix_handlehighlightrequested
    class_scmh0y_readercanvas -->|contains| method_1p3f1im_handleblockreached
    class_scmh0y_readercanvas -->|contains| method_1pp2oro_oninitializedasync
    class_scmh0y_readercanvas -->|contains| method_1qikoos_handleupdate
    class_scmh0y_readercanvas -->|contains| method_1rioxzo_handleselectioncleared
    class_scmh0y_readercanvas -->|contains| method_ero6bp_loadchapterasync
    class_scmh0y_readercanvas -->|contains| method_etczkb_onparameterssetasync
    class_scmh0y_readercanvas -->|contains| method_o7fqko_handlesyncprogressreceived
    class_scmh0y_readercanvas -->|contains| method_qspmus_onafterrenderasync
    class_scmh0y_readercanvas -->|contains| method_w4053o_initializeselectionlistenerasync
    class_scmh0y_readercanvas -->|unresolved interaction| unresolved_unresolved_1290kf4_interaction_target
    class_scmh0y_readercanvas -->|unresolved interaction| unresolved_unresolved_1bfvgf7_interaction_target
    class_scmh0y_readercanvas -->|unresolved interaction| unresolved_unresolved_1nywp45_interaction_target
    class_scmh0y_readercanvas -->|unresolved interaction| unresolved_unresolved_raqq7q_interaction_target
    class_scmh0y_readercanvas -->|unresolved interaction| unresolved_unresolved_wp86mw_interaction_target
    method_105vz8s_scrolltonodeasync -->|unresolved call| unresolved_unresolved_z4tu8x_call_target
    method_1ejbaxq_handlescrollrequested -->|unresolved call| unresolved_unresolved_1ecszuf_call_target
    method_1k0kfjg_onnavigationchanged -->|unresolved call| unresolved_unresolved_4b0xv6_call_target
    method_1l7jj8x_initializeobserverasync -->|unresolved call| unresolved_unresolved_ovldpq_call_target
    method_1l7jj8x_initializeobserverasync -->|unresolved call| unresolved_unresolved_oww71w_call_target
    method_1nqcmix_handlehighlightrequested -->|unresolved call| unresolved_unresolved_rtadvy_call_target
    method_1p3f1im_handleblockreached -->|unresolved call| unresolved_unresolved_14tu9s8_call_target
    method_1p3f1im_handleblockreached -->|unresolved call| unresolved_unresolved_cztvzm_call_target
    method_1pp2oro_oninitializedasync -->|unresolved call| unresolved_unresolved_1pzrppn_call_target
    method_ero6bp_loadchapterasync -->|unresolved call| unresolved_unresolved_1o4rxvq_call_target
    method_ero6bp_loadchapterasync -->|unresolved call| unresolved_unresolved_1ojxmgq_call_target
    method_ero6bp_loadchapterasync -->|unresolved call| unresolved_unresolved_1xmlex9_call_target
    method_ero6bp_loadchapterasync -->|unresolved call| unresolved_unresolved_1ykg7qx_call_target
    method_etczkb_onparameterssetasync -->|unresolved call| unresolved_unresolved_10oitcb_call_target
    method_o7fqko_handlesyncprogressreceived -->|unresolved call| unresolved_unresolved_1clpv1o_call_target
    method_qspmus_onafterrenderasync -->|unresolved call| unresolved_unresolved_1tl9hd6_call_target
    method_qspmus_onafterrenderasync -->|unresolved call| unresolved_unresolved_dmm0s1_call_target
    method_qspmus_onafterrenderasync -->|unresolved call| unresolved_unresolved_er2dng_call_target
    method_qspmus_onafterrenderasync -->|unresolved call| unresolved_unresolved_ihgsmk_call_target
    method_w4053o_initializeselectionlistenerasync -->|unresolved call| unresolved_unresolved_49c7i_call_target
    method_w4053o_initializeselectionlistenerasync -->|unresolved call| unresolved_unresolved_y0aono_call_target
```

### OnInitializedAsync() Control Flow

```mermaid
flowchart TD
    method_1pp2oro_oninitializedasync__call_73_ClearAsync[["ClearAsync"]]
    method_1pp2oro_oninitializedasync__action_73_oninitializedasync_await_73_0__await[["Waits for async work"]]
    method_1pp2oro_oninitializedasync__action_74_subscribe_event_74__linear("Subscribe theme change")
    method_1pp2oro_oninitializedasync__action_75_subscribe_event_75__linear("Subscribe navigation change")
    method_1pp2oro_oninitializedasync__action_77_subscribe_event_77__linear("Subscribe interaction events")
    method_1pp2oro_oninitializedasync__action_80_subscribe_event_80__linear("Subscribe sync progress")
    method_1pp2oro_oninitializedasync__entry(["OnInitializedAsync entry"])
    method_1pp2oro_oninitializedasync__implicit_return(["return"])
    method_1pp2oro_oninitializedasync__action_73_oninitializedasync_await_73_0__await -->|none| method_1pp2oro_oninitializedasync__call_73_ClearAsync
    method_1pp2oro_oninitializedasync__action_74_subscribe_event_74__linear -->|next| method_1pp2oro_oninitializedasync__action_75_subscribe_event_75__linear
    method_1pp2oro_oninitializedasync__action_75_subscribe_event_75__linear -->|next| method_1pp2oro_oninitializedasync__action_77_subscribe_event_77__linear
    method_1pp2oro_oninitializedasync__action_77_subscribe_event_77__linear -->|next| method_1pp2oro_oninitializedasync__action_80_subscribe_event_80__linear
    method_1pp2oro_oninitializedasync__action_80_subscribe_event_80__linear -->|return| method_1pp2oro_oninitializedasync__implicit_return
    method_1pp2oro_oninitializedasync__call_73_ClearAsync -->|next| method_1pp2oro_oninitializedasync__action_74_subscribe_event_74__linear
    method_1pp2oro_oninitializedasync__entry -->|next| method_1pp2oro_oninitializedasync__action_73_oninitializedasync_await_73_0__await
```

### OnAfterRenderAsync() Control Flow

_Warnings: diagram method_qspmus_onafterrenderasync__fragment_diagram exceeds preferred complexity thresholds (31 nodes, 35 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_qspmus_onafterrenderasync__call_101_InitializeAsync[["InitializeAsync"]]
    method_qspmus_onafterrenderasync__call_105_ProcessFullPageAsync[["ProcessFullPageAsync"]]
    method_qspmus_onafterrenderasync__call_112_InitializeObserverAsync[["InitializeObserverAsync"]]
    method_qspmus_onafterrenderasync__call_113_InitializeSelectionListenerAsync[["InitializeSelectionListenerAsync"]]
    method_qspmus_onafterrenderasync__action_101_onafterrenderasync_await_101_1__await[["Waits for async work"]]
    method_qspmus_onafterrenderasync__action_102_state_change_102__linear("Enable interactivity")
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__condition{"ViewModel != null"}
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__false("false")
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__merge("merge")
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__true("true")
    method_qspmus_onafterrenderasync__action_105_onafterrenderasync_await_105_3__await[["Waits for async work"]]
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__condition{"ViewModel != null && !_isJsInitialized"}
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__false("otherwise")
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__merge("merge")
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__true("init JS observer/listener")
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__condition{"ViewModel != null && !_isJsInitialized"}
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__false("false")
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__merge("merge")
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__true("true")
    method_qspmus_onafterrenderasync__action_112_onafterrenderasync_await_112_5__await[["Waits for async work"]]
    method_qspmus_onafterrenderasync__action_113_onafterrenderasync_await_113_6__await[["Waits for async work"]]
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__condition{"firstRender == true"}
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__false("process page")
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__merge("merge")
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__true("init sync")
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__condition{"firstRender"}
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__false("false")
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__merge("merge")
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__true("true")
    method_qspmus_onafterrenderasync__entry(["OnAfterRenderAsync entry"])
    method_qspmus_onafterrenderasync__implicit_return(["return"])
    method_qspmus_onafterrenderasync__action_101_onafterrenderasync_await_101_1__await -->|none SyncService.InitializeAsync| method_qspmus_onafterrenderasync__call_101_InitializeAsync
    method_qspmus_onafterrenderasync__action_102_state_change_102__linear -->|next| method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__condition
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__condition -->|false| method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__false
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__condition -->|true| method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__true
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__false -->|next| method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__merge
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__merge -->|next| method_qspmus_onafterrenderasync__action_105_onafterrenderasync_await_105_3__await
    method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__true -->|next| method_qspmus_onafterrenderasync__action_103_onafterrenderasync_branch_103_2__merge
    method_qspmus_onafterrenderasync__action_105_onafterrenderasync_await_105_3__await -->|GetFullPageContent| method_qspmus_onafterrenderasync__call_105_ProcessFullPageAsync
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__condition -->|otherwise| method_qspmus_onafterrenderasync__action_109_guard_clause_109__false
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__condition -->|init JS observer / listener| method_qspmus_onafterrenderasync__action_109_guard_clause_109__true
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__false -->|next| method_qspmus_onafterrenderasync__action_109_guard_clause_109__merge
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__merge -->|next| method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__condition
    method_qspmus_onafterrenderasync__action_109_guard_clause_109__true -->|next| method_qspmus_onafterrenderasync__action_109_guard_clause_109__merge
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__condition -->|false| method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__false
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__condition -->|true| method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__true
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__false -->|next| method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__merge
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__merge -->|next| method_qspmus_onafterrenderasync__action_112_onafterrenderasync_await_112_5__await
    method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__true -->|next| method_qspmus_onafterrenderasync__action_109_onafterrenderasync_branch_109_4__merge
    method_qspmus_onafterrenderasync__action_112_onafterrenderasync_await_112_5__await -->|none| method_qspmus_onafterrenderasync__call_112_InitializeObserverAsync
    method_qspmus_onafterrenderasync__action_113_onafterrenderasync_await_113_6__await -->|none| method_qspmus_onafterrenderasync__call_113_InitializeSelectionListenerAsync
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__condition -->|process page| method_qspmus_onafterrenderasync__action_99_guard_clause_99__false
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__condition -->|init sync| method_qspmus_onafterrenderasync__action_99_guard_clause_99__true
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__false -->|next| method_qspmus_onafterrenderasync__action_99_guard_clause_99__merge
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__merge -->|next| method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__condition
    method_qspmus_onafterrenderasync__action_99_guard_clause_99__true -->|next| method_qspmus_onafterrenderasync__action_99_guard_clause_99__merge
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__condition -->|false| method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__false
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__condition -->|true| method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__true
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__false -->|next| method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__merge
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__merge -->|next| method_qspmus_onafterrenderasync__action_101_onafterrenderasync_await_101_1__await
    method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__true -->|next| method_qspmus_onafterrenderasync__action_99_onafterrenderasync_branch_99_0__merge
    method_qspmus_onafterrenderasync__call_101_InitializeAsync -->|next| method_qspmus_onafterrenderasync__action_102_state_change_102__linear
    method_qspmus_onafterrenderasync__call_105_ProcessFullPageAsync -->|next| method_qspmus_onafterrenderasync__action_109_guard_clause_109__condition
    method_qspmus_onafterrenderasync__call_112_InitializeObserverAsync -->|next| method_qspmus_onafterrenderasync__action_113_onafterrenderasync_await_113_6__await
    method_qspmus_onafterrenderasync__call_113_InitializeSelectionListenerAsync -->|return| method_qspmus_onafterrenderasync__implicit_return
    method_qspmus_onafterrenderasync__entry -->|next| method_qspmus_onafterrenderasync__action_99_guard_clause_99__condition
```

### InitializeSelectionListenerAsync() Control Flow

```mermaid
flowchart TD
    method_w4053o_initializeselectionlistenerasync__call_121_InvokeAsync[["InvokeAsync"]]
    method_w4053o_initializeselectionlistenerasync__call_122_InvokeVoidAsync[["InvokeVoidAsync"]]
    method_w4053o_initializeselectionlistenerasync__action_119_initializeselectionlistenerasync_try_119_0__try("Begins protected execution")
    method_w4053o_initializeselectionlistenerasync__action_119_try_catch_119__linear("Fallback on JS init error")
    method_w4053o_initializeselectionlistenerasync__action_121_initializeselectionlistenerasync_await_121_1__await[["Waits for async work"]]
    method_w4053o_initializeselectionlistenerasync__action_122_initializeselectionlistenerasync_await_122_2__await[["Waits for async work"]]
    method_w4053o_initializeselectionlistenerasync__action_124_initializeselectionlistenerasync_catch_124_3__catch("catch Exception ex")
    method_w4053o_initializeselectionlistenerasync__action_126_initializeselectionlistenerasync_log_126_4__linear("Logs runtime state")
    method_w4053o_initializeselectionlistenerasync__entry(["InitializeSelectionListenerAsync entry"])
    method_w4053o_initializeselectionlistenerasync__action_121_external_call_121__linear("Import JS selection module")
    method_w4053o_initializeselectionlistenerasync__implicit_return(["return"])
    method_w4053o_initializeselectionlistenerasync__action_119_initializeselectionlistenerasync_try_119_0__try -->|next| method_w4053o_initializeselectionlistenerasync__action_121_initializeselectionlistenerasync_await_121_1__await
    method_w4053o_initializeselectionlistenerasync__action_119_try_catch_119__linear -->|next| method_w4053o_initializeselectionlistenerasync__action_119_initializeselectionlistenerasync_try_119_0__try
    method_w4053o_initializeselectionlistenerasync__action_121_external_call_121__linear -->|calls| method_w4053o_initializeselectionlistenerasync__call_121_InvokeAsync
    method_w4053o_initializeselectionlistenerasync__action_121_initializeselectionlistenerasync_await_121_1__await -->|next| method_w4053o_initializeselectionlistenerasync__action_121_external_call_121__linear
    method_w4053o_initializeselectionlistenerasync__action_122_initializeselectionlistenerasync_await_122_2__await -->|initSelectionListener , DotNetObjectReference.Create this, _containerRef| method_w4053o_initializeselectionlistenerasync__call_122_InvokeVoidAsync
    method_w4053o_initializeselectionlistenerasync__action_124_initializeselectionlistenerasync_catch_124_3__catch -->|next| method_w4053o_initializeselectionlistenerasync__action_126_initializeselectionlistenerasync_log_126_4__linear
    method_w4053o_initializeselectionlistenerasync__action_126_initializeselectionlistenerasync_log_126_4__linear -->|return| method_w4053o_initializeselectionlistenerasync__implicit_return
    method_w4053o_initializeselectionlistenerasync__call_121_InvokeAsync -->|next| method_w4053o_initializeselectionlistenerasync__action_122_initializeselectionlistenerasync_await_122_2__await
    method_w4053o_initializeselectionlistenerasync__call_122_InvokeVoidAsync -->|exception| method_w4053o_initializeselectionlistenerasync__action_124_initializeselectionlistenerasync_catch_124_3__catch
    method_w4053o_initializeselectionlistenerasync__entry -->|next| method_w4053o_initializeselectionlistenerasync__action_119_try_catch_119__linear
```

### InitializeObserverAsync() Control Flow

```mermaid
flowchart TD
    method_1l7jj8x_initializeobserverasync__call_134_InvokeAsync[["InvokeAsync"]]
    method_1l7jj8x_initializeobserverasync__call_135_InvokeVoidAsync[["InvokeVoidAsync"]]
    method_1l7jj8x_initializeobserverasync__action_132_initializeobserverasync_try_132_0__try("Begins protected execution")
    method_1l7jj8x_initializeobserverasync__action_132_try_catch_132__linear("Fallback on observer init error")
    method_1l7jj8x_initializeobserverasync__action_134_initializeobserverasync_await_134_1__await[["Waits for async work"]]
    method_1l7jj8x_initializeobserverasync__action_135_initializeobserverasync_await_135_2__await[["Waits for async work"]]
    method_1l7jj8x_initializeobserverasync__action_137_initializeobserverasync_catch_137_3__catch("catch Exception ex")
    method_1l7jj8x_initializeobserverasync__action_139_initializeobserverasync_log_139_4__linear("Logs runtime state")
    method_1l7jj8x_initializeobserverasync__entry(["InitializeObserverAsync entry"])
    method_1l7jj8x_initializeobserverasync__action_134_external_call_134__linear("Import JS observer module")
    method_1l7jj8x_initializeobserverasync__implicit_return(["return"])
    method_1l7jj8x_initializeobserverasync__action_132_initializeobserverasync_try_132_0__try -->|next| method_1l7jj8x_initializeobserverasync__action_134_initializeobserverasync_await_134_1__await
    method_1l7jj8x_initializeobserverasync__action_132_try_catch_132__linear -->|next| method_1l7jj8x_initializeobserverasync__action_132_initializeobserverasync_try_132_0__try
    method_1l7jj8x_initializeobserverasync__action_134_external_call_134__linear -->|calls| method_1l7jj8x_initializeobserverasync__call_134_InvokeAsync
    method_1l7jj8x_initializeobserverasync__action_134_initializeobserverasync_await_134_1__await -->|next| method_1l7jj8x_initializeobserverasync__action_134_external_call_134__linear
    method_1l7jj8x_initializeobserverasync__action_135_initializeobserverasync_await_135_2__await -->|initObserver , DotNetObjectReference.Create this, .reader-flow-container , .block-wrapper| method_1l7jj8x_initializeobserverasync__call_135_InvokeVoidAsync
    method_1l7jj8x_initializeobserverasync__action_137_initializeobserverasync_catch_137_3__catch -->|next| method_1l7jj8x_initializeobserverasync__action_139_initializeobserverasync_log_139_4__linear
    method_1l7jj8x_initializeobserverasync__action_139_initializeobserverasync_log_139_4__linear -->|return| method_1l7jj8x_initializeobserverasync__implicit_return
    method_1l7jj8x_initializeobserverasync__call_134_InvokeAsync -->|next| method_1l7jj8x_initializeobserverasync__action_135_initializeobserverasync_await_135_2__await
    method_1l7jj8x_initializeobserverasync__call_135_InvokeVoidAsync -->|exception| method_1l7jj8x_initializeobserverasync__action_137_initializeobserverasync_catch_137_3__catch
    method_1l7jj8x_initializeobserverasync__entry -->|next| method_1l7jj8x_initializeobserverasync__action_132_try_catch_132__linear
```

### HandleBlockReached() Control Flow

```mermaid
flowchart TD
    method_1p3f1im_handleblockreached__call_146_OnBlockReachedAsync[["OnBlockReachedAsync"]]
    method_1p3f1im_handleblockreached__call_152_UpdateProgressAsync[["UpdateProgressAsync"]]
    method_1p3f1im_handleblockreached__action_146_external_invocation_146__linear("Notify coordinator of block reached")
    method_1p3f1im_handleblockreached__action_146_handleblockreached_await_146_0__await[["Waits for async work"]]
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__condition{"ViewModel != null"}
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__false("call UpdateProgressAsync")
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__merge("merge")
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__true("compute progress")
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__condition{"ViewModel != null"}
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__false("false")
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__merge("merge")
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__true("true")
    method_1p3f1im_handleblockreached__action_150_computation_150__linear("Compute progress percent")
    method_1p3f1im_handleblockreached__action_152_handleblockreached_await_152_2__await[["Waits for async work"]]
    method_1p3f1im_handleblockreached__entry(["HandleBlockReached entry"])
    method_1p3f1im_handleblockreached__implicit_return(["return"])
    method_1p3f1im_handleblockreached__action_146_external_invocation_146__linear -->|blockId, content Coordinator| method_1p3f1im_handleblockreached__call_146_OnBlockReachedAsync
    method_1p3f1im_handleblockreached__action_146_handleblockreached_await_146_0__await -->|next| method_1p3f1im_handleblockreached__action_146_external_invocation_146__linear
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__condition -->|call UpdateProgressAsync| method_1p3f1im_handleblockreached__action_148_guard_clause_148__false
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__condition -->|compute progress| method_1p3f1im_handleblockreached__action_148_guard_clause_148__true
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__false -->|next| method_1p3f1im_handleblockreached__action_148_guard_clause_148__merge
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__merge -->|next| method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__condition
    method_1p3f1im_handleblockreached__action_148_guard_clause_148__true -->|next| method_1p3f1im_handleblockreached__action_148_guard_clause_148__merge
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__condition -->|false| method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__false
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__condition -->|true| method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__true
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__false -->|next| method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__merge
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__merge -->|next| method_1p3f1im_handleblockreached__action_150_computation_150__linear
    method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__true -->|next| method_1p3f1im_handleblockreached__action_148_handleblockreached_branch_148_1__merge
    method_1p3f1im_handleblockreached__action_150_computation_150__linear -->|next| method_1p3f1im_handleblockreached__action_152_handleblockreached_await_152_2__await
    method_1p3f1im_handleblockreached__action_152_handleblockreached_await_152_2__await -->|blockId, ViewModel.EbookId, progress, ViewModel.ChapterTitle, ViewModel.CurrentChapterIndex SyncService| method_1p3f1im_handleblockreached__call_152_UpdateProgressAsync
    method_1p3f1im_handleblockreached__call_146_OnBlockReachedAsync -->|next| method_1p3f1im_handleblockreached__action_148_guard_clause_148__condition
    method_1p3f1im_handleblockreached__call_152_UpdateProgressAsync -->|return| method_1p3f1im_handleblockreached__implicit_return
    method_1p3f1im_handleblockreached__entry -->|next| method_1p3f1im_handleblockreached__action_146_handleblockreached_await_146_0__await
```

### HandleHighlightRequested() Control Flow

```mermaid
flowchart TD
    method_1nqcmix_handlehighlightrequested__call_196_Delay[["Delay"]]
    method_1nqcmix_handlehighlightrequested__action_194_state_change_194__linear("Set highlighted block")
    method_1nqcmix_handlehighlightrequested__action_195_handlehighlightrequested_await_195_0__await[["Waits for async work"]]
    method_1nqcmix_handlehighlightrequested__action_196_handlehighlightrequested_await_196_1__await[["Waits for async work"]]
    method_1nqcmix_handlehighlightrequested__action_196_timed_fallback_196__linear("Clear highlight after timeout")
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__condition{"_highlightedBlockId == blockId"}
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__false("false")
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__merge("merge")
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__true("true")
    method_1nqcmix_handlehighlightrequested__action_200_handlehighlightrequested_await_200_3__await[["Waits for async work"]]
    method_1nqcmix_handlehighlightrequested__entry(["HandleHighlightRequested entry"])
    method_1nqcmix_handlehighlightrequested__implicit_return(["return"])
    method_1nqcmix_handlehighlightrequested__action_194_state_change_194__linear -->|next| method_1nqcmix_handlehighlightrequested__action_195_handlehighlightrequested_await_195_0__await
    method_1nqcmix_handlehighlightrequested__action_195_handlehighlightrequested_await_195_0__await -->|next| method_1nqcmix_handlehighlightrequested__action_196_handlehighlightrequested_await_196_1__await
    method_1nqcmix_handlehighlightrequested__action_196_handlehighlightrequested_await_196_1__await -->|next| method_1nqcmix_handlehighlightrequested__action_196_timed_fallback_196__linear
    method_1nqcmix_handlehighlightrequested__action_196_timed_fallback_196__linear -->|3000ms Task.Delay| method_1nqcmix_handlehighlightrequested__call_196_Delay
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__condition -->|false| method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__false
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__condition -->|true| method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__true
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__false -->|next| method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__merge
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__merge -->|next| method_1nqcmix_handlehighlightrequested__action_200_handlehighlightrequested_await_200_3__await
    method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__true -->|next| method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__merge
    method_1nqcmix_handlehighlightrequested__action_200_handlehighlightrequested_await_200_3__await -->|return| method_1nqcmix_handlehighlightrequested__implicit_return
    method_1nqcmix_handlehighlightrequested__call_196_Delay -->|next| method_1nqcmix_handlehighlightrequested__action_197_handlehighlightrequested_branch_197_2__condition
    method_1nqcmix_handlehighlightrequested__entry -->|next| method_1nqcmix_handlehighlightrequested__action_194_state_change_194__linear
```

### GetFullPageContent() Control Flow

```mermaid
flowchart TD
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__condition{"ViewModel == null"}
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__false("continue")
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__merge("merge")
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__true("exit")
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__condition{"ViewModel == null"}
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__false("build content")
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__merge("merge")
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__true("return ''")
    method_1i9kqly_getfullpagecontent__action_207_mapping_207__linear("Concatenate text blocks")
    method_1i9kqly_getfullpagecontent__action_209_getfullpagecontent_mapping_209_2__linear("Maps data or transforms shape")
    method_1i9kqly_getfullpagecontent__entry(["GetFullPageContent entry"])
    method_1i9kqly_getfullpagecontent__action_207_getfullpagecontent_return_207_1__return(["Returns result"])
    method_1i9kqly_getfullpagecontent__implicit_return(["return"])
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__condition -->|continue| method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__false
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__condition -->|exit| method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__true
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__false -->|next| method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__merge
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__merge -->|return| method_1i9kqly_getfullpagecontent__action_207_getfullpagecontent_return_207_1__return
    method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__true -->|next| method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__merge
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__condition -->|build content| method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__false
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__condition -->|transforms input| method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__true
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__false -->|next| method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__merge
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__merge -->|next| method_1i9kqly_getfullpagecontent__action_206_getfullpagecontent_guard_clause_206_0__condition
    method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__true -->|next| method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__merge
    method_1i9kqly_getfullpagecontent__action_207_getfullpagecontent_return_207_1__return -->|next| method_1i9kqly_getfullpagecontent__action_207_mapping_207__linear
    method_1i9kqly_getfullpagecontent__action_207_mapping_207__linear -->|next| method_1i9kqly_getfullpagecontent__action_209_getfullpagecontent_mapping_209_2__linear
    method_1i9kqly_getfullpagecontent__action_209_getfullpagecontent_mapping_209_2__linear -->|return| method_1i9kqly_getfullpagecontent__implicit_return
    method_1i9kqly_getfullpagecontent__entry -->|next| method_1i9kqly_getfullpagecontent__action_206_guard_clause_206__condition
```

### LoadChapterAsync() Control Flow

_Warnings: diagram method_ero6bp_loadchapterasync__fragment_diagram exceeds preferred complexity thresholds (40 nodes, 44 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_ero6bp_loadchapterasync__call_218_GetAuthenticationStateAsync[["GetAuthenticationStateAsync"]]
    method_ero6bp_loadchapterasync__call_230_Send[["Send"]]
    method_ero6bp_loadchapterasync__call_234_UpdateMetadataAsync[["UpdateMetadataAsync"]]
    method_ero6bp_loadchapterasync__call_238_ProcessFullPageAsync[["ProcessFullPageAsync"]]
    method_ero6bp_loadchapterasync__action_214_state_change_214__linear("Enter loading state")
    method_ero6bp_loadchapterasync__action_218_loadchapterasync_await_218_0__await[["Waits for async work"]]
    method_ero6bp_loadchapterasync__action_221_persistence_guard_221__linear("Guard for no ebook selected")
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__condition{"ebookId == Guid.Empty"}
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__false("false")
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__merge("merge")
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__true("true")
    method_ero6bp_loadchapterasync__action_230_external_query_230__linear("Query reader page via mediator")
    method_ero6bp_loadchapterasync__action_230_loadchapterasync_await_230_4__await[["Waits for async work"]]
    method_ero6bp_loadchapterasync__action_231_branch_231__condition{"Handle result success/failure"}
    method_ero6bp_loadchapterasync__action_231_branch_231__false("false")
    method_ero6bp_loadchapterasync__action_231_branch_231__merge("merge")
    method_ero6bp_loadchapterasync__action_231_branch_231__true("true")
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__condition{"result.IsSuccess"}
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__false("false")
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__merge("merge")
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__true("true")
    method_ero6bp_loadchapterasync__action_234_loadchapterasync_await_234_6__await[["Waits for async work"]]
    method_ero6bp_loadchapterasync__action_236_conditional_orchestration_236__linear("Process full page when interactive")
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__condition{"_isInteractive"}
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__false("false")
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__merge("merge")
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__true("true")
    method_ero6bp_loadchapterasync__action_238_loadchapterasync_await_238_8__await[["Waits for async work"]]
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__condition{"Falls back to alternate path"}
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__false("otherwise")
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__merge("merge")
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__true("fallback")
    method_ero6bp_loadchapterasync__action_245_loadchapterasync_log_245_11__linear("Logs runtime state")
    method_ero6bp_loadchapterasync__action_245_loadchapterasync_mapping_245_12__linear("Maps data or transforms shape")
    method_ero6bp_loadchapterasync__action_248_state_change_248__linear("Exit loading state")
    method_ero6bp_loadchapterasync__entry(["LoadChapterAsync entry"])
    method_ero6bp_loadchapterasync__action_219_loadchapterasync_repository_read_219_1__linear[("Reads repository or persistence state")]
    method_ero6bp_loadchapterasync__action_244_loadchapterasync_repository_read_244_10__linear[("Reads repository or persistence state")]
    method_ero6bp_loadchapterasync__action_227_loadchapterasync_return_227_3__return(["Returns result"])
    method_ero6bp_loadchapterasync__implicit_return(["return"])
    method_ero6bp_loadchapterasync__action_214_state_change_214__linear -->|next| method_ero6bp_loadchapterasync__action_218_loadchapterasync_await_218_0__await
    method_ero6bp_loadchapterasync__action_218_loadchapterasync_await_218_0__await -->|none AuthStateProvider| method_ero6bp_loadchapterasync__call_218_GetAuthenticationStateAsync
    method_ero6bp_loadchapterasync__action_219_loadchapterasync_repository_read_219_1__linear -->|next| method_ero6bp_loadchapterasync__action_221_persistence_guard_221__linear
    method_ero6bp_loadchapterasync__action_221_persistence_guard_221__linear -->|next| method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__condition
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__condition -->|false| method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__false
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__condition -->|true| method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__true
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__false -->|next| method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__merge
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__merge -->|return| method_ero6bp_loadchapterasync__action_227_loadchapterasync_return_227_3__return
    method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__true -->|next| method_ero6bp_loadchapterasync__action_222_loadchapterasync_branch_222_2__merge
    method_ero6bp_loadchapterasync__action_227_loadchapterasync_return_227_3__return -->|next| method_ero6bp_loadchapterasync__action_230_loadchapterasync_await_230_4__await
    method_ero6bp_loadchapterasync__action_230_external_query_230__linear -->|GetReaderPageQuery ebookId, index, userId via Mediator| method_ero6bp_loadchapterasync__call_230_Send
    method_ero6bp_loadchapterasync__action_230_loadchapterasync_await_230_4__await -->|next| method_ero6bp_loadchapterasync__action_230_external_query_230__linear
    method_ero6bp_loadchapterasync__action_231_branch_231__condition -->|false| method_ero6bp_loadchapterasync__action_231_branch_231__false
    method_ero6bp_loadchapterasync__action_231_branch_231__condition -->|true| method_ero6bp_loadchapterasync__action_231_branch_231__true
    method_ero6bp_loadchapterasync__action_231_branch_231__false -->|next| method_ero6bp_loadchapterasync__action_231_branch_231__merge
    method_ero6bp_loadchapterasync__action_231_branch_231__merge -->|next| method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__condition
    method_ero6bp_loadchapterasync__action_231_branch_231__true -->|next| method_ero6bp_loadchapterasync__action_231_branch_231__merge
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__condition -->|false| method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__false
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__condition -->|true| method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__true
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__false -->|next| method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__merge
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__merge -->|next| method_ero6bp_loadchapterasync__action_234_loadchapterasync_await_234_6__await
    method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__true -->|next| method_ero6bp_loadchapterasync__action_231_loadchapterasync_branch_231_5__merge
    method_ero6bp_loadchapterasync__action_234_loadchapterasync_await_234_6__await -->|ViewModel.CurrentChapterIndex, ViewModel.TotalChapters, ViewModel.ChapterTitle NavigationService| method_ero6bp_loadchapterasync__call_234_UpdateMetadataAsync
    method_ero6bp_loadchapterasync__action_236_conditional_orchestration_236__linear -->|next| method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__condition
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__condition -->|false| method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__false
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__condition -->|true| method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__true
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__false -->|next| method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__merge
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__merge -->|next| method_ero6bp_loadchapterasync__action_238_loadchapterasync_await_238_8__await
    method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__true -->|next| method_ero6bp_loadchapterasync__action_236_loadchapterasync_branch_236_7__merge
    method_ero6bp_loadchapterasync__action_238_loadchapterasync_await_238_8__await -->|GetFullPageContent Coordinator| method_ero6bp_loadchapterasync__call_238_ProcessFullPageAsync
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__condition -->|otherwise| method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__false
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__condition -->|fallback| method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__true
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__false -->|next| method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__merge
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__merge -->|next| method_ero6bp_loadchapterasync__action_244_loadchapterasync_repository_read_244_10__linear
    method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__true -->|next| method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__merge
    method_ero6bp_loadchapterasync__action_244_loadchapterasync_repository_read_244_10__linear -->|next| method_ero6bp_loadchapterasync__action_245_loadchapterasync_mapping_245_12__linear
    method_ero6bp_loadchapterasync__action_245_loadchapterasync_log_245_11__linear -->|next| method_ero6bp_loadchapterasync__action_248_state_change_248__linear
    method_ero6bp_loadchapterasync__action_245_loadchapterasync_mapping_245_12__linear -->|next| method_ero6bp_loadchapterasync__action_245_loadchapterasync_log_245_11__linear
    method_ero6bp_loadchapterasync__action_248_state_change_248__linear -->|return| method_ero6bp_loadchapterasync__implicit_return
    method_ero6bp_loadchapterasync__call_218_GetAuthenticationStateAsync -->|next| method_ero6bp_loadchapterasync__action_219_loadchapterasync_repository_read_219_1__linear
    method_ero6bp_loadchapterasync__call_230_Send -->|next| method_ero6bp_loadchapterasync__action_231_branch_231__condition
    method_ero6bp_loadchapterasync__call_234_UpdateMetadataAsync -->|next| method_ero6bp_loadchapterasync__action_236_conditional_orchestration_236__linear
    method_ero6bp_loadchapterasync__call_238_ProcessFullPageAsync -->|fallback| method_ero6bp_loadchapterasync__action_241_loadchapterasync_fallback_241_9__condition
    method_ero6bp_loadchapterasync__entry -->|next| method_ero6bp_loadchapterasync__action_214_state_change_214__linear
```

### ScrollToNodeAsync() Control Flow

```mermaid
flowchart TD
    method_105vz8s_scrolltonodeasync__call_256_InvokeVoidAsync[["InvokeVoidAsync"]]
    method_105vz8s_scrolltonodeasync__action_254_scrolltonodeasync_try_254_0__try("Begins protected execution")
    method_105vz8s_scrolltonodeasync__action_256_scrolltonodeasync_await_256_1__await[["Waits for async work"]]
    method_105vz8s_scrolltonodeasync__action_258_scrolltonodeasync_catch_258_2__catch("catch Exception ex")
    method_105vz8s_scrolltonodeasync__action_258_try_catch_258__linear("Log on scroll failure")
    method_105vz8s_scrolltonodeasync__action_260_scrolltonodeasync_log_260_3__linear("Logs runtime state")
    method_105vz8s_scrolltonodeasync__entry(["ScrollToNodeAsync entry"])
    method_105vz8s_scrolltonodeasync__action_256_external_call_256__linear("Scroll DOM node via JS eval")
    method_105vz8s_scrolltonodeasync__implicit_return(["return"])
    method_105vz8s_scrolltonodeasync__action_254_scrolltonodeasync_try_254_0__try -->|next| method_105vz8s_scrolltonodeasync__action_256_scrolltonodeasync_await_256_1__await
    method_105vz8s_scrolltonodeasync__action_256_external_call_256__linear -->|calls| method_105vz8s_scrolltonodeasync__call_256_InvokeVoidAsync
    method_105vz8s_scrolltonodeasync__action_256_scrolltonodeasync_await_256_1__await -->|next| method_105vz8s_scrolltonodeasync__action_256_external_call_256__linear
    method_105vz8s_scrolltonodeasync__action_258_scrolltonodeasync_catch_258_2__catch -->|next| method_105vz8s_scrolltonodeasync__action_260_scrolltonodeasync_log_260_3__linear
    method_105vz8s_scrolltonodeasync__action_258_try_catch_258__linear -->|exception| method_105vz8s_scrolltonodeasync__action_258_scrolltonodeasync_catch_258_2__catch
    method_105vz8s_scrolltonodeasync__action_260_scrolltonodeasync_log_260_3__linear -->|return| method_105vz8s_scrolltonodeasync__implicit_return
    method_105vz8s_scrolltonodeasync__call_256_InvokeVoidAsync -->|next| method_105vz8s_scrolltonodeasync__action_258_try_catch_258__linear
    method_105vz8s_scrolltonodeasync__entry -->|next| method_105vz8s_scrolltonodeasync__action_254_scrolltonodeasync_try_254_0__try
```

## Diagram Validation

- Status: warn
- Warning: Control-flow extraction left 15 unresolved jumps.
- Warning: neighborhood-view: diagram file_3sb16d_readercanvas_razor_neighborhood_view exceeds preferred complexity thresholds (19 nodes, 0 edges).
- Warning: execution-overview: diagram file_3sb16d_readercanvas_razor_execution_view exceeds preferred complexity thresholds (44 nodes, 43 edges).
- Warning: control-flow: diagram method_qspmus_onafterrenderasync__fragment_diagram exceeds preferred complexity thresholds (31 nodes, 35 edges).
- Warning: control-flow: diagram method_ero6bp_loadchapterasync__fragment_diagram exceeds preferred complexity thresholds (40 nodes, 44 edges).
