# BookIngestionModal

- File ID: file:8kve74:bookingestionmodal-razor
- Path: NexusReader.UI.Shared/Components/Organisms/BookIngestionModal.razor
- Role: ui-component
- Layer: frontend

## Purpose

Razor UI component that provides a modal for uploading .epub files, extracting metadata client-side, and sending an ingest request to the server to add a book to the user's library.

## Key Details

Component performs client-side EPUB parsing via IEpubMetadataExtractor, encodes content/cover as base64, posts to api/library/ingest, and navigates to the created book on success. It includes guards for file type/size, error handling with user-facing ErrorMessage, and clears large byte buffers on dispose.

## Symbols

- BookIngestionModal: Razor UI component that provides a modal for uploading .epub files, extracting metadata client-side, and sending an ingest request to the server to add a book to the user's library.
- CloseModal(): Closes the modal, resets internal state, and notifies consumers that IsOpen changed.
- Reset(): Clears parsing/verification/ingestion flags and temporary data (metadata, errors, drag state, epub bytes).
- OnDragEnter(): Sets drag-over UI state when a drag enters the drop zone.
- OnDragLeave(): Clears drag-over UI state when a drag leaves the drop zone.
- HandleFileSelected(): Handles file selection or drop: validates file type/size, reads bytes, invokes metadata extractor, and transitions UI to verification or error state.
- SaveToLibrary(): Sends the ingested ebook (metadata + base64 content) to the server API and on success closes the modal and navigates to the new book.
- DisposeAsync(): Clears the large epub byte array so it can be garbage-collected and completes disposal.
- IngestResult: Represents the server response when an ebook is ingested; contains the new book Id.

## Dependencies

- No resolved dependencies.

## Calls

- No resolved calls.

## Unresolved References

- dependency-target: NexusReader.Application.Abstractions.Services (IEpubMetadataExtractor)
- dependency-target: NexusReader.Application.Queries.Reader
- dependency-target: NexusReader.Application.Commands.Library (IngestEbookRequest)
- call-target: self
- call-target: unknown
- call-target: self
- call-target: unknown
- interaction-target: ErrorMessage = result.Errors.FirstOrDefault()?.Message ?? "Failed to parse EPUB.";
- interaction-target: MetadataExtractor.ExtractMetadataAsync(memoryStream) -> result (IsSuccess / Value / Errors)
- interaction-target: Http.PostAsJsonAsync("api/library/ingest", request)

## Coverage

- Symbols: 9
- Executable symbols: 7
- Executable symbols with control flow: 7
- Grounded edges: 9
- Unresolved references: 10
- Control-flow fragments: 7
- Unresolved jumps: 2
- Unsupported constructs: 0
- Control-flow coverage: 100%
- Required diagrams: 2
- Generated diagrams: 4

## Control Flow Fragments

- CloseModal: 7 nodes, 6 edges, 1 jumps, 0 unsupported constructs
- Reset: 4 nodes, 3 edges, 0 jumps, 0 unsupported constructs
- OnDragEnter: 3 nodes, 2 edges, 0 jumps, 0 unsupported constructs
- OnDragLeave: 3 nodes, 2 edges, 0 jumps, 0 unsupported constructs
- HandleFileSelected: 44 nodes, 50 edges, 1 jumps, 0 unsupported constructs
- SaveToLibrary: 42 nodes, 47 edges, 2 jumps, 0 unsupported constructs
- DisposeAsync: 4 nodes, 3 edges, 0 jumps, 0 unsupported constructs

## Diagrams

### BookIngestionModal Neighborhood

```mermaid
flowchart LR
    class_twnl84_bookingestionmodal("BookIngestionModal")
    file_8kve74_bookingestionmodal_razor("BookIngestionModal")
    method_10uf4tt_savetolibrary[["SaveToLibrary()"]]
    method_1ptxaoh_handlefileselected[["HandleFileSelected()"]]
    method_1u9mlsa_ondragenter[["OnDragEnter()"]]
    method_46fkcr_disposeasync[["DisposeAsync()"]]
    method_6bf66s_ondragleave[["OnDragLeave()"]]
    method_d54w6c_reset[["Reset()"]]
    method_ujsh2c_closemodal[["CloseModal()"]]
    type_1p7g8wz_ingestresult[/"IngestResult"/]
```

