<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kefer Astrology Documentation</title>
    <link>./</link>
    <description>Recent content on Kefer Astrology Documentation</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <atom:link href="./index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Project Overview</title>
      <link>./readme/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./readme/</guid>
      <description>&lt;h1 id=&#34;function-layer-for-kefer-astrology&#34;&gt;Function layer for Kefer Astrology&lt;/h1&gt;&#xA;&lt;h2 id=&#34;quickstart&#34;&gt;Quickstart&lt;/h2&gt;&#xA;&lt;p&gt;Get up and running in 3 steps:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt;# 1. Create and activate virtual environment&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 -m venv venv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt;# alternatively use makefile&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;source&lt;/span&gt; ./venv/bin/activate  &lt;span style=&#34;color:#57606a&#34;&gt;# Linux/Mac&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;venv&lt;span style=&#34;color:#0a3069&#34;&gt;\S&lt;/span&gt;cripts&lt;span style=&#34;color:#0a3069&#34;&gt;\a&lt;/span&gt;ctivate  &lt;span style=&#34;color:#57606a&#34;&gt;# Windows&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt;# 2. Install dependencies (choose your UI)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install -r requirements/base.txt  &lt;span style=&#34;color:#57606a&#34;&gt;# for base package&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install -r requirements/streamlit.txt  &lt;span style=&#34;color:#57606a&#34;&gt;# For Streamlit UI (browser)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install -r requirements/kivy.txt  &lt;span style=&#34;color:#57606a&#34;&gt;# For Kivy UI (desktop)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt;# Or install by package extras&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install .  &lt;span style=&#34;color:#57606a&#34;&gt;# core computation/storage package&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install .&lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;api&lt;span style=&#34;color:#0550ae&#34;&gt;]&lt;/span&gt;  &lt;span style=&#34;color:#57606a&#34;&gt;# FastAPI backend for Tauri/web frontends&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install .&lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;streamlit&lt;span style=&#34;color:#0550ae&#34;&gt;]&lt;/span&gt;  &lt;span style=&#34;color:#57606a&#34;&gt;# Streamlit UI + chart rendering&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install .&lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;kivy&lt;span style=&#34;color:#0550ae&#34;&gt;]&lt;/span&gt;  &lt;span style=&#34;color:#57606a&#34;&gt;# Kivy desktop UI + chart rendering&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#57606a&#34;&gt;# 3. Run the application&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 -m module --streamlit  &lt;span style=&#34;color:#57606a&#34;&gt;# Streamlit UI (browser)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 -m module --kivy  &lt;span style=&#34;color:#57606a&#34;&gt;# Kivy UI (desktop)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 -m module --tui   &lt;span style=&#34;color:#57606a&#34;&gt;# Text UI (terminal)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 -m module         &lt;span style=&#34;color:#57606a&#34;&gt;# Default: TUI&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For detailed setup instructions, troubleshooting, and advanced options, see the&#xA;&lt;a href=&#34;installation&#34;&gt;Installation and Venvs&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Streamlit UI</title>
      <link>./ui_streamlit/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./ui_streamlit/</guid>
      <description>&lt;h1 id=&#34;streamlit-ui&#34;&gt;Streamlit UI&lt;/h1&gt;&#xA;&lt;p&gt;The Streamlit UI provides a web-based interface for creating and visualizing astrological charts.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../example_streamlit.png&#34; alt=&#34;Streamlit UI Example&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-to-run&#34;&gt;How to Run&lt;/h2&gt;&#xA;&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;&#xA;&lt;p&gt;Install Streamlit and required dependencies:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install -r requirements/streamlit.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;starting-the-application&#34;&gt;Starting the Application&lt;/h3&gt;&#xA;&lt;p&gt;Run the Streamlit interface:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m module --streamlit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or directly:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;streamlit run module/ui_streamlit.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;features&#34;&gt;Features&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Interactive chart creation&lt;/li&gt;&#xA;&lt;li&gt;Real-time position calculations&lt;/li&gt;&#xA;&lt;li&gt;Aspect visualization&lt;/li&gt;&#xA;&lt;li&gt;Workspace management&lt;/li&gt;&#xA;&lt;li&gt;Chart export capabilities&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;configuration&#34;&gt;Configuration&lt;/h3&gt;&#xA;&lt;p&gt;The Streamlit UI uses the workspace configuration from &lt;code&gt;workspace.yaml&lt;/code&gt;. You can customize settings through the UI&amp;rsquo;s advanced options panel.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kivy UI</title>
      <link>./ui_kivy/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./ui_kivy/</guid>
      <description>&lt;h1 id=&#34;kivy-ui&#34;&gt;Kivy UI&lt;/h1&gt;&#xA;&lt;p&gt;The Kivy UI provides a native desktop application for astrological chart visualization with embedded interactive charts.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../example_kivy.png&#34; alt=&#34;Kivy UI Example&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-to-run&#34;&gt;How to Run&lt;/h2&gt;&#xA;&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;&#xA;&lt;p&gt;Install Kivy and required dependencies:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install -r requirements/kivy.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For embedded interactive Plotly charts, install the WebView widget:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install kivy-garden&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;garden install kivy_garden.webview&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;starting-the-application&#34;&gt;Starting the Application&lt;/h3&gt;&#xA;&lt;p&gt;Run the Kivy interface:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m module --kivy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;features&#34;&gt;Features&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Native desktop application&lt;/li&gt;&#xA;&lt;li&gt;Embedded interactive Plotly charts (with WebView)&lt;/li&gt;&#xA;&lt;li&gt;JPL engine toggle&lt;/li&gt;&#xA;&lt;li&gt;Standardized Radix chart renderer&lt;/li&gt;&#xA;&lt;li&gt;Cross-platform support (Windows, macOS, Linux)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;configuration&#34;&gt;Configuration&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Default JPL ephemeris file: &lt;code&gt;source/de421.bsp&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Chart files are saved to the workspace directory&lt;/li&gt;&#xA;&lt;li&gt;If WebView is unavailable, charts open in the default browser&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;troubleshooting&#34;&gt;Troubleshooting&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Unknown class &lt;code&gt;WebView&lt;/code&gt;&lt;/strong&gt;: Install via &lt;code&gt;garden install kivy_garden.webview&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;JPL not active&lt;/strong&gt;: Ensure &lt;code&gt;skyfield&lt;/code&gt; is installed and &lt;code&gt;source/de421.bsp&lt;/code&gt; exists&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Chart opens in browser&lt;/strong&gt;: WebView widget not installed (this is a fallback behavior)&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>cli Module</title>
      <link>./auto/cli/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/cli/</guid>
      <description>&lt;h1 id=&#34;cli-module&#34;&gt;&lt;code&gt;cli&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;p&gt;CLI interface for Tauri frontend integration.&lt;/p&gt;&#xA;&lt;p&gt;This module provides a JSON-based command interface that can be called&#xA;from the Tauri application via subprocess. All commands read JSON from&#xA;stdin or command-line arguments and output JSON to stdout.&lt;/p&gt;&#xA;&lt;p&gt;Usage:&#xA;python -m module.cli &amp;lt;command&amp;gt; [args_json]&lt;/p&gt;&#xA;&lt;p&gt;Commands:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;compute_chart: Compute positions and aspects for a chart&lt;/li&gt;&#xA;&lt;li&gt;compute_transit_series: Compute transit series for a time range&lt;/li&gt;&#xA;&lt;li&gt;get_workspace_settings: Get workspace settings and defaults&lt;/li&gt;&#xA;&lt;li&gt;list_charts: List all charts in workspace&lt;/li&gt;&#xA;&lt;li&gt;get_chart: Get chart details by ID&lt;/li&gt;&#xA;&lt;li&gt;sync_workspace: Synchronize workspace manifest with files on disk&lt;/li&gt;&#xA;&lt;li&gt;export_parquet: Export stored positions to Parquet files&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Storage:&lt;/p&gt;</description>
    </item>
    <item>
      <title>models Module</title>
      <link>./auto/models/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/models/</guid>
      <description>&lt;h1 id=&#34;models-module&#34;&gt;&lt;code&gt;models&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;h2 id=&#34;classes&#34;&gt;Classes&lt;/h2&gt;&#xA;&lt;h3 id=&#34;class-annotation&#34;&gt;class &lt;code&gt;Annotation&lt;/code&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Annotation(title: str, content: str, created: datetime.datetime | None, author: str)&lt;/p&gt;&#xA;&lt;h4 id=&#34;dataclass-fields&#34;&gt;Dataclass fields&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;title: str&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;content: str&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;created: Union&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;author: str&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;class-aspect&#34;&gt;class &lt;code&gt;Aspect&lt;/code&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Aspect(type: str, source_id: str, target_id: str, angle: float, orb: float)&lt;/p&gt;&#xA;&lt;h4 id=&#34;dataclass-fields-1&#34;&gt;Dataclass fields&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;type: str&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;source_id: str&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;target_id: str&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;angle: float&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;orb: float&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;class-aspectcontext-str-enum&#34;&gt;class &lt;code&gt;AspectContext&lt;/code&gt; (str, Enum)&lt;/h3&gt;&#xA;&lt;p&gt;Contexts where an aspect can be used.&lt;/p&gt;&#xA;&lt;h3 id=&#34;class-aspectdefinition&#34;&gt;class &lt;code&gt;AspectDefinition&lt;/code&gt;&lt;/h3&gt;&#xA;&lt;p&gt;AspectDefinition(id: str, glyph: str, angle: float, default_orb: float, i18n: Dict[str, str], color: str | None = None, importance: int | None = None, line_style: str | None = None, line_width: float | None = None, show_label: bool | None = None, valid_contexts: List[module.models.AspectContext] | None = None)&lt;/p&gt;</description>
    </item>
    <item>
      <title>services Module</title>
      <link>./auto/services/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/services/</guid>
      <description>&lt;h1 id=&#34;services-module&#34;&gt;&lt;code&gt;services&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;&#xA;&lt;h2 id=&#34;build_chart_instance&#34;&gt;&lt;code&gt;build_chart_instance&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;build_chart_instance&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;name&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; dt_str&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; loc_text&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; mode&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;ChartMode&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; ws&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; Optional&lt;span style=&#34;color:#1f2328&#34;&gt;[&lt;/span&gt;module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Workspace&lt;span style=&#34;color:#1f2328&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;None&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; ephemeris_path&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; Optional&lt;span style=&#34;color:#1f2328&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;None&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;ChartInstance&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Build a ChartInstance using workspace defaults when provided.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Resolves engine and house system from ws if available.&lt;/li&gt;&#xA;&lt;li&gt;Uses utils.prepare_horoscope to produce a fully-typed ChartInstance.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;build_radix_figure_for_chart&#34;&gt;&lt;code&gt;build_radix_figure_for_chart&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;build_radix_figure_for_chart&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;chart&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;ChartInstance&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; engine_override&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; Optional&lt;span style=&#34;color:#1f2328&#34;&gt;[&lt;/span&gt;module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;EngineType&lt;span style=&#34;color:#1f2328&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;None&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; ephemeris_path_override&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; Optional&lt;span style=&#34;color:#1f2328&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;None&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; ws&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; Optional&lt;span style=&#34;color:#1f2328&#34;&gt;[&lt;/span&gt;ForwardRef&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;Workspace&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)]&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;None&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; Any&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Extract positions from a ChartInstance&amp;rsquo;s computed_chart and return a Plotly Figure ready to render.&lt;/p&gt;&#xA;&lt;h4 id=&#34;parameters&#34;&gt;Parameters&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;chart&lt;/strong&gt;: ChartInstance to compute positions for&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;engine_override&lt;/strong&gt;: Optional engine to use instead of chart&amp;rsquo;s stored engine&lt;/p&gt;</description>
    </item>
    <item>
      <title>storage Module</title>
      <link>./auto/storage/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/storage/</guid>
      <description>&lt;h1 id=&#34;storage-module&#34;&gt;&lt;code&gt;storage&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;p&gt;DuckDB and Parquet storage helpers for computed astrological data.&lt;/p&gt;&#xA;&lt;p&gt;This module provides optional storage functionality for Python to write&#xA;computed positions and aspects directly to DuckDB/Parquet, avoiding&#xA;large JSON transfers for batch operations like transit series.&lt;/p&gt;&#xA;&lt;p&gt;Usage:&#xA;from module.storage import DuckDBStorage&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;storage = DuckDBStorage(&#39;/path/to/workspace/data/workspace.db&#39;)&#xA;storage.store_positions(chart_id, datetime, positions, engine=&#39;jpl&#39;)&#xA;&#xA;# Optimized batch computation&#xA;storage.compute_and_store_series(&#xA;    chart_id=&#39;transit_base&#39;,&#xA;    start_datetime=start_dt,&#xA;    end_datetime=end_dt,&#xA;    time_step=timedelta(minutes=1),&#xA;    location=location,&#xA;    engine=&#39;jpl&#39;,&#xA;    requested_objects=[&#39;sun&#39;, &#39;moon&#39;, ...],&#xA;    include_physical=True,&#xA;    include_topocentric=True&#xA;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;&#xA;&lt;h2 id=&#34;get_storage_path&#34;&gt;&lt;code&gt;get_storage_path&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_storage_path&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;workspace_path&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;|&lt;/span&gt; pathlib&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Path&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; pathlib&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Path&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Get DuckDB storage path for a workspace.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ui_streamlit Module</title>
      <link>./auto/ui_streamlit/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/ui_streamlit/</guid>
      <description>&lt;h1 id=&#34;ui_streamlit-module&#34;&gt;&lt;code&gt;ui_streamlit&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;&#xA;&lt;h2 id=&#34;main&#34;&gt;&lt;code&gt;main&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main&lt;span style=&#34;color:#1f2328&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;render_toolbar&#34;&gt;&lt;code&gt;render_toolbar&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;render_toolbar&lt;span style=&#34;color:#1f2328&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;how-the-ui-is-invoked&#34;&gt;How the UI is invoked&lt;/h2&gt;&#xA;&lt;p&gt;Entry point: &lt;code&gt;main()&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>utils Module</title>
      <link>./auto/utils/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/utils/</guid>
      <description>&lt;h1 id=&#34;utils-module&#34;&gt;&lt;code&gt;utils&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;&#xA;&lt;h2 id=&#34;combine_date_time&#34;&gt;&lt;code&gt;combine_date_time&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;combine_date_time&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;input_date&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; datetime&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;date&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; input_time&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; datetime&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;time&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; datetime&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;datetime&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Combine a date and time into a naive datetime (no timezone).&lt;/p&gt;&#xA;&lt;h4 id=&#34;parameters&#34;&gt;Parameters&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;input_date&lt;/strong&gt;: Date object&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;input_time&lt;/strong&gt;: Time object&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h4 id=&#34;returns&#34;&gt;Returns&lt;/h4&gt;&#xA;&lt;p&gt;Naive datetime combining date and time&lt;/p&gt;&#xA;&lt;h2 id=&#34;compute_vernal_equinox_offset&#34;&gt;&lt;code&gt;compute_vernal_equinox_offset&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;compute_vernal_equinox_offset&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;year&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; eph&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; observer&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; ts&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;float&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Compute the vernal equinox offset for tropical astrology adjustment.&lt;/p&gt;&#xA;&lt;h4 id=&#34;parameters-1&#34;&gt;Parameters&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;year&lt;/strong&gt;: The year to compute the vernal equinox for&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;eph&lt;/strong&gt;: Skyfield ephemeris object&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;observer&lt;/strong&gt;: Skyfield Topos observer object&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;ts&lt;/strong&gt;: Skyfield timescale object&lt;/p&gt;</description>
    </item>
    <item>
      <title>workspace Module</title>
      <link>./auto/workspace/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/workspace/</guid>
      <description>&lt;h1 id=&#34;workspace-module&#34;&gt;&lt;code&gt;workspace&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;&#xA;&lt;h2 id=&#34;add_chart&#34;&gt;&lt;code&gt;add_chart&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;add_chart&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;ws&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Workspace&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; chart&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;ChartInstance&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; base_dir&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;|&lt;/span&gt; pathlib&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Path&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add a chart to a Workspace and write its YAML file.&lt;/p&gt;&#xA;&lt;h4 id=&#34;parameters&#34;&gt;Parameters&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;ws&lt;/strong&gt;: Workspace to add chart to&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;chart&lt;/strong&gt;: ChartInstance to add&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;base_dir&lt;/strong&gt;: Base directory for workspace files&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h4 id=&#34;returns&#34;&gt;Returns&lt;/h4&gt;&#xA;&lt;p&gt;Relative path to chart YAML file&lt;/p&gt;&#xA;&lt;h4 id=&#34;notes&#34;&gt;Notes&lt;/h4&gt;&#xA;&lt;p&gt;Prevents duplicates by checking existing charts. Removes computed_chart&#xA;and ephemeral overrides before serialization.&lt;/p&gt;&#xA;&lt;h2 id=&#34;add_or_update_chart&#34;&gt;&lt;code&gt;add_or_update_chart&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;add_or_update_chart&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;ws&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Workspace&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; chart&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; module&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;models&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;ChartInstance&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; base_dir&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;|&lt;/span&gt; pathlib&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Path&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;str&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add a new chart or update an existing one by id or subject name; persist YAML and manifest.&lt;/p&gt;</description>
    </item>
    <item>
      <title>z_visual Module</title>
      <link>./auto/z_visual/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./auto/z_visual/</guid>
      <description>&lt;h1 id=&#34;z_visual-module&#34;&gt;&lt;code&gt;z_visual&lt;/code&gt; module&lt;/h1&gt;&#xA;&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;&#xA;&lt;h2 id=&#34;build_radix_figure&#34;&gt;&lt;code&gt;build_radix_figure&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;build_radix_figure&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;positions&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;dict&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; plotly&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;graph_objs&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;_figure&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;Figure&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Build a standardized polar (radix) chart figure from planet positions in degrees [0,360).&#xA;positions: mapping of planet name (lowercase or mixed) -&amp;gt; ecliptic longitude in degrees&lt;/p&gt;&#xA;&lt;h2 id=&#34;display_3d&#34;&gt;&lt;code&gt;display_3d&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;display_3d&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;categories&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;list&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; values_degrees&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;list&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; labels&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;list&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;None&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Render a simple Matplotlib 3D scatter plot for objects at given angles.&lt;/p&gt;&#xA;&lt;h2 id=&#34;display_radial&#34;&gt;&lt;code&gt;display_radial&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;display_radial&lt;span style=&#34;color:#1f2328&#34;&gt;(&lt;/span&gt;categories&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;list&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; values_degrees&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;list&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt; labels&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#6639ba&#34;&gt;list&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#0550ae&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;None&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Quick Matplotlib radial scatter demo for given categories and degrees.&lt;/p&gt;&#xA;&lt;h4 id=&#34;parameters&#34;&gt;Parameters&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;categories&lt;/strong&gt;: labels for angular ticks&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;values_degrees&lt;/strong&gt;: list of angles in degrees&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>./architecture/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./architecture/</guid>
      <description>&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;&#xA;&lt;p&gt;The architecture separates UI, computation, workspace management, and storage so multiple frontends can share the same backend behavior.&lt;/p&gt;&#xA;&lt;h2 id=&#34;repository-structure-top-level&#34;&gt;Repository Structure (top level)&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;cache: temporary files for computation&lt;/li&gt;&#xA;&lt;li&gt;module: all the program logic&lt;/li&gt;&#xA;&lt;li&gt;scripts: generators for documentation&lt;/li&gt;&#xA;&lt;li&gt;tests: scenario and functionality testing&lt;/li&gt;&#xA;&lt;li&gt;venv: python environment with libraries&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;core-layers&#34;&gt;Core Layers&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;UI layer&lt;/strong&gt;: Streamlit, Kivy, or Tauri/Svelte call Python services directly.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Services layer&lt;/strong&gt;: &lt;code&gt;module.services&lt;/code&gt; computes positions/aspects and builds charts.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Workspace layer&lt;/strong&gt;: &lt;code&gt;module.workspace&lt;/code&gt; loads/saves modular YAML workspaces.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Storage layer&lt;/strong&gt;: &lt;code&gt;module.storage&lt;/code&gt; persists positions to DuckDB and Parquet (positions-only).&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;data-flow&#34;&gt;Data Flow&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;UI collects inputs and opens a workspace.&lt;/li&gt;&#xA;&lt;li&gt;Services compute positions (and aspects on demand).&lt;/li&gt;&#xA;&lt;li&gt;Storage writes positions to DuckDB and/or Parquet.&lt;/li&gt;&#xA;&lt;li&gt;UI renders charts from computed positions.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;storage-model&#34;&gt;Storage Model&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Positions-only&lt;/strong&gt;: aspects are computed on demand.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Dual engines&lt;/strong&gt;: Kerykeion (fast) and JPL/Skyfield (extended properties).&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Radix support&lt;/strong&gt;: &lt;code&gt;radix_chart_id&lt;/code&gt; + &lt;code&gt;is_radix&lt;/code&gt; for transit comparisons.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Hybrid storage&lt;/strong&gt;: DuckDB for active queries, Parquet for time series.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;storage-backend&#34;&gt;Storage (Backend)&lt;/h2&gt;&#xA;&lt;h3 id=&#34;strategy-python-vs-rust&#34;&gt;Strategy (Python vs Rust)&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;Python storage&lt;/strong&gt; (batch):&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>./cli_reference/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./cli_reference/</guid>
      <description>&lt;h1 id=&#34;cli-reference&#34;&gt;CLI Reference&lt;/h1&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;&#xA;&lt;p&gt;The Python sidecar provides a JSON-based CLI interface for the Tauri frontend. All commands accept JSON arguments and return JSON results.&lt;/p&gt;&#xA;&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m module.cli &amp;lt;command&amp;gt; &lt;span style=&#34;color:#0550ae&#34;&gt;[&lt;/span&gt;args_json&lt;span style=&#34;color:#0550ae&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or with JSON from stdin:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6639ba&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#39;{&amp;#34;workspace_path&amp;#34;: &amp;#34;/path/to/workspace.yaml&amp;#34;, &amp;#34;chart_id&amp;#34;: &amp;#34;my-chart&amp;#34;}&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#1f2328&#34;&gt;|&lt;/span&gt; python -m module.cli compute_chart&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;commands&#34;&gt;Commands&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-compute_chart&#34;&gt;1. &lt;code&gt;compute_chart&lt;/code&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Compute positions and aspects for a chart.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Arguments:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;&amp;#34;workspace_path&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;/path/to/workspace.yaml&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;&amp;#34;chart_id&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#0a3069&#34;&gt;&amp;#34;chart-id&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;&amp;#34;include_physical&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;,&lt;/span&gt;      &lt;span style=&#34;color:#57606a&#34;&gt;// Optional: Include extended physical properties (JPL only)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#0550ae&#34;&gt;&amp;#34;include_topocentric&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#cf222e&#34;&gt;false&lt;/span&gt;   &lt;span style=&#34;color:#57606a&#34;&gt;// Optional: Include altitude/azimuth (JPL with location)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#1f2328&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Response:&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>./enums/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./enums/</guid>
      <description>&lt;h1 id=&#34;enum-overview&#34;&gt;Enum Overview&lt;/h1&gt;&#xA;&lt;p&gt;This document lists all enumerations defined in &lt;code&gt;module.models&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Enum&lt;/th&gt;&#xA;          &lt;th&gt;Description&lt;/th&gt;&#xA;          &lt;th&gt;Members&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;AspectContext&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Contexts where an aspect can be used.&lt;/td&gt;&#xA;          &lt;td&gt;CHART, TRANSIT, DIRECTION&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Ayanamsa&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Ayanamsa enumeration&lt;/td&gt;&#xA;          &lt;td&gt;LAHIRI, RAMAN, KRISHNAMURTI, FAGAN_BRADLEY, DE_LUCE, USER_DEFINED&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ChartMode&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;ChartMode enumeration&lt;/td&gt;&#xA;          &lt;td&gt;NATAL, EVENT, HORARY, COMPOSITE&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Element&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;The four classical elements.&lt;/td&gt;&#xA;          &lt;td&gt;FIRE, EARTH, AIR, WATER&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;EngineType&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Engine enumeration&lt;/td&gt;&#xA;          &lt;td&gt;SWISSEPH, JYOTISH, JPL, CUSTOM&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;HouseSystem&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;House enumeration&lt;/td&gt;&#xA;          &lt;td&gt;PLACIDUS, WHOLE_SIGN, CAMPANUS, KOCH, EQUAL, REGIOMONTANUS, VEHL, PORPHYRY, ALCABITIUS&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;LayoutStyle&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Layout enumeration&lt;/td&gt;&#xA;          &lt;td&gt;SINGLE, TIMELINE_OVERLAY, DUAL_WHEEL, COMPARISON&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ObjectType&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Type of observable object in the chart.&lt;/td&gt;&#xA;          &lt;td&gt;PLANET, ASTEROID, ANGLE, HOUSE_CUSP, CALCULATED_POINT, LUNAR_NODE, PART&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;RelationType&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Relation enumeration&lt;/td&gt;&#xA;          &lt;td&gt;TRANSIT, SYNASTRY, PROGRESSION, COMPOSITE&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;TimeSystem&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Time representation systems.&lt;/td&gt;&#xA;          &lt;td&gt;GREGORIAN, JULIAN_DAY, JULIAN_CALENDAR, UNIX_TIMESTAMP, ORDINAL_DATE, ISO_WEEK_DATE, COMPACT_DATE&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ViewModuleType&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;ViewModule enumeration&lt;/td&gt;&#xA;          &lt;td&gt;WHEEL, TIMELINE, GRID, TABLE, TEXT&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ZodiacType&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Zodiac enumeration&lt;/td&gt;&#xA;          &lt;td&gt;TROPICAL, SIDEREAL&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;</description>
    </item>
    <item>
      <title></title>
      <link>./ephemeris/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./ephemeris/</guid>
      <description>&lt;h1 id=&#34;ephemeris-files&#34;&gt;Ephemeris files&lt;/h1&gt;&#xA;&lt;h2 id=&#34;default-file-de440sbsp&#34;&gt;Default file: de440s.bsp&lt;/h2&gt;&#xA;&lt;p&gt;The default JPL ephemeris was upgraded from &lt;code&gt;de421.bsp&lt;/code&gt; to &lt;code&gt;de440s.bsp&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;default_ephemeris_path()&lt;/code&gt; in &lt;code&gt;module/utils.py&lt;/code&gt; resolves the file in this order:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;source&lt;span style=&#34;color:#0550ae&#34;&gt;/&lt;/span&gt;de440s&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;bsp   &lt;span style=&#34;color:#57606a&#34;&gt;# preferred&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;source&lt;span style=&#34;color:#0550ae&#34;&gt;/&lt;/span&gt;de421&lt;span style=&#34;color:#0550ae&#34;&gt;.&lt;/span&gt;bsp    &lt;span style=&#34;color:#57606a&#34;&gt;# legacy fallback&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The old &lt;code&gt;de421.bsp&lt;/code&gt; remains in &lt;code&gt;source/&lt;/code&gt; as a fallback for environments that have not yet received &lt;code&gt;de440s.bsp&lt;/code&gt;. Once &lt;code&gt;de440s.bsp&lt;/code&gt; is present, it is used automatically — no configuration change needed.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;what-de440s-actually-provides&#34;&gt;What de440s actually provides&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;de440s.bsp&lt;/code&gt; contains the same set of &lt;strong&gt;queryable bodies&lt;/strong&gt; as &lt;code&gt;de421.bsp&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>./fastapi_tauri/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./fastapi_tauri/</guid>
      <description>&lt;h1 id=&#34;fastapi--react--tauri-integration&#34;&gt;FastAPI + React + Tauri Integration&lt;/h1&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;&#xA;&lt;p&gt;This guide describes the recommended way to use the Python package in a desktop application built from:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;React (or Svelte) frontend&lt;/li&gt;&#xA;&lt;li&gt;FastAPI backend&lt;/li&gt;&#xA;&lt;li&gt;Tauri packaging&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The key idea is to treat the Python package as a reusable computation library, and to keep UI-specific modules optional.&lt;/p&gt;&#xA;&lt;p&gt;Recommended runtime flow:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Tauri shell&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; React frontend&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; HTTP calls to FastAPI on localhost&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -&amp;gt; FastAPI calls module.services / module.workspace / module.storage&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Do not build the Tauri app around &lt;code&gt;module/ui_streamlit.py&lt;/code&gt; or &lt;code&gt;module/ui_kivy.py&lt;/code&gt;.&#xA;Those files are alternative Python frontends, not the ideal integration surface for Tauri.&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>./installation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./installation/</guid>
      <description>&lt;h1 id=&#34;installation-and-venvs&#34;&gt;Installation and Venvs&lt;/h1&gt;&#xA;&lt;p&gt;This project uses multiple virtual environments so the core backend stays lean while UI wrappers remain optional.&lt;/p&gt;&#xA;&lt;h2 id=&#34;recommended-venvs&#34;&gt;Recommended venvs&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;venv&lt;/code&gt; (base): core backend only&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;venv-streamlit&lt;/code&gt;: Streamlit UI&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;venv-kivy&lt;/code&gt;: Kivy UI&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;venv-docs&lt;/code&gt;: documentation export (imports UI modules)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;makefile-targets&#34;&gt;Makefile targets&lt;/h2&gt;&#xA;&lt;p&gt;Use the Makefile to create isolated environments with pinned dependencies:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;make venv&lt;/code&gt; (creates &lt;code&gt;venv&lt;/code&gt; with &lt;code&gt;requirements/base.txt&lt;/code&gt;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;make venv-streamlit&lt;/code&gt; (creates &lt;code&gt;venv-streamlit&lt;/code&gt; with &lt;code&gt;requirements/streamlit.txt&lt;/code&gt;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;make venv-kivy&lt;/code&gt; (creates &lt;code&gt;venv-kivy&lt;/code&gt; with &lt;code&gt;requirements/kivy.txt&lt;/code&gt;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;make venv-docs&lt;/code&gt; (creates &lt;code&gt;venv-docs&lt;/code&gt; with &lt;code&gt;.[docs]&lt;/code&gt; extras)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;notes&#34;&gt;Notes&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A single venv cannot switch environments without uninstalling packages.&lt;/li&gt;&#xA;&lt;li&gt;Separate venvs avoid heavy or conflicting UI dependencies.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;environment-preparation&#34;&gt;Environment preparation&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Create virtual environment:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 -m venv venv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;Activate virtual environment:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Windows: &lt;code&gt;venv\Scripts\activate&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Linux: &lt;code&gt;source ./venv/bin/activate&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;Install libraries:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Using precompiled lockfiles (recommended):&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Base only: &lt;code&gt;pip install -r requirements/base.txt&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Streamlit UI: &lt;code&gt;pip install -r requirements/streamlit.txt&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Kivy UI: &lt;code&gt;pip install -r requirements/kivy.txt&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Dev all‑in: &lt;code&gt;pip install -r requirements/dev.txt&lt;/code&gt; (or top‑level &lt;code&gt;requirements.txt&lt;/code&gt; if present)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;To (re)compile lockfiles with pip‑tools:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Base: &lt;code&gt;pip-compile requirements/base.in -o requirements/base.txt&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Streamlit: &lt;code&gt;pip-compile requirements/streamlit.in -o requirements/streamlit.txt&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Kivy: &lt;code&gt;pip-compile requirements/kivy.in -o requirements/kivy.txt&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Dev all‑in: create &lt;code&gt;requirements/dev.in&lt;/code&gt; that includes &lt;code&gt;-r requirements/streamlit.in&lt;/code&gt; and &lt;code&gt;-r requirements/kivy.in&lt;/code&gt;, then:&#xA;&lt;code&gt;pip-compile requirements/dev.in -o requirements/dev.txt&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;ol start=&#34;4&#34;&gt;&#xA;&lt;li&gt;Run the application:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Default: &lt;code&gt;python3 -m module&lt;/code&gt; (runs TUI)&lt;/li&gt;&#xA;&lt;li&gt;Streamlit UI: &lt;code&gt;python3 -m module --streamlit&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Kivy UI: &lt;code&gt;python3 -m module --kivy&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;TUI explicitly: &lt;code&gt;python3 -m module --tui&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;ol start=&#34;5&#34;&gt;&#xA;&lt;li&gt;Run tests:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;See &lt;code&gt;docs/TESTING_GUIDE.md&lt;/code&gt; for detailed instructions&lt;/li&gt;&#xA;&lt;li&gt;Quick start: &lt;code&gt;python3 -m unittest discover tests -v&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Or use Makefile: &lt;code&gt;make run_tests&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;ol start=&#34;6&#34;&gt;&#xA;&lt;li&gt;Project structure (core modules):&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;services.py&lt;/code&gt; — chart creation/selection and compute orchestration&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;utils.py&lt;/code&gt; — utilities for date and location parsing&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;workspace.py&lt;/code&gt; — workspace, chart and settings management&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;z_visual.py&lt;/code&gt; — visualization&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;dependency-management&#34;&gt;Dependency management&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Dependency definitions live in &lt;code&gt;requirements/&lt;/code&gt; as &lt;code&gt;.in&lt;/code&gt; files:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;requirements/base.in&lt;/code&gt; contains core runtime deps.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;requirements/streamlit.in&lt;/code&gt; and &lt;code&gt;requirements/kivy.in&lt;/code&gt; should start with &lt;code&gt;-r base.in&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Reproducible installs use compiled lockfiles in &lt;code&gt;requirements/*.txt&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Dev/all‑in: keep &lt;code&gt;requirements/dev.txt&lt;/code&gt; under &lt;code&gt;requirements/&lt;/code&gt;. Optionally provide a root &lt;code&gt;requirements.txt&lt;/code&gt; that contains &lt;code&gt;-r requirements/dev.txt&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;environment-strategy-one-venv-vs-multiple&#34;&gt;Environment strategy (one venv vs multiple)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A single venv cannot &amp;ldquo;switch&amp;rdquo; environments without uninstalling packages; once installed, they persist.&lt;/li&gt;&#xA;&lt;li&gt;Recommended: use separate venvs per UI target (&lt;code&gt;base&lt;/code&gt;, &lt;code&gt;streamlit&lt;/code&gt;, &lt;code&gt;kivy&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;) to avoid heavy or conflicting deps.&lt;/li&gt;&#xA;&lt;li&gt;If you still want one venv, install the base first, then add extras:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;pip install -e .&lt;/code&gt; (core only)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;pip install -e &amp;quot;.[streamlit]&amp;quot;&lt;/code&gt; or &lt;code&gt;pip install -e &amp;quot;.[kivy]&amp;quot;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;pip install -e &amp;quot;.[docs]&amp;quot;&lt;/code&gt; (includes UI deps so &lt;code&gt;make docs&lt;/code&gt; can import UI modules)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;sync-pyproject-from-requirements&#34;&gt;Sync pyproject from requirements&lt;/h3&gt;&#xA;&lt;p&gt;&lt;code&gt;pyproject.toml&lt;/code&gt; is derived from &lt;code&gt;requirements/*.in&lt;/code&gt; (not from the compiled &lt;code&gt;.txt&lt;/code&gt; lockfiles).&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>./testing_guide/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>./testing_guide/</guid>
      <description>&lt;h1 id=&#34;testing-guide&#34;&gt;Testing Guide&lt;/h1&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;&#xA;&lt;p&gt;This guide covers testing strategies for the Kefer Astrology sidecar module, including CLI handlers, storage functionality, and core computation services.&lt;/p&gt;&#xA;&lt;h2 id=&#34;test-structure&#34;&gt;Test Structure&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;tests/&#xA;├── __init__.py&#xA;├── test_cli.py              # CLI command handlers&#xA;├── test_storage.py          # DuckDB storage (NEW)&#xA;├── test_workspace_flow.py   # Workspace operations&#xA;├── test_dates_places.py    # Date/location parsing&#xA;├── test_locations.py        # Location handling&#xA;├── test_starfisher.py      # Starfisher integration&#xA;├── test_polar.py           # Polar coordinates&#xA;└── test_docs.py            # Documentation generation&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;running-tests&#34;&gt;Running Tests&lt;/h2&gt;&#xA;&lt;h3 id=&#34;all-tests&#34;&gt;All Tests&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m unittest discover tests&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;specific-test-suite&#34;&gt;Specific Test Suite&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m unittest tests.test_cli&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m unittest tests.test_storage&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m unittest tests.test_workspace_flow&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;with-coverage&#34;&gt;With Coverage&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install coverage&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;coverage run -m unittest discover tests&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;coverage report&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;coverage html  &lt;span style=&#34;color:#57606a&#34;&gt;# Generate HTML report in htmlcov/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;test-coverage-status&#34;&gt;Test Coverage Status&lt;/h2&gt;&#xA;&lt;h3 id=&#34;-covered&#34;&gt;✅ Covered&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;CLI handlers (&lt;code&gt;test_cli.py&lt;/code&gt;)&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
