<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/default.xsl"?>
<fr:tree xmlns:fr="http://www.forester-notes.org" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" root="false" base-url="/">
  <fr:frontmatter>
    <fr:authors />
    <fr:uri>https://offshore.pressed.press/DOC/</fr:uri>
    <fr:display-uri>DOC</fr:display-uri>
    <fr:route>/DOC/</fr:route>
    <fr:title text="Documentation">Documentation</fr:title>
  </fr:frontmatter>
  <fr:mainmatter>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors />
        <fr:uri>https://offshore.pressed.press/PY/</fr:uri>
        <fr:display-uri>PY</fr:display-uri>
        <fr:route>/PY/</fr:route>
        <fr:title text="A working Python 3.11+ installation">A working Python 3.11+ installation</fr:title>
        <fr:taxon>Requirement</fr:taxon>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:p><fr:link href="/index/" title="offshore" uri="https://offshore.pressed.press/index/" display-uri="index" type="local">offshore</fr:link> is written in <fr:link href="https://www.python.org/" type="external">Python</fr:link> and thus requires Python to run. <fr:link href="/index/" title="offshore" uri="https://offshore.pressed.press/index/" display-uri="index" type="local">offshore</fr:link> should generally be installed through the <fr:link href="https://pypi.org/project/pip/" type="external">pip</fr:link> package manager. Guide for installing Python on your system is available <fr:link href="https://www.python.org/about/gettingstarted/" type="external">here</fr:link>.</html:p>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Installation">Installation</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/INST/</fr:uri>
            <fr:display-uri>INST</fr:display-uri>
            <fr:route>/INST/</fr:route>
            <fr:title text="Install from PyPI">Install from PyPI</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:code>pip install offshore-podcast</html:code>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/INST2/</fr:uri>
            <fr:display-uri>INST2</fr:display-uri>
            <fr:route>/INST2/</fr:route>
            <fr:title text="Install from source">Install from source</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[git clone https://git.sr.ht/~lamons/offshore
cd offshore
pip install -e .]]></html:pre>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Usage">Usage</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/WUI/</fr:uri>
            <fr:display-uri>WUI</fr:display-uri>
            <fr:route>/WUI/</fr:route>
            <fr:title text="Web UI">Web UI</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>All offshore features are accessible via its web UI. To launch, simply run <html:code>offshore serve</html:code>. The default serving port is <html:code>8765</html:code>.</html:p>
            <html:p>To override the serving host or port, run</html:p>
            <html:pre><![CDATA[offshore serve --host 0.0.0.0 --port 9000]]></html:pre>
            <html:p>The web UI provides:</html:p>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/WUI1/</fr:uri>
                <fr:display-uri>WUI1</fr:display-uri>
                <fr:route>/WUI1/</fr:route>
                <fr:title text="Dashboard">Dashboard</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.2_db.jpeg" />
                <html:p>Overview of the podcast. <fr:link href="/GEN/" title="Feed generation" uri="https://offshore.pressed.press/GEN/" display-uri="GEN" type="local">Generate</fr:link> feed, run <fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">check</fr:link>, and perform quick actions per check results.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/WUI2/</fr:uri>
                <fr:display-uri>WUI2</fr:display-uri>
                <fr:route>/WUI2/</fr:route>
                <fr:title text="Show settings">Show settings</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.0_ss.jpeg" />
                <html:p>Edit all show-level fields including <fr:link href="/sw-image_url/" title="Schema v1 › show › image_url" uri="https://offshore.pressed.press/sw-image_url/" display-uri="sw-image_url" type="local">cover image</fr:link>, <fr:link href="/sw-categories/" title="Schema v1 › show › categories" uri="https://offshore.pressed.press/sw-categories/" display-uri="sw-categories" type="local">categories</fr:link>, <fr:link href="/sw-feed_self_url/" title="Schema v1 › show › feed_self_url" uri="https://offshore.pressed.press/sw-feed_self_url/" display-uri="sw-feed_self_url" type="local">feed self-link</fr:link>, and <fr:link href="/sw-output_path/" title="Schema v2 › New show attributes › output_path" uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" type="local">output path</fr:link>. Show cover will be <fr:link href="/FT3/" title="Image validation" uri="https://offshore.pressed.press/FT3/" display-uri="FT3" type="local">automatically verified</fr:link> against <fr:link href="/APAG/" title="Apple Podcasts’ Artwork Guide" uri="https://offshore.pressed.press/APAG/" display-uri="APAG" type="local">Apple Podcasts’ standard</fr:link> to ensure compatibility.</html:p>
                <fr:tree show-metadata="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>https://offshore.pressed.press/FT1/</fr:uri>
                    <fr:display-uri>FT1</fr:display-uri>
                    <fr:route>/FT1/</fr:route>
                    <fr:title text="Set consistent feed output path per show">Set consistent feed output path per show</fr:title>
                    <fr:taxon>Feature</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>User can set a consistent output path of the feed XML file in per-show configuration. This enables serving the feed directly when using offshore on a server, or integrate it in other workflow. The path value is stored in <fr:link href="/sw-output_path/" title="Schema v2 › New show attributes › output_path" uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" /></fr:link>.</html:p>
                    <html:p>On first feed generation of a show, the user will be prompted to confirm or change the default feed output path. It can be changed in show settings anytime.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>https://offshore.pressed.press/CPRT/</fr:uri>
                    <fr:display-uri>CPRT</fr:display-uri>
                    <fr:route>/CPRT/</fr:route>
                    <fr:title text="&lt;copyright&gt;">
                      <html:code>&lt;copyright&gt;</html:code>
                    </fr:title>
                    <fr:taxon>tag</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>offshore implements a semi-smart generation of <html:code>&lt;copyright&gt;</html:code> tag. The copyright string fallback to <fr:link href="/sw-owner/" title="Schema v2 › New show attributes › owner" uri="https://offshore.pressed.press/sw-owner/" display-uri="sw-owner" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-owner/" display-uri="sw-owner" /></fr:link> if not set. Two options for auto injecting year to the copyright string:<html:ul><html:li><html:strong>Current year:</html:strong> <html:code>&lt;copyright&gt;<html:mark>2026</html:mark> offshore&lt;/copyright&gt;</html:code></html:li>
<html:li><html:strong>Year range:</html:strong> <html:code>&lt;copyright&gt;<html:mark>2019-2026</html:mark> offshore&lt;/copyright&gt;</html:code>, where the first episode on record will populate the first year.</html:li></html:ul></html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>https://offshore.pressed.press/PPL/</fr:uri>
                    <fr:display-uri>PPL</fr:display-uri>
                    <fr:route>/PPL/</fr:route>
                    <fr:title text="People roster">People roster</fr:title>
                    <fr:taxon>Feature</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A list of people entries to be included in episodes is maintained in show settings, and will automatically emit <html:code>&lt;podcast:person&gt;</html:code>, and <html:code>&lt;itunes:author&gt;</html:code> tags in proper locations on feed generation.</html:p>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/PPL1/</fr:uri>
                        <fr:display-uri>PPL1</fr:display-uri>
                        <fr:route>/PPL1/</fr:route>
                        <fr:title text="Schema v2 › Universal people entries in show metadata"><fr:link href="/SV2/" title="Schema v2" uri="https://offshore.pressed.press/SV2/" display-uri="SV2" type="local">Schema v2</fr:link> › Universal people entries in show metadata</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Show and episode participants are now all selected from entries linked to <fr:link href="/PPL/" title="People roster" uri="https://offshore.pressed.press/PPL/" display-uri="PPL" type="local">people roster</fr:link> at show or episode level and stored in <fr:link href="/sw-persons/" title="Schema v1 › show › persons" uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" /></fr:link>.</html:p>
                        <html:p><html:code>&lt;itunes:author&gt;</html:code> and <html:code>&lt;podcast:person&gt;</html:code> tags are automatically derived from the people entries in show metadata.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <html:p>The option to delete all data of a show is located at the bottom of this page.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/WUI3/</fr:uri>
                <fr:display-uri>WUI3</fr:display-uri>
                <fr:route>/WUI3/</fr:route>
                <fr:title text="Episode editor">Episode editor</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.2_ee.jpeg" />
                <html:p>Episode editor can be launched from the “New episode” button on the top navigation, or when editing an existing episode.</html:p>
                <html:p>User can enter all metadata of an episode in this page.</html:p>
                <fr:tree show-metadata="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>https://offshore.pressed.press/MD/</fr:uri>
                    <fr:display-uri>MD</fr:display-uri>
                    <fr:route>/MD/</fr:route>
                    <fr:title text="Markdown shownotes">Markdown shownotes</fr:title>
                    <fr:taxon>reference</fr:taxon>
                    <fr:meta name="external">https://commonmark.org/</fr:meta>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>offshore accepts commonmark markdown content for shownotes. It will be translated to proper HTML format on <fr:link href="/GEN/" title="Feed generation" uri="https://offshore.pressed.press/GEN/" display-uri="GEN" type="local">feed generation</fr:link>. HTML shownotes from external feed will be converted into markdown on <fr:link href="/IMP/" title="Importer" uri="https://offshore.pressed.press/IMP/" display-uri="IMP" type="local">import</fr:link> with <fr:link href="https://github.com/matthewwithanm/python-markdownify" type="external"><html:code>markdownify</html:code></fr:link>.</html:p>
                    <html:p>offshore supports the following list of markdown syntax.</html:p>
                    <html:table style="border-collapse: collapse;">
  
  <html:tr>
    
  <html:th>Syntax</html:th>

    
  <html:th>Format</html:th>

  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>*Italic*</html:code> or <html:code>_Italic_</html:code>
  </html:td>
    <html:td style="padding: .5em 0;"><html:em>Italic</html:em></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>**Bold**</html:code> or <html:code>__Bold__</html:code>
  </html:td>
    <html:td style="padding: .5em 0;"><html:strong>Bold</html:strong></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code># Heading 1</html:code> or <html:pre><![CDATA[Heading 1 
