# Shopify Competitor Monitor-Prices, Products, Apps & Tech Stack (`k.pavlenko/shopify-competitor-monitor`) Actor

Monitor any Shopify store for price changes, new products, app installs & theme switches. Detects 30+ apps price trackers can't see. 30x cheaper than Prisync.

- **URL**: https://apify.com/k.pavlenko/shopify-competitor-monitor.md
- **Developed by:** [Kostiantyn Pavlenko](https://apify.com/k.pavlenko) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.065 / store analyzed

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## 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

## Shopify Competitor Monitor — Track Prices, Products, Apps & Tech Stack

Track competitor Shopify stores for **app installs, theme switches, price changes, and new products** —
automatically. Most Shopify monitors watch prices and stock only. This actor does that **and** fingerprints
each store's **technology stack** — which of 30+ apps (Klaviyo, ReCharge, Yotpo, Gorgias…) and which theme a
competitor runs, and the moment any of it changes. It's full **Shopify store intelligence**, not just a price
tracker, for e-commerce teams, DTC brands, and agencies — at a fraction of the cost of Prisync ($99/mo) or
Price2Spy ($58/mo).

### What makes this different from other Shopify price monitors?

The Store has plenty of Shopify price/stock trackers. The gap they leave — and what this actor is built for —
is **tech-stack and app-install intelligence**:

- **Detect installed Shopify apps** — 30+ including Klaviyo, Yotpo, Judge.me, ReCharge, Bold, Loox, Gorgias,
  Privy, Omnisend, Smile.io, and more. Know a competitor's marketing/reviews/subscription stack — and get
  alerted the run they add or drop one.
- **Identify Shopify themes** — see which theme each store runs (Dawn, Debut, Brooklyn, or custom) and catch
  redesigns/replatforms as they happen.
- **Track the full catalog too** — price increases, price drops, new products, removed products, and stock
  changes across every variant, so you don't need a second actor for pricing.

App and theme change-detection is the wedge pure price monitors don't cover — and it reaches a different
buyer: agencies pitching app migrations, app vendors doing competitive intel, and DTC teams benchmarking
their stack against rivals.

### How does Shopify competitor monitoring work?

This actor reads publicly available data from any Shopify store and detects **what changed since your last
run**. Schedule it daily or weekly to build a complete history of your competitors' moves:

- **Track competitor prices on Shopify** — price increases, price drops, and discount patterns across every
  product variant
- **Monitor new product launches** — know the moment a competitor adds or removes products from their catalog
- **Detect installed Shopify apps** — 30+ apps fingerprinted from the storefront
- **Identify Shopify themes** — the theme each store runs, and when it changes
- **Track collection changes** — new/removed collections and shifts in product count per collection
- **Extract store metadata** — country, currency, payment methods, product count, and plan details

### Shopify Competitor Monitor vs. price-only tools

Free and cheap Shopify price trackers exist — but they stop at price and stock. None of them tell you a
competitor just installed Klaviyo or replatformed their theme.

| Feature | This Actor | Prisync / Price2Spy | Free Shopify price trackers | Manual |
|---|---|---|---|---|
| Cost for 100 stores/mo (weekly) | **~$26** | $58–99+/mo | $0 | Free (hours of work) |
| Price & new-product tracking | ✅ | ✅ | ✅ | Manual |
| **App / tech-stack detection** | ✅ **30+ apps** | ❌ | ❌ | ❌ |
| **Theme / replatform detection** | ✅ | ❌ | ❌ | ❌ |
| Snapshot diff (what changed) | ✅ | ✅ | Some | No |
| Whole-catalog, every variant | ✅ | Limited by SKU tier | Limited | No |
| No API key required | ✅ | N/A | Varies | N/A |

### What data can you extract from a Shopify store without an API key?

Every Shopify store exposes public JSON endpoints that this actor reads — no authentication, no API key, no
login required:

- **Products** — title, handle, vendor, type, tags, all variants with price, SKU, and availability
- **Collections** — name, type (custom or smart), product count
- **Store info** — name, country, currency, description, payment methods
- **Apps** — detected from script tags and meta tags in the storefront HTML
- **Theme** — name and ID from the `Shopify.theme` JavaScript variable

### How to monitor a competitor's Shopify store

1. **Add store URLs** — paste one or more Shopify store URLs (e.g., `https://allbirds.com`, `https://gymshark.com`)
2. **Choose what to track** — products, collections, apps, theme — or all of them
3. **Run the actor** — the first run creates a baseline snapshot of each store
4. **Schedule recurring runs** — daily or weekly. Each run compares current state against the previous
   snapshot and reports every change
5. **Export results** — JSON, CSV, or push directly to Google Sheets, Slack, or your CRM via Apify integrations

### Pricing

Pay-per-event pricing at **$0.065 per store analyzed**. No monthly subscription, no per-SKU tiers.

| Stores monitored | Weekly schedule | Monthly cost |
|---|---|---|
| 10 stores | 4 runs/month | **$2.60** |
| 50 stores | 4 runs/month | **$13.00** |
| 100 stores | 4 runs/month | **$26.00** |

Prisync charges $99/month for 100 products across just 5 competitors. This actor monitors 100 entire stores —
every product, every variant, **plus their app stack and theme** — for $26/month. Free price trackers cost
nothing but can't see the tech stack at all.

Platform compute costs (typically $0.001–0.005 per store) are charged separately by Apify.

### Input example

```json
{
    "storeUrls": [
        "https://allbirds.com",
        "https://gymshark.com",
        "https://fashionnova.com"
    ],
    "includeProducts": true,
    "includeCollections": true,
    "detectApps": true,
    "detectTheme": true,
    "maxProductsPerStore": 0
}
````

### Output example

Each store produces one dataset item with a summary and detailed changes:

```json
{
    "storeUrl": "https://allbirds.com",
    "storeName": "Allbirds",
    "scrapedAt": "2026-07-08T12:00:00Z",
    "isFirstRun": false,
    "summary": {
        "totalProducts": 292,
        "totalCollections": 45,
        "detectedApps": 12,
        "theme": "Dawn",
        "changesDetected": 7
    },
    "changes": {
        "newProducts": [{"id": 123, "title": "Tree Flyer 3", "handle": "tree-flyer-3"}],
        "removedProducts": [],
        "priceChanges": [{"productId": 456, "productTitle": "Tree Runner", "oldPrice": "98.00", "newPrice": "89.00"}],
        "stockChanges": [{"productId": 789, "productTitle": "Wool Runner", "variantTitle": "10", "wasAvailable": true, "isAvailable": false}],
        "newApps": ["Klaviyo"],
        "removedApps": [],
        "themeChanged": null
    }
}
```

### Use cases

- **E-commerce agencies** — monitor client competitors automatically and deliver weekly intelligence reports
  covering pricing *and* tech-stack moves
- **Shopify app & SaaS vendors** — track which competitor apps a target store installs or drops (churn/win
  signals for your own sales team)
- **DTC brands** — track competitor pricing strategies, product launches, and technology stack changes
- **Dropshippers** — find trending products early by watching what top stores add and remove
- **Market researchers** — analyze Shopify app adoption trends across hundreds of stores
- **Brand managers** — MAP compliance monitoring to detect unauthorized price drops by resellers

### FAQ

**How do I monitor my competitors' prices on Shopify?**
Add your competitor store URLs, run the actor once to create a baseline, then schedule weekly or daily runs.
Each run reports exactly what changed — price increases, drops, new products, removed products, and more.

**Can I see which apps a competitor's Shopify store uses?**
Yes — that's a core differentiator. The actor fingerprints 30+ Shopify apps from the storefront and reports
which are installed, plus flags newly added or removed apps between runs. It also identifies the store's theme.

**How is this different from a Shopify price tracker?**
Price trackers stop at price and stock. This actor adds app-install and theme detection with change alerts, so
you catch a competitor adopting Klaviyo or replatforming their theme — signals pure price tools can't see.

**How often should I check competitor prices on Shopify?**
Weekly suits most categories; daily works better for fast-moving niches like fashion or electronics. The actor
is lightweight enough to run hourly if needed.

**Can you scrape product data from any Shopify store?**
Any store built on Shopify that hasn't disabled its public JSON endpoints — the vast majority of the 4.8
million+ active Shopify stores. Non-Shopify URLs are automatically detected and skipped.

**Is it legal to scrape Shopify store data?**
This actor accesses only publicly available data through Shopify's standard JSON endpoints
(`/products.json`, `/collections.json`, `/meta.json`). No authentication is bypassed and no private data is
accessed.

**How much does it cost compared to Prisync or Price2Spy?**
$0.065 per store per run — about $26/month to monitor 100 stores weekly, versus Prisync's $99/month for 100
products across 5 competitors and Price2Spy's $57.95/month. For bulk monitoring it's 30–100× cheaper, and it
adds tech-stack intelligence neither offers.

**What Shopify apps can it detect?**
Over 30 including Klaviyo, Yotpo, Judge.me, Privy, ReCharge, Bold, Loox, Stamped.io, Oberlo, DSers, PageFly,
Shogun, Tidio, Gorgias, Omnisend, Smile.io, LoyaltyLion, Aftership, Hotjar, Zendesk, Intercom, Google
Analytics, Meta Pixel, TikTok Pixel, and more.

### Limitations

- Only works with Shopify-powered stores (non-Shopify URLs are automatically detected and skipped)
- Password-protected stores cannot be accessed
- Some stores disable the `/products.json` endpoint — product data will be unavailable for those, but metadata
  and app detection still work
- App detection is fingerprint-based and may not catch every installed app, especially custom or niche ones
- Stores behind aggressive Cloudflare protection may require proxy configuration

# Actor input Schema

## `storeUrls` (type: `array`):

List of Shopify store URLs to monitor (e.g., https://allbirds.com, https://gymshark.com)

## `includeProducts` (type: `boolean`):

Extract the full product catalog with prices, variants, and availability

## `includeCollections` (type: `boolean`):

Extract store collections and their product counts

## `detectApps` (type: `boolean`):

Detect which Shopify apps are installed (Klaviyo, Yotpo, Judge.me, etc.)

## `detectTheme` (type: `boolean`):

Identify which Shopify theme the store is using

## `maxProductsPerStore` (type: `integer`):

Maximum number of products to scrape per store. Set to 0 for unlimited.

## `proxyConfiguration` (type: `object`):

Optional proxy settings. Not required for most Shopify stores.

## Actor input object example

```json
{
  "storeUrls": [
    "https://allbirds.com"
  ],
  "includeProducts": true,
  "includeCollections": true,
  "detectApps": true,
  "detectTheme": true,
  "maxProductsPerStore": 0
}
```

# 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 = {
    "storeUrls": [
        "https://allbirds.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("k.pavlenko/shopify-competitor-monitor").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 = { "storeUrls": ["https://allbirds.com"] }

# Run the Actor and wait for it to finish
run = client.actor("k.pavlenko/shopify-competitor-monitor").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 '{
  "storeUrls": [
    "https://allbirds.com"
  ]
}' |
apify call k.pavlenko/shopify-competitor-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=k.pavlenko/shopify-competitor-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Shopify Competitor Monitor-Prices, Products, Apps & Tech Stack",
        "description": "Monitor any Shopify store for price changes, new products, app installs & theme switches. Detects 30+ apps price trackers can't see. 30x cheaper than Prisync.",
        "version": "0.1",
        "x-build-id": "bQdqLM8SdtWxfjql7"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/k.pavlenko~shopify-competitor-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-k.pavlenko-shopify-competitor-monitor",
                "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/k.pavlenko~shopify-competitor-monitor/runs": {
            "post": {
                "operationId": "runs-sync-k.pavlenko-shopify-competitor-monitor",
                "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/k.pavlenko~shopify-competitor-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-k.pavlenko-shopify-competitor-monitor",
                "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": [
                    "storeUrls"
                ],
                "properties": {
                    "storeUrls": {
                        "title": "Store URLs",
                        "type": "array",
                        "description": "List of Shopify store URLs to monitor (e.g., https://allbirds.com, https://gymshark.com)",
                        "items": {
                            "type": "string"
                        }
                    },
                    "includeProducts": {
                        "title": "Scrape Products",
                        "type": "boolean",
                        "description": "Extract the full product catalog with prices, variants, and availability",
                        "default": true
                    },
                    "includeCollections": {
                        "title": "Scrape Collections",
                        "type": "boolean",
                        "description": "Extract store collections and their product counts",
                        "default": true
                    },
                    "detectApps": {
                        "title": "Detect Installed Apps",
                        "type": "boolean",
                        "description": "Detect which Shopify apps are installed (Klaviyo, Yotpo, Judge.me, etc.)",
                        "default": true
                    },
                    "detectTheme": {
                        "title": "Detect Theme",
                        "type": "boolean",
                        "description": "Identify which Shopify theme the store is using",
                        "default": true
                    },
                    "maxProductsPerStore": {
                        "title": "Max Products Per Store",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum number of products to scrape per store. Set to 0 for unlimited.",
                        "default": 0
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Optional proxy settings. Not required for most Shopify stores."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