### BookIngestionModal Execution Overview

```mermaid
flowchart TD
    class_twnl84_bookingestionmodal("BookIngestionModal")
    method_10uf4tt_savetolibrary[["SaveToLibrary()"]]
    method_1ptxaoh_handlefileselected[["HandleFileSelected()"]]
    method_1u9mlsa_ondragenter[["OnDragEnter()"]]
    method_46fkcr_disposeasync[["DisposeAsync()"]]
    method_6bf66s_ondragleave[["OnDragLeave()"]]
    method_d54w6c_reset[["Reset()"]]
    method_ujsh2c_closemodal[["CloseModal()"]]
    unresolved_unresolved_143kb_interaction_target{"Unresolved: MetadataExtractor.ExtractMetadataAsync(memoryStream) -> result (IsSuccess / Value / Errors)"}
    unresolved_unresolved_18cvbct_interaction_target{"Unresolved: ErrorMessage = result.Errors.FirstOrDefault()?.Message ?? \\"Failed to parse EPUB.\\";"}
    unresolved_unresolved_1d5dsj5_call_target{"Unresolved: Reset"}
    unresolved_unresolved_1uo9v3m_call_target{"Unresolved: NavigateToBook"}
    unresolved_unresolved_adir2u_call_target{"Unresolved: CloseModal"}
    unresolved_unresolved_b3cagp_interaction_target{"Unresolved: Http.PostAsJsonAsync(\\"api/library/ingest\\", request)"}
    unresolved_unresolved_ewrxdq_call_target{"Unresolved: ExtractMetadataAsync"}
    class_twnl84_bookingestionmodal -->|contains| method_10uf4tt_savetolibrary
    class_twnl84_bookingestionmodal -->|contains| method_1ptxaoh_handlefileselected
    class_twnl84_bookingestionmodal -->|contains| method_1u9mlsa_ondragenter
    class_twnl84_bookingestionmodal -->|contains| method_46fkcr_disposeasync
    class_twnl84_bookingestionmodal -->|contains| method_6bf66s_ondragleave
    class_twnl84_bookingestionmodal -->|contains| method_d54w6c_reset
    class_twnl84_bookingestionmodal -->|contains| method_ujsh2c_closemodal
    class_twnl84_bookingestionmodal -->|unresolved interaction| unresolved_unresolved_143kb_interaction_target
    class_twnl84_bookingestionmodal -->|unresolved interaction| unresolved_unresolved_18cvbct_interaction_target
    class_twnl84_bookingestionmodal -->|unresolved interaction| unresolved_unresolved_b3cagp_interaction_target
    method_10uf4tt_savetolibrary -->|unresolved call| unresolved_unresolved_1uo9v3m_call_target
    method_10uf4tt_savetolibrary -->|unresolved call| unresolved_unresolved_adir2u_call_target
    method_1ptxaoh_handlefileselected -->|unresolved call| unresolved_unresolved_ewrxdq_call_target
    method_ujsh2c_closemodal -->|unresolved call| unresolved_unresolved_1d5dsj5_call_target
```

### HandleFileSelected() Control Flow