=========]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;"><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:title text="Heading 1">Heading 1</fr:title></fr:frontmatter><fr:mainmatter /></fr:tree></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>## Heading 2</html:code> or <html:pre><![CDATA[Heading 2 
---------]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;">Heading 2</html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code><![CDATA[ [Hyperlink](https://example.com)]]></html:code> or <html:pre><![CDATA[[Hyperlink][1]
...
[1]: https://example.com]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;">
    <fr:link href="https://example.com/" type="external">Hyperlink</fr:link>
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code><![CDATA[ ![Image](https://offshore.pressed.press/favicon-16x16.png)]]></html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:img src="https://offshore.pressed.press/favicon-16x16.png" />
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>&gt; Blockquote</html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:code>Blockquote</html:code>
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;"><html:pre><![CDATA[* List or - List
* List    - List
* List    - List]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;"><html:ul><html:li>List</html:li><html:li>List</html:li><html:li>List</html:li></html:ul></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;"><html:pre><![CDATA[1. One    or 1) One
2. Two       2) Two
3. Three     3) Three]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;"><html:ol><html:li>One</html:li><html:li>Two</html:li><html:li>Three</html:li></html:ol></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>---</html:code> or <html:code>***</html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:hr />
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>`Inline code` with backticks</html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:code>Inline code</html:code> with backticks
  </html:td>
  </html:tr>

  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;"><html:pre><![CDATA[```
