---
title: "Object Storage Query Input"
description: "query an object storage container for events matching target criteria"
source: "https://github.com/log-10x/modules/tree/main/pipelines/run/modules/input/objectStorage/query/module.yaml"
icon: "octicons/filter-24"

---
Defines a search query against an object storage container (e.g., AWS S3 bucket) [index](https://doc.log10x.com/run/input/objectStorage/index "Index files uploaded to a object storage container (e.g. AWS S3 bucket).").

Queries can execute periodically (e.g., k8s CronJob) or ad-demand via the [REST API](https://doc.log10x.com/api/launch/#quarkus) to populate log analytics dashboards, alerts, and ad-hoc queries.

Each query specifies _criteria_ and _actions_.

**Criteria** select events to fetch and transform into [TenXObjects](https://doc.log10x.com/api/js/#tenxobject):

- [**Target**](#queryfiltertarget): target app/service whose events to query (e.g., 'myApp').
- [**Time range**](#queryfrom "beginning of the search time range (inclusive)"): of log/trace events to fetch.
- [**Terms**](#querysearch "list of terms to search for"): query to execute against the underling storage
- [**Filters**](#queryfilters "list of terms to search for"): list of JavaScript expressions which allows for more complex filtering of which TenXObjects matching the search terms to select.

**Actions** specify how to further filter, [enrich](https://doc.log10x.com/run/transform/script/object/#enrich), aggregate, and stream TenXObjects to log analyzers and metric outputs (e.g., AWS CloudWatch, Prometheus).

## :material-floor-plan: Architecture

A distributed [Stream Processing Architecture](https://docs.aws.amazon.com/whitepapers/latest/build-modern-data-streaming-analytics-architectures/what-is-a-modern-streaming-data-architecture.html){target="\_blank"} executes queries via parallel [scan](#scan) and [stream](#stream) workers to select, transform and stream TenXObjects to target output(s).

### :material-filter-variant: Scan

Scan workers process [TenXTemplate Filters](https://doc.log10x.com/run/input/objectStorage/index/#tenxtemplate-filters) to identify blobs matching a target prefix (i.e., app/service name), time frame (e.g., last 10min) and search terms (e.g., ERROR).

Multiple scan workers perform this workload in parallel, submitting matching byte ranges to stream workers via SQS.

### :material-set-split: Stream

Stream workers read object storage blob byte ranges identified by the scan workers and transform them into TenXObjects
on which they perform the [actions](#queryactions) specified by the query.

### :material-counter: Summaries

Stream workers optionally write per-pattern rollups to a parallel S3 prefix `qrs/{queryId}/{sliceFrom}_{sliceTo}/{worker}.jsonl`, alongside or instead of raw events at `qr/{queryId}/{sliceFrom}_{sliceTo}/{worker}.jsonl`. Each summary record carries `summaryVolume` (event count), `summaryBytes` (UTF-8 byte total), and the named enrichment fields the pipeline initialized.

Toggle via [`queryWriteSummaries`](#querywritesummaries "sets whether per-slice TenXSummary aggregates are buffered to JSONL and uploaded") on the query module, or by setting `writeSummaries: true` on the `POST /retriever/query` REST request. Raw events (`qr/`) carry forensic payloads; summaries (`qrs/`) keep counts exact across all matched events instead of capped per worker.

## :material-sitemap-outline: Architecture Flow

The following diagram illustrates the complete distributed, parallel architecture for query execution:

```mermaid
graph TD
    Client["🔍 Query Request<br/>API /search"] --> S3["☁️ S3 Object Storage<br/>Log Files + Bloom Filters"]
    
    S3 --> ScanLayer
    
    subgraph ScanLayer["⚡ Parallel Scan Functions<br/> "]
        Scan1["Scan #1<br/>Time: 00:00-05:00<br/>• Filter prefix<br/>• Test Bloom filters<br/>• Find byte ranges"]
        Scan2["Scan #2<br/>Time: 05:00-10:00<br/>• Filter prefix<br/>• Test Bloom filters<br/>• Find byte ranges"]
        Scan3["Scan #3<br/>Time: 10:00-15:00<br/>• Filter prefix<br/>• Test Bloom filters<br/>• Find byte ranges"]
        ScanN["Scan #N<br/>Time: N+5:00<br/>• Filter prefix<br/>• Test Bloom filters<br/>• Find byte ranges"]
    end
    
    ScanLayer --> StreamLayer
    
    subgraph StreamLayer["🌊 Parallel Stream Functions<br/> "]
        Stream1["Stream #1<br/>• Fetch ranges<br/>• Parse logs<br/>• Create TenXObjects<br/>• Filter & enrich"]
        Stream2["Stream #2<br/>• Fetch ranges<br/>• Parse logs<br/>• Create TenXObjects<br/>• Filter & enrich"]
        Stream3["Stream #3<br/>• Fetch ranges<br/>• Parse logs<br/>• Create TenXObjects<br/>• Filter & enrich"]
        StreamM["Stream #M<br/>• Fetch ranges<br/>• Parse logs<br/>• Create TenXObjects<br/>• Filter & enrich"]
    end
    
    StreamLayer --> OutputLayer
    
    subgraph OutputLayer["📊 Output Targets<br/> "]
        Elastic["Elasticsearch<br/>Events & Logs"]
        Prometheus["Prometheus<br/>Metrics & Gauges"]
        Datadog["Datadog<br/>Custom Metrics"]
        Splunk["Splunk<br/>Search Indexes"]
    end
    
    %% Elegant dark theme styling
    classDef default fill:#2d3748,stroke:#4a5568,stroke-width:2px,color:#e2e8f0
    classDef client fill:#2b6cb0,stroke:#3182ce,stroke-width:2px,color:#ffffff
    classDef storage fill:#d69e2e,stroke:#ed8936,stroke-width:2px,color:#ffffff
    classDef scan fill:#38a169,stroke:#48bb78,stroke-width:2px,color:#ffffff
    classDef stream fill:#d53f8c,stroke:#ed64a6,stroke-width:2px,color:#ffffff
    classDef output fill:#805ad5,stroke:#9f7aea,stroke-width:2px,color:#ffffff
    
    class Client client
    class S3 storage
    class Scan1,Scan2,Scan3,ScanN scan
    class Stream1,Stream2,Stream3,StreamM stream
    class Elastic,Prometheus,Datadog,Splunk output
```

### :material-check: Benefits

- **Scalability**: Functions auto-scale based on query complexity and data volume
- **Parallelism**: Time-based partitioning enables concurrent processing across multiple workers
- **Efficiency**: Bloom filters minimize unnecessary data reads from object storage
- **Flexibility**: Multiple output targets support different analytics use cases (logs, metrics, alerts)
- **Cost-Effective**: SQS-based execution model scales with demand

## :material-speedometer: Performance

Index lookups identify matching files in under 1 second. Fetching and streaming events depends on result set size and parallel worker configuration.

### Baseline

- **~10K events:** 10–30 seconds with default parallel scan/stream configuration
- **Index filters:** Identify matching files in \<1 second ([accuracy](https://doc.log10x.com/run/input/objectStorage/index/#accuracy) is configurable, default ~1% false positive rate)
- **Network limits:** S3 API throughput and network bandwidth are the practical limits at scale

### Parallelism

Parallel [scan](#scan) and [stream](#stream) workers fetch and parse events concurrently. Three configuration options control parallelism:

- [`queryScanFunctionParallelTimeslice`](#queryscanfunctionparalleltimeslice "max time range to process by a scan worker instance"), max time range per scan worker (e.g., `1m` = each worker scans 1 minute of index)
- [`queryScanFunctionParallelMaxInstances`](#queryscanfunctionparallelmaxinstances "max number of instances of the scan worker"), max number of parallel scan workers (default 1000)
- [`queryStreamFunctionParallelObjects`](#querystreamfunctionparallelobjects "max number of input object byte ranges to process in a single 'stream' instance"), max byte ranges per stream worker (default 50)

**Example:** 100K events over a 10-minute time range with a 1-minute timeslice produces ~10 parallel scan workers. Total query time approaches the single-worker baseline (~10–30 sec) rather than scaling linearly with result set size. Actual time depends on file size distribution, S3 API rate limits, network bandwidth, and log parsing overhead.

### Optimization Tips

- Use narrow [time ranges](#queryfrom "beginning of the search time range (inclusive)") to reduce scan volume
- Add service/host filters to narrow scope
- For massive result sets (\>10M events), split into smaller time windows
- Use [query limits](#querylimitprocessingtime "max milliseconds alloted for this query") to prevent runaway queries

## :material-wrench-outline: Config Files

To configure the Object storage query input module, [:material-cog: Edit](https://doc.log10x.com/config/app/#module-config "Learn how to edit app and module configurations") these files.  

Below is the default configuration from: [query/config.yaml](https://github.dev/log-10x/config/blob/main/pipelines/run/input/objectStorage/query/config.yaml "query/config.yaml"){target="\_blank"} (<span class="tenx-tooltip" data-tooltip="The config file below contains required fields to activate this module, marked with &#10071;">** Required Fields*</span>).  
  
<div class="edit-options">
    <a class="md-button tenx-edit-online-button" data-tooltip="Edit online on github.dev" href="https://github.dev/log-10x/config/blob/main/pipelines/run/input/objectStorage/query/config.yaml" target="_blank" rel="noopener noreferrer">
        <span class="twemoji" style="margin-right: 0.3rem;">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
            </svg>
        </span> Edit Online
    </a>
    <button class="md-button tenx-config.yaml0-edit-button" data-tooltip="Edit configuration file" data-dialog-id="config-yaml0-dialog">
        <span style="margin-right: 0.3rem;">
            <span class="twemoji">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z"></path>
                </svg>
            </span>
        </span>Edit Locally
    </button>
</div>

<dialog id="config-yaml0-dialog" class="md-dialog md-dialog--editor">
    <div class="editor-dialog-wrapper">
        <div class="editor-dialog-header">
            <span class="editor-dialog-title">Edit config.yaml Locally</span>
            <div class="editor-header-actions">
                <button class="editor-toolbar-btn yaml-editor-locations" data-tooltip="Save">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M5 20h14v-2H5v2m14-9h-4V3H9v8H5l7 7 7-7Z"></path></svg>
                </button>
                <button class="editor-toolbar-btn yaml-editor-reset" data-tooltip="Reset to default">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M12.5 8c-2.65 0-5.05 1-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"></path></svg>
                </button>
                <button class="editor-toolbar-btn yaml-editor-copy" data-tooltip="Copy to clipboard">
                    <svg class="icon-copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path></svg>
                    <svg class="icon-check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="display:none;"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg>
                </button>
                <span class="header-divider"></span>
                <button class="editor-toolbar-btn yaml-editor-fullscreen" data-tooltip="Fullscreen">
                    <svg class="icon-maximize" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z"></path></svg>
                    <svg class="icon-minimize" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="display:none;"><path fill="currentColor" d="M5,16H8V19H10V14H5V16M14,14V19H16V16H19V14H14M16,5V8H19V10H14V5H16M10,5V10H5V8H8V5H10Z"></path></svg>
                </button>
                <span class="header-divider"></span>
                <button class="editor-toolbar-btn editor-dialog-close" onclick="closeDialog('config-yaml0-dialog')" data-tooltip="Close">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"></path></svg>
                </button>
            </div>
        </div>
        <div class="editor-dialog-content">
            <div class="yaml-editor-container"></div>
        </div>
        <div class="yaml-editor-statusbar">
            <span class="yaml-editor-status"></span>
        </div>
    </div>
    <!-- Locations Popup -->
    <div class="locations-popup" style="display: none;">
        <div class="locations-popup-content">
            <div class="locations-popup-header">
                <span class="locations-header-label">Download and save to:</span>
                <button class="locations-popup-close" aria-label="Close">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
                        <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"></path>
                    </svg>
                </button>
            </div>
            <ul class="locations-list">
                <li>
                    <span class="location-label">Linux / Docker / macOS
                        <span class="help-icon" data-tooltip="Default system location. The engine automatically reads configs from here at startup. Best for production deployments.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="default-path location-path" data-tooltip=""
                            data-copy-osx="/etc/log10x/config/run/input/objectStorage/query/config.yaml"
                            data-copy-nix="/etc/log10x/config/run/input/objectStorage/query/config.yaml"
                            data-copy-win="C:\log10x\configs/run/input/objectStorage/query/config.yaml"></code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
                <li>
                    <span class="location-label">Custom directory
                        <span class="help-icon" data-tooltip="Set TENX_CONFIG environment variable to point to a custom config directory. Useful when you want configs in a non-standard location.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="location-path" data-tooltip="$TENX_CONFIG/run/input/objectStorage/query/config.yaml">$TENX_CONFIG/run/input/objectStorage/query/config.yaml</code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
                <li>
                    <span class="location-label">Within cloned repo
                        <span class="help-icon" data-tooltip="First run: git clone github.com/log-10x/config. Then save the file to this path within the cloned folder. Use for version control.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="location-path" data-tooltip="./pipelines/run/input/objectStorage/query/config.yaml">./pipelines/run/input/objectStorage/query/config.yaml</code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
            </ul>
            <div class="locations-popup-footer">
                <button class="locations-download-btn" title="Download config file">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                        <path fill="currentColor" d="M5 20h14v-2H5v2m14-9h-4V3H9v8H5l7 7 7-7Z"></path>
                    </svg>
                    <span>Download</span>
                </button>
            </div>
        </div>
    </div>
</dialog>

<template class="tenx-config-schema" data-encoding="base64">ewogICJ0eXBlIiA6ICJvYmplY3QiLAogICJwcm9wZXJ0aWVzIiA6IHsKICAgICJpbmNsdWRlIiA6IHsKICAgICAgInR5cGUiIDogImFycmF5IiwKICAgICAgIml0ZW1zIiA6IHsKICAgICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgICB9CiAgICB9LAogICAgInRlbngiIDogewogICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgfSwKICAgICJxdWVyeSIgOiB7CiAgICAgICJ0eXBlIiA6ICJhcnJheSIsCiAgICAgICJpdGVtcyIgOiB7CiAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IGZhbHNlLAogICAgICAgICJwcm9wZXJ0aWVzIiA6IHsKICAgICAgICAgICJuYW1lIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTG9naWNhbCBuYW1lIGZvciB0aGUgcXVlcnlcblxuU3BlY2lmaWVzIGEgbG9naWNhbCBuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGUgcXVlcnkgKGUuZy4sIGBlcnJvcnNRdWVyeWApIFRoaXMgdmFsdWUgaWRlbnRpZmllcyB0aGlzIHF1ZXJ5IG9wZXJhdGlvbiBpbiBhZ2dyZWdhdGVkIG1ldHJpY3MgcmVwb3J0cy4gSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gYSBjb25jYXRlbmF0aW9uIG9mIFtxdWVyeVRhcmdldF0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9xdWVyeS8jcXVlcnl0YXJnZXQpIGFuZCBbcXVlcnlTZWFyY2hdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvcXVlcnkvI3F1ZXJ5c2VhcmNocykiCiAgICAgICAgICB9LAogICAgICAgICAgInJlYWRQcmludFByb2dyZXNzIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJib29sZWFuIiwKICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlNldHMgd2hldGhlciB0aGlzIGlucHV0IHByaW50cyB0aHJvdWdocHV0IHN0YXRzIHRvIHRoZSBjb25zb2xlXG5cblNldHMgd2hldGhlciB0aGlzIGlucHV0IHByaW50cyB0aHJvdWdocHV0IHN0YXRzIHRvIHRoZSBjb25zb2xlIFRoaXMgdmFsdWUgaXMgY29tbW9ubHkgdXNlZCB3aGVuIHRlc3RpbmcgYW4gaW50ZWdyYXRpb24gdG8gYSByZW1vdGUgZW5kcG9pbnQuIChBY2NlcHRzIGJvb2xlYW4gb3Igc3RyaW5nIHdpdGggJD0gcHJlZml4IGZvciBydW50aW1lIGV2YWx1YXRpb24pIgogICAgICAgICAgfSwKICAgICAgICAgICJsb2dMZXZlbHMiIDogewogICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJMb2cgbGV2ZWxzIHRvIHNlbmQgdG8gQ2xvdWRXYXRjaCBMb2dzIGZvciBxdWVyeSBwcm9ncmVzcyB0cmFja2luZ1xuXG5TcGVjaWZpZXMgd2hpY2ggcXVlcnkgZXZlbnQgbG9nIGxldmVscyBhcmUgc2VudCB0byBDbG91ZFdhdGNoIExvZ3MgZm9yIHRyYWNraW5nIHF1ZXJ5IHByb2dyZXNzLiBWYWxpZCB2YWx1ZXM6IGBFUlJPUmAsIGBJTkZPYCwgYERFQlVHYCwgYFBFUkZgLiAgSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gYEVSUk9SYCwgYElORk9gLCBgUEVSRmAuICAqKk5vdGU6KiogYFBFUkZgIGlzIHJlcXVpcmVkIGZvciBjb25zb2xlIHByb2dyZXNzIHRyYWNraW5nIChnYXVnZXMsIGNvbXBsZXRpb24gZGV0ZWN0aW9uKS4gRGlzYWJsaW5nIGl0IHdpbGwgY2F1c2UgdGhlIGNvbnNvbGUgdG8gbm90IGRldGVjdCBxdWVyeSBjb21wbGV0aW9uLiAgYGBgIHlhbWwgcXVlcnlMb2dMZXZlbHM6IEVSUk9SLElORk8sUEVSRiBgYGAiCiAgICAgICAgICB9LAogICAgICAgICAgImxvZ0dyb3VwIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiQ2xvdWRXYXRjaCBMb2dzIGxvZyBncm91cCBmb3IgcXVlcnkgZXZlbnQgbG9nZ2luZ1xuXG5TcGVjaWZpZXMgdGhlIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXAgbmFtZSBmb3IgbG9nZ2luZyBxdWVyeSBsaWZlY3ljbGUgZXZlbnRzLiBUaGUgbG9nIGdyb3VwIG11c3QgYmUgcHJlLWNyZWF0ZWQgKGUuZy4gYnkgVGVycmFmb3JtKS4gSWYgbm90IHNwZWNpZmllZCBvciBlbXB0eSwgcXVlcnkgZXZlbnQgbG9nZ2luZyBpcyBkaXNhYmxlZC4gIGBgYCB5YW1sIHF1ZXJ5TG9nR3JvdXA6IC9sb2cxMHgvcXVlcnkgYGBgIgogICAgICAgICAgfSwKICAgICAgICAgICJ3cml0ZVJlc3VsdHMiIDogewogICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgImJvb2xlYW4iLAogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiU2V0cyB3aGV0aGVyIG1hdGNoZWQgZXZlbnRzIGFyZSBidWZmZXJlZCB0byBKU09OTCBhbmQgdXBsb2FkZWQgdG8gb2JqZWN0IHN0b3JhZ2VcblxuQ29udHJvbHMgd2hldGhlciB0aGUgc3RyZWFtIHBpcGVsaW5lIGxhdW5jaGVzIHRoZSBKU09OTCByZXN1bHRzIHdyaXRlciBpbiBhZGRpdGlvbiB0byB0aGUgYnl0ZS1jb3VudCBtYXJrZXIgYmFja3N0b3AgdXNlZCBieSB0aGUgcXVlcnkgY29vcmRpbmF0b3IuICBEZWZhdWx0cyB0byBgZmFsc2VgIHNvIHRoZSBleHRyYSBKU09OTCB1cGxvYWQgb25seSBydW5zIHdoZW4gYSBjYWxsZXIgZXhwbGljaXRseSBvcHRzIGluLiBUaGUgcXVlcnkgY29vcmRpbmF0b3IgZm9yd2FyZHMgdGhpcyBmbGFnIHRvIGVhY2ggc3RyZWFtIHdvcmtlciBpdCBkaXNwYXRjaGVzIHZpYSBhIGBxdWVyeU9iamVjdFdyaXRlUmVzdWx0cz08dmFsdWU+YCBib290c3RyYXAgYXJnIG9uIHRoZSBzdHJlYW0gcGlwZWxpbmUgbGF1bmNoLiAgT3V0LW9mLWJhbmQgY29uc3VtZXJzIGxpa2UgdGhlIExvZzEweCBNQ1Agc2VydmVyIHNldCB0aGlzIHRvIGB0cnVlYCBzbyB0aGV5IGNhbiByZXRyaWV2ZSBmdWxsIGV2ZW50IHBheWxvYWRzIGZyb20gUzMgdW5kZXIgYHtpbmRleE9iamVjdFBhdGgocXVlcnlSZXN1bHRzKX0ve3F1ZXJ5SWR9L3tzbGljZUZyb219X3tzbGljZVRvfS8qLmpzb25sYC4gRGVwbG95bWVudHMgdGhhdCBvbmx5IHJlbHkgb24gdGhlIGNvb3JkaW5hdG9yJ3MgbnVtZXJpYy1rZXkgcG9sbCBsZWF2ZSB0aGlzIG9mZi4gIGBgYCB5YW1sIHF1ZXJ5V3JpdGVSZXN1bHRzOiB0cnVlIGBgYCAoQWNjZXB0cyBib29sZWFuIG9yIHN0cmluZyB3aXRoICQ9IHByZWZpeCBmb3IgcnVudGltZSBldmFsdWF0aW9uKSAoRGVmYXVsdDogZmFsc2UpIiwKICAgICAgICAgICAgImRlZmF1bHQiIDogZmFsc2UKICAgICAgICAgIH0sCiAgICAgICAgICAid3JpdGVTdW1tYXJpZXMiIDogewogICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgImJvb2xlYW4iLAogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiU2V0cyB3aGV0aGVyIHBlci1zbGljZSBUZW5YU3VtbWFyeSBhZ2dyZWdhdGVzIGFyZSBidWZmZXJlZCB0byBKU09OTCBhbmQgdXBsb2FkZWRcblxuQ29udHJvbHMgd2hldGhlciB0aGUgc3RyZWFtIHBpcGVsaW5lIGxhdW5jaGVzIGEgVGVuWFN1bW1hcnktbW9kZSByZXN1bHRzIHdyaXRlciBpbiBhZGRpdGlvbiB0byB0aGUgZXZlbnRzIHdyaXRlciAoZ2F0ZWQgYnkgYHF1ZXJ5V3JpdGVSZXN1bHRzYCkgYW5kIHRoZSBieXRlLWNvdW50IG1hcmtlciBiYWNrc3RvcC4gIERlZmF1bHRzIHRvIGBmYWxzZWAuIFRoZSBxdWVyeSBjb29yZGluYXRvciBmb3J3YXJkcyB0aGlzIGZsYWcgdG8gZWFjaCBzdHJlYW0gd29ya2VyIGl0IGRpc3BhdGNoZXMgdmlhIGEgYHF1ZXJ5T2JqZWN0V3JpdGVTdW1tYXJpZXM9PHZhbHVlPmAgYm9vdHN0cmFwIGFyZyBvbiB0aGUgc3RyZWFtIHBpcGVsaW5lIGxhdW5jaC4gIFdoZW4gc2V0IHRvIGB0cnVlYCwgcGVyLXNsaWNlIGFnZ3JlZ2F0ZWQgc3VtbWFyaWVzIChjb3VudCwgYnl0ZXN1bSwgZ3JvdXBpbmcgZmllbGRzIHByb2R1Y2VkIGJ5IGBydW4vYWdncmVnYXRlL3N0cmVhbWApIGFyZSB3cml0dGVuIHRvIGB7aW5kZXhPYmplY3RQYXRoKHF1ZXJ5U3VtbWFyaWVzKX0ve3F1ZXJ5SWR9L3tzbGljZUZyb219X3tzbGljZVRvfS8qLmpzb25sYC4gQ29uc3VtZXJzIChlLmcuIGxvZzEweF9wYXR0ZXJuX3RyZW5kLCBsb2cxMHhfdG9wX3BhdHRlcm5zKSBjYW4gcG9sbCB0aGVzZSBwZXItc2xpY2Ugc3VtbWFyaWVzIHRvIHJlbmRlciB0aW1lLXNwcmVhZCByZXN1bHRzIGZvciBoaWdoLWNhcmRpbmFsaXR5IHBhdHRlcm5zIHdpdGhvdXQgcGF5aW5nIHRoZSBiYW5kd2lkdGggY29zdCBvZiBmdWxsIGV2ZW50IEpTT05MLiAgSW5kZXBlbmRlbnQgb2YgYHF1ZXJ5V3JpdGVSZXN1bHRzYDsgZWl0aGVyIGNhbiBiZSBvbiBpbiBpc29sYXRpb24gb3IgYm90aCB0b2dldGhlci4gIGBgYCB5YW1sIHF1ZXJ5V3JpdGVTdW1tYXJpZXM6IHRydWUgYGBgIChBY2NlcHRzIGJvb2xlYW4gb3Igc3RyaW5nIHdpdGggJD0gcHJlZml4IGZvciBydW50aW1lIGV2YWx1YXRpb24pIChEZWZhdWx0OiBmYWxzZSkiLAogICAgICAgICAgICAiZGVmYXVsdCIgOiBmYWxzZQogICAgICAgICAgfSwKICAgICAgICAgICJ0YXJnZXQiIDogewogICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJMb2dpY2FsIHByZWZpeCB0byBmaWx0ZXIgaW5kZXggb2JqZWN0cyBieVxuXG5TcGVjaWZpZXMgYSBsb2dpY2FsIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZWFyY2ggdGFyZ2V0LiBUaGlzIHZhbHVlIGlkZW50aWZpZXMgdGhlIGFwcCB0aGF0IHByb2R1Y2VkIHRoZSBxdWVyaWVkIGV2ZW50cyAoZS5nLiwgYGFjbWUtY2xpZW50YCkuICBUaGlzIHZhbHVlIGNvcnJlc3BvbmRzIHdpdGggdGhlIFtpbmRleFdyaXRlVGFyZ2V0XShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9vYmplY3RTdG9yYWdlL2luZGV4LyNpbmRleHdyaXRldGFyZ2V0KSBhcmd1bWVudC4iCiAgICAgICAgICB9LAogICAgICAgICAgInJlc3VsdFRhcmdldCIgOiB7CiAgICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIk9wdGlvbmFsIFRpZXItMSByZXN1bHQtc2luayByZWRpcmVjdCBwcmVmaXggZm9yIHF1ZXJ5IE9VVFBVVFxuXG5PcHRpb25hbCBiYXJlLXRva2VuIHByZWZpeCB1bmRlciB3aGljaCBxdWVyeSBSRVNVTFQgb2JqZWN0cyAoYHFyL2AsIGBxcnMvYCwgYHEvYCBtYXJrZXJzLCBgX0RPTkUuanNvbmApIGFyZSB3cml0dGVuLCBpbnNpZGUgdGhlIFNBTUUgaW5kZXggY29udGFpbmVyIGFzIGBxdWVyeVRhcmdldGAuIFdoZW4gb21pdHRlZCBvciBibGFuaywgcmVzdWx0cyBhcmUgd3JpdHRlbiB1bmRlciBgcXVlcnlUYXJnZXRgLCBieXRlLWlkZW50aWNhbCB0byBsZWdhY3kgYmVoYXZpb3IuIE11c3QgbWF0Y2ggYFtBLVphLXowLTlfLV0rYCAobm8gc2xhc2hlcywgc2VwYXJhdG9ycywgb3IgYC4uYCk7IGEgdmlvbGF0aW5nIHZhbHVlIGZhaWxzIHRoZSBxdWVyeSBjbG9zZWQuIFRoZSBSRUFEIHBhdGggZm9yIHRoZSBkdXJhYmxlIGluZGV4ICh0ZW1wbGF0ZXMsIGJ5dGUgcmFuZ2VzLCByZXZlcnNlIGluZGV4KSBpcyB1bmFmZmVjdGVkIGFuZCBhbHdheXMgdXNlcyBgcXVlcnlUYXJnZXRgLiIKICAgICAgICAgIH0sCiAgICAgICAgICAic2VhcmNoIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTGlzdCBvZiB0ZXJtcyB0byBzZWFyY2ggZm9yXG5cblNwZWNpZmllcyBhIHNlYXJjaCBleHByZXNzaW9uIGFwcGxpZWQgdG8gdGhlIHVuZGVybHlpbmcgc3RvcmFnZSB2aWEgW1RlblhUZW1wbGF0ZSBmaWx0ZXJzXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9vYmplY3RTdG9yYWdlL2luZGV4LyN0ZW54dGVtcGxhdGUtZmlsdGVycykgZm9yIGVmZmljaWVudCBwcmUtZmlsdGVyaW5nLiBTdXBwb3J0cyBvbmx5IGJhc2ljIG9wZXJhdGlvbnM6IGAmJmAgKEFORCksIGB8fGAgKE9SKSwgPT0gKGVxdWFsaXR5KSwgYW5kIFtpbmNsdWRlc10oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9hcGkvanMvI1RlblhTdHJpbmcuaW5jbHVkZXMpIChzdWJzdHJpbmcgbWF0Y2gpLiAgRXhhbXBsZTogICBgYGAganMgKGxldmVsPT1JTkZPIHx8IGxldmVsPT1XQVJOKSAmJiBpbmNsdWRlcyh0ZXh0LCBcIlBPU1RcIikgYGBgICBUaGlzIG5hcnJvd3MgZG93biBkYXRhIGZldGNoZWQgZnJvbSBzdG9yYWdlIGJlZm9yZSBpbi1tZW1vcnkgcHJvY2Vzc2luZy4gIFRvIHBlcmZvcm0gbW9yZSBjb21wbGV4IGluLW1lbW9yeSBmaWx0ZXJpbmcsIHNwZWNpZnkgW3F1ZXJ5RmlsdGVyc10oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9xdWVyeS8jcXVlcnlmaWx0ZXJzKS4iCiAgICAgICAgICB9LAogICAgICAgICAgImZpbHRlcnMiIDogewogICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgImFycmF5IiwKICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIkxpc3Qgb2YgdGVybXMgdG8gc2VhcmNoIGZvclxuXG5TcGVjaWZpZXMgSmF2YVNjcmlwdCBleHByZXNzaW9ucyBhcHBsaWVkIGluLW1lbW9yeSB0byBhbGwgVGVuWE9iamVjdHMgdGhhdCBtYXRjaCB0aGUgW3F1ZXJ5U2VhcmNoXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9vYmplY3RTdG9yYWdlL3F1ZXJ5LyNxdWVyeXNlYXJjaCkgZXhwcmVzc2lvbi4gU3VwcG9ydHMgYWxsIHZhbGlkIFtUZW5YIEphdmFTY3JpcHRdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vYXBpL2pzLykgZXhwcmVzc2lvbnMgZm9yIGNvbXBsZXggZmlsdGVyaW5nLCBlbnJpY2htZW50LCBhbmQgcHJvY2Vzc2luZy4gIFRoaXMgcHJvdmlkZXMgcHJlY2lzZSwgZXhhY3QgZmlsdGVyaW5nIGFmdGVyIGRhdGEgaXMgZmV0Y2hlZCBmcm9tIHN0b3JhZ2UuICBgYGAgeWFtbCBxdWVyeUZpbHRlcnM6ICAgLSBMZXZlbFRlbXBsYXRlLmxldmVsID09IFwiRVJST1JcIiAgICAtIE1hdGgubWF4KHRoaXMucHJpY2UsIDEwMCkgYGBgIiwKICAgICAgICAgICAgIml0ZW1zIiA6IHsKICAgICAgICAgICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgImZyb20iIDogewogICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJCZWdpbm5pbmcgb2YgdGhlIHNlYXJjaCB0aW1lIHJhbmdlIChpbmNsdXNpdmUpXG5cbkRlZmluZXMgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2VhcmNoIHRpbWUgcmFuZ2UgKGluY2x1c2l2ZSkgZXhwcmVzc2VkIGFzIGEgVU5JWCBtaWxsaXNlY29uZCBlcG9jaCB2YWx1ZS4gVGhpcyB2YWx1ZSBjb21tb25seSB1c2VzIHRoZSBbbm93XShodHRwczovL2RvYy5sb2cxMHguY29tL2FwaS9qcy8jVGVuWERhdGUubm93KSBmdW5jdGlvbi4gIEZvciBleGFtcGxlLCB0byBleHByZXNzIHRoZSB2YWx1ZSBvZiBvbmUgaG91ciBiZWZvcmUgdGhlIGN1cnJlbnQgbWlsbGlzZWNvbmQgZXBvY2gsIHNwZWNpZnk6ICBgYGAgeWFtbCBxdWVyeUZyb206IG5vdyhcIi0xaFwiKSBgYGAiCiAgICAgICAgICB9LAogICAgICAgICAgInRvIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiRW5kIG9mIHRoZSBzZWFyY2ggdGltZSByYW5nZSAoZXhjbHVzaXZlKVxuXG5EZWZpbmVzIHRoZSBlbmQgb2YgdGhlIHNlYXJjaCB0aW1lIHJhbmdlIGV4cHJlc3NlZCBhcyBhIFVOSVggbWlsbGlzZWNvbmQgZXBvY2ggdmFsdWUgKGV4Y2x1c2l2ZSkuIFRoaXMgdmFsdWUgY29tbW9ubHkgdXNlcyB0aGUgW25vd10oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9hcGkvanMvI1RlblhEYXRlLm5vdykgZnVuY3Rpb24uICBGb3IgZXhhbXBsZSwgdG8gZXhwcmVzcyB0aGUgdmFsdWUgb2YgdGhlIGN1cnJlbnQgbWlsbGlzZWNvbmQgZXBvY2gsIHNwZWNpZnk6ICBgYGAgeWFtbCBxdWVyeVRvOiBub3coKSBgYGAiCiAgICAgICAgICB9LAogICAgICAgICAgIm9iamVjdFN0b3JhZ2VOYW1lIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiT2JqZWN0IHN0b3JhZ2UgbG9naWNhbCBuYW1lXG5cbklkZW50aWZpZXMgdGhlIFtPYmplY3QgU3RvcmFnZV0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS8jb2JqZWN0c3RvcmFnZWNsYXNzbmFtZSkgYWdhaW5zdCB3aGljaCB0aGlzIHF1ZXJ5IGlzIG1hZGUgKGUuZy4sIGBBV1NgKS4iCiAgICAgICAgICB9LAogICAgICAgICAgImluZGV4Q29udGFpbmVyIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiT2JqZWN0IHN0b3JhZ2UgY29udGFpbmVyIGNvbnRhaW5pbmcgaW5kZXggb2JqZWN0c1xuXG5TcGVjaWZpZXMgdGhlIG9iamVjdCBzdG9yYWdlIGNvbnRhaW5lciAoZS5nLiwgQVdTIFMzIGJ1Y2tldCkgbmFtZSBpbiB3aGljaCB0byBzdG9yZSBbVGVuWFRlbXBsYXRlIEZpbHRlcnNdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvaW5kZXgvI3Rlbnh0ZW1wbGF0ZS1maWx0ZXJzKScuIFRoaXMgdmFsdWUgY29ycmVzcG9uZHMgd2l0aCB0aGUgW2luZGV4V3JpdGVDb250YWluZXJdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvaW5kZXgpIgogICAgICAgICAgfSwKICAgICAgICAgICJyZWFkQ29udGFpbmVyIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTG9jYXRpb24gb2YgdGhlIG91dHB1dCBmaWxlIGZvciB3cml0aW5nIFRlblhPYmplY3QgZmllbGQgdmFsdWVzXG5cblNwZWNpZmllcyB0aGUgb2JqZWN0IHN0b3JhZ2UgY29udGFpbmVyIChlLmcuLCBTMyBidWNrZXQpIG5hbWUgd2hlcmUgaW5wdXQgb2JqZWN0cyAoZS5nLiwgbG9nIGZpbGUpIHRvIHNjYW4gYXJlIHN0b3JlZC4gVGhpcyB2YWx1ZSBjb3JyZXNwb25kcyB3aXRoIHRoZSBbaW5kZXhXcml0ZUNvbnRhaW5lcl0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9pbmRleCkiCiAgICAgICAgICB9LAogICAgICAgICAgIm9iamVjdFN0b3JhZ2VBcmdzIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJhcnJheSIsCiAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJDdXN0b20gb2JqZWN0IHN0b3JhZ2UgYXJnc1xuXG5DdXN0b20gYXJndW1lbnRzIHBhc3NlZCBhcyBhIG1hcCB0byB0aGUgY29uc3RydWN0b3Igb2YgdGhlIHVuZGVybHlpbmcgW29iamVjdCBzdG9yYWdlXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9vYmplY3RTdG9yYWdlL3F1ZXJ5LyNpbmRleG9iamVjdHN0b3JhZ2VuYW1lKS4gVGhpcyBsaXN0IGlzIGV4cGVjdGVkIHRvIGhvbGQgcGFpcnMgb2Yga2V5IHZhbHVlcyAoZS5nLiwgYXJnczogW2tleTEsIHZhbHVlMSwga2V5MiwgdmFsdWUyXSkiLAogICAgICAgICAgICAiaXRlbXMiIDogewogICAgICAgICAgICAgICJ0eXBlIiA6ICJzdHJpbmciCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAibGltaXQiIDogewogICAgICAgICAgICAidHlwZSIgOiAib2JqZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IGZhbHNlLAogICAgICAgICAgICAicHJvcGVydGllcyIgOiB7CiAgICAgICAgICAgICAgInByb2Nlc3NpbmdUaW1lIiA6IHsKICAgICAgICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJNYXggbWlsbGlzZWNvbmRzIGFsbG90ZWQgZm9yIHRoaXMgcXVlcnlcblxuTWlsbGlzZWNvbmRzIGFsbG90dGVkIGZvciB0aGlzIHF1ZXJ5IHRvIGNvbXBsZXRlLiBPbmNlIHRoaXMgcGVyaW9kIGhhcyBlbGFwc2VkIHRoZSBxdWVyeSB3aWxsIHRlcm1pbmF0ZSByZWdhcmRsZXNzIG9mIHdoZXRoZXIgW3F1ZXJ5TGltaXRSZXN1bHRTaXplXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9vYmplY3RTdG9yYWdlL3F1ZXJ5LyNxdWVyeWxpbWl0cmVzdWx0c2l6ZSkgaGFzIG5vdCBiZWVuIGV4Y2VlZGVkLiIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZXN1bHRTaXplIiA6IHsKICAgICAgICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJNYXggYnl0ZSB2b2x1bWUgb2YgbWF0Y2hpbmcgZXZlbnRzIHRvIGZldGNoXG5cblZvbHVtZSBpbiBieXRlcyBvZiBldmVudHMgbWF0Y2hpbmcgdGhlIGFwcCBwcmVmaXgsIHRlcm1zIGFuZCB0aW1lIHJhbmdlIHRvIGZldGNoLiBPbmNlIHRoaXMgdm9sdW1lIGhhcyBiZWVuIHJlYWNoZWQgdGhlIHF1ZXJ5IHdpbGwgdGVybWluYXRlLiAgSWYgW3F1ZXJ5TGltaXRQcm9jZXNzaW5nVGltZV0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9xdWVyeS8jcXVlcnlsaW1pdHByb2Nlc3Npbmd0aW1lKSBoYXMgZWxhcHNlZCBiZWZvcmUgdGhlIHJlcXVlc3RlZCByZXN1bHQgdm9sdW1lIGhhcyBiZWVuIGZldGNoZWQsIHRoZSBxdWVyeSB3aWxsIHN0aWxsIHRlcm1pbmF0ZS4iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVxdWlyZWQiIDogWwogICAgICAgICAgICAgICJwcm9jZXNzaW5nVGltZSIsCiAgICAgICAgICAgICAgInJlc3VsdFNpemUiCiAgICAgICAgICAgIF0KICAgICAgICAgIH0sCiAgICAgICAgICAic2NhbkZ1bmN0aW9uIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyIgOiBmYWxzZSwKICAgICAgICAgICAgInByb3BlcnRpZXMiIDogewogICAgICAgICAgICAgICJwYXJhbGxlbCIgOiB7CiAgICAgICAgICAgICAgICAidHlwZSIgOiAib2JqZWN0IiwKICAgICAgICAgICAgICAgICJhZGRpdGlvbmFsUHJvcGVydGllcyIgOiBmYWxzZSwKICAgICAgICAgICAgICAgICJwcm9wZXJ0aWVzIiA6IHsKICAgICAgICAgICAgICAgICAgInRpbWVzbGljZSIgOiB7CiAgICAgICAgICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJNYXggdGltZSByYW5nZSB0byBwcm9jZXNzIGJ5IGEgc2NhbiB3b3JrZXIgaW5zdGFuY2VcblxuU3BlY2lmaWVzIHRoZSBtYXggdGltZSBkdXJhdGlvbiAoZS5nLiwgMW1pbikgYW4gaW5zdGFuY2Ugb2YgdGhlIFtzY2FuXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9vYmplY3RTdG9yYWdlL3F1ZXJ5LyNzY2FuKSB3b3JrZXIgd2lsbCB0cmF2ZXJzZSB3aXRoaW4gdGhlIGluZGV4LiBGb3IgZXhhbXBsZSwgaWYgYSBxdWVyeSBzcGVjaWZpZXMgYSB0aW1lIHJhbmdlIG9mIGAxNW1pbmAgYW5kIHRoaXMgdmFsdWUgaXMgc2V0IHRvIGAxbWAsIDE1IGluc3RhbmNlcyBvZiB0aGUgc2NhbiB3b3JrZXIgd2lsbCBleGVjdXRlIGluIHBhcmFsbGVsIHRvIHNjYW4gdGhyb3VnaCB0aGUgaW5kZXguIElmIHRoaXMgdmFsdWUgaXMgMCwgYSBzaW5nbGUgd29ya2VyIGluc3RhbmNlIHdpbGwgc2VxdWVudGlhbGx5IHNjYW4gdGhyb3VnaCB0aGUgaW5kZXguIgogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAibWF4SW5zdGFuY2VzIiA6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAgICAgICAibnVtYmVyIiwKICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTWF4IG51bWJlciBvZiBpbnN0YW5jZXMgb2YgdGhlIHNjYW4gd29ya2VyXG5cblNwZWNpZmllcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgW3NjYW5dKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvcXVlcnkvI3NjYW4pIHdvcmtlciBpbnN0YW5jZXMgdGhhdCB3aWxsIHRyYXZlcnNlIHRoZSBpbmRleC4gaWYgdGhlIHByb3ZpZGVkIHRpbWUgcmFuZ2UgYW5kIFt0aW1lU2xpY2VdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvcXVlcnkvI3F1ZXJ5c2NhbmZ1bmN0aW9ucGFyYWxsZWx0aW1lc2xpY2UpIHByb3ZpZGVkIHdpbGwgcmVzdWx0IGluIG1vcmUgaW5zdGFuY2VzIHRoYW4gdGhlIHByb3ZpZGVkIHZhbHVlLCB0aGUgdGltZSBzbGljZSB3aWxsIGluY3JlYXNlIGl0cyBzaXplIHVudGlsIHRoZSBhbW91bnQgb2Ygd29ya2VycyBuZWVkZWQgd2lsbCBiZSBsZXNzIHRoYW4gdGhpcyB2YWx1ZS4gIEZvciBleGFtcGxlLCBpZiBhIHF1ZXJ5IHNwZWNpZmllcyBhIHRpbWUgcmFuZ2Ugb2YgYDYwbWluYCBhbmQgYSB0aW1lIHNsaWNlIG9mIGAxbWAsIHdoaWxlIHRoaXMgdmFsdWUgaXMgc2V0IHRvIGAyNWAsIHRoZSB0aW1lIHNsaWNlIHdpbGwgYmUgZWZmZWN0aXZlbHkgaW5jcmVhc2VkIHRvIGAzbWAgdG8gYWNjb21tb2RhdGUgdGhpcy4gIFRoZSBtYXhpbXVtIHZhbHVlIGZvciB0aGlzIG9wdGlvbiBpczogMTAsMDAwIChBY2NlcHRzIG51bWJlciBvciBzdHJpbmcgd2l0aCAkPSBwcmVmaXggZm9yIHJ1bnRpbWUgZXZhbHVhdGlvbikgKERlZmF1bHQ6IDEwMDApIiwKICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdCIgOiAxMDAwCiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICJ0aHJlYWRzIiA6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAgICAgICAibnVtYmVyIiwKICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTWF4IG51bWJlciBvZiB0aHJlYWRzIGFsbG9jYXRlZCBwZXIgZWFjaCAnc2Nhbicgd29ya2VyIGluc3RhbmNlXG5cblNldHMgdGhlIG51bWJlciBvZiBKVk0gdGhyZWFkcyB0byBzY2FuIHRocm91Z2ggYSB0aW1lIHNsaWNlIG9mIHRoZSBpbmRleCB3aXRoaW4gYSBbc2Nhbl0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9xdWVyeS8jc2Nhbikgd29ya2VyIGluc3RhbmNlLiBGb3IgZXhhbXBsZSwgaWYgW3RpbWVTbGljZV0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9xdWVyeS8jcXVlcnlzY2FuZnVuY3Rpb25wYXJhbGxlbHRpbWVzbGljZSkgaXMgYDEwbWluYCBhbmQgdGhpcyB2YWx1ZSBpcyBzZXQgdG8gMTAsIHNjYW4gZWFjaCAxbSBpbmRleCB0aW1lIHJhbmdlIHVzaW5nIGEgZGVkaWNhdGVkIHRocmVhZC4gSWYgc2V0IHRvIDEgb3IgMCwgYSBzaW5nbGUgdGhyZWFkIHdpbGwgc2NhbiB0aHJvdWdoIHRoZSBlbnRpcmUgaW5kZXggdGltZSByYW5nZSAoZS5nLiwgMTBtaW4pLiAoQWNjZXB0cyBudW1iZXIgb3Igc3RyaW5nIHdpdGggJD0gcHJlZml4IGZvciBydW50aW1lIGV2YWx1YXRpb24pIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAidXJsIiA6IHsKICAgICAgICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJTY2FuIHdvcmtlciBlbmRwb2ludCBVUkxcblxuU3BlY2lmaWVzIHRoZSBlbmRwb2ludCB1c2VkIHRvIGludm9rZSB0aGUgW3NjYW5dKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvcXVlcnkvI3NjYW4pIHdvcmtlciIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJsaW1pdFJlc3VsdFNpemVJbnRlcnZhbCIgOiB7CiAgICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiSW50ZXJ2YWwgYnkgd2hpY2ggdG8gY2hlY2sgd2hldGhlciAncXVlcnlMaW1pdFJlc3VsdFNpemUnIGlzIGV4Y2VlZGVkXG5cbkludGVydmFsIGJ5IHdoaWNoIHRvIGNoZWNrIHdoZXRoZXIgW3F1ZXJ5TGltaXRSZXN1bHRTaXplXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9vYmplY3RTdG9yYWdlL3F1ZXJ5LyNxdWVyeWxpbWl0cmVzdWx0c2l6ZSkgdGhhdCBpcyB0aGUgcXVlcnkgaGFzIHJldHVybmVkID49IHRoZSByZXF1ZXN0IHJlc3VsdCB2b2x1bWUuIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlcXVpcmVkIiA6IFsKICAgICAgICAgICAgICAidXJsIgogICAgICAgICAgICBdCiAgICAgICAgICB9LAogICAgICAgICAgInNjYW5GbHVzaEludGVydmFsIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiSW50ZXJ2YWwgdG8gd2FpdCBiZWZvcmUgcG9zdGluZyBwZW5kaW5nICdzdHJlYW0nIHdvcmtlciByZXF1ZXN0c1xuXG5TcGVjaWZpZXMgYSBtYXhpbXVtIGludGVydmFsIChlLmcuLCBgMnNlY2ApIHdoZW4gc2Nhbm5pbmcgYW4gaW5kZXggdGltZSBzbGljZSB0byB3YWl0IHRvIHN1Ym1pdCBwZW5kaW5nIFtzdHJlYW1dKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvcXVlcnkvI3N0cmVhbSkgd29ya2VyIHJlcXVlc3RzLiBJZiBub3Qgc2V0LCBhbGwgc3RyZWFtIHdvcmtlciByZXF1ZXN0cyBhcmUgc2VudCBhZnRlciB0aGUgaW5kZXggc2Nhbm5pbmcgcHJvY2VzcyBmb3IgYSB0YXJnZXQgaW5kZXggdGltZSBzbGljZSBoYXMgZmluaXNoZWQuIgogICAgICAgICAgfSwKICAgICAgICAgICJzdHJlYW1GdW5jdGlvbiIgOiB7CiAgICAgICAgICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogZmFsc2UsCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIiA6IHsKICAgICAgICAgICAgICAicGFyYWxsZWwiIDogewogICAgICAgICAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogZmFsc2UsCiAgICAgICAgICAgICAgICAicHJvcGVydGllcyIgOiB7CiAgICAgICAgICAgICAgICAgICJvYmplY3RzIiA6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAgICAgICAibnVtYmVyIiwKICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTWF4IG51bWJlciBvZiBpbnB1dCBvYmplY3QgYnl0ZSByYW5nZXMgdG8gcHJvY2VzcyBpbiBhIHNpbmdsZSAnc3RyZWFtJyBpbnN0YW5jZVxuXG5EZWZpbmVzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBTdG9yYWdlIG9iamVjdHMgdG8gcHJvY2VzcyBieSBhIHNpbmdsZSBpbnN0YW5jZSBvZiB0aGUgW3N0cmVhbV0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9xdWVyeS8jc3RyZWFtKSB3b3JrZXIuICBGb3IgZXhhbXBsZSwgaWYgc2V0IHRvIDUwIGFuZCB0aGUgW3NjYW5dKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvcXVlcnkvI3NjYW4pIHBoYXNlIGhhcyBpZGVudGlmaWVkIDIwMCBwb3RlbnRpYWxseSBtYXRjaGluZyBpbnB1dCBvYmplY3QgYnl0ZSByYW5nZXMsIGZvdXIgaW5zdGFuY2VzIG9mIHRoZSBzdHJlYW0gd29ya2VyIHdpbGwgc3BsaXQgdGhlIHdvcmtsb2FkIGluIHBhcmFsbGVsLiAoQWNjZXB0cyBudW1iZXIgb3Igc3RyaW5nIHdpdGggJD0gcHJlZml4IGZvciBydW50aW1lIGV2YWx1YXRpb24pIgogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAiYnl0ZVJhbmdlIiA6IHsKICAgICAgICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIk1heCBpbnB1dCBvYmplY3QgYnl0ZXMgZm9yIGEgc2luZ2xlIGZldGNoIHJlcXVlc3RcblxuRGVmaW5lcyB0aGUgbWF4IGJ5dGUgcmFuZ2Ugd2l0aGluIGFuIGlucHV0IG9iamVjdCAoZS5nLiwgbG9nIGZpbGUpIHRoYXQgY2FuIGZldGNoZWQgdmlhIGEgc2luZ2xlIHJlcXVlc3QuIEZvciBleGFtcGxlLCBpZiB0aGlzIHZhbHVlIGlzIGA1TWJgIGFuZCB0d28gbWF0Y2hpbmcgMU1iIGJ5dGUgcmFuZ2VzIHNwYWNlZCAyTWIgYXBhcnQgYXJlIGlkZW50aWZpZWQgd2l0aGluIGEgdGFyZ2V0IG9iamVjdCBmZXRjaCBib3RoIGZyb20gdGhlIHN0b3JhZ2UgdmlhIGEgc2luZ2xlIG9wZXJhdGlvbi4gSWYgdGhlcmUgaXMgYSAyTWIgZ2FwLCBsYXVuY2ggdHdvIGluc3RhbmNlcyBvZiB0aGUgW3N0cmVhbV0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvb2JqZWN0U3RvcmFnZS9xdWVyeS8jc3RyZWFtKSB3b3JrZXIuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInJlcXVpcmVkIiA6IFsKICAgICAgICAgICAgICAgICAgImJ5dGVSYW5nZSIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJ1cmwiIDogewogICAgICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlN0cmVhbSB3b3JrZXIgZW5kcG9pbnQgVVJMXG5cblNwZWNpZmllcyB0aGUgZW5kcG9pbnQgdXNlZCB0byBpbnZva2UgdGhlIFtzdHJlYW1dKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2lucHV0L29iamVjdFN0b3JhZ2UvcXVlcnkvI3N0cmVhbSkgd29ya2VyIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlcXVpcmVkIiA6IFsKICAgICAgICAgICAgICAidXJsIgogICAgICAgICAgICBdCiAgICAgICAgICB9LAogICAgICAgICAgImZpbHRlciIgOiB7CiAgICAgICAgICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogZmFsc2UsCiAgICAgICAgICAgICJwcm9wZXJ0aWVzIiA6IHsKICAgICAgICAgICAgICAidmFycyIgOiB7CiAgICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAgICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiU3BlY2lmaWVzIGEgbGlzdCBvZiB2YXJpYWJsZSB2YWx1ZXMgdG8gc2NhbiBmb3JcblxuU3BlY2lmaWVzIGEgbGlzdCBvZiB2YXJpYWJsZSB2YWx1ZXMgdG8gc2NhbiBmb3IiLAogICAgICAgICAgICAgICAgIml0ZW1zIiA6IHsKICAgICAgICAgICAgICAgICAgInR5cGUiIDogInN0cmluZyIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJ0ZW1wbGF0ZUhhc2hlcyIgOiB7CiAgICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAgICJhcnJheSIsCiAgICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiU3BlY2lmaWVzIGEgbGlzdCBvZiBUZW5YVGVtcGxhdGUgaGFzaCB2YWx1ZXMgdG8gc2NhbiBmb3JcblxuU3BlY2lmaWVzIGEgbGlzdCBvZiBUZW5YVGVtcGxhdGUgaGFzaCB2YWx1ZXMgdG8gc2NhbiBmb3IiLAogICAgICAgICAgICAgICAgIml0ZW1zIiA6IHsKICAgICAgICAgICAgICAgICAgInR5cGUiIDogInN0cmluZyIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAiaWQiIDogewogICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJVbmlxdWUgSUQgb2YgaG9zdCBxdWVyeVxuXG5VVUlEIGlkZW50aWZ5aW5nIHRoaXMgcXVlcnkuIFRoaXMgdmFsdWUgaXMgYXV0b21hdGljYWxseSBhc3NpZ25lZCBpZiBub3QgZXhwbGljaXRseSBzZXQuIgogICAgICAgICAgfSwKICAgICAgICAgICJlbGFwc2VUaW1lIiA6IHsKICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICJudW1iZXIiLAogICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICBdLAogICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiRXBvY2ggYWZ0ZXIgd2hpY2ggcHJvY2Vzc2luZyB0aW1lcyBvdXRcblxuRXBvY2ggdmFsdWUgd2hpY2ggaWYgZXhjZWVkcyB0aGUgY3VycmVudCBzeXN0ZW0gdGltZSB3aWxsIHJlc3VsdCBpbiB0aGlzIHJlcXVlc3QgYmVpbmcgY2FuY2VsbGVkIChBY2NlcHRzIG51bWJlciBvciBzdHJpbmcgd2l0aCAkPSBwcmVmaXggZm9yIHJ1bnRpbWUgZXZhbHVhdGlvbikiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmVxdWlyZWQiIDogWwogICAgICAgICAgInRhcmdldCIsCiAgICAgICAgICAiZnJvbSIsCiAgICAgICAgICAidG8iLAogICAgICAgICAgIm9iamVjdFN0b3JhZ2VOYW1lIiwKICAgICAgICAgICJpbmRleENvbnRhaW5lciIsCiAgICAgICAgICAicmVhZENvbnRhaW5lciIKICAgICAgICBdCiAgICAgIH0KICAgIH0KICB9LAogICJhZGRpdGlvbmFsUHJvcGVydGllcyIgOiB0cnVlCn0=</template>

```yaml
# 🔟❎ 'run' Object storage query AWS S3 configuration

# Configure query AWS S3 bucket settings
# To learn more see https://doc.log10x.com/run/input/objectStorage/query/

# Set the 10x pipeline to 'run'
tenx: run

# =============================== Dependencies ================================

include:
  - run/modules/input/objectStorage/input
  - run/modules/input/objectStorage/query

# =============================== Query Options ===============================

query:

    # 'name' specifies a logical name associated with this query
  - name: my-query

    # 'readPrintProgress' sets whether this input prints throughput stats to the console
    readPrintProgress: $=!TenXEnv.get("quiet")

    # ---------------------------- Storage Options ----------------------------

    # 'objectStorage' selects the underlying storage (e.g., S3). To learn more see: https://doc.log10x.com/run/input/objectStorage

    # 'objectStorageName' selects the storage accessor alias registered by 'objectStorageClassName' (AWS or Azure).
    #  Set TENX_OBJECT_STORAGE_NAME to Azure to target Azure Blob Storage. Defaults to AWS.

    # AWS authentication is made via the default provider credentials chain:
    # https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html

    # AWS region selection is made via the default region provider chain:
    # https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/regions/providers/DefaultAwsRegionProviderChain.html

    # Azure resolves the storage account from the first segment of 'indexContainer' (account/container/path),
    # or from AZURE_STORAGE_ACCOUNT when 'indexContainer' is container/path. 'readContainer' is a bare container name.

    objectStorageName: $=TenXEnv.get("TENX_OBJECT_STORAGE_NAME", "AWS")

    # 'readContainer' specifies the container (e.g., S3 bucket, Azure Blob container) in which to search
    readContainer: $=TenXEnv.get("TENX_STREAMER_INPUT_BUCKET", "")  # (❗ REQUIRED)

    # 'indexContainer' specifies the container (e.g., S3 bucket, Azure account/container/path) in which index objects created by the 'index' module reside.
    indexContainer: $=TenXEnv.get("TENX_STREAMER_INDEX_BUCKET", "") # (❗ REQUIRED)

    # ----------------------------- Search Options ----------------------------

    # 'target' specifies a user app/service name (e.g., 'acme-client') to search in.
    target: app          # (❗ REQUIRED)

    # 'from' sets the query's beginning epoch time range (inclusive).
    #  The 'now' function returns the current epoch value with an optional positive/negative offset.
    from: now("-5m")   # (❗ REQUIRED)

    # 'to' sets the end epoch time range (exclusive), must be greater than 'from'.
    to: now()          # (❗ REQUIRED)

    # 'search' Specifies a search expression applied to raw events in the underlying storage 
    #  Supports basic operations: `&&` (AND), `||` (OR), == (equality), and includes(field, text) (substring match).
    search: (severity_level == "ERROR") || (severity_level == "FATAL")
    
    # 'id' specifies a unique query identifier. Automatically assigned if not set.
    id: ""

    # 'logLevels' specifies which log levels are sent to CloudWatch Logs for query progress tracking.
    #  Default (when empty): ERROR, INFO, PERF. Set to include DEBUG for diagnostic output.
    #  NOTE: PERF is required for console progress tracking (gauges, completion detection).
    #  Disabling it will cause the console to not detect query completion.
    logLevels: ""

    # 'logGroup' specifies the CloudWatch Logs log group for query event logging.
    #  The log group must be pre-created (e.g. by Terraform). If empty, query event logging is disabled.
    logGroup: $=TenXEnv.get("TENX_QUERY_LOG_GROUP", "")

    # 'writeResults' gates the stream pipeline's JSONL results writer, which
    #  buffers matched TenXObjects to object storage under
    #  `{indexObjectPath(queryResults)}/{queryId}/{sliceFrom}_{sliceTo}/*.jsonl`
    #  alongside the byte-count marker backstop used by the query coordinator.
    #  Defaults to false so the extra JSONL upload only runs when a caller
    #  explicitly opts in. Out-of-band consumers like the Log10x MCP server
    #  pass `writeResults=true` on their query request to retrieve full event
    #  payloads from S3; other deployments leave this off to avoid the
    #  results-writer overhead.
    writeResults: false

    # 'writeSummaries' gates the stream pipeline's JSONL summaries writer
    #  (TenXSummary records produced by run/aggregate/stream). Defaults to
    #  false. When true, per-slice summaries are buffered to object storage
    #  under `{indexObjectPath(querySummaries)}/{queryId}/{sliceFrom}_{sliceTo}/*.jsonl`
    #  so consumers can fetch a low-volume per-slice rollup (count, bytesum,
    #  grouping fields) for high-cardinality patterns instead of pulling
    #  raw events. Independent of `writeResults`; either can be on in
    #  isolation or both together.
    writeSummaries: false

    # 'filters' specify expressions TenXObjects transformed from matching events in storage must meet.
    # The `$?queryFilters` macro lets the CLI/REST `queryFilters` override
    # plumb through to the worker pipeline. With ACCEPT_SINGLE_VALUE_AS_ARRAY
    # in the engine's Jackson config, a single-string override value also
    # hydrates into the List<String> queryFilters field correctly.
    #  To learn more see https://doc.log10x.com/run/output/receive/#filter-expressions
    filters: $?queryFilters

    # ----------------------------- Limit Options ------------------------------

    # 'limit' options caps the query's processing time and volume of results it will return
    limit:

      # 'processingTime' specifies the time in ms allotted for this query to complete.
      #  Once this period has elapsed the query will terminate regardless of
      #  whether 'resultSize' has not been exceeded.
      processingTime: parseDuration("1m")

      # 'resultSize' specifies the volume in bytes of events matching the target app name, terms and time range to fetch.
      #  Once this volume has been reached the query will terminate.
      resultSize: parseBytes("10MB")

```

## :material-menu: Options

Specify the options below to [configure](/config "configure") multiple Object storage query input:

|Name|Description|Category|
|---|---|---|
|[queryName](#queryname "logical name for the query")|Logical name for the query|General|
|[queryReadPrintProgress](#queryreadprintprogress "sets whether this input prints throughput stats to the console")|Sets whether this input prints throughput stats to the console|General|
|[queryLogLevels](#queryloglevels "log levels to send to CloudWatch Logs for query progress tracking")|Log levels to send to CloudWatch Logs for query progress tracking|General|
|[queryLogGroup](#queryloggroup "CloudWatch Logs log group for query event logging")|CloudWatch Logs log group for query event logging|General|
|[queryWriteResults](#querywriteresults "sets whether matched events are buffered to JSONL and uploaded to object storage")|Sets whether matched events are buffered to JSONL and uploaded to object storage|General|
|[queryWriteSummaries](#querywritesummaries "sets whether per-slice TenXSummary aggregates are buffered to JSONL and uploaded")|Sets whether per-slice TenXSummary aggregates are buffered to JSONL and uploaded|General|
|[queryTarget](#querytarget "logical prefix to filter index objects by")|Logical prefix to filter index objects by|Filter|
|[queryResultTarget](#queryresulttarget "optional Tier-1 result-sink redirect prefix for query OUTPUT")|Optional Tier-1 result-sink redirect prefix for query OUTPUT|Filter|
|[querySearch](#querysearch "list of terms to search for")|List of terms to search for|Filter|
|[queryFilters](#queryfilters "list of terms to search for")|List of terms to search for|Filter|
|[queryFrom](#queryfrom "beginning of the search time range (inclusive)")|Beginning of the search time range (inclusive)|Filter|
|[queryTo](#queryto "end of the search time range (exclusive)")|End of the search time range (exclusive)|Filter|
|[queryObjectStorageName](#queryobjectstoragename "object storage logical name")|Object storage logical name|Access|
|[queryIndexContainer](#queryindexcontainer "Object storage container containing index objects")|Object storage container containing index objects|Scan|
|[queryScanFunctionParallelTimeslice](#queryscanfunctionparalleltimeslice "max time range to process by a scan worker instance")|Max time range to process by a scan worker instance|Scan|
|[queryScanFunctionParallelMaxInstances](#queryscanfunctionparallelmaxinstances "max number of instances of the scan worker")|Max number of instances of the scan worker|Scan|
|[queryScanFunctionParallelThreads](#queryscanfunctionparallelthreads "max number of threads allocated per each 'scan' worker instance")|Max number of threads allocated per each 'scan' worker instance|Scan|
|[queryScanFlushInterval](#queryscanflushinterval "interval to wait before posting pending 'stream' worker requests")|Interval to wait before posting pending 'stream' worker requests|Scan|
|[queryScanFunctionUrl](#queryscanfunctionurl "scan worker endpoint URL")|Scan worker endpoint URL|Scan|
|[queryReadContainer](#queryreadcontainer "location of the output file for writing TenXObject field values")|Location of the output file for writing TenXObject field values|Stream|
|[queryStreamFunctionParallelObjects](#querystreamfunctionparallelobjects "max number of input object byte ranges to process in a single 'stream' instance")|Max number of input object byte ranges to process in a single 'stream' instance|Stream|
|[queryStreamFunctionParallelByteRange](#querystreamfunctionparallelbyterange "max input object bytes for a single fetch request")|Max input object bytes for a single fetch request|Stream|
|[queryStreamFunctionUrl](#querystreamfunctionurl "stream worker endpoint URL")|Stream worker endpoint URL|Stream|
|[queryObjectStorageArgs](#queryobjectstorageargs "custom object storage args")|Custom object storage args|Advanced|
|[queryFilterVars](#queryfiltervars "specifies a list of variable values to scan for")|Specifies a list of variable values to scan for|Advanced|
|[queryFilterTemplateHashes](#queryfiltertemplatehashes "specifies a list of TenXTemplate hash values to scan for")|Specifies a list of TenXTemplate hash values to scan for|Advanced|
|[queryId](#queryid "unique ID of host query")|Unique ID of host query|Advanced|
|[queryElapseTime](#queryelapsetime "epoch after which processing times out")|Epoch after which processing times out|Advanced|
|[queryScanFunctionLimitResultSizeInterval](#queryscanfunctionlimitresultsizeinterval "interval by which to check whether 'queryLimitResultSize' is exceeded")|Interval by which to check whether 'queryLimitResultSize' is exceeded|Advanced|
|[queryLimitProcessingTime](#querylimitprocessingtime "max milliseconds alloted for this query")|Max milliseconds alloted for this query|Limit|
|[queryLimitResultSize](#querylimitresultsize "max byte volume of matching events to fetch")|Max byte volume of matching events to fetch|Limit|

### General

#### :material-menu-right-outline:**`queryName`**

Logical name for the query.

|Type|Default|Category|
|---|---|---|
|String|""|General|

Specifies a logical name associated with the query (e.g., `errorsQuery`)
This value identifies this query operation in aggregated metrics reports.
If not specified, defaults to a concatenation of [queryTarget](https://doc.log10x.com/run/input/objectStorage/query/#querytarget "logical prefix to filter index objects by") and [querySearch](https://doc.log10x.com/run/input/objectStorage/query/#querysearchs).


#### :material-menu-right-outline:**`queryReadPrintProgress`**

Sets whether this input prints throughput stats to the console.

|Type|Default|Category|
|---|---|---|
|Boolean|false|General|

Sets whether this input prints throughput stats to the console
This value is commonly used when testing an integration to a remote endpoint.


#### :material-menu-right-outline:**`queryLogLevels`**

Log levels to send to CloudWatch Logs for query progress tracking.

|Type|Default|Category|
|---|---|---|
|String|""|General|

Specifies which query event log levels are sent to CloudWatch Logs for tracking query progress.
Valid values: `ERROR`, `INFO`, `DEBUG`, `PERF`.

If not specified, defaults to `ERROR`, `INFO`, `PERF`.

**Note:** `PERF` is required for console progress tracking (gauges, completion detection).
Disabling it will cause the console to not detect query completion.

```yaml
queryLogLevels: ERROR,INFO,PERF
```


#### :material-menu-right-outline:**`queryLogGroup`**

CloudWatch Logs log group for query event logging.

|Type|Default|Category|
|---|---|---|
|String|""|General|

Specifies the CloudWatch Logs log group name for logging query lifecycle events.
The log group must be pre-created (e.g. by Terraform). If not specified or empty,
query event logging is disabled.

```yaml
queryLogGroup: /log10x/query
```


#### :material-menu-right-outline:**`queryWriteResults`**

Sets whether matched events are buffered to JSONL and uploaded to object storage.

|Type|Default|Category|
|---|---|---|
|Boolean|false|General|

Controls whether the stream pipeline launches the JSONL results writer
in addition to the byte-count marker backstop used by the query
coordinator.

Defaults to `false` so the extra JSONL upload only runs when a caller
explicitly opts in. The query coordinator forwards this flag to each
stream worker it dispatches via a `queryObjectWriteResults=<value>`
bootstrap arg on the stream pipeline launch.

Out-of-band consumers like the Log10x MCP server set this to `true`
so they can retrieve full event payloads from S3 under
`{indexObjectPath(queryResults)}/{queryId}/{sliceFrom}_{sliceTo}/*.jsonl`.
Deployments that only rely on the coordinator's numeric-key poll
leave this off.

```yaml
queryWriteResults: true
```


#### :material-menu-right-outline:**`queryWriteSummaries`**

Sets whether per-slice TenXSummary aggregates are buffered to JSONL and uploaded.

|Type|Default|Category|
|---|---|---|
|Boolean|false|General|

Controls whether the stream pipeline launches a TenXSummary-mode
results writer in addition to the events writer (gated by
`queryWriteResults`) and the byte-count marker backstop.

Defaults to `false`. The query coordinator forwards this flag to each
stream worker it dispatches via a `queryObjectWriteSummaries=<value>`
bootstrap arg on the stream pipeline launch.

When set to `true`, per-slice aggregated summaries (count, bytesum,
grouping fields produced by `run/aggregate/stream`) are written to
`{indexObjectPath(querySummaries)}/{queryId}/{sliceFrom}_{sliceTo}/*.jsonl`.
Consumers (e.g. log10x\_pattern\_trend, log10x\_top\_patterns) can poll
these per-slice summaries to render time-spread results for high-cardinality
patterns without paying the bandwidth cost of full event JSONL.

Independent of `queryWriteResults`; either can be on in isolation
or both together.

```yaml
queryWriteSummaries: true
```


### Filter

#### :material-menu-right-outline:**`queryTarget`**

Logical prefix to filter index objects by.

|Type|Required|Category|
|---|---|---|
|String|✔|Filter|

Specifies a logical name associated with the search target.
This value identifies the app that produced the queried events (e.g., `acme-client`).

This value corresponds with the [indexWriteTarget](https://doc.log10x.com/run/input/objectStorage/index/#indexwritetarget "logical name identifying the origin of 'indexReadObject'") argument.


#### :material-menu-right-outline:**`queryResultTarget`**

Optional Tier-1 result-sink redirect prefix for query OUTPUT.

|Type|Default|Category|
|---|---|---|
|String|""|Filter|

Optional bare-token prefix under which query RESULT objects
(`qr/`, `qrs/`, `q/` markers, `_DONE.json`) are written, inside the
SAME index container as `queryTarget`. When omitted or blank, results
are written under `queryTarget`, byte-identical to legacy behavior.
Must match `[A-Za-z0-9_-]+` (no slashes, separators, or `..`); a
violating value fails the query closed. The READ path for the durable
index (templates, byte ranges, reverse index) is unaffected and always
uses `queryTarget`.


#### :material-menu-right-outline:**`querySearch`**

List of terms to search for.

|Type|Default|Category|
|---|---|---|
|String|""|Filter|

Specifies a search expression applied to the underlying storage via [TenXTemplate filters](https://doc.log10x.com/run/input/objectStorage/index/#tenxtemplate-filters) for efficient pre-filtering.
Supports only basic operations: `&&` (AND), `||` (OR), == (equality), and [includes](https://doc.log10x.com/api/js/#TenXString.includes) (substring match).

Example:

```js
(level==INFO || level==WARN) && includes(text, "POST")
```

This narrows down data fetched from storage before in-memory processing.
To perform more complex in-memory filtering, specify [queryFilters](https://doc.log10x.com/run/input/objectStorage/query/#queryfilters "list of terms to search for").


#### :material-menu-right-outline:**`queryFilters`**

List of terms to search for.

|Type|Default|Category|
|---|---|---|
|List|\[\]|Filter|

Specifies JavaScript expressions applied in-memory to all TenXObjects that match the [querySearch](https://doc.log10x.com/run/input/objectStorage/query/#querysearch "list of terms to search for") expression.

Supports all valid [TenX JavaScript](https://doc.log10x.com/api/js/) expressions for complex filtering, enrichment, and processing.

This provides precise, exact filtering after data is fetched from storage.

```yaml
queryFilters:
  - LevelTemplate.level == "ERROR" 
  - Math.max(this.price, 100)
```


#### :material-menu-right-outline:**`queryFrom`**

Beginning of the search time range (inclusive).

|Type|Required|Category|
|---|---|---|
|String|✔|Filter|

defines the beginning of the search time range (inclusive) expressed as a UNIX millisecond epoch value.

This value commonly uses the [now](https://doc.log10x.com/api/js/#TenXDate.now) function.

For example, to express the value of one hour before the current millisecond epoch, specify:

```yaml
queryFrom: now("-1h")
```


#### :material-menu-right-outline:**`queryTo`**

End of the search time range (exclusive).

|Type|Required|Category|
|---|---|---|
|String|✔|Filter|

defines the end of the search time range expressed as a UNIX millisecond epoch value (exclusive).

This value commonly uses the [now](https://doc.log10x.com/api/js/#TenXDate.now) function.

For example, to express the value of the current millisecond epoch, specify:

```yaml
queryTo: now()
```


### Access

#### :material-menu-right-outline:**`queryObjectStorageName`**

Object storage logical name.

|Type|Required|Category|
|---|---|---|
|String|✔|Access|

Identifies the [Object Storage](https://doc.log10x.com/run/input/objectStorage/#objectstorageclassname) against which this query is made (e.g., `AWS`).


### Scan

#### :material-menu-right-outline:**`queryIndexContainer`**

Object storage container containing index objects.

|Type|Required|Category|
|---|---|---|
|String|✔|Scan|

Specifies the object storage container (e.g., AWS S3 bucket) name in which to store [TenXTemplate Filters](https://doc.log10x.com/run/input/objectStorage/index/#tenxtemplate-filters)'.

This value corresponds with the [indexWriteContainer](https://doc.log10x.com/run/input/objectStorage/index "Index files uploaded to a object storage container (e.g. AWS S3 bucket).").


#### :material-menu-right-outline:**`queryScanFunctionParallelTimeslice`**

Max time range to process by a scan worker instance.

|Type|Default|Category|
|---|---|---|
|String|""|Scan|

Specifies the max time duration (e.g., 1min) an instance of the [scan](https://doc.log10x.com/run/input/objectStorage/query/#scan) worker will traverse within the index.
For example, if a query specifies a time range of `15min` and this value is set to `1m`, 15 instances of the scan
worker will execute in parallel to scan through the index.
If this value is 0, a single worker instance will sequentially scan through the index.


#### :material-menu-right-outline:**`queryScanFunctionParallelMaxInstances`**

Max number of instances of the scan worker.

|Type|Default|Category|
|---|---|---|
|Number|1000|Scan|

Specifies the maximum number of [scan](https://doc.log10x.com/run/input/objectStorage/query/#scan) worker instances that will traverse the index.
if the provided time range and [timeSlice](https://doc.log10x.com/run/input/objectStorage/query/#queryscanfunctionparalleltimeslice "max time range to process by a scan worker instance") provided will result in more instances than the
provided value, the time slice will increase its size until the amount of workers needed
will be less than this value.

For example, if a query specifies a time range of `60min` and a time slice of `1m`, while this
value is set to `25`, the time slice will be effectively increased to `3m` to accommodate this.

The maximum value for this option is: 10,000.


#### :material-menu-right-outline:**`queryScanFunctionParallelThreads`**

Max number of threads allocated per each 'scan' worker instance.

|Type|Default|Category|
|---|---|---|
|Number|0|Scan|

Sets the number of JVM threads to scan through a time slice of the index within a [scan](https://doc.log10x.com/run/input/objectStorage/query/#scan) worker instance.
For example, if [timeSlice](https://doc.log10x.com/run/input/objectStorage/query/#queryscanfunctionparalleltimeslice "max time range to process by a scan worker instance") is `10min` and this value is set to 10,
scan each 1m index time range using a dedicated thread.
If set to 1 or 0, a single thread will scan through the entire index time range (e.g., 10min).


#### :material-menu-right-outline:**`queryScanFlushInterval`**

Interval to wait before posting pending 'stream' worker requests.

|Type|Default|Category|
|---|---|---|
|String|""|Scan|

Specifies a maximum interval (e.g., `2sec`) when scanning an index time slice to wait
to submit pending [stream](https://doc.log10x.com/run/input/objectStorage/query/#stream) worker requests.
If not set, all stream worker requests are sent after the index scanning process for a target index time slice has finished.


#### :material-menu-right-outline:**`queryScanFunctionUrl`**

Scan worker endpoint URL.

|Type|Required|Category|
|---|---|---|
|String|✔|Scan|

Specifies the endpoint used to invoke the [scan](https://doc.log10x.com/run/input/objectStorage/query/#scan) worker.


### Stream

#### :material-menu-right-outline:**`queryReadContainer`**

Location of the output file for writing TenXObject field values.

|Type|Required|Category|
|---|---|---|
|String|✔|Stream|

Specifies the object storage container (e.g., S3 bucket) name where input objects (e.g., log file) to scan are stored.

This value corresponds with the [indexWriteContainer](https://doc.log10x.com/run/input/objectStorage/index "Index files uploaded to a object storage container (e.g. AWS S3 bucket).").


#### :material-menu-right-outline:**`queryStreamFunctionParallelObjects`**

Max number of input object byte ranges to process in a single 'stream' instance.

|Type|Default|Category|
|---|---|---|
|Number|0|Stream|

Defines the maximum number of Storage objects to process
by a single instance of the [stream](https://doc.log10x.com/run/input/objectStorage/query/#stream) worker.

For example, if set to 50 and the [scan](https://doc.log10x.com/run/input/objectStorage/query/#scan) phase
has identified 200 potentially matching input object byte ranges,
four instances of the stream worker will split the workload in parallel.


#### :material-menu-right-outline:**`queryStreamFunctionParallelByteRange`**

Max input object bytes for a single fetch request.

|Type|Required|Category|
|---|---|---|
|String|✔|Stream|

Defines the max byte range within an input object (e.g., log file) that can fetched via a single request.

For example, if this value is `5Mb` and two matching 1Mb
byte ranges spaced 2Mb apart are identified within a target object
fetch both from the storage via a single operation.
If there is a 2Mb gap, launch two instances of the [stream](https://doc.log10x.com/run/input/objectStorage/query/#stream) worker.


#### :material-menu-right-outline:**`queryStreamFunctionUrl`**

Stream worker endpoint URL.

|Type|Required|Category|
|---|---|---|
|String|✔|Stream|

Specifies the endpoint used to invoke the [stream](https://doc.log10x.com/run/input/objectStorage/query/#stream) worker.


### Advanced

#### :material-menu-right-outline:**`queryObjectStorageArgs`**

Custom object storage args.

|Type|Default|Category|
|---|---|---|
|List|\[\]|Advanced|

Custom arguments passed as a map to the constructor of the underlying [object storage](https://doc.log10x.com/run/input/objectStorage/query/#indexobjectstoragename).
This list is expected to hold pairs of key values (e.g., args: \[key1, value1, key2, value2\]).


#### :material-menu-right-outline:**`queryFilterVars`**

Specifies a list of variable values to scan for.

|Type|Default|Category|
|---|---|---|
|List|\[\]|Advanced|

Specifies a list of variable values to scan for.


#### :material-menu-right-outline:**`queryFilterTemplateHashes`**

Specifies a list of TenXTemplate hash values to scan for.

|Type|Default|Category|
|---|---|---|
|List|\[\]|Advanced|

Specifies a list of TenXTemplate hash values to scan for.


#### :material-menu-right-outline:**`queryId`**

Unique ID of host query.

|Type|Default|Category|
|---|---|---|
|String|""|Advanced|

UUID identifying this query. This value is automatically assigned if not explicitly set.


#### :material-menu-right-outline:**`queryElapseTime`**

Epoch after which processing times out.

|Type|Default|Category|
|---|---|---|
|Number|0|Advanced|

Epoch value which if exceeds the current system time will result in this request being cancelled.


#### :material-menu-right-outline:**`queryScanFunctionLimitResultSizeInterval`**

Interval by which to check whether 'queryLimitResultSize' is exceeded.

|Type|Default|Category|
|---|---|---|
|String|""|Advanced|

Interval by which to check whether [queryLimitResultSize](https://doc.log10x.com/run/input/objectStorage/query/#querylimitresultsize "max byte volume of matching events to fetch")
that is the query has returned \>= the request result volume.


### Limit

#### :material-menu-right-outline:**`queryLimitProcessingTime`**

Max milliseconds alloted for this query.

|Type|Required|Category|
|---|---|---|
|String|✔|Limit|

Milliseconds allotted for this query to complete. Once this period has elapsed the query will terminate regardless of
whether [queryLimitResultSize](https://doc.log10x.com/run/input/objectStorage/query/#querylimitresultsize "max byte volume of matching events to fetch") has not been exceeded.


#### :material-menu-right-outline:**`queryLimitResultSize`**

Max byte volume of matching events to fetch.

|Type|Required|Category|
|---|---|---|
|String|✔|Limit|

Volume in bytes of events matching the app prefix, terms and time range to fetch.
Once this volume has been reached the query will terminate.

If [queryLimitProcessingTime](https://doc.log10x.com/run/input/objectStorage/query/#querylimitprocessingtime "max milliseconds alloted for this query") has elapsed before the requested result volume has been fetched, the query will still terminate.


<br/>:material-github: This module is defined in [query/module.yaml](https://github.com/log-10x/modules/tree/main/pipelines/run/modules/input/objectStorage/query/module.yaml "query/module.yaml"){target="\_blank"}.