_Warnings: diagram method_1ptxaoh_handlefileselected__fragment_diagram exceeds preferred complexity thresholds (44 nodes, 50 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_1ptxaoh_handlefileselected__call_174_ExtractMetadataAsync[["ExtractMetadataAsync"]]
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__condition{"file == null"}
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__false("otherwise")
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__merge("merge")
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__true("return")
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__condition{"file == null"}
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__false("continue")
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__merge("merge")
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__true("exit")
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__condition{"file.Name endsWith .epub"}
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__false("continue")
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__merge("merge")
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__true("invalid->set ErrorMessage")
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__condition{"!file.Name.EndsWith(\\".epub\\", StringComparison.OrdinalIgnoreCase)"}
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__false("false")
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__merge("merge")
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__true("true")
    method_1ptxaoh_handlefileselected__action_163_state_change_163__linear("Start parsing")
    method_1ptxaoh_handlefileselected__action_166_handlefileselected_try_166_3__try("Begins protected execution")
    method_1ptxaoh_handlefileselected__action_168_io_168__linear("Read uploaded file into memory")
    method_1ptxaoh_handlefileselected__action_170_handlefileselected_await_170_4__await[["Waits for async work"]]
    method_1ptxaoh_handlefileselected__action_174_handlefileselected_await_174_5__await[["Waits for async work"]]
    method_1ptxaoh_handlefileselected__action_176_branch_176__condition{"Metadata extraction success check"}
    method_1ptxaoh_handlefileselected__action_176_branch_176__false("false")
    method_1ptxaoh_handlefileselected__action_176_branch_176__merge("merge")
    method_1ptxaoh_handlefileselected__action_176_branch_176__true("true")
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__condition{"result.IsSuccess"}
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__false("false")
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__merge("merge")
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__true("true")
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__condition{"Falls back to alternate path"}
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__false("otherwise")
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__merge("merge")
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__true("fallback")
    method_1ptxaoh_handlefileselected__action_186_error_handling_186__linear("Catch exceptions during upload/parsing")
    method_1ptxaoh_handlefileselected__action_186_handlefileselected_catch_186_9__catch("catch Exception ex")
    method_1ptxaoh_handlefileselected__action_188_handlefileselected_log_188_10__linear("Logs runtime state")
    method_1ptxaoh_handlefileselected__action_191_handlefileselected_finally_191_11__finally("Runs cleanup or finalization")
    method_1ptxaoh_handlefileselected__action_193_finalize_193__linear("Stop parsing and refresh UI")
    method_1ptxaoh_handlefileselected__entry(["HandleFileSelected entry"])
    method_1ptxaoh_handlefileselected__action_174_external_call_174__linear("Extract EPUB metadata")
    method_1ptxaoh_handlefileselected__action_183_handlefileselected_repository_read_183_8__linear[("Reads repository or persistence state")]
    method_1ptxaoh_handlefileselected__action_159_handlefileselected_return_159_2__return(["Returns result"])
    method_1ptxaoh_handlefileselected__implicit_return(["return"])
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__condition -->|otherwise| method_1ptxaoh_handlefileselected__action_154_guard_clause_154__false
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__condition -->|return| method_1ptxaoh_handlefileselected__action_154_guard_clause_154__true
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__false -->|next| method_1ptxaoh_handlefileselected__action_154_guard_clause_154__merge
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__merge -->|next| method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__condition
    method_1ptxaoh_handlefileselected__action_154_guard_clause_154__true -->|next| method_1ptxaoh_handlefileselected__action_154_guard_clause_154__merge
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__condition -->|continue| method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__false
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__condition -->|exit| method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__true
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__false -->|next| method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__merge
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__merge -->|next| method_1ptxaoh_handlefileselected__action_156_guard_clause_156__condition
    method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__true -->|next| method_1ptxaoh_handlefileselected__action_154_handlefileselected_guard_clause_154_0__merge
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__condition -->|continue| method_1ptxaoh_handlefileselected__action_156_guard_clause_156__false
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__condition -->|invalid -> set ErrorMessage| method_1ptxaoh_handlefileselected__action_156_guard_clause_156__true
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__false -->|next| method_1ptxaoh_handlefileselected__action_156_guard_clause_156__merge
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__merge -->|next| method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__condition
    method_1ptxaoh_handlefileselected__action_156_guard_clause_156__true -->|next| method_1ptxaoh_handlefileselected__action_156_guard_clause_156__merge
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__condition -->|false| method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__false
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__condition -->|true| method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__true
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__false -->|next| method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__merge
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__merge -->|return| method_1ptxaoh_handlefileselected__action_159_handlefileselected_return_159_2__return
    method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__true -->|next| method_1ptxaoh_handlefileselected__action_156_handlefileselected_branch_156_1__merge
    method_1ptxaoh_handlefileselected__action_159_handlefileselected_return_159_2__return -->|next| method_1ptxaoh_handlefileselected__action_163_state_change_163__linear
    method_1ptxaoh_handlefileselected__action_163_state_change_163__linear -->|next| method_1ptxaoh_handlefileselected__action_166_handlefileselected_try_166_3__try
    method_1ptxaoh_handlefileselected__action_166_handlefileselected_try_166_3__try -->|next| method_1ptxaoh_handlefileselected__action_168_io_168__linear
    method_1ptxaoh_handlefileselected__action_168_io_168__linear -->|next| method_1ptxaoh_handlefileselected__action_170_handlefileselected_await_170_4__await
    method_1ptxaoh_handlefileselected__action_170_handlefileselected_await_170_4__await -->|next| method_1ptxaoh_handlefileselected__action_174_handlefileselected_await_174_5__await
    method_1ptxaoh_handlefileselected__action_174_external_call_174__linear -->|memoryStream stream of uploaded .epub| method_1ptxaoh_handlefileselected__call_174_ExtractMetadataAsync
    method_1ptxaoh_handlefileselected__action_174_handlefileselected_await_174_5__await -->|next| method_1ptxaoh_handlefileselected__action_174_external_call_174__linear
    method_1ptxaoh_handlefileselected__action_176_branch_176__condition -->|false| method_1ptxaoh_handlefileselected__action_176_branch_176__false
    method_1ptxaoh_handlefileselected__action_176_branch_176__condition -->|true| method_1ptxaoh_handlefileselected__action_176_branch_176__true
    method_1ptxaoh_handlefileselected__action_176_branch_176__false -->|next| method_1ptxaoh_handlefileselected__action_176_branch_176__merge
    method_1ptxaoh_handlefileselected__action_176_branch_176__merge -->|next| method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__condition
    method_1ptxaoh_handlefileselected__action_176_branch_176__true -->|next| method_1ptxaoh_handlefileselected__action_176_branch_176__merge
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__condition -->|false| method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__false
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__condition -->|true| method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__true
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__false -->|next| method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__merge
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__merge -->|fallback| method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__condition
    method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__true -->|next| method_1ptxaoh_handlefileselected__action_176_handlefileselected_branch_176_6__merge
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__condition -->|otherwise| method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__false
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__condition -->|fallback| method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__true
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__false -->|next| method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__merge
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__merge -->|next| method_1ptxaoh_handlefileselected__action_183_handlefileselected_repository_read_183_8__linear
    method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__true -->|next| method_1ptxaoh_handlefileselected__action_181_handlefileselected_fallback_181_7__merge
    method_1ptxaoh_handlefileselected__action_183_handlefileselected_repository_read_183_8__linear -->|exception| method_1ptxaoh_handlefileselected__action_186_handlefileselected_catch_186_9__catch
    method_1ptxaoh_handlefileselected__action_186_error_handling_186__linear -->|next| method_1ptxaoh_handlefileselected__action_188_handlefileselected_log_188_10__linear
    method_1ptxaoh_handlefileselected__action_186_handlefileselected_catch_186_9__catch -->|next| method_1ptxaoh_handlefileselected__action_186_error_handling_186__linear
    method_1ptxaoh_handlefileselected__action_188_handlefileselected_log_188_10__linear -->|next| method_1ptxaoh_handlefileselected__action_191_handlefileselected_finally_191_11__finally
    method_1ptxaoh_handlefileselected__action_191_handlefileselected_finally_191_11__finally -->|next| method_1ptxaoh_handlefileselected__action_193_finalize_193__linear
    method_1ptxaoh_handlefileselected__action_193_finalize_193__linear -->|return| method_1ptxaoh_handlefileselected__implicit_return
    method_1ptxaoh_handlefileselected__call_174_ExtractMetadataAsync -->|next| method_1ptxaoh_handlefileselected__action_176_branch_176__condition
    method_1ptxaoh_handlefileselected__entry -->|next| method_1ptxaoh_handlefileselected__action_154_guard_clause_154__condition
```

### SaveToLibrary() Control Flow

_Warnings: diagram method_10uf4tt_savetolibrary__fragment_diagram exceeds preferred complexity thresholds (42 nodes, 47 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_10uf4tt_savetolibrary__call_223_CloseModal[["CloseModal"]]
    method_10uf4tt_savetolibrary__call_224_NavigateToBook[["NavigateToBook"]]
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__condition{"Metadata != null && _epubBytes != null"}
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__false("otherwise")
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__merge("merge")
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__true("return if missing")
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__condition{"Metadata == null || _epubBytes == null"}
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__false("continue")
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__merge("merge")
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__true("exit")
    method_10uf4tt_savetolibrary__action_202_state_change_202__linear("Start ingesting")
    method_10uf4tt_savetolibrary__action_206_savetolibrary_try_206_1__try("Begins protected execution")
    method_10uf4tt_savetolibrary__action_208_mapping_208__linear("Build ingest request DTO")
    method_10uf4tt_savetolibrary__action_216_savetolibrary_await_216_2__await[["Waits for async work"]]
    method_10uf4tt_savetolibrary__action_218_branch_218__condition{"Handle response success/failure"}
    method_10uf4tt_savetolibrary__action_218_branch_218__false("false")
    method_10uf4tt_savetolibrary__action_218_branch_218__merge("merge")
    method_10uf4tt_savetolibrary__action_218_branch_218__true("true")
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__condition{"response.IsSuccessStatusCode"}
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__false("false")
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__merge("merge")
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__true("true")
    method_10uf4tt_savetolibrary__action_220_io_220__linear("Read response and parse result")
    method_10uf4tt_savetolibrary__action_220_savetolibrary_await_220_4__await[["Waits for async work"]]
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__condition{"result != null"}
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__false("false")
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__merge("merge")
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__true("true")
    method_10uf4tt_savetolibrary__action_223_savetolibrary_await_223_6__await[["Waits for async work"]]
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__condition{"Falls back to alternate path"}
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__false("otherwise")
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__merge("merge")
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__true("fallback")
    method_10uf4tt_savetolibrary__action_229_savetolibrary_await_229_8__await[["Waits for async work"]]
    method_10uf4tt_savetolibrary__action_232_error_handling_232__linear("Catch exceptions during ingest")
    method_10uf4tt_savetolibrary__action_232_savetolibrary_catch_232_9__catch("catch Exception ex")
    method_10uf4tt_savetolibrary__action_234_savetolibrary_log_234_10__linear("Logs runtime state")
    method_10uf4tt_savetolibrary__action_237_savetolibrary_finally_237_11__finally("Runs cleanup or finalization")
    method_10uf4tt_savetolibrary__action_239_finalize_239__linear("Stop ingesting and refresh UI")
    method_10uf4tt_savetolibrary__entry(["SaveToLibrary entry"])
    method_10uf4tt_savetolibrary__action_216_external_call_216__linear("POST ingest request to server API")
    method_10uf4tt_savetolibrary__implicit_return(["return"])
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__condition -->|otherwise| method_10uf4tt_savetolibrary__action_200_guard_clause_200__false
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__condition -->|return if missing| method_10uf4tt_savetolibrary__action_200_guard_clause_200__true
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__false -->|next| method_10uf4tt_savetolibrary__action_200_guard_clause_200__merge
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__merge -->|next| method_10uf4tt_savetolibrary__action_202_state_change_202__linear
    method_10uf4tt_savetolibrary__action_200_guard_clause_200__true -->|next| method_10uf4tt_savetolibrary__action_200_guard_clause_200__merge
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__condition -->|continue| method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__false
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__condition -->|exit| method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__true
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__false -->|next| method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__merge
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__merge -->|next| method_10uf4tt_savetolibrary__action_200_guard_clause_200__condition
    method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__true -->|next| method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__merge
    method_10uf4tt_savetolibrary__action_202_state_change_202__linear -->|next| method_10uf4tt_savetolibrary__action_206_savetolibrary_try_206_1__try
    method_10uf4tt_savetolibrary__action_206_savetolibrary_try_206_1__try -->|next| method_10uf4tt_savetolibrary__action_208_mapping_208__linear
    method_10uf4tt_savetolibrary__action_208_mapping_208__linear -->|next| method_10uf4tt_savetolibrary__action_216_savetolibrary_await_216_2__await
    method_10uf4tt_savetolibrary__action_216_external_call_216__linear -->|next| method_10uf4tt_savetolibrary__action_218_branch_218__condition
    method_10uf4tt_savetolibrary__action_216_savetolibrary_await_216_2__await -->|next| method_10uf4tt_savetolibrary__action_216_external_call_216__linear
    method_10uf4tt_savetolibrary__action_218_branch_218__condition -->|false| method_10uf4tt_savetolibrary__action_218_branch_218__false
    method_10uf4tt_savetolibrary__action_218_branch_218__condition -->|true| method_10uf4tt_savetolibrary__action_218_branch_218__true
    method_10uf4tt_savetolibrary__action_218_branch_218__false -->|next| method_10uf4tt_savetolibrary__action_218_branch_218__merge
    method_10uf4tt_savetolibrary__action_218_branch_218__merge -->|next| method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__condition
    method_10uf4tt_savetolibrary__action_218_branch_218__true -->|next| method_10uf4tt_savetolibrary__action_218_branch_218__merge
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__condition -->|false| method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__false
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__condition -->|true| method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__true
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__false -->|next| method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__merge
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__merge -->|next| method_10uf4tt_savetolibrary__action_220_savetolibrary_await_220_4__await
    method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__true -->|next| method_10uf4tt_savetolibrary__action_218_savetolibrary_branch_218_3__merge
    method_10uf4tt_savetolibrary__action_220_io_220__linear -->|next| method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__condition
    method_10uf4tt_savetolibrary__action_220_savetolibrary_await_220_4__await -->|next| method_10uf4tt_savetolibrary__action_220_io_220__linear
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__condition -->|false| method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__false
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__condition -->|true| method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__true
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__false -->|next| method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__merge
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__merge -->|next| method_10uf4tt_savetolibrary__action_223_savetolibrary_await_223_6__await
    method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__true -->|next| method_10uf4tt_savetolibrary__action_221_savetolibrary_branch_221_5__merge
    method_10uf4tt_savetolibrary__action_223_savetolibrary_await_223_6__await -->|none| method_10uf4tt_savetolibrary__call_223_CloseModal
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__condition -->|otherwise| method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__false
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__condition -->|fallback| method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__true
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__false -->|next| method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__merge
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__merge -->|next| method_10uf4tt_savetolibrary__action_229_savetolibrary_await_229_8__await
    method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__true -->|next| method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__merge
    method_10uf4tt_savetolibrary__action_229_savetolibrary_await_229_8__await -->|exception| method_10uf4tt_savetolibrary__action_232_savetolibrary_catch_232_9__catch
    method_10uf4tt_savetolibrary__action_232_error_handling_232__linear -->|next| method_10uf4tt_savetolibrary__action_234_savetolibrary_log_234_10__linear
    method_10uf4tt_savetolibrary__action_232_savetolibrary_catch_232_9__catch -->|next| method_10uf4tt_savetolibrary__action_232_error_handling_232__linear
    method_10uf4tt_savetolibrary__action_234_savetolibrary_log_234_10__linear -->|next| method_10uf4tt_savetolibrary__action_237_savetolibrary_finally_237_11__finally
    method_10uf4tt_savetolibrary__action_237_savetolibrary_finally_237_11__finally -->|next| method_10uf4tt_savetolibrary__action_239_finalize_239__linear
    method_10uf4tt_savetolibrary__action_239_finalize_239__linear -->|return| method_10uf4tt_savetolibrary__implicit_return
    method_10uf4tt_savetolibrary__call_223_CloseModal -->|result.Id Guid| method_10uf4tt_savetolibrary__call_224_NavigateToBook
    method_10uf4tt_savetolibrary__call_224_NavigateToBook -->|fallback| method_10uf4tt_savetolibrary__action_227_savetolibrary_fallback_227_7__condition
    method_10uf4tt_savetolibrary__entry -->|next| method_10uf4tt_savetolibrary__action_200_savetolibrary_guard_clause_200_0__condition
```

## Diagram Validation

- Status: warn
- Warning: Control-flow extraction left 2 unresolved jumps.
- Warning: control-flow: diagram method_1ptxaoh_handlefileselected__fragment_diagram exceeds preferred complexity thresholds (44 nodes, 50 edges).
- Warning: control-flow: diagram method_10uf4tt_savetolibrary__fragment_diagram exceeds preferred complexity thresholds (42 nodes, 47 edges).