# code block
print '3'
print 'home'
```]]></html:pre></html:td>
    <html:td style="padding: .5em 0;"><html:pre><![CDATA[# code block
print '3'
print 'home']]></html:pre></html:td>
  </html:tr>

  </html:table>
                  </fr:mainmatter>
                </fr:tree>
                <html:p>Audio URL is <fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">checked</fr:link> for format and reachability on save. Episode artworks are also <fr:link href="/FT3/" title="Image validation" uri="https://offshore.pressed.press/FT3/" display-uri="FT3" type="local">validated</fr:link> when newly set or changed.</html:p>
                <fr:tree show-metadata="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>https://offshore.pressed.press/GUID/</fr:uri>
                    <fr:display-uri>GUID</fr:display-uri>
                    <fr:route>/GUID/</fr:route>
                    <fr:title text="GUID">GUID</fr:title>
                    <fr:taxon>Feature</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Globally unique identifiers (GUID) are unique identifiers for episodes. An episode’s GUID must remain unique and unchanged for it to be identified correctly. If an episode’s GUID is moodified in the feed, it will be recognized as a different episode.</html:p>
                    <html:p>offshore generates uuidv5 GUIDs that fully compliant with the <fr:link href="/PCNS/" title="Podcast Namespace" uri="https://offshore.pressed.press/PCNS/" display-uri="PCNS" type="local">podcast namespace</fr:link> for each episodes created in offshore. This value is write-once and cannot be changed in anyway. For imported show, the GUID is inherited from the original feed and won’t be touched. All GUIDs are protected by <fr:link href="/LK/" title="&lt;slug&gt;.lock.json" uri="https://offshore.pressed.press/LK/" display-uri="LK" type="local"><html:code>&lt;slug&gt;.lock.json</html:code></fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/WUI4/</fr:uri>
                <fr:display-uri>WUI4</fr:display-uri>
                <fr:route>/WUI4/</fr:route>
                <fr:title text="Switch show">Switch show</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.0_sws.png" />
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors />
        <fr:uri>https://offshore.pressed.press/FEATS/</fr:uri>
        <fr:display-uri>FEATS</fr:display-uri>
        <fr:route>/FEATS/</fr:route>
        <fr:title text="Core features">Core features</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/CK/</fr:uri>
            <fr:display-uri>CK</fr:display-uri>
            <fr:route>/CK/</fr:route>
            <fr:title text="Check">Check</fr:title>
            <fr:taxon>Feature</fr:taxon>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/CK2/</fr:uri>
                <fr:display-uri>CK2</fr:display-uri>
                <fr:route>/CK2/</fr:route>
                <fr:title text="Check report">Check report</fr:title>
              </fr:frontmatter>
              <fr:mainmatter />
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/FT3/</fr:uri>
                <fr:display-uri>FT3</fr:display-uri>
                <fr:route>/FT3/</fr:route>
                <fr:title text="Image validation">Image validation</fr:title>
                <fr:taxon>Feature</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Podcast and episode artworks are verified against <fr:link href="/APAG/" title="Apple Podcasts’ Artwork Guide" uri="https://offshore.pressed.press/APAG/" display-uri="APAG" type="local">Apple Podcast standards</fr:link>. Failing this check will produce notice to user, but won’t block feed generation.</html:p>
                <html:p>The automatic image validation is triggered in two occasions:<html:ol><html:li>when a new artwork url is added to a show, or an episode; or</html:li>
    <html:li>when a show or episode’s artwork url is changed.</html:li></html:ol></html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/FT2/</fr:uri>
                <fr:display-uri>FT2</fr:display-uri>
                <fr:route>/FT2/</fr:route>
                <fr:title text="&lt;slug&gt;.report.json">
                  <html:code>&lt;slug&gt;.report.json</html:code>
                </fr:title>
                <fr:taxon>Feature</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Check findings and audio probe results are stored in a separate <html:code>&lt;slug&gt;.report.json</html:code> file. This file will be automatically updated with <fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">checks</fr:link> representing the issues and things to improve in show metadata or assets.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/GEN/</fr:uri>
            <fr:display-uri>GEN</fr:display-uri>
            <fr:route>/GEN/</fr:route>
            <fr:title text="Feed generation">Feed generation</fr:title>
            <fr:taxon>Feature</fr:taxon>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Based on the show metadata, offshore aim to generate podcast feed accurately and intelligently. offshore generates feed following <fr:link href="https://www.rssboard.org/rss-specification" type="external">RSS 2.0</fr:link> specification, and incorporates <fr:link href="/APNS/" title="Apple Podcasts namespace" uri="https://offshore.pressed.press/APNS/" display-uri="APNS" type="local">Reference <fr:contextual-number uri="https://offshore.pressed.press/APNS/" display-uri="APNS" /></fr:link> and <fr:link href="/PCNS/" title="Podcast Namespace" uri="https://offshore.pressed.press/PCNS/" display-uri="PCNS" type="local">Reference <fr:contextual-number uri="https://offshore.pressed.press/PCNS/" display-uri="PCNS" /></fr:link> at the same time.</html:p>
            <html:p>offshore use <fr:link href="https://markdown-it-py.readthedocs.io/en/latest/" type="external"><html:code>markdown-it-py</html:code></fr:link> to translate markdown shownotes into HTML.</html:p>
            <html:p>The generated feed can be downloaded right away, or <fr:link href="/FT1/" title="Set consistent feed output path per show" uri="https://offshore.pressed.press/FT1/" display-uri="FT1" type="local">saved to a custom path</fr:link> configurable in the <fr:link href="/WUI2/" title="Show settings" uri="https://offshore.pressed.press/WUI2/" display-uri="WUI2" type="local">show settings</fr:link>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/IMP/</fr:uri>
            <fr:display-uri>IMP</fr:display-uri>
            <fr:route>/IMP/</fr:route>
            <fr:title text="Importer">Importer</fr:title>
            <fr:taxon>feature</fr:taxon>
          </fr:frontmatter>
          <fr:mainmatter />
        </fr:tree>
        <fr:tree show-metadata="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/PPL/</fr:uri>
            <fr:display-uri>PPL</fr:display-uri>
            <fr:route>/PPL/</fr:route>
            <fr:title text="People roster">People roster</fr:title>
            <fr:taxon>Feature</fr:taxon>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>A list of people entries to be included in episodes is maintained in show settings, and will automatically emit <html:code>&lt;podcast:person&gt;</html:code>, and <html:code>&lt;itunes:author&gt;</html:code> tags in proper locations on feed generation.</html:p>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/PPL1/</fr:uri>
                <fr:display-uri>PPL1</fr:display-uri>
                <fr:route>/PPL1/</fr:route>
                <fr:title text="Schema v2 › Universal people entries in show metadata"><fr:link href="/SV2/" title="Schema v2" uri="https://offshore.pressed.press/SV2/" display-uri="SV2" type="local">Schema v2</fr:link> › Universal people entries in show metadata</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Show and episode participants are now all selected from entries linked to <fr:link href="/PPL/" title="People roster" uri="https://offshore.pressed.press/PPL/" display-uri="PPL" type="local">people roster</fr:link> at show or episode level and stored in <fr:link href="/sw-persons/" title="Schema v1 › show › persons" uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" /></fr:link>.</html:p>
                <html:p><html:code>&lt;itunes:author&gt;</html:code> and <html:code>&lt;podcast:person&gt;</html:code> tags are automatically derived from the people entries in show metadata.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
  </fr:mainmatter>
  <fr:backmatter>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="References">References</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/APNS/</fr:uri>
            <fr:display-uri>APNS</fr:display-uri>
            <fr:route>/APNS/</fr:route>
            <fr:title text="Apple Podcasts namespace">Apple Podcasts namespace</fr:title>
            <fr:taxon>Reference</fr:taxon>
            <fr:meta name="external">https://help.apple.com/itc/podcasts_connect/#/itcb54353390</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Apple proposed its own podcast RSS namespace in 2005, which is first of its kind to enable a standard delivery of podcast specific features. It’s still active and one of the most commonly used standard for podcast feeds.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/APAG/</fr:uri>
            <fr:display-uri>APAG</fr:display-uri>
            <fr:route>/APAG/</fr:route>
            <fr:title text="Apple Podcasts’ Artwork Guide">Apple Podcasts’ Artwork Guide</fr:title>
            <fr:taxon>Reference</fr:taxon>
            <fr:meta name="external">https://podcasters.apple.com/artwork-guide</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Apple Podcasts is the <html:em>de facto</html:em> most common podcast distributor and catelogue. Although RSS standards of podcast doesn’t have a hard requirement for artworks, fail to meet Apple Podcasts’ standards may causse your show not being displayed correctly on Apple Podcasts and many other services relying on it.</html:p>
            <html:p>Currently, Apple Podcasts’ standards for artworks are 
  <html:table>
    
  
  <html:tr>
    
  <html:td><html:strong>Size:</html:strong></html:td>

    
  <html:td>1400 × 1400 to 3000 × 3000 pixels. The largest size is preferred.</html:td>

  </html:tr>


    
  
  <html:tr>
    
  <html:td><html:strong>File type:</html:strong></html:td>

    
  <html:td>PNG (without alpha channel) or JPG.</html:td>

  </html:tr>


</html:table></html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://offshore.pressed.press/PCNS/</fr:uri>
            <fr:display-uri>PCNS</fr:display-uri>
            <fr:route>/PCNS/</fr:route>
            <fr:title text="Podcast Namespace">Podcast Namespace</fr:title>
            <fr:taxon>Reference</fr:taxon>
            <fr:meta name="external">https://github.com/Podcastindex-org/podcast-namespace/</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>A wholistic rss namespace for podcasting, is widely supported by major podcast clients and services. It is part of the <fr:link href="https://podcasting2.org/" type="external">Podcasting 2.0</fr:link> project.</html:p>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Context">Context</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
              </fr:author>
              <fr:contributor>
                <fr:link href="/lechynte/" title="lechynte" uri="https://offshore.pressed.press/lechynte/" display-uri="lechynte" type="local">lechynte</fr:link>
              </fr:contributor>
            </fr:authors>
            <fr:uri>https://offshore.pressed.press/index/</fr:uri>
            <fr:display-uri>index</fr:display-uri>
            <fr:route>/index/</fr:route>
            <fr:title text="offshore">offshore</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p><html:code>offshore</html:code> is a local-first podcast feed generator and editor.</html:p>
            <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.2_db.jpeg" />
            <html:p>︎☃ Explore <html:mark><fr:link href="/shows/" title="offshore powered podcasts" uri="https://offshore.pressed.press/shows/" display-uri="shows" type="local">podcasts powered by offshore</fr:link></html:mark>!</html:p>
            <fr:tree show-metadata="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/INFO/</fr:uri>
                <fr:display-uri>INFO</fr:display-uri>
                <fr:route>/INFO/</fr:route>
                <fr:title text="Project information">Project information</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
  <html:table>
  
  
  <html:tr>
    
  <html:td><html:strong>source code:</html:strong></html:td>

    
  <html:td>
    <fr:link href="https://sr.ht/~lamons/offshore" type="external">sr.ht/~lamons/offshore</fr:link>
  </html:td>

  </html:tr>



  
  <html:tr>
    
  <html:td><html:strong>feedback:</html:strong></html:td>

    
  <html:td>
    <fr:link href="https://todo.sr.ht/~lamons/offshore" type="external">todo.sr.ht/~lamons/offshore</fr:link>
  </html:td>

  </html:tr>



  
  <html:tr>
    
  <html:td><html:strong>discussion:</html:strong></html:td>

    
  <html:td>
    <fr:link href="https://lists.sr.ht/~lamons/offshore-discuss" type="external">lists.sr.ht/~lamons/offshore-discuss</fr:link>
  </html:td>

  </html:tr>



  
  <html:tr>
    
  <html:td><html:strong>PyPI <html:span style="opacity: 0.6;">v0.5.2</html:span>:</html:strong></html:td>

    
  <html:td><fr:link href="https://pypi.org/project/offshore-podcast/" type="external">pypi.org/project/offshore-podcast</fr:link></html:td>

  </html:tr>


</html:table>
</fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/DOC/</fr:uri>
                <fr:display-uri>DOC</fr:display-uri>
                <fr:route>/DOC/</fr:route>
                <fr:title text="Documentation">Documentation</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>https://offshore.pressed.press/PY/</fr:uri>
                    <fr:display-uri>PY</fr:display-uri>
                    <fr:route>/PY/</fr:route>
                    <fr:title text="A working Python 3.11+ installation">A working Python 3.11+ installation</fr:title>
                    <fr:taxon>Requirement</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><fr:link href="/index/" title="offshore" uri="https://offshore.pressed.press/index/" display-uri="index" type="local">offshore</fr:link> is written in <fr:link href="https://www.python.org/" type="external">Python</fr:link> and thus requires Python to run. <fr:link href="/index/" title="offshore" uri="https://offshore.pressed.press/index/" display-uri="index" type="local">offshore</fr:link> should generally be installed through the <fr:link href="https://pypi.org/project/pip/" type="external">pip</fr:link> package manager. Guide for installing Python on your system is available <fr:link href="https://www.python.org/about/gettingstarted/" type="external">here</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:title text="Installation">Installation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/INST/</fr:uri>
                        <fr:display-uri>INST</fr:display-uri>
                        <fr:route>/INST/</fr:route>
                        <fr:title text="Install from PyPI">Install from PyPI</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:code>pip install offshore-podcast</html:code>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/INST2/</fr:uri>
                        <fr:display-uri>INST2</fr:display-uri>
                        <fr:route>/INST2/</fr:route>
                        <fr:title text="Install from source">Install from source</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:pre><![CDATA[git clone https://git.sr.ht/~lamons/offshore
cd offshore
pip install -e .]]></html:pre>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:title text="Usage">Usage</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/WUI/</fr:uri>
                        <fr:display-uri>WUI</fr:display-uri>
                        <fr:route>/WUI/</fr:route>
                        <fr:title text="Web UI">Web UI</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>All offshore features are accessible via its web UI. To launch, simply run <html:code>offshore serve</html:code>. The default serving port is <html:code>8765</html:code>.</html:p>
                        <html:p>To override the serving host or port, run</html:p>
                        <html:pre><![CDATA[offshore serve --host 0.0.0.0 --port 9000]]></html:pre>
                        <html:p>The web UI provides:</html:p>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/WUI1/</fr:uri>
                            <fr:display-uri>WUI1</fr:display-uri>
                            <fr:route>/WUI1/</fr:route>
                            <fr:title text="Dashboard">Dashboard</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.2_db.jpeg" />
                            <html:p>Overview of the podcast. <fr:link href="/GEN/" title="Feed generation" uri="https://offshore.pressed.press/GEN/" display-uri="GEN" type="local">Generate</fr:link> feed, run <fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">check</fr:link>, and perform quick actions per check results.</html:p>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/WUI2/</fr:uri>
                            <fr:display-uri>WUI2</fr:display-uri>
                            <fr:route>/WUI2/</fr:route>
                            <fr:title text="Show settings">Show settings</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.0_ss.jpeg" />
                            <html:p>Edit all show-level fields including <fr:link href="/sw-image_url/" title="Schema v1 › show › image_url" uri="https://offshore.pressed.press/sw-image_url/" display-uri="sw-image_url" type="local">cover image</fr:link>, <fr:link href="/sw-categories/" title="Schema v1 › show › categories" uri="https://offshore.pressed.press/sw-categories/" display-uri="sw-categories" type="local">categories</fr:link>, <fr:link href="/sw-feed_self_url/" title="Schema v1 › show › feed_self_url" uri="https://offshore.pressed.press/sw-feed_self_url/" display-uri="sw-feed_self_url" type="local">feed self-link</fr:link>, and <fr:link href="/sw-output_path/" title="Schema v2 › New show attributes › output_path" uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" type="local">output path</fr:link>. Show cover will be <fr:link href="/FT3/" title="Image validation" uri="https://offshore.pressed.press/FT3/" display-uri="FT3" type="local">automatically verified</fr:link> against <fr:link href="/APAG/" title="Apple Podcasts’ Artwork Guide" uri="https://offshore.pressed.press/APAG/" display-uri="APAG" type="local">Apple Podcasts’ standard</fr:link> to ensure compatibility.</html:p>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/FT1/</fr:uri>
                                <fr:display-uri>FT1</fr:display-uri>
                                <fr:route>/FT1/</fr:route>
                                <fr:title text="Set consistent feed output path per show">Set consistent feed output path per show</fr:title>
                                <fr:taxon>Feature</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>User can set a consistent output path of the feed XML file in per-show configuration. This enables serving the feed directly when using offshore on a server, or integrate it in other workflow. The path value is stored in <fr:link href="/sw-output_path/" title="Schema v2 › New show attributes › output_path" uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" /></fr:link>.</html:p>
                                <html:p>On first feed generation of a show, the user will be prompted to confirm or change the default feed output path. It can be changed in show settings anytime.</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/CPRT/</fr:uri>
                                <fr:display-uri>CPRT</fr:display-uri>
                                <fr:route>/CPRT/</fr:route>
                                <fr:title text="&lt;copyright&gt;">
                                  <html:code>&lt;copyright&gt;</html:code>
                                </fr:title>
                                <fr:taxon>tag</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>offshore implements a semi-smart generation of <html:code>&lt;copyright&gt;</html:code> tag. The copyright string fallback to <fr:link href="/sw-owner/" title="Schema v2 › New show attributes › owner" uri="https://offshore.pressed.press/sw-owner/" display-uri="sw-owner" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-owner/" display-uri="sw-owner" /></fr:link> if not set. Two options for auto injecting year to the copyright string:<html:ul><html:li><html:strong>Current year:</html:strong> <html:code>&lt;copyright&gt;<html:mark>2026</html:mark> offshore&lt;/copyright&gt;</html:code></html:li>
<html:li><html:strong>Year range:</html:strong> <html:code>&lt;copyright&gt;<html:mark>2019-2026</html:mark> offshore&lt;/copyright&gt;</html:code>, where the first episode on record will populate the first year.</html:li></html:ul></html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/PPL/</fr:uri>
                                <fr:display-uri>PPL</fr:display-uri>
                                <fr:route>/PPL/</fr:route>
                                <fr:title text="People roster">People roster</fr:title>
                                <fr:taxon>Feature</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>A list of people entries to be included in episodes is maintained in show settings, and will automatically emit <html:code>&lt;podcast:person&gt;</html:code>, and <html:code>&lt;itunes:author&gt;</html:code> tags in proper locations on feed generation.</html:p>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/PPL1/</fr:uri>
                                    <fr:display-uri>PPL1</fr:display-uri>
                                    <fr:route>/PPL1/</fr:route>
                                    <fr:title text="Schema v2 › Universal people entries in show metadata"><fr:link href="/SV2/" title="Schema v2" uri="https://offshore.pressed.press/SV2/" display-uri="SV2" type="local">Schema v2</fr:link> › Universal people entries in show metadata</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Show and episode participants are now all selected from entries linked to <fr:link href="/PPL/" title="People roster" uri="https://offshore.pressed.press/PPL/" display-uri="PPL" type="local">people roster</fr:link> at show or episode level and stored in <fr:link href="/sw-persons/" title="Schema v1 › show › persons" uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" /></fr:link>.</html:p>
                                    <html:p><html:code>&lt;itunes:author&gt;</html:code> and <html:code>&lt;podcast:person&gt;</html:code> tags are automatically derived from the people entries in show metadata.</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <html:p>The option to delete all data of a show is located at the bottom of this page.</html:p>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/WUI3/</fr:uri>
                            <fr:display-uri>WUI3</fr:display-uri>
                            <fr:route>/WUI3/</fr:route>
                            <fr:title text="Episode editor">Episode editor</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.2_ee.jpeg" />
                            <html:p>Episode editor can be launched from the “New episode” button on the top navigation, or when editing an existing episode.</html:p>
                            <html:p>User can enter all metadata of an episode in this page.</html:p>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/MD/</fr:uri>
                                <fr:display-uri>MD</fr:display-uri>
                                <fr:route>/MD/</fr:route>
                                <fr:title text="Markdown shownotes">Markdown shownotes</fr:title>
                                <fr:taxon>reference</fr:taxon>
                                <fr:meta name="external">https://commonmark.org/</fr:meta>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>offshore accepts commonmark markdown content for shownotes. It will be translated to proper HTML format on <fr:link href="/GEN/" title="Feed generation" uri="https://offshore.pressed.press/GEN/" display-uri="GEN" type="local">feed generation</fr:link>. HTML shownotes from external feed will be converted into markdown on <fr:link href="/IMP/" title="Importer" uri="https://offshore.pressed.press/IMP/" display-uri="IMP" type="local">import</fr:link> with <fr:link href="https://github.com/matthewwithanm/python-markdownify" type="external"><html:code>markdownify</html:code></fr:link>.</html:p>
                                <html:p>offshore supports the following list of markdown syntax.</html:p>
                                <html:table style="border-collapse: collapse;">
  
  <html:tr>
    
  <html:th>Syntax</html:th>

    
  <html:th>Format</html:th>

  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>*Italic*</html:code> or <html:code>_Italic_</html:code>
  </html:td>
    <html:td style="padding: .5em 0;"><html:em>Italic</html:em></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>**Bold**</html:code> or <html:code>__Bold__</html:code>
  </html:td>
    <html:td style="padding: .5em 0;"><html:strong>Bold</html:strong></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code># Heading 1</html:code> or <html:pre><![CDATA[Heading 1 
=========]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;"><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:title text="Heading 1">Heading 1</fr:title></fr:frontmatter><fr:mainmatter /></fr:tree></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>## Heading 2</html:code> or <html:pre><![CDATA[Heading 2 
---------]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;">Heading 2</html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code><![CDATA[ [Hyperlink](https://example.com)]]></html:code> or <html:pre><![CDATA[[Hyperlink][1]
...
[1]: https://example.com]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;">
    <fr:link href="https://example.com/" type="external">Hyperlink</fr:link>
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code><![CDATA[ ![Image](https://offshore.pressed.press/favicon-16x16.png)]]></html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:img src="https://offshore.pressed.press/favicon-16x16.png" />
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>&gt; Blockquote</html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:code>Blockquote</html:code>
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;"><html:pre><![CDATA[* List or - List
* List    - List
* List    - List]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;"><html:ul><html:li>List</html:li><html:li>List</html:li><html:li>List</html:li></html:ul></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;"><html:pre><![CDATA[1. One    or 1) One
2. Two       2) Two
3. Three     3) Three]]></html:pre>
  </html:td>
    <html:td style="padding: .5em 0;"><html:ol><html:li>One</html:li><html:li>Two</html:li><html:li>Three</html:li></html:ol></html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>---</html:code> or <html:code>***</html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:hr />
  </html:td>
  </html:tr>

  
  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;">
    <html:code>`Inline code` with backticks</html:code>
  </html:td>
    <html:td style="padding: .5em 0;">
    <html:code>Inline code</html:code> with backticks
  </html:td>
  </html:tr>

  <html:tr style="border-bottom: 1px solid color(srgb 0 0 0 / 0.19);border-top: 1px solid color(srgb 0 0 0 / 0.19);">
    <html:td style="padding: .5em .5em .5em 0;"><html:pre><![CDATA[```
