# Podcast Show Notes Generator — AI Transcription & Chapters (`toshiusklay/wisprs-podcast-show-notes`) Actor

Transcribe any podcast episode and auto-generate show notes, timestamped chapters, and guest quotes. Accepts MP3, RSS feeds, M4A, Spotify embed URLs. Speaker diarization. 100+ languages. No Wisprs account needed.

- **URL**: https://apify.com/toshiusklay/wisprs-podcast-show-notes.md
- **Developed by:** [Gitonga Mwaura](https://apify.com/toshiusklay) (community)
- **Categories:** AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Podcast Show Notes Generator — AI Transcription & Chapters

Submit any podcast episode URL — mp3, m4a, RSS feed link — and get back a full transcript, structured show notes, timestamped chapters, speaker-attributed guest quotes, and SRT/VTT subtitle files saved to your Apify Dataset.

The Podcast Show Notes Generator uses the [Wisprs API](https://wisprs.co) to transcribe audio directly from episode URLs using Whisper-based speech-to-text. Unlike tools that rely on pre-existing transcripts, Wisprs transcribes the actual audio — which means it works for every episode, whether or not the host has published a transcript. Accuracy is excellent on clear audio; results vary by language, accent, and recording quality.

---

### What does this Actor do?

The dirty secret of podcasting is that the episode itself is the easy part. A typical post-production workflow takes 3–5 hours of mechanical work after recording. This Actor collapses that entire workflow into two API calls.

1. Submit episode URLs from your input
2. Queue each for async transcription (handles episodes of any length — no timeout)
3. Generate structured show notes including:
   - **Summary** — 2–4 sentences capturing the episode's core argument
   - **Chapters** — timestamped chapter markers with titles and descriptions
   - **Quotes** — top verbatim guest quotes with speaker attribution and timestamps
   - **Show notes markdown** — ready to paste directly into your CMS or podcast host
4. Export the transcript in your chosen formats: TXT, SRT, VTT, JSON, Markdown
5. Save everything to your Apify Dataset — one row per episode

---

### How do I use this Actor to generate podcast show notes?

**Step 1 — Run the Actor**

```json
{
  "startUrls": [
    { "url": "https://feeds.example.com/episodes/episode-42.mp3" }
  ],
  "language": "auto",
  "diarize": true,
  "exportFormats": ["txt", "srt"]
}
````

**Step 2 — Check your Dataset**

Each episode produces one dataset row containing structured show notes, the full transcript, SRT subtitles, and speaker-labeled quotes.

***

### What data does the Actor extract?

| Field | Description |
|---|---|
| `url` | The submitted episode URL |
| `jobId` | Wisprs job identifier |
| `transcriptionId` | Transcription identifier |
| `status` | `completed` or `failed` |
| `durationSeconds` | Episode audio duration |
| `detectedLanguage` | Detected language ISO code |
| `transcript_txt` | Full plain-text transcript |
| `transcript_srt` | SRT subtitle file |
| `transcript_vtt` | WebVTT subtitle file |
| `repurposed_show_notes.summary` | Episode summary paragraph |
| `repurposed_show_notes.chapters` | Array of `{ title, startSeconds, description }` |
| `repurposed_show_notes.quotes` | Array of `{ speaker, text, startSeconds }` |
| `repurposed_show_notes.showNotes` | Formatted Markdown show notes ready to publish |

***

### Show notes output example

```json
{
  "summary": "Sarah Chen joins us to explain why her team consolidated 47 microservices back into a modular monolith — and what the deployment numbers looked like on the other side.",
  "chapters": [
    { "title": "Introduction", "startSeconds": 0, "description": "Host introduces Sarah Chen, VP Engineering at Acme Corp." },
    { "title": "The Microservices Trap", "startSeconds": 312, "description": "How 47 services became impossible to debug." },
    { "title": "The Great Consolidation", "startSeconds": 894, "description": "Moving back to a monolith in 6 weeks." }
  ],
  "quotes": [
    {
      "speaker": "Sarah Chen",
      "text": "We had 47 services and nobody could tell you what half of them did. That's not a microservices problem — that's an organizational problem we tried to solve with infrastructure.",
      "startSeconds": 318
    }
  ],
  "showNotes": "**Episode 42: Why We Killed Our Microservices**\n\nSarah Chen, VP of Engineering at Acme Corp, shares the real story...\n\n**Chapters:**\n- [0:00] Introduction\n- [5:12] The Microservices Trap\n- [14:54] The Great Consolidation"
}
```

***

### How much will it cost to process a 45-minute podcast episode?

Pricing is pay-per-event:

- **$0.005** per episode submitted
- **$0.015 per audio minute** (45-min episode = $0.675)
- **$0.075** per show notes result generated

**Example: 10 × 45-minute episodes with show notes**

- Submit: 10 × $0.005 = $0.05
- Audio: 10 × 45 × $0.015 = $6.75
- Show notes: 10 × $0.075 = $0.75
- **Total: ~$7.55**

The Apify free plan includes $5/month in credits — enough to test 5–6 episodes.

***

### What can I automate with this?

**RSS-to-CMS pipeline** — monitor your podcast RSS feed, submit new episode URLs as they publish, and write the generated show notes directly back to your CMS via webhook. Every episode gets show notes on publish with zero manual work.

**Guest quote library** — the `quotes` array includes speaker attribution and timestamps for every notable thing every guest has ever said. Pipe this into a database and you have a searchable quote library across your entire back-catalog — perfect for social media clip selection.

**Transcript SEO pages** — publish the `transcript_txt` or `transcript_md` export as a dedicated page for each episode. Long-tail podcast transcripts drive search traffic without any additional writing effort.

**Chapter markers for Podcast Namespace** — the `chapters` array maps directly to the Podcasting 2.0 chapter format used by Fountain, Overcast, and Pocket Casts. Inject chapters automatically on every episode.

**Multi-show network dashboard** — submit episodes from all shows in your network concurrently. The async job model handles parallel processing — one run covers an entire network.

***

### Supported URL formats

- Direct audio: mp3, wav, m4a, ogg, flac
- RSS feed episode URLs (standard podcast hosting platforms)
- Buzzsprout, Transistor, Simplecast, Anchor, Captivate, RSS.com, Podbean
- YouTube podcast episodes
- Spotify episode audio links (public)

***

### Language support

100+ languages with automatic detection. Speaker diarization (host vs guest labeling) works best on clear two-speaker recordings. For episodes with more participants, speakers are labeled `"Speaker 1"`, `"Speaker 2"`, etc.

***

### Related Actors

- [Wisprs — Audio & Video Transcription](https://apify.com/wisprs/audio-video-transcription) — universal transcription for any URL
- [Wisprs — YouTube Content Repurposer](https://apify.com/wisprs/youtube-repurposer) — YouTube → thread, blog, chapters
- [Wisprs — Social Media Transcriber](https://apify.com/wisprs/social-media-transcriber) — TikTok, Reels, Shorts

***

### FAQ

**Does this work for podcasts without published transcripts?**
Yes. Wisprs transcribes the audio directly using Whisper — it does not rely on pre-existing transcript files or RSS transcript tags.

**How long does a 60-minute episode take to process?**
Typically 3–8 minutes, depending on server load. The Actor polls automatically and saves results when complete.

**Can I process an entire podcast back-catalog?**
Yes. Add all episode URLs to `startUrls`. The Actor processes them sequentially, saving each result to the Dataset as it completes.

**Does speaker diarization work in languages other than English?**
Speaker detection works across all supported languages. Accuracy on non-English content is excellent on clear recordings.

***

### Support

- Documentation: [wisprs.co/docs](https://wisprs.co/docs)
- Email: tosh@belvadigital.com

***

*Two API calls. One polished episode. Ship faster.*

# Actor input Schema

## `startUrls` (type: `array`):

List of podcast episode URLs to transcribe. Supports direct mp3/m4a/wav links, RSS feed episode URLs, and most podcast hosting platforms (Buzzsprout, Transistor, Simplecast, Anchor, etc.).

## `language` (type: `string`):

ISO 639-1 language code (e.g. 'en', 'es', 'fr'). Leave as 'auto' to detect automatically.

## `diarize` (type: `boolean`):

Label who is speaking in the transcript. Recommended for interview-style podcasts. Results in speaker-attributed quotes in show notes.

## `showNotesOptions` (type: `object`):

Configure the show notes output.

## `exportFormats` (type: `array`):

Transcript formats to include alongside show notes.

## `webhookUrl` (type: `string`):

URL to POST a completion notification to for each episode. Leave blank to poll instead.

## `maxPollSeconds` (type: `integer`):

Maximum time to wait for each episode to complete. Podcast episodes often run 30–90 minutes so this is set higher. Default 1800 seconds (30 minutes).

## `pollIntervalSeconds` (type: `integer`):

How often to check job status. Default 15 seconds.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://feeds.example.com/episodes/episode-42.mp3"
    }
  ],
  "language": "auto",
  "diarize": true,
  "showNotesOptions": {
    "maxChapters": 8,
    "quotesCount": 5,
    "includeTimestamps": true
  },
  "exportFormats": [
    "txt",
    "srt"
  ],
  "maxPollSeconds": 1800,
  "pollIntervalSeconds": 15
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://feeds.example.com/episodes/episode-42.mp3"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("toshiusklay/wisprs-podcast-show-notes").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": [{ "url": "https://feeds.example.com/episodes/episode-42.mp3" }] }

# Run the Actor and wait for it to finish
run = client.actor("toshiusklay/wisprs-podcast-show-notes").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://feeds.example.com/episodes/episode-42.mp3"
    }
  ]
}' |
apify call toshiusklay/wisprs-podcast-show-notes --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=toshiusklay/wisprs-podcast-show-notes",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Podcast Show Notes Generator — AI Transcription & Chapters",
        "description": "Transcribe any podcast episode and auto-generate show notes, timestamped chapters, and guest quotes. Accepts MP3, RSS feeds, M4A, Spotify embed URLs. Speaker diarization. 100+ languages. No Wisprs account needed.",
        "version": "1.0",
        "x-build-id": "4O1cORSaDq4lKXKia"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/toshiusklay~wisprs-podcast-show-notes/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-toshiusklay-wisprs-podcast-show-notes",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/toshiusklay~wisprs-podcast-show-notes/runs": {
            "post": {
                "operationId": "runs-sync-toshiusklay-wisprs-podcast-show-notes",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/toshiusklay~wisprs-podcast-show-notes/run-sync": {
            "post": {
                "operationId": "run-sync-toshiusklay-wisprs-podcast-show-notes",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "Podcast Episode URLs",
                        "type": "array",
                        "description": "List of podcast episode URLs to transcribe. Supports direct mp3/m4a/wav links, RSS feed episode URLs, and most podcast hosting platforms (Buzzsprout, Transistor, Simplecast, Anchor, etc.).",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "ISO 639-1 language code (e.g. 'en', 'es', 'fr'). Leave as 'auto' to detect automatically.",
                        "default": "auto"
                    },
                    "diarize": {
                        "title": "Speaker Diarization (Host vs Guest)",
                        "type": "boolean",
                        "description": "Label who is speaking in the transcript. Recommended for interview-style podcasts. Results in speaker-attributed quotes in show notes.",
                        "default": true
                    },
                    "showNotesOptions": {
                        "title": "Show Notes Options",
                        "type": "object",
                        "description": "Configure the show notes output.",
                        "default": {
                            "maxChapters": 8,
                            "quotesCount": 5,
                            "includeTimestamps": true
                        }
                    },
                    "exportFormats": {
                        "title": "Additional Export Formats",
                        "type": "array",
                        "description": "Transcript formats to include alongside show notes.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "txt",
                                "srt",
                                "vtt",
                                "json",
                                "md"
                            ]
                        },
                        "default": [
                            "txt",
                            "srt"
                        ]
                    },
                    "webhookUrl": {
                        "title": "Webhook URL (optional)",
                        "type": "string",
                        "description": "URL to POST a completion notification to for each episode. Leave blank to poll instead."
                    },
                    "maxPollSeconds": {
                        "title": "Max Poll Time (seconds)",
                        "minimum": 60,
                        "maximum": 3600,
                        "type": "integer",
                        "description": "Maximum time to wait for each episode to complete. Podcast episodes often run 30–90 minutes so this is set higher. Default 1800 seconds (30 minutes).",
                        "default": 1800
                    },
                    "pollIntervalSeconds": {
                        "title": "Poll Interval (seconds)",
                        "minimum": 5,
                        "maximum": 60,
                        "type": "integer",
                        "description": "How often to check job status. Default 15 seconds.",
                        "default": 15
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