# code block
print '3'
print 'home'
```]]></html:pre></html:td>
    <html:td style="padding: .5em 0;"><html:pre><![CDATA[# code block
print '3'
print 'home']]></html:pre></html:td>
  </html:tr>

  </html:table>
                              </fr:mainmatter>
                            </fr:tree>
                            <html:p>Audio URL is <fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">checked</fr:link> for format and reachability on save. Episode artworks are also <fr:link href="/FT3/" title="Image validation" uri="https://offshore.pressed.press/FT3/" display-uri="FT3" type="local">validated</fr:link> when newly set or changed.</html:p>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/GUID/</fr:uri>
                                <fr:display-uri>GUID</fr:display-uri>
                                <fr:route>/GUID/</fr:route>
                                <fr:title text="GUID">GUID</fr:title>
                                <fr:taxon>Feature</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>Globally unique identifiers (GUID) are unique identifiers for episodes. An episode’s GUID must remain unique and unchanged for it to be identified correctly. If an episode’s GUID is moodified in the feed, it will be recognized as a different episode.</html:p>
                                <html:p>offshore generates uuidv5 GUIDs that fully compliant with the <fr:link href="/PCNS/" title="Podcast Namespace" uri="https://offshore.pressed.press/PCNS/" display-uri="PCNS" type="local">podcast namespace</fr:link> for each episodes created in offshore. This value is write-once and cannot be changed in anyway. For imported show, the GUID is inherited from the original feed and won’t be touched. All GUIDs are protected by <fr:link href="/LK/" title="&lt;slug&gt;.lock.json" uri="https://offshore.pressed.press/LK/" display-uri="LK" type="local"><html:code>&lt;slug&gt;.lock.json</html:code></fr:link>.</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/WUI4/</fr:uri>
                            <fr:display-uri>WUI4</fr:display-uri>
                            <fr:route>/WUI4/</fr:route>
                            <fr:title text="Switch show">Switch show</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:img src="https://git.sr.ht/~lamons/offshore/blob/main/docs/0.5.0_sws.png" />
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>https://offshore.pressed.press/FEATS/</fr:uri>
                    <fr:display-uri>FEATS</fr:display-uri>
                    <fr:route>/FEATS/</fr:route>
                    <fr:title text="Core features">Core features</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/CK/</fr:uri>
                        <fr:display-uri>CK</fr:display-uri>
                        <fr:route>/CK/</fr:route>
                        <fr:title text="Check">Check</fr:title>
                        <fr:taxon>Feature</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/CK2/</fr:uri>
                            <fr:display-uri>CK2</fr:display-uri>
                            <fr:route>/CK2/</fr:route>
                            <fr:title text="Check report">Check report</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter />
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/FT3/</fr:uri>
                            <fr:display-uri>FT3</fr:display-uri>
                            <fr:route>/FT3/</fr:route>
                            <fr:title text="Image validation">Image validation</fr:title>
                            <fr:taxon>Feature</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>Podcast and episode artworks are verified against <fr:link href="/APAG/" title="Apple Podcasts’ Artwork Guide" uri="https://offshore.pressed.press/APAG/" display-uri="APAG" type="local">Apple Podcast standards</fr:link>. Failing this check will produce notice to user, but won’t block feed generation.</html:p>
                            <html:p>The automatic image validation is triggered in two occasions:<html:ol><html:li>when a new artwork url is added to a show, or an episode; or</html:li>
    <html:li>when a show or episode’s artwork url is changed.</html:li></html:ol></html:p>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/FT2/</fr:uri>
                            <fr:display-uri>FT2</fr:display-uri>
                            <fr:route>/FT2/</fr:route>
                            <fr:title text="&lt;slug&gt;.report.json">
                              <html:code>&lt;slug&gt;.report.json</html:code>
                            </fr:title>
                            <fr:taxon>Feature</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>Check findings and audio probe results are stored in a separate <html:code>&lt;slug&gt;.report.json</html:code> file. This file will be automatically updated with <fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">checks</fr:link> representing the issues and things to improve in show metadata or assets.</html:p>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/GEN/</fr:uri>
                        <fr:display-uri>GEN</fr:display-uri>
                        <fr:route>/GEN/</fr:route>
                        <fr:title text="Feed generation">Feed generation</fr:title>
                        <fr:taxon>Feature</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Based on the show metadata, offshore aim to generate podcast feed accurately and intelligently. offshore generates feed following <fr:link href="https://www.rssboard.org/rss-specification" type="external">RSS 2.0</fr:link> specification, and incorporates <fr:link href="/APNS/" title="Apple Podcasts namespace" uri="https://offshore.pressed.press/APNS/" display-uri="APNS" type="local">Reference <fr:contextual-number uri="https://offshore.pressed.press/APNS/" display-uri="APNS" /></fr:link> and <fr:link href="/PCNS/" title="Podcast Namespace" uri="https://offshore.pressed.press/PCNS/" display-uri="PCNS" type="local">Reference <fr:contextual-number uri="https://offshore.pressed.press/PCNS/" display-uri="PCNS" /></fr:link> at the same time.</html:p>
                        <html:p>offshore use <fr:link href="https://markdown-it-py.readthedocs.io/en/latest/" type="external"><html:code>markdown-it-py</html:code></fr:link> to translate markdown shownotes into HTML.</html:p>
                        <html:p>The generated feed can be downloaded right away, or <fr:link href="/FT1/" title="Set consistent feed output path per show" uri="https://offshore.pressed.press/FT1/" display-uri="FT1" type="local">saved to a custom path</fr:link> configurable in the <fr:link href="/WUI2/" title="Show settings" uri="https://offshore.pressed.press/WUI2/" display-uri="WUI2" type="local">show settings</fr:link>.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/IMP/</fr:uri>
                        <fr:display-uri>IMP</fr:display-uri>
                        <fr:route>/IMP/</fr:route>
                        <fr:title text="Importer">Importer</fr:title>
                        <fr:taxon>feature</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/PPL/</fr:uri>
                        <fr:display-uri>PPL</fr:display-uri>
                        <fr:route>/PPL/</fr:route>
                        <fr:title text="People roster">People roster</fr:title>
                        <fr:taxon>Feature</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>A list of people entries to be included in episodes is maintained in show settings, and will automatically emit <html:code>&lt;podcast:person&gt;</html:code>, and <html:code>&lt;itunes:author&gt;</html:code> tags in proper locations on feed generation.</html:p>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/PPL1/</fr:uri>
                            <fr:display-uri>PPL1</fr:display-uri>
                            <fr:route>/PPL1/</fr:route>
                            <fr:title text="Schema v2 › Universal people entries in show metadata"><fr:link href="/SV2/" title="Schema v2" uri="https://offshore.pressed.press/SV2/" display-uri="SV2" type="local">Schema v2</fr:link> › Universal people entries in show metadata</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>Show and episode participants are now all selected from entries linked to <fr:link href="/PPL/" title="People roster" uri="https://offshore.pressed.press/PPL/" display-uri="PPL" type="local">people roster</fr:link> at show or episode level and stored in <fr:link href="/sw-persons/" title="Schema v1 › show › persons" uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" /></fr:link>.</html:p>
                            <html:p><html:code>&lt;itunes:author&gt;</html:code> and <html:code>&lt;podcast:person&gt;</html:code> tags are automatically derived from the people entries in show metadata.</html:p>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/PY/</fr:uri>
                <fr:display-uri>PY</fr:display-uri>
                <fr:route>/PY/</fr:route>
                <fr:title text="A working Python 3.11+ installation">A working Python 3.11+ installation</fr:title>
                <fr:taxon>Requirement</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p><fr:link href="/index/" title="offshore" uri="https://offshore.pressed.press/index/" display-uri="index" type="local">offshore</fr:link> is written in <fr:link href="https://www.python.org/" type="external">Python</fr:link> and thus requires Python to run. <fr:link href="/index/" title="offshore" uri="https://offshore.pressed.press/index/" display-uri="index" type="local">offshore</fr:link> should generally be installed through the <fr:link href="https://pypi.org/project/pip/" type="external">pip</fr:link> package manager. Guide for installing Python on your system is available <fr:link href="https://www.python.org/about/gettingstarted/" type="external">here</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" expanded="true" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:uri>https://offshore.pressed.press/INST/</fr:uri>
                <fr:display-uri>INST</fr:display-uri>
                <fr:route>/INST/</fr:route>
                <fr:title text="Install from PyPI">Install from PyPI</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:code>pip install offshore-podcast</html:code>
              </fr:mainmatter>
            </fr:tree>
            <html:p>Conventional podcast hosts like Fireside or Transistor work fine, but they can be expensive for small shows, and handing all your data to a single service is a real dependency. Self-hosted alternatives exist, but most are still designed as full-stack replacements that bundles frontend website, audio storage, and feed generation into one thing.</html:p>
            <html:p>A podcast feed is just a plain-text XML file. Hosting a handful of audio files and a text file is much easier, and cheaper than running a media server with a web frontend and database. And if you don’t want the website that comes with a podcast host then that part just becomes redundant.</html:p>
            <html:p>offshore aims to be a more basic solution. It simply helps you manages your show metadata locally and generates feed you can host wherever makes sense — a static site, an object storage, a CDN. Audio files and any other asset live wherever you want to host them. offshore ensures your metadata and assets comply with podcast standards, but otherwise stays out of the way. It can be used as a local feed generator, or reliably on a server to serve the feed directly.</html:p>
            <fr:tree show-metadata="false" expanded="true" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:contributor>
                    <fr:link href="/lechynte/" title="lechynte" uri="https://offshore.pressed.press/lechynte/" display-uri="lechynte" type="local">lechynte</fr:link>
                  </fr:contributor>
                  <fr:contributor>
                    <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                  </fr:contributor>
                </fr:authors>
                <fr:uri>https://offshore.pressed.press/RN/</fr:uri>
                <fr:display-uri>RN</fr:display-uri>
                <fr:route>/RN/</fr:route>
                <fr:title text="Release notes">Release notes</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>18</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.5.2</fr:uri>
                    <fr:display-uri>RL0.5.2</fr:display-uri>
                    <fr:route>/RL0.5.2</fr:route>
                    <fr:title text="0.5.2">0.5.2</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>UI:</html:strong>
    <html:ul><html:li>Refine badges for simpler display;</html:li>
    <html:li>Refine the ignore button as single button with an one-time (per session) confirm dialogue;</html:li>
    <html:li>Reformat activity boxes as non-nested tables.</html:li></html:ul></html:p>
                    <html:p><html:strong>Fixes:</html:strong>
    <html:ul><html:li>Fixes draft flag not working properly;</html:li>
    <html:li>Safer report saving when probing multiple assets;</html:li>
    <html:li>Fixes disabled asset check sometimes not respected.</html:li></html:ul></html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>18</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.5.1</fr:uri>
                    <fr:display-uri>RL0.5.1</fr:display-uri>
                    <fr:route>/RL0.5.1</fr:route>
                    <fr:title text="0.5.1">0.5.1</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>Fixes:</html:strong>
    <html:ul><html:li>Draft flag not working properly;</html:li>
    <html:li>Disabled asset check not being respected in some occasion.</html:li></html:ul>
    <html:strong>Improvement:</html:strong> Safer report saving function when probing multiple assets.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>17</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.5.0</fr:uri>
                    <fr:display-uri>RL0.5.0</fr:display-uri>
                    <fr:route>/RL0.5.0</fr:route>
                    <fr:title text="0.5.0">0.5.0</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:strong>Web UI:</html:strong>
                    <html:ul><html:li>All new web UI built with Tailwind;</html:li>
    <html:li>feat: live asset preview.</html:li></html:ul>
                    <html:p><html:strong>Fixes:</html:strong> <fr:link href="/FT1/" title="Set consistent feed output path per show" uri="https://offshore.pressed.press/FT1/" display-uri="FT1" type="local">Custom feed output path</fr:link> now handles filename correctly.</html:p>
                    <html:p><html:strong>Improvements:</html:strong> CLI can now pass optional fields; validate urls; implement category selection.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>15</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.4.2</fr:uri>
                    <fr:display-uri>RL0.4.2</fr:display-uri>
                    <fr:route>/RL0.4.2</fr:route>
                    <fr:title text="0.4.2">0.4.2</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>Fixes:</html:strong> <fr:link href="/FT1/" title="Set consistent feed output path per show" uri="https://offshore.pressed.press/FT1/" display-uri="FT1" type="local">custom path</fr:link> still output default filename <html:code>podcast.xml</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>15</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.4.1</fr:uri>
                    <fr:display-uri>RL0.4.1</fr:display-uri>
                    <fr:route>/RL0.4.1</fr:route>
                    <fr:title text="0.4.1">0.4.1</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>Refactor CLI:</html:strong><html:ul><html:li>Align fuctionality with web ui;</html:li>
    <html:li>Implement interactive sub menues for full show/episode editing ability;</html:li>
    <html:li>Allow passing text file to multi-line fields e.g. description and shownotes;</html:li>
    <html:li>Remove Typer border which can cause display issue on some system.</html:li></html:ul>
<html:strong>Improvement:</html:strong><html:ul><html:li>Improve code efficiency.</html:li></html:ul></html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>14</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.4.0</fr:uri>
                    <fr:display-uri>RL0.4.0</fr:display-uri>
                    <fr:route>/RL0.4.0</fr:route>
                    <fr:title text="0.4.0">0.4.0</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>Function:</html:strong><html:ul><html:li>Option to create draft episode;</html:li>
<html:li>Options to disable asset probing completely;</html:li>
<html:li>Option to auto inject year to <fr:link href="/CPRT/" title="&lt;copyright&gt;" uri="https://offshore.pressed.press/CPRT/" display-uri="CPRT" type="local">tag <fr:contextual-number uri="https://offshore.pressed.press/CPRT/" display-uri="CPRT" /></fr:link>;</html:li></html:ul>
<html:strong>Improvements:</html:strong><html:ul><html:li><fr:link href="/LK/" title="&lt;slug&gt;.lock.json" uri="https://offshore.pressed.press/LK/" display-uri="LK" type="local">feature <fr:contextual-number uri="https://offshore.pressed.press/LK/" display-uri="LK" /></fr:link> can now better detect alterd guid;</html:li>
    <html:li>Support decimal episode numbers.</html:li></html:ul>
<html:strong>Fixes:</html:strong><html:ul><html:li>Missing lock file won't throw guid mismatch error.</html:li></html:ul></html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>13</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.3.1</fr:uri>
                    <fr:display-uri>RL0.3.1</fr:display-uri>
                    <fr:route>/RL0.3.1</fr:route>
                    <fr:title text="0.3.1">0.3.1</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>Core:</html:strong> Add back support for <html:code><fr:link href="/TAG1/" title="&lt;itunes:owner&gt;" uri="https://offshore.pressed.press/TAG1/" display-uri="TAG1" type="local">&lt;itunes:owner&gt;</fr:link></html:code> for compatibility via implementing of <fr:link href="/sw-owner/" title="Schema v2 › New show attributes › owner" uri="https://offshore.pressed.press/sw-owner/" display-uri="sw-owner" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-owner/" display-uri="sw-owner" /></fr:link>. The same data will also emit <fr:link href="/TAG3/" title="&lt;podcast:locked&gt;" uri="https://offshore.pressed.press/TAG3/" display-uri="TAG3" type="local">tag <fr:contextual-number uri="https://offshore.pressed.press/TAG3/" display-uri="TAG3" /></fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>12</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.3.0</fr:uri>
                    <fr:display-uri>RL0.3.0</fr:display-uri>
                    <fr:route>/RL0.3.0</fr:route>
                    <fr:title text="0.3.0">0.3.0</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/SV2/</fr:uri>
                        <fr:display-uri>SV2</fr:display-uri>
                        <fr:route>/SV2/</fr:route>
                        <fr:title text="Schema v2">Schema v2</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Schema v2 introduces new fields to the show metadata and centralizes check results into a separate report file.</html:p>
                        <fr:tree show-metadata="false" numbered="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/OBJ-SW2/</fr:uri>
                            <fr:display-uri>OBJ-SW2</fr:display-uri>
                            <fr:route>/OBJ-SW2/</fr:route>
                            <fr:title text="New show attributes">New <html:code>show</html:code> attributes</fr:title>
                            <fr:taxon>key</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false" numbered="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/sw-output_path/</fr:uri>
                                <fr:display-uri>sw-output_path</fr:display-uri>
                                <fr:route>/sw-output_path/</fr:route>
                                <fr:title text="output_path">
                                  <html:code>output_path</html:code>
                                </fr:title>
                                <fr:taxon>key</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
  <html:p>An absolute path where the podcast feed file will be saved when generated. <html:code>/shows/&lt;slug&gt;/podcast.xml</html:code> by default.</html:p>
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false" numbered="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/sw-owner/</fr:uri>
                                <fr:display-uri>sw-owner</fr:display-uri>
                                <fr:route>/sw-owner/</fr:route>
                                <fr:title text="owner">
                                  <html:code>owner</html:code>
                                </fr:title>
                                <fr:taxon>key</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
  <html:p>Optional owner metadata for the show. Emits <fr:link href="/TAG1/" title="&lt;itunes:owner&gt;" uri="https://offshore.pressed.press/TAG1/" display-uri="TAG1" type="local"><html:code>&lt;itunes:owner&gt;</html:code></fr:link> (contains <html:code>&lt;itunes:name&gt;</html:code> and <html:code>&lt;itunes:email&gt;</html:code>), and <html:code>&lt;podcast:locked&gt;</html:code>. Contains <html:code>name</html:code>, <html:code>email</html:code>, and <html:code>locked</html:code> boolean attributes. The <html:code>name</html:code> field also acts as a fallback for <html:code>&lt;copyright&gt;</html:code> if <fr:link href="/sw-copyright/" title="Schema v1 › show › copyright" uri="https://offshore.pressed.press/sw-copyright/" display-uri="sw-copyright" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-copyright/" display-uri="sw-copyright" /></fr:link> is emptry.</html:p>
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false" numbered="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/PPL1/</fr:uri>
                            <fr:display-uri>PPL1</fr:display-uri>
                            <fr:route>/PPL1/</fr:route>
                            <fr:title text="Schema v2 › Universal people entries in show metadata"><fr:link href="/SV2/" title="Schema v2" uri="https://offshore.pressed.press/SV2/" display-uri="SV2" type="local">Schema v2</fr:link> › Universal people entries in show metadata</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>Show and episode participants are now all selected from entries linked to <fr:link href="/PPL/" title="People roster" uri="https://offshore.pressed.press/PPL/" display-uri="PPL" type="local">people roster</fr:link> at show or episode level and stored in <fr:link href="/sw-persons/" title="Schema v1 › show › persons" uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-persons/" display-uri="sw-persons" /></fr:link>.</html:p>
                            <html:p><html:code>&lt;itunes:author&gt;</html:code> and <html:code>&lt;podcast:person&gt;</html:code> tags are automatically derived from the people entries in show metadata.</html:p>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false" numbered="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/OBJ-REP/</fr:uri>
                            <fr:display-uri>OBJ-REP</fr:display-uri>
                            <fr:route>/OBJ-REP/</fr:route>
                            <fr:title text="Schema v2 › &lt;slug&gt;.report.json"><fr:link href="/SV2/" title="Schema v2" uri="https://offshore.pressed.press/SV2/" display-uri="SV2" type="local">Schema v2</fr:link> › <html:code>&lt;slug&gt;.report.json</html:code></fr:title>
                            <fr:taxon>key</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p><fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">Assets verification</fr:link> results will all be saved in the <html:code><fr:link href="/FT2/" title="&lt;slug&gt;.report.json" uri="https://offshore.pressed.press/FT2/" display-uri="FT2" type="local">&lt;slug&gt;.report.json</fr:link></html:code> file, with only information useful to feed generation (e.g. audio duration, image size, or asset MIME type) will be write to the main show json file.</html:p>
                            <html:p>This <html:code>report.json</html:code> contains separate chunks that log different information relavent to the assset checks:</html:p>
                            <fr:tree show-metadata="false" numbered="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/rep-check/</fr:uri>
                                <fr:display-uri>rep-check</fr:display-uri>
                                <fr:route>/rep-check/</fr:route>
                                <fr:title text="check">
                                  <html:code>check</html:code>
                                </fr:title>
                                <fr:taxon>key</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>The results of the most recent check run.</html:p>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/ckc-checked_at/</fr:uri>
                                    <fr:display-uri>ckc-checked_at</fr:display-uri>
                                    <fr:route>/ckc-checked_at/</fr:route>
                                    <fr:title text="checked_at">
                                      <html:code>checked_at</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The timestamp of the most recent check run.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/ckc-remote/</fr:uri>
                                    <fr:display-uri>ckc-remote</fr:display-uri>
                                    <fr:route>/ckc-remote/</fr:route>
                                    <fr:title text="remote">
                                      <html:code>remote</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>Boolean indicating if the check was run remotely or locally.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/ckc-findings/</fr:uri>
                                    <fr:display-uri>ckc-findings</fr:display-uri>
                                    <fr:route>/ckc-findings/</fr:route>
                                    <fr:title text="findings">
                                      <html:code>findings</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>An array of finding objects. See <fr:link href="/OBJ-FINDING/" title="Schema v2 › &lt;slug&gt;.report.json › Finding" uri="https://offshore.pressed.press/OBJ-FINDING/" display-uri="OBJ-FINDING" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/OBJ-FINDING/" display-uri="OBJ-FINDING" /></fr:link>.</html:p>
</fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false" numbered="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/OBJ-FINDING/</fr:uri>
                                <fr:display-uri>OBJ-FINDING</fr:display-uri>
                                <fr:route>/OBJ-FINDING/</fr:route>
                                <fr:title text="Finding">
                                  <html:code>Finding</html:code>
                                </fr:title>
                                <fr:taxon>key</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>A single finding from a persisted check run.</html:p>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/fnd-level/</fr:uri>
                                    <fr:display-uri>fnd-level</fr:display-uri>
                                    <fr:route>/fnd-level/</fr:route>
                                    <fr:title text="level">
                                      <html:code>level</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The severity level, either <html:code>fail</html:code> or <html:code>note</html:code>.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/fnd-where/</fr:uri>
                                    <fr:display-uri>fnd-where</fr:display-uri>
                                    <fr:route>/fnd-where/</fr:route>
                                    <fr:title text="where">
                                      <html:code>where</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>A string indicating where the issue was found (e.g., episode GUID).</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/fnd-domain/</fr:uri>
                                    <fr:display-uri>fnd-domain</fr:display-uri>
                                    <fr:route>/fnd-domain/</fr:route>
                                    <fr:title text="domain">
                                      <html:code>domain</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The domain of the check: <html:code>meta</html:code>, <html:code>image</html:code>, or <html:code>audio</html:code>.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/fnd-code/</fr:uri>
                                    <fr:display-uri>fnd-code</fr:display-uri>
                                    <fr:route>/fnd-code/</fr:route>
                                    <fr:title text="code">
                                      <html:code>code</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>A short error code string.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/fnd-message/</fr:uri>
                                    <fr:display-uri>fnd-message</fr:display-uri>
                                    <fr:route>/fnd-message/</fr:route>
                                    <fr:title text="message">
                                      <html:code>message</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>A human-readable description of the finding.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/fnd-url/</fr:uri>
                                    <fr:display-uri>fnd-url</fr:display-uri>
                                    <fr:route>/fnd-url/</fr:route>
                                    <fr:title text="url">
                                      <html:code>url</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>An optional URL related to the finding.</html:p>
</fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false" numbered="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/rep-probe/</fr:uri>
                                <fr:display-uri>rep-probe</fr:display-uri>
                                <fr:route>/rep-probe/</fr:route>
                                <fr:title text="probe">
                                  <html:code>probe</html:code>
                                </fr:title>
                                <fr:taxon>key</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>A dictionary keyed by episode guid containing audio probe results.</html:p>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-probed_at/</fr:uri>
                                    <fr:display-uri>prb-probed_at</fr:display-uri>
                                    <fr:route>/prb-probed_at/</fr:route>
                                    <fr:title text="probed_at">
                                      <html:code>probed_at</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The timestamp when the probe was last run.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-url/</fr:uri>
                                    <fr:display-uri>prb-url</fr:display-uri>
                                    <fr:route>/prb-url/</fr:route>
                                    <fr:title text="url">
                                      <html:code>url</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The URL of the probed audio file.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-ok/</fr:uri>
                                    <fr:display-uri>prb-ok</fr:display-uri>
                                    <fr:route>/prb-ok/</fr:route>
                                    <fr:title text="ok">
                                      <html:code>ok</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>Boolean indicating if the probe succeeded.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-method/</fr:uri>
                                    <fr:display-uri>prb-method</fr:display-uri>
                                    <fr:route>/prb-method/</fr:route>
                                    <fr:title text="method">
                                      <html:code>method</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The method used for probing: <html:code>light</html:code> (HEAD request) or <html:code>full</html:code>.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-mime_type/</fr:uri>
                                    <fr:display-uri>prb-mime_type</fr:display-uri>
                                    <fr:route>/prb-mime_type/</fr:route>
                                    <fr:title text="mime_type">
                                      <html:code>mime_type</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The content type returned by the probe.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-length_bytes/</fr:uri>
                                    <fr:display-uri>prb-length_bytes</fr:display-uri>
                                    <fr:route>/prb-length_bytes/</fr:route>
                                    <fr:title text="length_bytes">
                                      <html:code>length_bytes</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The size of the audio file in bytes.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-duration_seconds/</fr:uri>
                                    <fr:display-uri>prb-duration_seconds</fr:display-uri>
                                    <fr:route>/prb-duration_seconds/</fr:route>
                                    <fr:title text="duration_seconds">
                                      <html:code>duration_seconds</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The duration of the audio in seconds.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/prb-error/</fr:uri>
                                    <fr:display-uri>prb-error</fr:display-uri>
                                    <fr:route>/prb-error/</fr:route>
                                    <fr:title text="error">
                                      <html:code>error</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>An error message if <html:code>ok</html:code> is false.</html:p>
</fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false" numbered="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/rep-show_image/</fr:uri>
                                <fr:display-uri>rep-show_image</fr:display-uri>
                                <fr:route>/rep-show_image/</fr:route>
                                <fr:title text="show_image &amp; image"><html:code>show_image</html:code> &amp; <html:code>image</html:code></fr:title>
                                <fr:taxon>key</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>Verification results for cover images. <html:code>show_image</html:code> contains the show cover result, and <html:code>image</html:code> is a dictionary keyed by episode guid.</html:p>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/img-image/</fr:uri>
                                    <fr:display-uri>img-image</fr:display-uri>
                                    <fr:route>/img-image/</fr:route>
                                    <fr:title text="image">
                                      <html:code>image</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The status of the image check: <html:code>ok</html:code>, <html:code>fail</html:code>, <html:code>unknown</html:code>, or <html:code>not_set</html:code>.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/img-image_warnings/</fr:uri>
                                    <fr:display-uri>img-image_warnings</fr:display-uri>
                                    <fr:route>/img-image_warnings/</fr:route>
                                    <fr:title text="image_warnings">
                                      <html:code>image_warnings</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>An array of warning strings from the image validation.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/img-url/</fr:uri>
                                    <fr:display-uri>img-url</fr:display-uri>
                                    <fr:route>/img-url/</fr:route>
                                    <fr:title text="url">
                                      <html:code>url</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The URL of the validated image.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/img-width/</fr:uri>
                                    <fr:display-uri>img-width</fr:display-uri>
                                    <fr:route>/img-width/</fr:route>
                                    <fr:title text="width">
                                      <html:code>width</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The width of the image in pixels.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/img-height/</fr:uri>
                                    <fr:display-uri>img-height</fr:display-uri>
                                    <fr:route>/img-height/</fr:route>
                                    <fr:title text="height">
                                      <html:code>height</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The height of the image in pixels.</html:p>
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false" numbered="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:uri>https://offshore.pressed.press/img-mime_type/</fr:uri>
                                    <fr:display-uri>img-mime_type</fr:display-uri>
                                    <fr:route>/img-mime_type/</fr:route>
                                    <fr:title text="mime_type">
                                      <html:code>mime_type</html:code>
                                    </fr:title>
                                    <fr:taxon>key</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  <html:p>The MIME type of the image.</html:p>
</fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false" numbered="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:uri>https://offshore.pressed.press/rep-bypassed_urls/</fr:uri>
                                <fr:display-uri>rep-bypassed_urls</fr:display-uri>
                                <fr:route>/rep-bypassed_urls/</fr:route>
                                <fr:title text="bypassed_urls">
                                  <html:code>bypassed_urls</html:code>
                                </fr:title>
                                <fr:taxon>key</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
  <html:p>A list of URLs that have been manually bypassed for verification checks.</html:p>
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false" numbered="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:uri>https://offshore.pressed.press/SKIP/</fr:uri>
                            <fr:display-uri>SKIP</fr:display-uri>
                            <fr:route>/SKIP/</fr:route>
                            <fr:title text="Bypassing">Bypassing</fr:title>
                            <fr:taxon>Feature</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
                              <html:mark>Using assets with issue may cause podcast not able to be played or displayed properly. This feature should be used with caution.</html:mark>
                            </html:p>
                            <html:p>User can choose to bypass all check on any asset that has issue. The bypass option will be visible on the <fr:link href="/CK2/" title="Check report" uri="https://offshore.pressed.press/CK2/" display-uri="CK2" type="local">check report</fr:link> alongside asset errors, and if persistent error found on repeated rechecks in episode specific error list.</html:p>
                            <html:p>The bypass status is tied to asset url, stored in <fr:link href="/FT2/" title="&lt;slug&gt;.report.json" uri="https://offshore.pressed.press/FT2/" display-uri="FT2" type="local"><html:code>&lt;slug&gt;.report.json</html:code></fr:link>. The status will be automatically disabled if the asset url is changed. User can also manually disable the bypass flag by clicking on the “recheck” or “reprobe” button.</html:p>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/TAG2/</fr:uri>
                        <fr:display-uri>TAG2</fr:display-uri>
                        <fr:route>/TAG2/</fr:route>
                        <fr:title text="&lt;podcast:image&gt;">
                          <html:code>&lt;podcast:image&gt;</html:code>
                        </fr:title>
                        <fr:taxon>tag</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Part of <fr:link href="/PCNS/" title="Podcast Namespace" uri="https://offshore.pressed.press/PCNS/" display-uri="PCNS" type="local">podcast namespace</fr:link>. offshore will emit <html:code>&lt;podcast:image&gt;</html:code> tags on feed generation for show or episode level images.</html:p>
                        <html:p>Defination of attributes of this tag can be found <fr:link href="https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/tags/image.md" type="external">here</fr:link>.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <html:p><html:strong>Improvement:</html:strong> <fr:link href="/PPL/" title="People roster" uri="https://offshore.pressed.press/PPL/" display-uri="PPL" type="local">People roster</fr:link> entries now can be created directly from episode or show editor.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:contributor>
                        <fr:link href="/lechynte/" title="lechynte" uri="https://offshore.pressed.press/lechynte/" display-uri="lechynte" type="local">lechynte</fr:link>
                      </fr:contributor>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>10</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.2.1</fr:uri>
                    <fr:display-uri>RL0.2.1</fr:display-uri>
                    <fr:route>/RL0.2.1</fr:route>
                    <fr:title text="0.2.1">0.2.1</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>Fixed:</html:strong> <fr:link href="https://todo.sr.ht/~lamons/offshore/5" type="external">first-run setup should not consume piped stdin</fr:link></html:p>
                    <html:p>Detect when stdin is not a TTY via <html:code>sys.stdin.isatty()</html:code> and skip the interactive prompt, using the default <html:code>shows_dir</html:code> instead. This mirrors the existing <html:code>OFFSHORE_SHOWS_DIR</html:code> env-var guard.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>9</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.2.0</fr:uri>
                    <fr:display-uri>RL0.2.0</fr:display-uri>
                    <fr:route>/RL0.2.0</fr:route>
                    <fr:title text="0.2.0">0.2.0</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/FT1/</fr:uri>
                        <fr:display-uri>FT1</fr:display-uri>
                        <fr:route>/FT1/</fr:route>
                        <fr:title text="Set consistent feed output path per show">Set consistent feed output path per show</fr:title>
                        <fr:taxon>Feature</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>User can set a consistent output path of the feed XML file in per-show configuration. This enables serving the feed directly when using offshore on a server, or integrate it in other workflow. The path value is stored in <fr:link href="/sw-output_path/" title="Schema v2 › New show attributes › output_path" uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" type="local">key <fr:contextual-number uri="https://offshore.pressed.press/sw-output_path/" display-uri="sw-output_path" /></fr:link>.</html:p>
                        <html:p>On first feed generation of a show, the user will be prompted to confirm or change the default feed output path. It can be changed in show settings anytime.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/FT2/</fr:uri>
                        <fr:display-uri>FT2</fr:display-uri>
                        <fr:route>/FT2/</fr:route>
                        <fr:title text="&lt;slug&gt;.report.json">
                          <html:code>&lt;slug&gt;.report.json</html:code>
                        </fr:title>
                        <fr:taxon>Feature</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Check findings and audio probe results are stored in a separate <html:code>&lt;slug&gt;.report.json</html:code> file. This file will be automatically updated with <fr:link href="/CK/" title="Check" uri="https://offshore.pressed.press/CK/" display-uri="CK" type="local">checks</fr:link> representing the issues and things to improve in show metadata or assets.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:uri>https://offshore.pressed.press/FT3/</fr:uri>
                        <fr:display-uri>FT3</fr:display-uri>
                        <fr:route>/FT3/</fr:route>
                        <fr:title text="Image validation">Image validation</fr:title>
                        <fr:taxon>Feature</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Podcast and episode artworks are verified against <fr:link href="/APAG/" title="Apple Podcasts’ Artwork Guide" uri="https://offshore.pressed.press/APAG/" display-uri="APAG" type="local">Apple Podcast standards</fr:link>. Failing this check will produce notice to user, but won’t block feed generation.</html:p>
                        <html:p>The automatic image validation is triggered in two occasions:<html:ol><html:li>when a new artwork url is added to a show, or an episode; or</html:li>
    <html:li>when a show or episode’s artwork url is changed.</html:li></html:ol></html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <html:p><html:strong>Improvements:</html:strong>
<html:ul><html:li>Adjust the fail/note level for several check items;</html:li> <html:li>Implement async checking backend to improve check speed;</html:li> <html:li>Refined UI, remove redundant buttons on dashboard (e.g. force generate, probe all) and only shown them when they’re useful.</html:li></html:ul></html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>8</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.1.1</fr:uri>
                    <fr:display-uri>RL0.1.1</fr:display-uri>
                    <fr:route>/RL0.1.1</fr:route>
                    <fr:title text="0.1.1">0.1.1</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:strong>Fixed:</html:strong> Probing for m4a files may have wrong result due to the metadata block put after data stream, this may also cause crash when saving an episode.</html:p>
                    <html:p><html:strong>Improvements:</html:strong> Removed redundant “description” field in episode form; <html:code>&lt;description&gt;</html:code> field in generated feed now derive from shownotes; Categories are now dropdowns.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" expanded="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/ts/" title="tianshi" uri="https://offshore.pressed.press/ts/" display-uri="ts" type="local">tianshi</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>7</fr:day>
                    </fr:date>
                    <fr:uri>https://offshore.pressed.press/RL0.1.0</fr:uri>
                    <fr:display-uri>RL0.1.0</fr:display-uri>
                    <fr:route>/RL0.1.0</fr:route>
                    <fr:title text="0.1.0">0.1.0</fr:title>
                    <fr:taxon>Release</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Initiala release.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Backlinks">Backlinks</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Related">Related</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Contributions">Contributions</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
  </fr:backmatter>
</fr:tree>
