From 29caf98e72991cc986f4643a9ff9f94e787ef5ee Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Mon, 25 May 2026 10:58:23 -0700 Subject: [PATCH 01/12] integration of test suite (Moshe's origianl content) + quick start (from Mark's ppt) Signed-off-by: Ori Shadmon --- .github/scripts/navigation.py | 2 + _config.yml | 6 + _docs/Getting-Started/quick-start.md | 153 +++++++++++ _docs/Tools-UI/test-suite.md | 368 +++++++++++++++++++++++++++ 4 files changed, 529 insertions(+) create mode 100644 _docs/Getting-Started/quick-start.md create mode 100644 _docs/Tools-UI/test-suite.md diff --git a/.github/scripts/navigation.py b/.github/scripts/navigation.py index b26c5c0..f6bf457 100644 --- a/.github/scripts/navigation.py +++ b/.github/scripts/navigation.py @@ -1,5 +1,6 @@ ITEM_ORDER = { "Getting Started": [ + "quick-start" "getting-started", "installing-anylog", "install-ova", @@ -67,6 +68,7 @@ ], "Reference": [ "FAQ", + "test-suite", "troubleshooting" ], } \ No newline at end of file diff --git a/_config.yml b/_config.yml index 382bce0..6cd08c0 100644 --- a/_config.yml +++ b/_config.yml @@ -48,6 +48,9 @@ nav: - slug: Getting-Started/deployment-scripts title: Deployment Scripts file: Getting-Started/deployment-scripts.md + - slug: Getting-Started/quick-start + title: Quick Deployment + file: Getting-Started/quick-start.md - title: CLI items: - slug: CLI/AnyLog-CLI @@ -186,6 +189,9 @@ nav: - slug: Tools-UI/remote-gui title: Remote GUI file: Tools-UI/remote-gui.md + - slug: Tools-UI/test-suite + title: Test Suites + file: Tools-UI/test-suite.md - title: Version Control items: - slug: Version-Control/SOURCE-CHANGELOGS diff --git a/_docs/Getting-Started/quick-start.md b/_docs/Getting-Started/quick-start.md new file mode 100644 index 0000000..1857a49 --- /dev/null +++ b/_docs/Getting-Started/quick-start.md @@ -0,0 +1,153 @@ +--- +title: Quick Deployment +description: Deploy a minimal AnyLog network (Master, Query, two Operators) using Docker Compose. +layout: page +--- + + +Using the [deployment scripts](https://github.com/AnyLog-co/deployment-scripts), users can configure nodes with +custom port values, naming conventions, MQTT settings, and more. For cases where you just need a running network +quickly, each node type ships with a ready-made `docker-compose.yaml` that requires only minimal environment +configuration. + +**Other deployments:** +- [Training](../training) — Standard training environment for learning AnyLog +- [Configuration Based](../deployments/deploying_node.md) — Deploy using a config file with environment variables +- [Empty Node](deploying_node.md) — Manually deploy and configure an AnyLog node from scratch + +--- + +## Prerequisites + +- Docker and Docker Compose installed +- AnyLog Docker Hub credentials and an active license key — [contact us](mailto:info@anylog.co) if you need access +- All nodes on the same machine, **or** the Master node's TCP connection info (`get connections`) if deploying across machines + +--- + +## Deployment + +The following steps bring up a minimal network: one Master, one Query, and two Operator nodes. +Run each step in its own terminal so you can detach and leave the container running. + +> **Multi-machine note:** if any node runs on a different machine from the Master, add +> `-e LEDGER_CONN=${MASTER_NODE_TCP_CONN_INFO}` to that node's `docker-compose.yaml` (or export it into the +> environment) before running `docker compose up`. + +--- + +### Step 1 — Log in to Docker Hub + +```shell +docker login -u anyloguser -p ${ANYLOG_DOCKER_PASSWORD} +``` + +--- + +### Step 2 — Start the Master node + +The Master node hosts the global metadata ledger. Start it first; all other nodes register against it. + +```shell +cd deployments/docker-compose/anylog-master/ +docker compose up -d +``` + +Attach to the container to verify it is running, then detach with **ctrl-d**: + +```shell +docker attach --detach-keys=ctrl-d anylog-master +``` + +Confirm the node is up and note the TCP connection string for use in later steps: + +```anylog +get status +get connections +``` + +--- + +### Step 3 — Start the Query node + +The Query node orchestrates distributed SQL across Operator nodes and exposes results to Grafana and REST clients. + +```shell +cd deployments/docker-compose/anylog-query/ +docker compose up -d +docker attach --detach-keys=ctrl-d anylog-query +``` + +--- + +### Step 4 — Start Operator node 1 + +Operator nodes host data in local databases and satisfy queries. To automatically populate the node with sample +data over MQTT, set `ENABLE_MQTT=true` in the node's `.env` file before starting. + +```shell +cd deployments/docker-compose/anylog-operator/ +docker compose up -d +docker attach --detach-keys=ctrl-d anylog-operator +``` + +--- + +### Step 5 — Start Operator node 2 + +A second Operator provides a second cluster and demonstrates distributed query behaviour. + +If both Operators run on the **same machine**, make sure their TCP and REST ports don't collide — edit the +`.env` file (or the `docker-compose.yaml`) before starting: + +```shell +# Example overrides for a same-machine second operator +ANYLOG_SERVER_PORT=32158 +ANYLOG_REST_PORT=32159 +NODE_NAME=operator2 +CLUSTER_NAME=cluster2 +``` + +Then start the node: + +```shell +cd deployments/docker-compose/anylog-operator2/ +docker compose up -d +docker attach --detach-keys=ctrl-d anylog-operator2 +``` + +--- + +## Verifying the network + +Once all four nodes are running, connect to any node and run the standard health checks: + +```anylog +get processes # confirm services are running +get connections # confirm TCP/REST ports +test node # local TCP + REST + blockchain check +test network # peer connectivity across all nodes +blockchain test # local ledger integrity +``` + +See [Troubleshooting](troubleshooting.md) for a full diagnostic walkthrough. + +--- + +## Optional environment variables + +The table below lists commonly used variables you can set in a node's `.env` file. A full reference is available +in [sample_config_file.env](Support/sample_config_file.env). + +| Variable | Applies to | Description | +|---|---|---| +| `LICENSE_KEY` | All | Required — your AnyLog license key | +| `LEDGER_CONN` | Query, Operator | Master node TCP address (`IP:port`) when nodes are on different machines | +| `NODE_NAME` | All | Logical name registered in the metadata ledger | +| `CLUSTER_NAME` | Operator | Cluster the Operator belongs to | +| `ANYLOG_SERVER_PORT` | All | TCP port (default 32048 / 32148) | +| `ANYLOG_REST_PORT` | All | REST port (default 32049 / 32149) | +| `ENABLE_MQTT` | Operator | Set `true` to subscribe to sample MQTT data on startup | \ No newline at end of file diff --git a/_docs/Tools-UI/test-suite.md b/_docs/Tools-UI/test-suite.md new file mode 100644 index 0000000..0028904 --- /dev/null +++ b/_docs/Tools-UI/test-suite.md @@ -0,0 +1,368 @@ +--- +title: Test Suites +description: Commands to define, run, and compare test cases and test suites across AnyLog Network nodes. +layout: page +--- + + +Nodes in the network can treat queries and their outputs as test cases and group them into test suites. +A single command can trigger one or more tests across one or more nodes; results from all participating nodes +can be stored in a database and queried from a single point, the same way time-series data is managed by the network. + +| Step | Command | Confirms | +|---|---|---| +| 1 | `run client () sql … test=true file=…` | Query output written in test format | +| 2 | `analyze output` | Two test files are identical | +| 3 | `test case` | Single source file passes against live query | +| 4 | `test suite` | All source files in a directory pass | + +--- + +## Test format + +When a query is executed, query options can mark it as a test case and direct the output to a file in **test format**. + +A test-format file has three sections: + +| Section | Contents | +|---|---| +| **Header** | Title, date/time, query syntax, DBMS, output format | +| **Body** | The query result rows | +| **Footer** | Row count and execution time | + +**Example output:** + +```output +========================================================================== +Title: List Unique Values +Date: 2022-01-21 10:20:28.681237 +Command: select distinct(value) as value from ping_sensor order by value +DBMS: lsl_demo +Format: json:output +========================================================================== +{"value": 2} +{"value": 21} +{"value": 121} +{"value": 201} +{"value": 221} +{"value": 231} +{"value": 241} +{"value": 261} +{"value": 1021} +{"value": 2021} +{"value": 2100} +{"value": 2221} +{"value": 3221} +{"value": 5621} +========================================================================== +Rows: 14 +Run Time: 00:00:03 +========================================================================== +``` + +--- + +## Comparison process + +Any two files in test format can be compared: + +- **Header differences** are ignored. +- **Body differences** trigger a failure with the reason and line number. +- **Footer differences** — slower execution time is flagged only when the `time` option is enabled. + +--- + +## `analyze output` + +**When:** You have two test-format files and want to verify they are identical. + +**Why:** Confirms that a query result matches a previously captured trusted output, without re-running a full test case. + +```anylog +analyze output where file = [file path and name] and source = [file path and name] and option = time +``` + +| Key | Value | Details | Default | +|---|---|---|---| +| `file` | path and file name | The output being tested | | +| `source` | path and file name | The trusted reference output | | +| `option` | `time` | Also fail if execution is slower than the source | (off) | + +**Example:** + +```anylog +analyze output where file = !test_dir/test_file3.out and source = !test_dir/test_file2.out and option = time +``` + +--- + +## Directing a query to a test-format file + +Add the following key-value pairs to the query options section to write output in test format: + +| Key | Value | Details | Default | +|---|---|---|---| +| `test` | `true` / `false` | Enable test format | `false` | +| `title` | any string | Added to the header | | +| `file` | path and file name | Destination file | | + +> **Note:** If the file name is prefixed with `*`, the system appends a unique suffix to avoid overwriting existing files. + +**Example:** + +```anylog +run client () sql lsl_demo format=json and stat=true and test=true and file=!test_dir\query_*.out and title="Data set #35" "select distinct(value) as value from ping_sensor order by value" +``` + +--- + +## Executing a query and comparing to expected output + +**When:** You want to run a query and immediately validate the result against a trusted reference file. + +**Why:** Combines query execution and comparison into a single step, leaving a diff file only when the result diverges. + +Add the standard test-format keys (above) plus: + +| Key | Value | Details | Default | +|---|---|---|---| +| `source` | path and file name | File with expected results | | +| `option` | `time` | Also fail on slower execution | (off) | + +**Example:** + +```anylog +run client () sql lsl_demo format=json and stat=true and test=true and file=!test_dir\test_*.test and source=!test_dir\query_1.out and title="Data set #35" "select distinct(value) as value from ping_sensor order by value" +``` + +> **Notes:** +> - If the file name is `*`, a unique name is generated automatically. +> - If the result matches, the output file is deleted. If it differs, the file is kept for inspection. +> - Without `option=time`, execution time differences are ignored. + +--- + +## `test case` + +**When:** You have a single source file in test format and want to re-run its query and verify the result. + +**Why:** Reads the query and metadata directly from the source file header — no need to re-specify the query manually. Results can be written to a database for monitoring and alerting. + +```anylog +test case where source = [file path and name] and inform = [destination] and time = [true/false] and dest = [destination nodes] +``` + +| Key | Value | Details | +|---|---|---| +| `source` | path and file name | The trusted reference file | +| `inform` | see table below | Where test results are sent | +| `time` | `true` / `false` | Whether to fail on slower execution | +| `dest` | `IP:Port, …` | Optional: restrict to specific Operator nodes | + +**`inform` destinations:** + +| Value | Description | +|---|---| +| `stdout` | The stdout of the node running the query | +| `stdout@ip:port` | The stdout of a remote node (TCP port) | +| `dbms.dbms_name.table_name@ip:port` | A table on a remote node (REST port) | + +Multiple `inform` values are allowed. + +**Example:** + +```anylog +test case where source = !test_dir/output_test.out and inform = stdout and inform = dbms.qa.testing@!qa_node +``` + +**Example failure output:** + +```anylog +{"result" : "Failed", + "Title" : "List Unique Values", + "Reason" : "The value for the key 'timestamp' in line 11 is different: '2019-10-11 10:15:53.150009' vs. '2019-10-11 10:15:53.15000", + "File" : "D:\Node\AnyLog-Network\data\test\run_of_test_1642789228.out", + "Trusted" : "D:\Node\AnyLog-Network\data\test\test_1642789228.out"} +``` + +--- + +## `test suite` + +**When:** You have multiple test cases organized in a directory (or directory tree) and want to run them all in one call. + +**Why:** Scales `test case` across an entire folder of source files — useful for regression testing a deployment or validating a data set after a network change. + +```anylog +test suite where source = [file path and name] and inform = [destination] and subdir = [true/false] and time = [true/false] and dest = [destination nodes] +``` + +| Key | Value | Details | +|---|---|---| +| `source` | path and file pattern | Source files to test; supports `*` prefix on name or type | +| `inform` | see `test case` | Where results are sent | +| `subdir` | `true` / `false` | If `true`, recurse into subdirectories | +| `time` | `true` / `false` | Whether to fail on slower execution | +| `dest` | `IP:Port, …` | Optional: restrict to specific Operator nodes | + +**Examples:** + +```anylog +test suite where source = !test_dir/test_*.out and inform = dbms.qa.testing@!dest_node +test suite where source = !test_dir/test_*.out and inform = stdout and subdir = true and dest = 127.32.52.103:20048 +``` + +--- + +## Scheduling tests + +Test cases and test suites can be added to the scheduler so they run periodically: + +```anylog +schedule time = 1 hour and name = "Hourly regression" task test suite where source = !test_dir/test_*.out and inform = dbms.qa.testing@!dest_node +``` + +Results written to a database table via `inform` can then be monitored and used to trigger alerts. + +--- + +## End-to-end example + +The following walkthrough uses a real power-monitoring data set (`cos` DBMS, `pp_pm` table) to illustrate the full +test suite workflow: load data → generate trusted output files → re-run and validate. + +### Step 1 — Load the test data set + +Save the 50 rows below to a file named `cos.pp_pm.json` and load it into the `cos` database before running any queries. + +```json +{"monitor_id": "KPL ", "a_current": 249, "a_n_voltage": 737, "b_current": 250, "b_n_voltage": 740, "c_current": 246, "c_n_voltage": 736, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 99, "reactivepower": 644, "realpower": 5454, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DSP ", "a_current": 8, "a_n_voltage": 245, "b_current": 15, "b_n_voltage": 247, "c_current": 11, "c_n_voltage": 245, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 99, "reactivepower": 5, "realpower": 46, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DG2 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DG3 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DG4 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DG5 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DG6 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DF1 ", "a_current": 50, "a_n_voltage": 245, "b_current": 23, "b_n_voltage": 247, "c_current": 49, "c_n_voltage": 245, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 97, "reactivepower": 39, "realpower": 161, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DF2 ", "a_current": 21, "a_n_voltage": 245, "b_current": 18, "b_n_voltage": 246, "c_current": 21, "c_n_voltage": 244, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 94, "reactivepower": 28, "realpower": 80, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DF3 ", "a_current": 0, "a_n_voltage": 245, "b_current": 0, "b_n_voltage": 247, "c_current": 0, "c_n_voltage": 245, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DF4 ", "a_current": 75, "a_n_voltage": 245, "b_current": 46, "b_n_voltage": 247, "c_current": 79, "c_n_voltage": 245, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 98, "reactivepower": 52, "realpower": 272, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "DCT ", "a_current": 154, "a_n_voltage": 245, "b_current": 102, "b_n_voltage": 247, "c_current": 158, "c_n_voltage": 245, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 98, "reactivepower": 122, "realpower": 564, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CSP ", "a_current": 2, "a_n_voltage": 739, "b_current": 2, "b_n_voltage": 741, "c_current": 2, "c_n_voltage": 738, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 100, "reactivepower": 5, "realpower": 52, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CG7 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CG12", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CF1 ", "a_current": 16, "a_n_voltage": 739, "b_current": 18, "b_n_voltage": 741, "c_current": 13, "c_n_voltage": 737, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 100, "reactivepower": -34, "realpower": 348, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CF2 ", "a_current": 48, "a_n_voltage": 739, "b_current": 42, "b_n_voltage": 741, "c_current": 30, "c_n_voltage": 738, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 98, "reactivepower": 192, "realpower": 863, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CF3 ", "a_current": 8, "a_n_voltage": 739, "b_current": 11, "b_n_voltage": 741, "c_current": 18, "c_n_voltage": 738, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 99, "reactivepower": 46, "realpower": 265, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CDT ", "a_current": 22, "a_n_voltage": 739, "b_current": 25, "b_n_voltage": 741, "c_current": 33, "c_n_voltage": 737, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 98, "reactivepower": 126, "realpower": 566, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "CBT ", "a_current": 96, "a_n_voltage": 739, "b_current": 98, "b_n_voltage": 741, "c_current": 97, "c_n_voltage": 738, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 98, "reactivepower": 400, "realpower": 2114, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BG8 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BG9 ", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BG10", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BG11", "a_current": 0, "a_n_voltage": 0, "b_current": 0, "b_n_voltage": 0, "c_current": 0, "c_n_voltage": 0, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 0, "realpower": 0, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BF1 ", "a_current": 30, "a_n_voltage": 737, "b_current": 35, "b_n_voltage": 740, "c_current": 30, "c_n_voltage": 736, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 99, "reactivepower": 83, "realpower": 696, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BF2 ", "a_current": 36, "a_n_voltage": 738, "b_current": 34, "b_n_voltage": 739, "c_current": 35, "c_n_voltage": 737, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 100, "reactivepower": 11, "realpower": 772, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BF3 ", "a_current": 34, "a_n_voltage": 737, "b_current": 24, "b_n_voltage": 740, "c_current": 32, "c_n_voltage": 736, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 100, "reactivepower": -20, "realpower": 665, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BF4 ", "a_current": 21, "a_n_voltage": 738, "b_current": 22, "b_n_voltage": 740, "c_current": 22, "c_n_voltage": 736, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 100, "reactivepower": 20, "realpower": 476, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BCT ", "a_current": 96, "a_n_voltage": 738, "b_current": 99, "b_n_voltage": 740, "c_current": 97, "c_n_voltage": 736, "commsstatus": true, "energymultiplier": 1, "frequency": 6000, "powerfactor": 98, "reactivepower": 401, "realpower": 2118, "timestamp": "2025-12-22 00:00:26.023786"} +{"monitor_id": "BSP ", "a_current": 1, "a_n_voltage": 738, "b_current": 1, "b_n_voltage": 740, "c_current": 1, "c_n_voltage": 736, "commsstatus": true, "energymultiplier": 1, "frequency": 6001, "powerfactor": 100, "reactivepower": -1, "realpower": 17, "timestamp": "2025-12-22 00:00:26.023786"} +``` + +--- + +### Step 2 — Generate trusted output files + +Run all eight queries once against the loaded data set. Each query writes its result to a numbered `.out` file in `!test_dir`. +These files become the trusted reference for all future validation runs. + +| File | Query | What it tests | +|---|---|---| +| `query_1.out` | Q1 | `AVG`/`MIN`/`MAX` powerfactor per monitor, ordered by `max_powerfactor DESC` | +| `query_2.out` | Q2 | Same aggregation, ordered by `avg_powerfactor ASC` | +| `query_3.out` | Q3 | Per-minute increments of `MAX(b_n_voltage)` per monitor, ordered by `max_b_n_voltage` | +| `query_4.out` | Q4 | Per-minute increments of `AVG(b_n_voltage)` per monitor, ordered by `avg_b_n_voltage` | +| `query_5.out` | Q5 | Voltage stats with compound `AND` filter — expected row count: 9 | +| `query_6.out` | Q6 | Voltage stats with compound `OR` filter — expected row count: 41 | +| `query_7.out` | Q7 | Per-monitor voltage averages and extremes filtered by `a_n_voltage > 500 OR < 200`, ordered by `max_voltage DESC` | +| `query_8.out` | Q8 | Same filter as Q7, ordered by `avg_a_voltage DESC` | + +```anylog +# Q1 — order by Max powerfactor +run client () sql cos format=json and stat=true and test=true and file=!test_dir\query_1.out and title="Data set #1 - Sabetha Q1" SELECT monitor_id, AVG(powerfactor) as avg_powerfactor, MIN(powerfactor) as min_powerfactor, MAX(powerfactor) as max_powerfactor FROM pp_pm WHERE timestamp > '2025-01-01 00:00:00' GROUP BY monitor_id ORDER BY max_powerfactor desc + +# Q2 — order by Avg powerfactor +run client () sql cos format=json and stat=true and test=true and file=!test_dir\query_2.out and title="Data set #1 - Sabetha Q2" SELECT monitor_id, AVG(powerfactor) as avg_powerfactor, MIN(powerfactor) as min_powerfactor, MAX(powerfactor) as max_powerfactor FROM pp_pm WHERE timestamp > '2025-01-01 00:00:00' GROUP BY monitor_id ORDER BY avg_powerfactor + +# Q3 — increments, order by Max voltage +run client () sql cos format=json and stat=true and test=true and file=!test_dir\query_3.out and title="Data set #1 - Sabetha Q3" "SELECT increments(minute, 1, timestamp), monitor_id, min(timestamp), max(timestamp), MAX(b_n_voltage) as max_b_n_voltage FROM pp_pm WHERE insert_timestamp > '20250101' GROUP BY monitor_id ORDER BY max_b_n_voltage" + +# Q4 — increments, order by Avg voltage +run client () sql cos format=json and stat=true and test=true and file=!test_dir\query_4.out and title="Data set #1 - Sabetha Q4" "SELECT increments(minute, 1, timestamp), monitor_id, min(timestamp), max(timestamp), AVG(b_n_voltage) as max_b_n_voltage FROM pp_pm WHERE insert_timestamp > '20250101' GROUP BY monitor_id ORDER BY max_b_n_voltage" + +# Q5 — AND filter (expected count: 9) +run client () sql cos format=json and stat=true and test=true and file=!test_dir\query_5.out and title="Data set #1 - Sabetha Q5" "SELECT MAX(a_n_voltage) as max_voltage, MIN(a_n_voltage) as min_voltage, AVG(a_n_voltage) as avg_voltage, COUNT(a_n_voltage) as count_voltage from pp_pm where a_n_voltage < 739 and a_n_voltage > 700" + +# Q6 — OR filter (expected count: 41) +run client () sql cos format=json and stat=true and test=true and file=!test_dir\query_6.out and title="Data set #1 - Sabetha Q6" "SELECT MAX(a_n_voltage) as max_voltage, MIN(a_n_voltage) as min_voltage, AVG(a_n_voltage) as avg_voltage, COUNT(a_n_voltage) as count_voltage from pp_pm where a_n_voltage >= 739 or a_n_voltage <= 700" + +# Q7 — per-monitor voltage stats, order by max_voltage DESC + 500 OR a_n_voltage < 200 +GROUP BY monitor_id +ORDER BY max_voltage DESC;> + +# Q8 — same filter as Q7, order by avg_a_voltage DESC + 500 OR a_n_voltage < 200 +GROUP BY monitor_id +ORDER BY avg_a_voltage DESC;> +``` + +--- + +### Step 3 — Validate a single query + +Re-run one query and compare it against its trusted output file: + +```anylog +test case where source = !test_dir/query_1.out and inform = stdout +``` + +--- + +### Step 4 — Validate all queries in one call + +Re-run all eight queries and compare each against its trusted output file: + +```anylog +test suite where source = !test_dir/query_*.out and inform = stdout +``` + +To also store results in a QA database on a remote node: + +```anylog +test suite where source = !test_dir/query_*.out and inform = stdout and inform = dbms.qa.testing@!dest_node +``` \ No newline at end of file From 4ac8b4ff5f9ef93f6a06d1fea88decf3da160896 Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Fri, 29 May 2026 13:13:54 -0700 Subject: [PATCH 02/12] enhance scheduler + notification support Signed-off-by: Ori Shadmon --- .github/scripts/navigation.py | 1 + _config.yml | 3 + _docs/Monitoring-Operations/scheduler.md | 211 ++++++++++++++++++ .../Querying-Data-Northbound/notification.md | 211 +++++++++++++----- 4 files changed, 375 insertions(+), 51 deletions(-) create mode 100644 _docs/Monitoring-Operations/scheduler.md diff --git a/.github/scripts/navigation.py b/.github/scripts/navigation.py index f6bf457..dddf791 100644 --- a/.github/scripts/navigation.py +++ b/.github/scripts/navigation.py @@ -53,6 +53,7 @@ "notification", ], "Monitoring & Operations": [ + "scheduler", "node-monitoring", "aggregations", "high-availability", diff --git a/_config.yml b/_config.yml index 6cd08c0..3199603 100644 --- a/_config.yml +++ b/_config.yml @@ -181,6 +181,9 @@ nav: - slug: Monitoring-Operations/high-availability title: High Availability (HA) file: Monitoring-Operations/high-availability.md + - slug: Monitoring-Operations/scheduler + title: Scheduler & Scheduled Tasks + file: Monitoring-Operations/scheduler.md - title: Tools & UI items: - slug: Tools-UI/mcp diff --git a/_docs/Monitoring-Operations/scheduler.md b/_docs/Monitoring-Operations/scheduler.md new file mode 100644 index 0000000..3479ca5 --- /dev/null +++ b/_docs/Monitoring-Operations/scheduler.md @@ -0,0 +1,211 @@ +--- +title: Scheduler & Scheduled Tasks +description: Run repeatable tasks on a fixed interval to monitor node state, collect metrics, and trigger actions. +layout: page +--- + + +The scheduler executes commands or scripts at a configured interval without manual intervention. Tasks can read local or remote node state, query data across the network, update summary tables, and trigger alerts. + +Scheduler `0` is reserved for system use. User schedulers start at `1`. + +--- + +## Quick reference + +```anylog +run scheduler [id] # start a scheduler (default id = 1) +exit scheduler [id] # stop one scheduler, or all if id omitted +schedule time = [interval] and name = [name] task [command] # add a task +get scheduler # list all scheduled tasks +get scheduler 1 # tasks on scheduler 1 +task stop where name = [name] # pause a task +task resume where name = [name] # resume a paused task +task remove where name = [name] # remove a task +task run where name = [name] # run a task immediately +task init where name = [name] and start = [time] # reschedule a task's start time +``` + +--- + +## Starting and stopping the scheduler + +```anylog +run scheduler 1 # start user scheduler +exit scheduler 1 # stop scheduler 1 only +exit scheduler # stop all schedulers +``` + +See Background Services — Scheduler for startup configuration. + +--- + +## Adding tasks + +```anylog +schedule [options] task [command or script] +``` + +### Options + +| Option | Explanation | +| --- | --- | +| `time` | Interval between executions (e.g. `15 seconds`, `5 minutes`, `1 day`) | +| `start` | When to run the first execution. Defaults to current date and time | +| `name` | Unique name for the task within the scheduler | +| `scheduler` | Scheduler ID to add the task to. Defaults to `1` | + +### Examples + +```anylog +# Store CPU usage every 15 seconds +schedule time = 15 seconds and name = "Store CPU" task get node info cpu_percent into dbms = monitor and table = cpu_percent + +# Check disk space every minute +schedule time = 1 minute and name = "Check disk" task disk_free = get disk free . + +# Collect row counts every 5 minutes +schedule time = 5 minutes and name = "Row count" task get rows count where dbms = my_data into dbms = monitor and table = row_counts + +# Run a script at the start of each day +schedule time = 1 day and name = "Sync Devices" and start = "start of day" task process !local_scripts/sync_script.al +``` + +### Setting the start time + +The `start` option accepts a date/time string or one of the following keywords: + +| Value | Meaning | +| --- | --- | +| `now()` | Immediately | +| `start of year` | First moment of the current year | +| `start of month` | First moment of the current month | +| `start of day` | Midnight of the current day | +| `start of hour` | Top of the current hour | +| `start of minute` | Top of the current minute | + +Time-forward values (relative to now) are also accepted: + +| Unit | Meaning | +| --- | --- | +| `y` | Year | +| `m` | Month | +| `w` | Week | +| `d` | Day | +| `h` | Hour | +| `t` | Minute | +| `s` | Second | + +Example — start two hours from now: +```anylog +task init where name = "Get Disk Space" and start = +2h +``` + +--- + +## Viewing scheduled tasks + +```anylog +get scheduler # all schedulers +get scheduler 1 # scheduler 1 only +``` + +--- + +## Managing tasks + +All `task` commands default to scheduler `1` when no `scheduler` option is given. Tasks can be referenced by name or by their numeric ID shown in `get scheduler`. + +### Pause and resume + +```anylog +task stop where scheduler = 1 and name = "Monitor CPU" +task resume where scheduler = 1 and name = "Monitor CPU" +``` + +### Remove + +```anylog +task remove where scheduler = 1 and name = "Monitor CPU" +``` + +### Immediate execution + +```anylog +task run where scheduler = 1 and name = "Monitor CPU" +``` + +### Reschedule start time + +Use `task init` to push a task's next execution forward — useful to suppress repeated alerts after one has already fired: + +```anylog +# Pause disk-space alerts for 2 hours +task init where scheduler = 1 and name = "Monitor Space" and start = +2h + +# Resume at the start of the next day +task init where scheduler = 1 and name = "Monitor Space" and start = +1d +``` + +--- + +## Storing metrics in a database + +Connect a database and partition the table before scheduling writes: + +```anylog +connect dbms monitor where type = sqlite +partition monitor cpu_percent using timestamp by 1 day +``` + +Then schedule collection and cleanup: + +```anylog +# Collect every 15 seconds +schedule time = 15 seconds and name = "Store CPU" task get node info cpu_percent into dbms = monitor and table = cpu_percent + +# Drop yesterday's partition daily +schedule time = 1 day and start = +1d and name = "Drop old CPU" task drop partition where dbms = monitor and table = cpu_percent +``` + +--- + +## Repeatable queries + +A repeatable query runs on a fixed interval and writes results into a summary (rollup) table. `TIME(PREVIOUS)` and `TIME(CURRENT)` are substituted dynamically at each execution. + +```anylog +schedule time = 5 minutes and name = "Summary sensor data" task run client () sql my_data table = summary_sensor and drop = false "SELECT max(timestamp), min(value), max(value), avg(value) from cos_data where timestamp >= TIME(PREVIOUS) and timestamp < TIME(CURRENT)" +``` + +The summary table can be used as a Grafana data source to alert on missing data, late-reporting nodes, or out-of-range values. + +--- + +## Common patterns + +### Monitor disk space and alert + +```anylog +# Step 1 — collect free space every 5 minutes +schedule time = 5 minutes and name = "Get Disk Space" task disk_free = get disk free d:\ + +# Step 2 — alert if below threshold, then suspend for 1 day +schedule time = 5 minutes and name = "Alert Disk Space" task if !disk_free < 1000000000 then +do email to admin@company.com where subject = "Disk Space Alert" and message = "Disk drive is under threshold" +do sms to 6505550000 where gateway = tmomail.net and subject = "Disk Space Alert" and message = "Disk drive is under threshold" +do task init where name = "Alert Disk Space" and start = +1d +``` + +Using `task init` after sending the alert prevents the same message from firing every 5 minutes. + +### Distribute row-count checks across the network + +```anylog +schedule time = 5 minutes and name = "Network row counts" task run client (blockchain get operator bring.ip_port) get rows count where dbms = my_data +``` + +See Get Commands for the full list of commands that can be used inside tasks. \ No newline at end of file diff --git a/_docs/Querying-Data-Northbound/notification.md b/_docs/Querying-Data-Northbound/notification.md index 99e0d0d..164f2dc 100644 --- a/_docs/Querying-Data-Northbound/notification.md +++ b/_docs/Querying-Data-Northbound/notification.md @@ -1,104 +1,213 @@ --- -title: Notification Services -description: Utilizing node / data insight to notify users of the state of either data (from sensors) or physical node +title: Alerts & Messaging +description: Send email, SMS, and webhook notifications from scheduled tasks or streaming conditions. layout: page --- +- 2026-05-29 | Rewrote document to better different notification / scheduler options +--> -AnyLog provides services like _REST_, _SMS_ and _STMP_ (eMail) in order allow your network to send notifications regarding -the system; this can be things like CPU utilization, data not coming in or simply when ever a partition is being dropped / created. +AnyLog can send email, SMS, and webhook notifications when thresholds are crossed or conditions are met. Messages are +triggered from scheduled tasks or +streaming conditions. +--- -## Setting up Webhooks +## Quick reference -_Webhooks_ are user-defined _HTTP_ callbacks that enable real-time communication between web applications; they are the -simplest and fastest way to send messages into third-party applications as it simply uses a _REST_ (post) request as -opposed to needing to develop a full application for messaging. +```anylog +run smtp client where email = [address] and password = [pwd] and ssl = true # enable SMTP -* [Slack](https://api.slack.com/messaging/webhooks) -* [Discord](https://docs.gitlab.com/ee/user/project/integrations/discord_notifications.html#create-webhook) -* [Microsoft Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?tabs=newteams%2Cdotnet) -* [Google Hangouts](https://developers.google.com/workspace/chat/quickstart/webhooks) +email to [address] where subject = [text] and message = [text] # send email +sms to [phone] where gateway = [gateway] and subject = [text] and message = [text] # send SMS +rest post where url = [webhook-url] and body = [json-payload] and headers = "{'Content-Type': 'application/json'}" # webhook +``` -### Steps -1. Go https://api.slack.com/apps/ -2. Under _Create_, Create an app from manifest +--- -| | | -|:------------------------------------------------------------------------------:|:------------------------------------------------------------------------------:| +## Enabling the SMTP client -3. Select the preferred channel +Start the SMTP client before issuing any `email` or `sms` commands: - +```anylog +run smtp client where email = alerts@company.com and password = mypassword and ssl = true +``` +See Background Services — SMTP for full configuration options. -4. Press continue / next till the end +--- -5. Select _Incoming Webhooks_ +## Sending email - +```anylog +email to [receiver email] where subject = [subject] and message = [message text] +``` -6. Enable Webhooks +| Option | Explanation | Default | +| --- | --- | --- | +| `receiver email` | Destination address | — | +| `subject` | Subject line text | `AnyLog Alert` | +| `message` | Body text | `AnyLog Network Alert from Node: [node name]` | - +Multiple `message` options appear as separate lines in the email body: -7. At the bottom, add _Webbook_ to workspace +```anylog +email to admin@company.com where subject = "High CPU Alert" and message = "CPU utilization exceeded threshold" and message = "Reporting node: 10.0.0.5 (Operator-West)" +``` - +--- +## Sending SMS -8. Select which channel in Slack to send messages to +```anylog +sms to [phone number] where gateway = [sms gateway] and subject = [subject] and message = [message text] +``` +| Option | Explanation | Default | +| --- | --- | --- | +| `phone number` | Destination phone number | — | +| `gateway` | SMS carrier email gateway | — | +| `subject` | Subject line text | `AnyLog Alert` | +| `message` | Message text | `AnyLog Network Alert from Node: [node name]` | - +Example with T-Mobile: +```anylog +sms to 6508147334 where gateway = tmomail.net and subject = "Threshold exceeded" and message = "Sensor value above limit" +``` -9. When done you should see a _webhook_ (URL) - this will be used as part of your REST request in AnyLog +### US carrier gateways - +| Carrier | Gateway | +| --- | --- | +| AT&T | `txt.att.net` | +| Sprint | `messaging.sprintpcs.com` | +| T-Mobile | `tmomail.net` | +| Verizon | `vtext.com` | +| Boost Mobile | `myboostmobile.com` | +| Metro PCS | `mymetropcs.com` | +| Tracfone | `mmst5.tracfone.com` | +| U.S. Cellular | `email.uscc.net` | +| Virgin Mobile | `vmobl.com` | +A full carrier list is available at the [SMS gateway reference](https://kb.sandisk.com/app/answers/detail/a_id/17056/). -**Generated URL**: -```URL -https://hooks.slack.com/services/T9EB83JTF/B06Q4F5R0QK/ -``` +--- -## Send Notifications via AnyLog +## Triggering alerts from scheduled tasks -### Slack Webhooks -AnyLog allows to send cURL requests the _rest_ command. Since _Webhooks_ are -essentially URLs to send messages into a system, we'll be using the _rest_ command to send notifictaions from AnyLog into -Slack. +Combine a condition check with messaging inside a scheduled task: -1. Create webhook URL as a variable ```anylog -webhook_url = "https://hooks.slack.com/services/T9EB83JTF/" +# Alert if disk space drops below 1 GB, then suppress for 1 day +schedule time = 5 minutes and name = "Monitor Space" task process !scripts_dir/monitor_space.al ``` -2. get percentage of CPU used and current timestamp +Where `monitor_space.al` contains: + ```anylog +disk_free = get disk free !monitored_drive +if !disk_free < 1000000000 then +do email to admin@company.com where subject = "Disk Space Alert" and message = "Disk drive is under threshold" +do sms to 6505550000 where gateway = tmomail.net and subject = "Disk Space Alert" and message = "Disk drive is under threshold" +do task init where name = "Monitor Space" and start = +1d +``` + +The `task init` call at the end pushes the task's next start time forward by one day, preventing the alert from re-firing every 5 minutes. See Scheduler & Scheduled Tasks for details on `task init`. + +--- + +## Webhooks + +Webhooks are HTTP callbacks that deliver messages into third-party applications using a single REST POST — no custom integration required. AnyLog sends webhook notifications using the `rest` command. + +Supported platforms and their setup guides: + +- [Slack](https://api.slack.com/messaging/webhooks) +- [Discord](https://docs.gitlab.com/ee/user/project/integrations/discord_notifications.html#create-webhook) +- [Microsoft Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook) +- [Google Chat](https://developers.google.com/workspace/chat/quickstart/webhooks) + +### Send a webhook notification + +Once you have a webhook URL from your platform, use the `rest` command to POST a message: + +```anylog +# Store the webhook URL +webhook_url = "https://hooks.slack.com/services/T9EB83JTF/B06Q4F5R0QK/..." + +# Build the payload (Slack uses "text"; Discord, Teams, and Google Chat use "content") cpu_percent = get node info cpu_percent date_time = python "datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')" +text_msg = !date_time + " CPU usage: " + !cpu_percent +payload = json {"text": !text_msg} + +# POST to Slack +rest post where url = !webhook_url and body = !payload and headers = "{'Content-Type': 'application/json'}" ``` -3. Create payload +> **Note:** Discord, Microsoft Teams, and Google Chat use `content` as the payload key instead of `text`. + +### Use in a scheduled task + ```anylog -text_msg = !date_time + " CPU usage: " + !cpu_percent -payload = json {"text": !text_msg} +schedule time = 15 seconds and name = "CPU webhook" task +do cpu_percent = get node info cpu_percent +do date_time = python "datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')" +do text_msg = !date_time + " CPU usage: " + !cpu_percent +do payload = json {"text": !text_msg} +do rest post where url = !webhook_url and body = !payload and headers = "{'Content-Type': 'application/json'}" +``` + +See AnyLog Commands — REST for full `rest` command syntax. + +--- + +## Triggering alerts from streaming conditions + +Streaming conditions evaluate incoming data rows in real time, before they are written to the database. Use them for low-latency alerting without polling. + +### Set a condition + +```anylog +set streaming condition where dbms = [dbms] and table = [table] and limit = [n] if [condition] then [command] ``` -4. Publish information to Slack via _REST_ +| Option | Explanation | +| --- | --- | +| `limit` | Maximum number of times the action fires. `0` = unlimited | +| `condition` | Expression evaluated against each incoming row, e.g. `[value] > 100` | +| `command` | Any AnyLog command — email, SMS, SQL insert, etc. | + +Examples: + ```anylog -rest post where url = !webhook_url and body = !payload and headers = "{'Content-Type': 'application/json'}" +# SMS alert, fires at most 2 times +set streaming condition where dbms = my_data and table = sensors and limit = 2 if [value] > 85 then sms to 6508147334 where gateway = tmomail.net and subject = "High temp alert" and message = "Value exceeded 85" + +# Email alert for negative readings +set streaming condition where dbms = my_data and table = sensors if [value] < 0 then email to alerts@company.com where subject = "Below zero" and message = "Sensor reading is negative" + +# Write error rows to a separate table +set streaming condition where dbms = my_data and table = sensors if [status] == "error" then run client () sql my_data "insert into errors values (!timestamp, !device, !value)" ``` -Once sent, an output would appear in the proper Slack channel +### View conditions - +```anylog +get streaming conditions +get streaming conditions where dbms = my_data +get streaming conditions where dbms = my_data and table = sensors +``` -**Note**: _Google Hangouts_, _Discord_ and _Microsoft Teams_ use `content` for the _payload_ key as opposed to `text`. +### Remove conditions +```anylog +# Remove a specific condition by ID +reset streaming conditions where dbms = my_data and table = sensors and id = [condition-id] +# Remove all conditions on a database +reset streaming conditions where dbms = my_data +``` \ No newline at end of file From df7246d843398dc693d80b8522d767c83d4022a9 Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Sun, 21 Jun 2026 20:14:55 -0700 Subject: [PATCH 03/12] fixed homepage to be nicer + decreased footer size Signed-off-by: Ori Shadmon --- _layouts/default.html | 1 + assets/css/main.css | 57 ++++++++++++++++++++++++++++--------------- index.md | 11 ++------- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/_layouts/default.html b/_layouts/default.html index ad22f4b..394eb55 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -10,6 +10,7 @@ {% seo %} + {% include header.html %}
diff --git a/assets/css/main.css b/assets/css/main.css index 4ed5c6f..b818050 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -99,7 +99,7 @@ img { max-width: 100%; height: auto; display: block; } .logo-wordmark { font-size: 15px; font-weight: 600; - color: var(--white); + color: #ffffff; letter-spacing: -.01em; } .logo-wordmark em { @@ -526,31 +526,42 @@ img { max-width: 100%; height: auto; display: block; } /* ── Homepage ────────────────────────────────────────── */ .home-hero { max-width: var(--content-max); - padding: 2rem 0 3rem; + padding: 1.5rem 0 .25rem; } .home-hero h1 { - font-size: 2.25rem; + font-size: 2rem; font-weight: 600; letter-spacing: -.025em; line-height: 1.2; - margin-bottom: .75rem; + margin-bottom: .5rem; } .home-hero p { - font-size: 1.1rem; + font-size: 1.05rem; color: var(--text-muted); max-width: 560px; - margin-bottom: 2rem; + margin-bottom: 0; +} +.home-diagram { + text-align: center; + margin: 0 0 .75rem; +} +.home-diagram svg { + display: inline-block; + width: 100%; + max-width: 650px; + height: auto; + max-height: 260px; } .home-cards { display: grid; - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(165px, 1fr)); gap: 1rem; - margin-top: 1rem; + margin-top: .5rem; } .home-card { border: 1px solid var(--border); border-radius: var(--radius-lg); - padding: 1.25rem; + padding: .95rem; text-decoration: none; transition: border-color .15s, box-shadow .15s; background: var(--surface); @@ -561,24 +572,24 @@ img { max-width: 100%; height: auto; display: block; } text-decoration: none; } .home-card-icon { - width: 36px; height: 36px; + width: 27px; height: 27px; background: var(--teal-faint); border-radius: var(--radius); display: flex; align-items: center; justify-content: center; - margin-bottom: .875rem; + margin-bottom: .65rem; color: var(--teal); - font-size: 18px; + font-size: 14px; } .home-card h3 { - font-size: .95rem; + font-size: .72rem; font-weight: 600; color: var(--text); - margin-bottom: .35rem; + margin-bottom: .27rem; } .home-card p { - font-size: .85rem; + font-size: .68rem; color: var(--text-muted); - line-height: 1.5; + line-height: 1.45; margin: 0; } @@ -587,14 +598,18 @@ img { max-width: 100%; height: auto; display: block; } background: var(--navy); color: rgba(255,255,255,.6); margin-left: var(--sidebar-w); - padding: 2rem 2.5rem; + padding: 1rem 2rem; +} +.site-footer img { + height: 28px; + width: auto; } .footer-inner { max-width: calc(var(--content-max) + var(--sidebar-w)); display: flex; align-items: center; flex-wrap: wrap; - gap: 1.25rem; + gap: 1rem; } .footer-brand { display: flex; @@ -603,12 +618,15 @@ img { max-width: 100%; height: auto; display: block; } font-size: 13.5px; font-weight: 500; color: rgba(255,255,255,.75); + line-height: 1.2; } .footer-links { display: flex; gap: 1.25rem; flex-wrap: wrap; margin-left: auto; + line-height: 1.2; + } .footer-links a { font-size: 13px; @@ -621,7 +639,8 @@ img { max-width: 100%; height: auto; display: block; } width: 100%; font-size: 12px; color: rgba(255,255,255,.3); - margin-top: .25rem; + margin-top: .15rem; + line-height: 1.2; } /* ── Responsive ──────────────────────────────────────── */ diff --git a/index.md b/index.md index 00903c2..893bc89 100644 --- a/index.md +++ b/index.md @@ -6,6 +6,7 @@ title: AnyLog Documentation ## Changelog - 2026-04-20 | Created document - 2026-04-24 | updated document with new image + proper links +- 2026-06-21 | update image sizing -->
@@ -13,14 +14,6 @@ title: AnyLog Documentation

AnyLog — Enable independent (industrial) databases to function as a single logical data network.

-[//]: # (
) - -[//]: # ( ) - -[//]: # ( ) - -[//]: # (
) -
{% include anylog_network_fabric_animated.svg %}
@@ -36,7 +29,7 @@ title: AnyLog Documentation

Southbound services

OPC-UA, Modbus TCP, REST, Kafka, gRPC — all the ways to get data in.

- +
🔍

Northbound services

Query distributed edge nodes via REST, Kafka, and BI tools.

From db68ac28a734b3c9f6f2e953993e4d7579944c53 Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Sat, 8 Aug 2026 15:57:03 -0700 Subject: [PATCH 04/12] docker cconfigs Signed-off-by: Ori Shadmon --- Dockerfile | 10 ++++++---- _config.yml | 43 +++++++++++++++++++++++++------------------ deploy_docker.sh | 23 +++++++++++++++++++++++ docker-compose.yaml | 7 +++++-- 4 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 deploy_docker.sh diff --git a/Dockerfile b/Dockerfile index e07803c..3b8067a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,9 +6,11 @@ WORKDIR /srv/content USER root ENV BUNDLE_PATH=/srv/bundle -RUN apk add --no-cache python3 bash \ - && mkdir -p /srv/bundle && \ - chmod -R 777 /srv/bundle +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 bash \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /srv/bundle \ + && chmod -R 777 /srv/bundle # Keep container running root for gem installation and avoid permission issues -# Scripts will handle gem install automatically +# Scripts will handle gem install automatically \ No newline at end of file diff --git a/_config.yml b/_config.yml index 90d6954..f6e584a 100644 --- a/_config.yml +++ b/_config.yml @@ -530,20 +530,20 @@ nav: title: "Trusted Platform Module (TPM)" match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/" children: - - kind: "page" - title: "TMP Configuration" - match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration/" - slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration" - url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration/" - file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration.md" - source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/01- TMP Configuration.md" - kind: "page" title: "Software TPM" - match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm/" - slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm" - url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm/" - file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm.md" - source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/02- Software TPM.md" + match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm/" + slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm" + url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm/" + file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm.md" + source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/01- Software TPM.md" + - kind: "page" + title: "TMP Configuration" + match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration/" + slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration" + url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration/" + file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration.md" + source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/02- TMP Configuration.md" - kind: "section" title: "CLI" match_path: "/docs/07-cli/" @@ -832,12 +832,12 @@ nav: file: "11-extended-services/02-mcpai.md" source_path: "11- Extended Services/02- mcpAI.md" - kind: "page" - title: "federated learning (demo)" - match_path: "/docs/11-extended-services/03-federated-learning-demo/" - slug: "11-extended-services/03-federated-learning-demo" - url: "/docs/11-extended-services/03-federated-learning-demo/" - file: "11-extended-services/03-federated-learning-demo.md" - source_path: "11- Extended Services/03- federated learning (demo).md" + title: "Federated Learning" + match_path: "/docs/11-extended-services/03-federated-learning/" + slug: "11-extended-services/03-federated-learning" + url: "/docs/11-extended-services/03-federated-learning/" + file: "11-extended-services/03-federated-learning.md" + source_path: "11- Extended Services/03- Federated Learning.md" - kind: "section" title: "Examples & Use Cases" match_path: "/docs/12-examples-and-use-cases/" @@ -974,3 +974,10 @@ nav: url: "/docs/15-appendices/01-legal-and-licensing/04-anylogedf-used-opensource-notice/" file: "15-appendices/01-legal-and-licensing/04-anylogedf-used-opensource-notice.md" source_path: "15- Appendices/01- Legal & Licensing/04- AnylogEDF used OPENSOURCE-NOTICE.md" +- kind: "page" + title: "TODO" + match_path: "/docs/todo/" + slug: "todo" + url: "/docs/todo/" + file: "todo.md" + source_path: "TODO.md" diff --git a/deploy_docker.sh b/deploy_docker.sh new file mode 100644 index 0000000..b76a216 --- /dev/null +++ b/deploy_docker.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +CMD=${1:-up} +LOCAL_SCRIPTS=${2:-.} + +# if LOCAL_SCRIPTS directory DNE && is not equal to "." +if [[ -z ${LOCAL_SCRIPTS} ]] && [[ ! ${LOCAL_SCRIPTS} == "." ]] && [[ ! -d ${LOCAL_SCRITPS} ]] ; then + echo "Failed to locate Docker directory: ${LOCAL_SCRIPTS}" + exit 1 +fi + +if [[ "${CMD}" -eq "up" ]] ; then + LOCAL_DOCS=${LOCAL_SCRIPTS} docker compose -f ./docker-compose.yml up -d +elif [[ "${CMD}" -eq "logs" ]] ; then + docker logs -f anylog-docs +elif [[ "${CMD}" -eq "down" ]] ; then + LOCAL_DOCS=${LOCAL_SCRIPTS} docker compose -f ./docker-compose.yml down +elif [[ "${CMD}" -eq "clean" ]] ; then + LOCAL_DOCS=${LOCAL_SCRIPTS} docker compose -f ./docker-compose.yml down -v --rmi all +else + echo "Invalid option: ${CMD}" +fi + diff --git a/docker-compose.yaml b/docker-compose.yaml index 80c679d..527c1aa 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,9 +7,12 @@ services: - "4000:4000" - "35729:35729" command: bash /srv/content/.github/scripts/dev-start.sh + environment: + - ANYLOG_DOCS_SOURCE_DIR=/srv/documentation volumes: - - .:/srv/content:cached # your docs project - - bundle-cache:/srv/bundle # Docker-managed volume for gems + - ${LOCAL_DOCS:-.}:/srv/documentation:cached + - .:/srv/content:cached + - bundle-cache:/srv/bundle volumes: bundle-cache: \ No newline at end of file From 6f92b49b2f9cb4e50feeb419bcc0e4b1fb222be2 Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Sat, 8 Aug 2026 16:01:01 -0700 Subject: [PATCH 05/12] Makefile for quick deployment Signed-off-by: Ori Shadmon --- Makefile | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ deploy_docker.sh | 23 ----------------------- 2 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 Makefile delete mode 100644 deploy_docker.sh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..10d2c36 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +COMPOSE_FILE := ./docker-compose.yaml +CONTAINER := anylog-docs + +# Directory to mount as the documentation source. +# Override on the command line, e.g.: +# make up LOCAL_DOCS=/path/to/docs +LOCAL_DOCS ?= . + +.PHONY: up logs down clean check-dir help + +.DEFAULT_GOAL := help + +help: + @echo "Usage: make [target] [LOCAL_DOCS=/path/to/docs]" + @echo "" + @echo "Targets:" + @echo " up Start the docs container (docker compose up -d)" + @echo " logs Follow logs for the $(CONTAINER) container" + @echo " down Stop the docs container (docker compose down)" + @echo " clean Stop and remove containers, volumes, and images" + @echo " help Show this message" + @echo "" + @echo "LOCAL_DOCS defaults to '.' and sets the mounted documentation directory." + +# Validate LOCAL_DOCS exists before doing anything, unless it's "." +check-dir: + @if [ "$(LOCAL_DOCS)" != "." ] && [ ! -d "$(LOCAL_DOCS)" ]; then \ + echo "Failed to locate Docker directory: $(LOCAL_DOCS)"; \ + exit 1; \ + fi + +up: check-dir + LOCAL_DOCS=$(LOCAL_DOCS) docker compose -f $(COMPOSE_FILE) up -d + +logs: + docker logs -f $(CONTAINER) + +down: check-dir + LOCAL_DOCS=$(LOCAL_DOCS) docker compose -f $(COMPOSE_FILE) down + +clean: check-dir + LOCAL_DOCS=$(LOCAL_DOCS) docker compose -f $(COMPOSE_FILE) down -v --rmi all + +# Catch-all: anything that isn't a defined target is an invalid option +%: + @echo "Invalid option: $@" + @$(MAKE) --no-print-directory help + @exit 1 \ No newline at end of file diff --git a/deploy_docker.sh b/deploy_docker.sh deleted file mode 100644 index b76a216..0000000 --- a/deploy_docker.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -CMD=${1:-up} -LOCAL_SCRIPTS=${2:-.} - -# if LOCAL_SCRIPTS directory DNE && is not equal to "." -if [[ -z ${LOCAL_SCRIPTS} ]] && [[ ! ${LOCAL_SCRIPTS} == "." ]] && [[ ! -d ${LOCAL_SCRITPS} ]] ; then - echo "Failed to locate Docker directory: ${LOCAL_SCRIPTS}" - exit 1 -fi - -if [[ "${CMD}" -eq "up" ]] ; then - LOCAL_DOCS=${LOCAL_SCRIPTS} docker compose -f ./docker-compose.yml up -d -elif [[ "${CMD}" -eq "logs" ]] ; then - docker logs -f anylog-docs -elif [[ "${CMD}" -eq "down" ]] ; then - LOCAL_DOCS=${LOCAL_SCRIPTS} docker compose -f ./docker-compose.yml down -elif [[ "${CMD}" -eq "clean" ]] ; then - LOCAL_DOCS=${LOCAL_SCRIPTS} docker compose -f ./docker-compose.yml down -v --rmi all -else - echo "Invalid option: ${CMD}" -fi - From 4b8fd28f852368eedd18c6469220537464e76eda Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Sat, 8 Aug 2026 16:04:38 -0700 Subject: [PATCH 06/12] README Signed-off-by: Ori Shadmon --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 947b984..370b723 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,22 @@ This is the technical documentation for [AnyLog Edge Data Fabric](https://www.anylog.network/), built with Jekyll and hosted on GitHub Pages. +--- + +## How to deploy + +1. Make sure you have `make`, `docker`, and `docker compose` installed +2. Clone the [Frontend](https://github.com/AnyLog-co/anylog-docs.github.io) & [Content](https://github.com/AnyLog-co/documentation) repositories +3. Start the docs locally: +```shell +make up LOCAL_DOCS=${PATH to documentation} + +# Example + +make up LOCAL_DOCS=/mnt/c/Users/oshad/AnyLog-docs/documentation +``` + + --- ## Goal From 573a65f82f2791880ef7f0c85c5d0e95eb91d0ef Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Sat, 8 Aug 2026 16:07:33 -0700 Subject: [PATCH 07/12] merge from main Signed-off-by: Ori Shadmon --- .github/scripts/navigation.py | 3 - _config.yml | 1128 +++++++++++++++++++++++++++------ _layouts/default.html | 1 - assets/css/main.css | 601 +++++++++++++++--- assets/js/main.js | 410 +++++++++--- index.md | 33 +- 6 files changed, 1784 insertions(+), 392 deletions(-) diff --git a/.github/scripts/navigation.py b/.github/scripts/navigation.py index dddf791..b26c5c0 100644 --- a/.github/scripts/navigation.py +++ b/.github/scripts/navigation.py @@ -1,6 +1,5 @@ ITEM_ORDER = { "Getting Started": [ - "quick-start" "getting-started", "installing-anylog", "install-ova", @@ -53,7 +52,6 @@ "notification", ], "Monitoring & Operations": [ - "scheduler", "node-monitoring", "aggregations", "high-availability", @@ -69,7 +67,6 @@ ], "Reference": [ "FAQ", - "test-suite", "troubleshooting" ], } \ No newline at end of file diff --git a/_config.yml b/_config.yml index 3199603..4945985 100644 --- a/_config.yml +++ b/_config.yml @@ -1,12 +1,14 @@ title: AnyLog Docs description: Technical documentation for AnyLog Edge Data Fabric baseurl: '' -url: https://anylog-docs.github.io +url: https://docs.anylog.network markdown: kramdown highlighter: rouge kramdown: input: GFM syntax_highlighter: rouge + parse_block_html: true + parse_span_html: true collections: docs: output: true @@ -25,192 +27,950 @@ exclude: - Gemfile - Gemfile.lock - README.md +- .external-docs - vendor include: - _includes/sample-post.py - _includes/sample-put.py - _includes/node_configs.env nav: -- title: Getting Started - items: - - slug: Getting-Started/getting-started - title: Introduction to AnyLog - file: Getting-Started/getting-started.md - - slug: Getting-Started/installing-anylog - title: Installing & Deploying AnyLog - file: Getting-Started/installing-anylog.md - - slug: Getting-Started/install-ova - title: Installing AnyLog via OVA - file: Getting-Started/install-ova.md - - slug: Getting-Started/anylog-as-service - title: Installing AnyLog as a Service - file: Getting-Started/anylog-as-service.md - - slug: Getting-Started/deployment-scripts - title: Deployment Scripts - file: Getting-Started/deployment-scripts.md - - slug: Getting-Started/quick-start - title: Quick Deployment - file: Getting-Started/quick-start.md -- title: CLI - items: - - slug: CLI/AnyLog-CLI - title: AnyLog CLI - file: CLI/AnyLog-CLI.md - - slug: CLI/node-status - title: Node Status - file: CLI/node-status.md - - slug: CLI/get-cmds - title: Get Commands - file: CLI/get-cmds.md -- title: Network & Services - items: - - slug: Network-Services/background-services - title: Background Services - file: Network-Services/background-services.md - - slug: Network-Services/network-configurations - title: Network Configuration - file: Network-Services/network-configurations.md - - slug: Network-Services/using-rest - title: Using REST - file: Network-Services/using-rest.md - - slug: Network-Services/messaging-services - title: Messaging Service - file: Network-Services/messaging-services.md - - slug: Network-Services/blockchain - title: Blockchain & Metadata - file: Network-Services/blockchain.md - - slug: Network-Services/policies-metadata - title: Policies & Metadata - file: Network-Services/policies-metadata.md - - slug: Network-Services/node-architecture - title: Node Architecture - file: Network-Services/node-architecture.md -- title: Managing Data (Southbound) - items: - - slug: Managing-Data-Southbound/southbound-overview - title: Data Ingestion (Southbound) - file: Managing-Data-Southbound/southbound-overview.md - - slug: Managing-Data-Southbound/data-ingestion - title: Data Ingestion - file: Managing-Data-Southbound/data-ingestion.md - - slug: Managing-Data-Southbound/mapping-policies - title: Mapping Policies - file: Managing-Data-Southbound/mapping-policies.md - - slug: Managing-Data-Southbound/UNS - title: Unified Namespace - file: Managing-Data-Southbound/UNS.md - - slug: Managing-Data-Southbound/UNS-custom - title: Custom UNS (data stream, ISA-95) - file: Managing-Data-Southbound/UNS-custom.md - - slug: Managing-Data-Southbound/opcua - title: OPC-UA - file: Managing-Data-Southbound/opcua.md - - slug: Managing-Data-Southbound/using-kafka - title: Kafka - file: Managing-Data-Southbound/using-kafka.md - - slug: Managing-Data-Southbound/telegraf - title: Telegraf - file: Managing-Data-Southbound/telegraf.md - - slug: Managing-Data-Southbound/etherip - title: EtherNet/IP - file: Managing-Data-Southbound/etherip.md - - slug: Managing-Data-Southbound/modbus - title: Modbus TCP - file: Managing-Data-Southbound/modbus.md - - slug: Managing-Data-Southbound/grpc - title: gRPC - file: Managing-Data-Southbound/grpc.md - - slug: Managing-Data-Southbound/node-red - title: Node-RED - file: Managing-Data-Southbound/node-red.md - - slug: Managing-Data-Southbound/node-monitoring - title: Node Monitoring - file: Managing-Data-Southbound/node-monitoring.md - - slug: Managing-Data-Southbound/syslog - title: Syslog - file: Managing-Data-Southbound/syslog.md - - slug: Managing-Data-Southbound/video-streaming - title: Video Streaming - file: Managing-Data-Southbound/video-streaming.md - - slug: Managing-Data-Southbound/live-data-generator - title: Live Data Generator - file: Managing-Data-Southbound/live-data-generator.md - - slug: Managing-Data-Southbound/edgex - title: EdgeX Integration - file: Managing-Data-Southbound/edgex.md -- title: Querying Data (Northbound) - items: - - slug: Querying-Data-Northbound/northbound-overview - title: Northbound Connectors - file: Querying-Data-Northbound/northbound-overview.md - - slug: Querying-Data-Northbound/queries - title: Querying Data (Northbound) - file: Querying-Data-Northbound/queries.md - - slug: Querying-Data-Northbound/sql-setup - title: SQL & Database Setup - file: Querying-Data-Northbound/sql-setup.md - - slug: Querying-Data-Northbound/grafana - title: Grafana - file: Querying-Data-Northbound/grafana.md - - slug: Querying-Data-Northbound/import-grafana-dashboard - title: Grafana Dashboards - file: Querying-Data-Northbound/import-grafana-dashboard.md - - slug: Querying-Data-Northbound/PowerBI - title: PowerBI - file: Querying-Data-Northbound/PowerBI.md - - slug: Querying-Data-Northbound/Qlik - title: Qlik - file: Querying-Data-Northbound/Qlik.md - - slug: Querying-Data-Northbound/Google - title: Google Drive - file: Querying-Data-Northbound/Google.md - - slug: Querying-Data-Northbound/postgres-connector - title: PostgresSQL Connector - file: Querying-Data-Northbound/postgres-connector.md - - slug: Querying-Data-Northbound/notification - title: Notification Services - file: Querying-Data-Northbound/notification.md -- title: Monitoring & Operations - items: - - slug: Monitoring-Operations/node-monitoring - title: Monitoring & Alerts - file: Monitoring-Operations/node-monitoring.md - - slug: Monitoring-Operations/aggregations - title: Aggregations - file: Monitoring-Operations/aggregations.md - - slug: Monitoring-Operations/high-availability - title: High Availability (HA) - file: Monitoring-Operations/high-availability.md - - slug: Monitoring-Operations/scheduler - title: Scheduler & Scheduled Tasks - file: Monitoring-Operations/scheduler.md -- title: Tools & UI - items: - - slug: Tools-UI/mcp - title: MCP & AI Integration - file: Tools-UI/mcp.md - - slug: Tools-UI/remote-gui - title: Remote GUI - file: Tools-UI/remote-gui.md - - slug: Tools-UI/test-suite - title: Test Suites - file: Tools-UI/test-suite.md -- title: Version Control - items: - - slug: Version-Control/SOURCE-CHANGELOGS - title: Source Changelog - file: Version-Control/SOURCE-CHANGELOGS.md - - slug: Version-Control/DEPLOYMENT_SCRIPTS-CHANGELOGS - title: Deployment-Scripts Changelog - file: Version-Control/DEPLOYMENT_SCRIPTS-CHANGELOGS.md - - slug: Version-Control/DOCKER_COMPOSE-CHANGELOG - title: Docker-Compose Changelog - file: Version-Control/DOCKER_COMPOSE-CHANGELOG.md -- title: Reference - items: - - slug: Reference/FAQ - title: FAQ & Troubleshooting - file: Reference/FAQ.md - - slug: Reference/troubleshooting - title: Troubleshooting - file: Reference/troubleshooting.md +- kind: "page" + title: "Overview" + match_path: "/docs/readme/" + slug: "readme" + url: "/docs/readme/" + file: "readme.md" + source_path: "README.md" +- kind: "section" + title: "Getting Started" + match_path: "/docs/01-getting-started/" + children: + - kind: "page" + title: "Introduction" + match_path: "/docs/01-getting-started/01-introduction/" + slug: "01-getting-started/01-introduction" + url: "/docs/01-getting-started/01-introduction/" + file: "01-getting-started/01-introduction.md" + source_path: "01- Getting Started/01- Introduction.md" + - kind: "page" + title: "Prerequisite" + match_path: "/docs/01-getting-started/02-prerequisite/" + slug: "01-getting-started/02-prerequisite" + url: "/docs/01-getting-started/02-prerequisite/" + file: "01-getting-started/02-prerequisite.md" + source_path: "01- Getting Started/02- Prerequisite.md" + - kind: "page" + title: "install" + match_path: "/docs/01-getting-started/03-install/" + slug: "01-getting-started/03-install" + url: "/docs/01-getting-started/03-install/" + file: "01-getting-started/03-install.md" + source_path: "01- Getting Started/03- install.md" +- kind: "section" + title: "Installation & Deployment" + match_path: "/docs/02-installation-and-deployment/" + children: + - kind: "page" + title: "Install" + match_path: "/docs/02-installation-and-deployment/01-install/" + slug: "02-installation-and-deployment/01-install" + url: "/docs/02-installation-and-deployment/01-install/" + file: "02-installation-and-deployment/01-install.md" + source_path: "02- Installation & Deployment/01- Install.md" + - kind: "section" + title: "Virtualization" + match_path: "/docs/02-installation-and-deployment/02-virtualization/" + children: + - kind: "page" + title: "Docker" + match_path: "/docs/02-installation-and-deployment/02-virtualization/01-docker/" + slug: "02-installation-and-deployment/02-virtualization/01-docker" + url: "/docs/02-installation-and-deployment/02-virtualization/01-docker/" + file: "02-installation-and-deployment/02-virtualization/01-docker.md" + source_path: "02- Installation & Deployment/02- Virtualization/01- Docker.md" + - kind: "page" + title: "Installing the VM OVA" + match_path: "/docs/02-installation-and-deployment/02-virtualization/02-installing-the-vm-ova/" + slug: "02-installation-and-deployment/02-virtualization/02-installing-the-vm-ova" + url: "/docs/02-installation-and-deployment/02-virtualization/02-installing-the-vm-ova/" + file: "02-installation-and-deployment/02-virtualization/02-installing-the-vm-ova.md" + source_path: "02- Installation & Deployment/02- Virtualization/02- Installing the VM OVA.md" + - kind: "page" + title: "Data Persistence" + match_path: "/docs/02-installation-and-deployment/02-virtualization/02-1-data-persistence/" + slug: "02-installation-and-deployment/02-virtualization/02-1-data-persistence" + url: "/docs/02-installation-and-deployment/02-virtualization/02-1-data-persistence/" + file: "02-installation-and-deployment/02-virtualization/02-1-data-persistence.md" + source_path: "02- Installation & Deployment/02- Virtualization/02-1 Data Persistence.md" + - kind: "page" + title: "Kubernetes" + match_path: "/docs/02-installation-and-deployment/02-virtualization/03-kubernetes/" + slug: "02-installation-and-deployment/02-virtualization/03-kubernetes" + url: "/docs/02-installation-and-deployment/02-virtualization/03-kubernetes/" + file: "02-installation-and-deployment/02-virtualization/03-kubernetes.md" + source_path: "02- Installation & Deployment/02- Virtualization/03- Kubernetes.md" + - kind: "section" + title: "Orchestrators" + match_path: "/docs/02-installation-and-deployment/03-orchestrators/" + children: + - kind: "page" + title: "Open Horizon" + match_path: "/docs/02-installation-and-deployment/03-orchestrators/01-open-horizon/" + slug: "02-installation-and-deployment/03-orchestrators/01-open-horizon" + url: "/docs/02-installation-and-deployment/03-orchestrators/01-open-horizon/" + file: "02-installation-and-deployment/03-orchestrators/01-open-horizon.md" + source_path: "02- Installation & Deployment/03- Orchestrators/01- Open Horizon.md" + - kind: "page" + title: "IBM IEAM (Edge Application Manager)" + match_path: "/docs/02-installation-and-deployment/03-orchestrators/02-ibm-ieam-edge-application-manager/" + slug: "02-installation-and-deployment/03-orchestrators/02-ibm-ieam-edge-application-manager" + url: "/docs/02-installation-and-deployment/03-orchestrators/02-ibm-ieam-edge-application-manager/" + file: "02-installation-and-deployment/03-orchestrators/02-ibm-ieam-edge-application-manager.md" + source_path: "02- Installation & Deployment/03- Orchestrators/02- IBM IEAM (Edge Application Manager).md" + - kind: "page" + title: "Barbara" + match_path: "/docs/02-installation-and-deployment/03-orchestrators/03-barbara/" + slug: "02-installation-and-deployment/03-orchestrators/03-barbara" + url: "/docs/02-installation-and-deployment/03-orchestrators/03-barbara/" + file: "02-installation-and-deployment/03-orchestrators/03-barbara.md" + source_path: "02- Installation & Deployment/03- Orchestrators/03- Barbara.md" + - kind: "page" + title: "DELL Distributed Private Cloud" + match_path: "/docs/02-installation-and-deployment/03-orchestrators/04-dell-distributed-private-cloud/" + slug: "02-installation-and-deployment/03-orchestrators/04-dell-distributed-private-cloud" + url: "/docs/02-installation-and-deployment/03-orchestrators/04-dell-distributed-private-cloud/" + file: "02-installation-and-deployment/03-orchestrators/04-dell-distributed-private-cloud.md" + source_path: "02- Installation & Deployment/03- Orchestrators/04- DELL Distributed Private Cloud.md" + - kind: "page" + title: "Zededa" + match_path: "/docs/02-installation-and-deployment/03-orchestrators/05-zededa/" + slug: "02-installation-and-deployment/03-orchestrators/05-zededa" + url: "/docs/02-installation-and-deployment/03-orchestrators/05-zededa/" + file: "02-installation-and-deployment/03-orchestrators/05-zededa.md" + source_path: "02- Installation & Deployment/03- Orchestrators/05- Zededa.md" + - kind: "section" + title: "Cloud Support" + match_path: "/docs/02-installation-and-deployment/04-cloud-support/" + children: + - kind: "page" + title: "AWS Deployment" + match_path: "/docs/02-installation-and-deployment/04-cloud-support/01-aws-deployment/" + slug: "02-installation-and-deployment/04-cloud-support/01-aws-deployment" + url: "/docs/02-installation-and-deployment/04-cloud-support/01-aws-deployment/" + file: "02-installation-and-deployment/04-cloud-support/01-aws-deployment.md" + source_path: "02- Installation & Deployment/04- Cloud Support/01- AWS Deployment.md" +- kind: "section" + title: "Training & Tutorials" + match_path: "/docs/03-training-and-tutorials/" + children: + - kind: "page" + title: "Training" + match_path: "/docs/03-training-and-tutorials/01-training/" + slug: "03-training-and-tutorials/01-training" + url: "/docs/03-training-and-tutorials/01-training/" + file: "03-training-and-tutorials/01-training.md" + source_path: "03- Training & Tutorials/01- Training.md" + - kind: "page" + title: "Basic Commands" + match_path: "/docs/03-training-and-tutorials/02-basic-commands/" + slug: "03-training-and-tutorials/02-basic-commands" + url: "/docs/03-training-and-tutorials/02-basic-commands/" + file: "03-training-and-tutorials/02-basic-commands.md" + source_path: "03- Training & Tutorials/02- Basic Commands.md" + - kind: "page" + title: "Query Data" + match_path: "/docs/03-training-and-tutorials/03-query-data/" + slug: "03-training-and-tutorials/03-query-data" + url: "/docs/03-training-and-tutorials/03-query-data/" + file: "03-training-and-tutorials/03-query-data.md" + source_path: "03- Training & Tutorials/03- Query Data.md" + - kind: "page" + title: "deployment-process" + match_path: "/docs/03-training-and-tutorials/04-deployment-process/" + slug: "03-training-and-tutorials/04-deployment-process" + url: "/docs/03-training-and-tutorials/04-deployment-process/" + file: "03-training-and-tutorials/04-deployment-process.md" + source_path: "03- Training & Tutorials/04- deployment-process.md" + - kind: "page" + title: "deployment-scripts" + match_path: "/docs/03-training-and-tutorials/05-deployment-scripts/" + slug: "03-training-and-tutorials/05-deployment-scripts" + url: "/docs/03-training-and-tutorials/05-deployment-scripts/" + file: "03-training-and-tutorials/05-deployment-scripts.md" + source_path: "03- Training & Tutorials/05- deployment-scripts.md" + - kind: "page" + title: "Nodes" + match_path: "/docs/03-training-and-tutorials/06-nodes/" + slug: "03-training-and-tutorials/06-nodes" + url: "/docs/03-training-and-tutorials/06-nodes/" + file: "03-training-and-tutorials/06-nodes.md" + source_path: "03- Training & Tutorials/06- Nodes.md" +- kind: "section" + title: "Southbound Interfaces" + match_path: "/docs/04-southbound-interfaces/" + children: + - kind: "page" + title: "Southbound Interfaces" + match_path: "/docs/04-southbound-interfaces/01-southbound-interfaces/" + slug: "04-southbound-interfaces/01-southbound-interfaces" + url: "/docs/04-southbound-interfaces/01-southbound-interfaces/" + file: "04-southbound-interfaces/01-southbound-interfaces.md" + source_path: "04- Southbound Interfaces/01- Southbound Interfaces.md" + - kind: "section" + title: "Direct Connectors" + match_path: "/docs/04-southbound-interfaces/02-direct-connectors/" + children: + - kind: "page" + title: "REST" + match_path: "/docs/04-southbound-interfaces/02-direct-connectors/01-rest/" + slug: "04-southbound-interfaces/02-direct-connectors/01-rest" + url: "/docs/04-southbound-interfaces/02-direct-connectors/01-rest/" + file: "04-southbound-interfaces/02-direct-connectors/01-rest.md" + source_path: "04- Southbound Interfaces/02- Direct Connectors/01- REST.md" + - kind: "page" + title: "Message Broker" + match_path: "/docs/04-southbound-interfaces/02-direct-connectors/02-message-broker/" + slug: "04-southbound-interfaces/02-direct-connectors/02-message-broker" + url: "/docs/04-southbound-interfaces/02-direct-connectors/02-message-broker/" + file: "04-southbound-interfaces/02-direct-connectors/02-message-broker.md" + source_path: "04- Southbound Interfaces/02- Direct Connectors/02- Message Broker.md" + - kind: "section" + title: "Industrial Connectors" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/" + children: + - kind: "page" + title: "Modbus" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/01-modbus/" + slug: "04-southbound-interfaces/03-industrial-connectors/01-modbus" + url: "/docs/04-southbound-interfaces/03-industrial-connectors/01-modbus/" + file: "04-southbound-interfaces/03-industrial-connectors/01-modbus.md" + source_path: "04- Southbound Interfaces/03- Industrial Connectors/01- Modbus.md" + - kind: "page" + title: "OPC-UA" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/02-opc-ua/" + slug: "04-southbound-interfaces/03-industrial-connectors/02-opc-ua" + url: "/docs/04-southbound-interfaces/03-industrial-connectors/02-opc-ua/" + file: "04-southbound-interfaces/03-industrial-connectors/02-opc-ua.md" + source_path: "04- Southbound Interfaces/03- Industrial Connectors/02- OPC-UA.md" + - kind: "page" + title: "EtherIP" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/03-etherip/" + slug: "04-southbound-interfaces/03-industrial-connectors/03-etherip" + url: "/docs/04-southbound-interfaces/03-industrial-connectors/03-etherip/" + file: "04-southbound-interfaces/03-industrial-connectors/03-etherip.md" + source_path: "04- Southbound Interfaces/03- Industrial Connectors/03- EtherIP.md" + - kind: "page" + title: "DNP3" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-dnp3/" + slug: "04-southbound-interfaces/03-industrial-connectors/04-dnp3" + url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-dnp3/" + file: "04-southbound-interfaces/03-industrial-connectors/04-dnp3.md" + source_path: "04- Southbound Interfaces/03- Industrial Connectors/04- DNP3.md" + - kind: "section" + title: "DNP3" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/" + children: + - kind: "page" + title: "DNP3 - Deploying Connector via Script" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script/" + slug: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script" + url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script/" + file: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script.md" + source_path: "04- Southbound Interfaces/03- Industrial Connectors/04-1 DNP3/01- DNP3 - Deploying Connector via Script.md" + - kind: "page" + title: "DNP3 - Mapping-Policies" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies/" + slug: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies" + url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies/" + file: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies.md" + source_path: "04- Southbound Interfaces/03- Industrial Connectors/04-1 DNP3/02- DNP3 - Mapping-Policies.md" + - kind: "page" + title: "DNP3 - TLS test certificates" + match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates/" + slug: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates" + url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates/" + file: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates.md" + source_path: "04- Southbound Interfaces/03- Industrial Connectors/04-1 DNP3/03- DNP3 - TLS test certificates.md" + - kind: "section" + title: "Monitoring" + match_path: "/docs/04-southbound-interfaces/04-monitoring/" + children: + - kind: "page" + title: "Node Monitoring" + match_path: "/docs/04-southbound-interfaces/04-monitoring/01-node-monitoring/" + slug: "04-southbound-interfaces/04-monitoring/01-node-monitoring" + url: "/docs/04-southbound-interfaces/04-monitoring/01-node-monitoring/" + file: "04-southbound-interfaces/04-monitoring/01-node-monitoring.md" + source_path: "04- Southbound Interfaces/04- Monitoring/01- Node Monitoring.md" + - kind: "page" + title: "Syslog" + match_path: "/docs/04-southbound-interfaces/04-monitoring/02-syslog/" + slug: "04-southbound-interfaces/04-monitoring/02-syslog" + url: "/docs/04-southbound-interfaces/04-monitoring/02-syslog/" + file: "04-southbound-interfaces/04-monitoring/02-syslog.md" + source_path: "04- Southbound Interfaces/04- Monitoring/02- Syslog.md" + - kind: "section" + title: "RPC & Media Streaming" + match_path: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/" + children: + - kind: "page" + title: "gRPC" + match_path: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc/" + slug: "04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc" + url: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc/" + file: "04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc.md" + source_path: "04- Southbound Interfaces/05- RPC & Media Streaming/01- gRPC.md" + - kind: "page" + title: "Video Streaming" + match_path: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming/" + slug: "04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming" + url: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming/" + file: "04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming.md" + source_path: "04- Southbound Interfaces/05- RPC & Media Streaming/02- Video Streaming.md" + - kind: "section" + title: "Third-Party" + match_path: "/docs/04-southbound-interfaces/06-third-party/" + children: + - kind: "page" + title: "node-RED" + match_path: "/docs/04-southbound-interfaces/06-third-party/01-node-red/" + slug: "04-southbound-interfaces/06-third-party/01-node-red" + url: "/docs/04-southbound-interfaces/06-third-party/01-node-red/" + file: "04-southbound-interfaces/06-third-party/01-node-red.md" + source_path: "04- Southbound Interfaces/06- Third-Party/01- node-RED.md" + - kind: "page" + title: "Telegraf" + match_path: "/docs/04-southbound-interfaces/06-third-party/02-telegraf/" + slug: "04-southbound-interfaces/06-third-party/02-telegraf" + url: "/docs/04-southbound-interfaces/06-third-party/02-telegraf/" + file: "04-southbound-interfaces/06-third-party/02-telegraf.md" + source_path: "04- Southbound Interfaces/06- Third-Party/02- Telegraf.md" + - kind: "page" + title: "EdgeX" + match_path: "/docs/04-southbound-interfaces/06-third-party/03-edgex/" + slug: "04-southbound-interfaces/06-third-party/03-edgex" + url: "/docs/04-southbound-interfaces/06-third-party/03-edgex/" + file: "04-southbound-interfaces/06-third-party/03-edgex.md" + source_path: "04- Southbound Interfaces/06- Third-Party/03- EdgeX.md" + - kind: "page" + title: "Kubearmor" + match_path: "/docs/04-southbound-interfaces/06-third-party/04-kubearmor/" + slug: "04-southbound-interfaces/06-third-party/04-kubearmor" + url: "/docs/04-southbound-interfaces/06-third-party/04-kubearmor/" + file: "04-southbound-interfaces/06-third-party/04-kubearmor.md" + source_path: "04- Southbound Interfaces/06- Third-Party/04- Kubearmor.md" + - kind: "page" + title: "Data Ingestion" + match_path: "/docs/04-southbound-interfaces/07-data-ingestion/" + slug: "04-southbound-interfaces/07-data-ingestion" + url: "/docs/04-southbound-interfaces/07-data-ingestion/" + file: "04-southbound-interfaces/07-data-ingestion.md" + source_path: "04- Southbound Interfaces/07- Data Ingestion.md" +- kind: "section" + title: "Northbound Connectors" + match_path: "/docs/05-northbound-connectors/" + children: + - kind: "page" + title: "Northbound Connectors" + match_path: "/docs/05-northbound-connectors/01-northbound-connectors/" + slug: "05-northbound-connectors/01-northbound-connectors" + url: "/docs/05-northbound-connectors/01-northbound-connectors/" + file: "05-northbound-connectors/01-northbound-connectors.md" + source_path: "05- Northbound Connectors/01- Northbound Connectors.md" + - kind: "page" + title: "Postman Integration" + match_path: "/docs/05-northbound-connectors/02-postman-integration/" + slug: "05-northbound-connectors/02-postman-integration" + url: "/docs/05-northbound-connectors/02-postman-integration/" + file: "05-northbound-connectors/02-postman-integration.md" + source_path: "05- Northbound Connectors/02- Postman Integration.md" + - kind: "page" + title: "Grafana" + match_path: "/docs/05-northbound-connectors/03-grafana/" + slug: "05-northbound-connectors/03-grafana" + url: "/docs/05-northbound-connectors/03-grafana/" + file: "05-northbound-connectors/03-grafana.md" + source_path: "05- Northbound Connectors/03- Grafana.md" + - kind: "page" + title: "Postgres Connector (Tableau)" + match_path: "/docs/05-northbound-connectors/04-postgres-connector-tableau/" + slug: "05-northbound-connectors/04-postgres-connector-tableau" + url: "/docs/05-northbound-connectors/04-postgres-connector-tableau/" + file: "05-northbound-connectors/04-postgres-connector-tableau.md" + source_path: "05- Northbound Connectors/04- Postgres Connector (Tableau).md" + - kind: "page" + title: "Microsoft (PowerBI)" + match_path: "/docs/05-northbound-connectors/05-microsoft-powerbi/" + slug: "05-northbound-connectors/05-microsoft-powerbi" + url: "/docs/05-northbound-connectors/05-microsoft-powerbi/" + file: "05-northbound-connectors/05-microsoft-powerbi.md" + source_path: "05- Northbound Connectors/05- Microsoft (PowerBI).md" + - kind: "page" + title: "Google" + match_path: "/docs/05-northbound-connectors/06-google/" + slug: "05-northbound-connectors/06-google" + url: "/docs/05-northbound-connectors/06-google/" + file: "05-northbound-connectors/06-google.md" + source_path: "05- Northbound Connectors/06- Google.md" + - kind: "page" + title: "Qlik" + match_path: "/docs/05-northbound-connectors/07-qlik/" + slug: "05-northbound-connectors/07-qlik" + url: "/docs/05-northbound-connectors/07-qlik/" + file: "05-northbound-connectors/07-qlik.md" + source_path: "05- Northbound Connectors/07- Qlik.md" + - kind: "page" + title: "Data Forwarding" + match_path: "/docs/05-northbound-connectors/08-data-forwarding/" + slug: "05-northbound-connectors/08-data-forwarding" + url: "/docs/05-northbound-connectors/08-data-forwarding/" + file: "05-northbound-connectors/08-data-forwarding.md" + source_path: "05- Northbound Connectors/08- Data Forwarding.md" +- kind: "section" + title: "Networking & Security" + match_path: "/docs/06-networking-and-security/" + children: + - kind: "page" + title: "Networking & Security" + match_path: "/docs/06-networking-and-security/01-networking-and-security/" + slug: "06-networking-and-security/01-networking-and-security" + url: "/docs/06-networking-and-security/01-networking-and-security/" + file: "06-networking-and-security/01-networking-and-security.md" + source_path: "06- Networking & Security/01- Networking & Security.md" + - kind: "page" + title: "Network Processing" + match_path: "/docs/06-networking-and-security/02-network-processing/" + slug: "06-networking-and-security/02-network-processing" + url: "/docs/06-networking-and-security/02-network-processing/" + file: "06-networking-and-security/02-network-processing.md" + source_path: "06- Networking & Security/02- Network Processing.md" + - kind: "page" + title: "Securing the Network" + match_path: "/docs/06-networking-and-security/03-securing-the-network/" + slug: "06-networking-and-security/03-securing-the-network" + url: "/docs/06-networking-and-security/03-securing-the-network/" + file: "06-networking-and-security/03-securing-the-network.md" + source_path: "06- Networking & Security/03- Securing the Network.md" + - kind: "page" + title: "Using REST" + match_path: "/docs/06-networking-and-security/04-using-rest/" + slug: "06-networking-and-security/04-using-rest" + url: "/docs/06-networking-and-security/04-using-rest/" + file: "06-networking-and-security/04-using-rest.md" + source_path: "06- Networking & Security/04- Using REST.md" + - kind: "page" + title: "Message Broker" + match_path: "/docs/06-networking-and-security/05-message-broker/" + slug: "06-networking-and-security/05-message-broker" + url: "/docs/06-networking-and-security/05-message-broker/" + file: "06-networking-and-security/05-message-broker.md" + source_path: "06- Networking & Security/05- Message Broker.md" + - kind: "page" + title: "Connectors To Data Sources" + match_path: "/docs/06-networking-and-security/05-1-connectors-to-data-sources/" + slug: "06-networking-and-security/05-1-connectors-to-data-sources" + url: "/docs/06-networking-and-security/05-1-connectors-to-data-sources/" + file: "06-networking-and-security/05-1-connectors-to-data-sources.md" + source_path: "06- Networking & Security/05-1 Connectors To Data Sources.md" + - kind: "section" + title: "Network" + match_path: "/docs/06-networking-and-security/06-network/" + children: + - kind: "page" + title: "Intro Overlay Network" + match_path: "/docs/06-networking-and-security/06-network/01-intro-overlay-network/" + slug: "06-networking-and-security/06-network/01-intro-overlay-network" + url: "/docs/06-networking-and-security/06-network/01-intro-overlay-network/" + file: "06-networking-and-security/06-network/01-intro-overlay-network.md" + source_path: "06- Networking & Security/06- Network/01- Intro Overlay Network.md" + - kind: "page" + title: "Nebula" + match_path: "/docs/06-networking-and-security/06-network/02-nebula/" + slug: "06-networking-and-security/06-network/02-nebula" + url: "/docs/06-networking-and-security/06-network/02-nebula/" + file: "06-networking-and-security/06-network/02-nebula.md" + source_path: "06- Networking & Security/06- Network/02- Nebula.md" + - kind: "page" + title: "Nebula Certifications" + match_path: "/docs/06-networking-and-security/06-network/02-1-nebula-certifications/" + slug: "06-networking-and-security/06-network/02-1-nebula-certifications" + url: "/docs/06-networking-and-security/06-network/02-1-nebula-certifications/" + file: "06-networking-and-security/06-network/02-1-nebula-certifications.md" + source_path: "06- Networking & Security/06- Network/02-1 Nebula Certifications.md" + - kind: "page" + title: "NGINX" + match_path: "/docs/06-networking-and-security/06-network/03-nginx/" + slug: "06-networking-and-security/06-network/03-nginx" + url: "/docs/06-networking-and-security/06-network/03-nginx/" + file: "06-networking-and-security/06-network/03-nginx.md" + source_path: "06- Networking & Security/06- Network/03- NGINX.md" + - kind: "section" + title: "Security" + match_path: "/docs/06-networking-and-security/07-security/" + children: + - kind: "section" + title: "Built-in Authentication" + match_path: "/docs/06-networking-and-security/07-security/01-built-in-authentication/" + children: + - kind: "page" + title: "Authentication" + match_path: "/docs/06-networking-and-security/07-security/01-built-in-authentication/01-authentication/" + slug: "06-networking-and-security/07-security/01-built-in-authentication/01-authentication" + url: "/docs/06-networking-and-security/07-security/01-built-in-authentication/01-authentication/" + file: "06-networking-and-security/07-security/01-built-in-authentication/01-authentication.md" + source_path: "06- Networking & Security/07- Security/01- Built-in Authentication/01- Authentication.md" + - kind: "page" + title: "Authentication-policies" + match_path: "/docs/06-networking-and-security/07-security/01-built-in-authentication/02-authentication-policies/" + slug: "06-networking-and-security/07-security/01-built-in-authentication/02-authentication-policies" + url: "/docs/06-networking-and-security/07-security/01-built-in-authentication/02-authentication-policies/" + file: "06-networking-and-security/07-security/01-built-in-authentication/02-authentication-policies.md" + source_path: "06- Networking & Security/07- Security/01- Built-in Authentication/02- Authentication-policies.md" + - kind: "section" + title: "Trusted Platform Module (TPM)" + match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/" + children: + - kind: "page" + title: "TMP Configuration" + match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration/" + slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration" + url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration/" + file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration.md" + source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/01- TMP Configuration.md" + - kind: "page" + title: "Software TPM" + match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm/" + slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm" + url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm/" + file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm.md" + source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/02- Software TPM.md" +- kind: "section" + title: "CLI" + match_path: "/docs/07-cli/" + children: + - kind: "page" + title: "CLI" + match_path: "/docs/07-cli/01-cli/" + slug: "07-cli/01-cli" + url: "/docs/07-cli/01-cli/" + file: "07-cli/01-cli.md" + source_path: "07- CLI/01- CLI.md" + - kind: "page" + title: "Background Processes" + match_path: "/docs/07-cli/02-background-processes/" + slug: "07-cli/02-background-processes" + url: "/docs/07-cli/02-background-processes/" + file: "07-cli/02-background-processes.md" + source_path: "07- CLI/02- Background Processes.md" + - kind: "page" + title: "Nodes" + match_path: "/docs/07-cli/02-1-nodes/" + slug: "07-cli/02-1-nodes" + url: "/docs/07-cli/02-1-nodes/" + file: "07-cli/02-1-nodes.md" + source_path: "07- CLI/02-1 Nodes.md" + - kind: "page" + title: "Get & Set" + match_path: "/docs/07-cli/03-get-and-set/" + slug: "07-cli/03-get-and-set" + url: "/docs/07-cli/03-get-and-set/" + file: "07-cli/03-get-and-set.md" + source_path: "07- CLI/03- Get & Set.md" + - kind: "page" + title: "SQL" + match_path: "/docs/07-cli/04-sql/" + slug: "07-cli/04-sql" + url: "/docs/07-cli/04-sql/" + file: "07-cli/04-sql.md" + source_path: "07- CLI/04- SQL.md" + - kind: "section" + title: "Notification" + match_path: "/docs/07-cli/04-1-notification/" + children: + - kind: "page" + title: "SMTP" + match_path: "/docs/07-cli/04-1-notification/01-smtp/" + slug: "07-cli/04-1-notification/01-smtp" + url: "/docs/07-cli/04-1-notification/01-smtp/" + file: "07-cli/04-1-notification/01-smtp.md" + source_path: "07- CLI/04-1 Notification/01- SMTP.md" + - kind: "page" + title: "REST" + match_path: "/docs/07-cli/04-1-notification/02-rest/" + slug: "07-cli/04-1-notification/02-rest" + url: "/docs/07-cli/04-1-notification/02-rest/" + file: "07-cli/04-1-notification/02-rest.md" + source_path: "07- CLI/04-1 Notification/02- REST.md" + - kind: "page" + title: "Webhooks" + match_path: "/docs/07-cli/04-1-notification/02-1-webhooks/" + slug: "07-cli/04-1-notification/02-1-webhooks" + url: "/docs/07-cli/04-1-notification/02-1-webhooks/" + file: "07-cli/04-1-notification/02-1-webhooks.md" + source_path: "07- CLI/04-1 Notification/02-1 Webhooks.md" + - kind: "page" + title: "JSON Data Transformation" + match_path: "/docs/07-cli/05-json-data-transformation/" + slug: "07-cli/05-json-data-transformation" + url: "/docs/07-cli/05-json-data-transformation/" + file: "07-cli/05-json-data-transformation.md" + source_path: "07- CLI/05- JSON Data Transformation.md" + - kind: "page" + title: "Test & Node Status" + match_path: "/docs/07-cli/06-test-and-node-status/" + slug: "07-cli/06-test-and-node-status" + url: "/docs/07-cli/06-test-and-node-status/" + file: "07-cli/06-test-and-node-status.md" + source_path: "07- CLI/06- Test & Node Status.md" + - kind: "page" + title: "Monitoring & Notifications" + match_path: "/docs/07-cli/07-monitoring-and-notifications/" + slug: "07-cli/07-monitoring-and-notifications" + url: "/docs/07-cli/07-monitoring-and-notifications/" + file: "07-cli/07-monitoring-and-notifications.md" + source_path: "07- CLI/07- Monitoring & Notifications.md" + - kind: "page" + title: "Conditional Execution and Control Flow" + match_path: "/docs/07-cli/08-conditional-execution-and-control-flow/" + slug: "07-cli/08-conditional-execution-and-control-flow" + url: "/docs/07-cli/08-conditional-execution-and-control-flow/" + file: "07-cli/08-conditional-execution-and-control-flow.md" + source_path: "07- CLI/08- Conditional Execution and Control Flow.md" + - kind: "page" + title: "File Commands" + match_path: "/docs/07-cli/09-file-commands/" + slug: "07-cli/09-file-commands" + url: "/docs/07-cli/09-file-commands/" + file: "07-cli/09-file-commands.md" + source_path: "07- CLI/09- File Commands.md" +- kind: "section" + title: "Blockchain & Metadata" + match_path: "/docs/08-blockchain-and-metadata/" + children: + - kind: "page" + title: "Blockchain" + match_path: "/docs/08-blockchain-and-metadata/01-blockchain/" + slug: "08-blockchain-and-metadata/01-blockchain" + url: "/docs/08-blockchain-and-metadata/01-blockchain/" + file: "08-blockchain-and-metadata/01-blockchain.md" + source_path: "08- Blockchain & Metadata/01- Blockchain.md" + - kind: "page" + title: "Policy & Metadata" + match_path: "/docs/08-blockchain-and-metadata/02-policy-and-metadata/" + slug: "08-blockchain-and-metadata/02-policy-and-metadata" + url: "/docs/08-blockchain-and-metadata/02-policy-and-metadata/" + file: "08-blockchain-and-metadata/02-policy-and-metadata.md" + source_path: "08- Blockchain & Metadata/02- Policy & Metadata.md" + - kind: "page" + title: "ANMP Policy" + match_path: "/docs/08-blockchain-and-metadata/02-1-anmp-policy/" + slug: "08-blockchain-and-metadata/02-1-anmp-policy" + url: "/docs/08-blockchain-and-metadata/02-1-anmp-policy/" + file: "08-blockchain-and-metadata/02-1-anmp-policy.md" + source_path: "08- Blockchain & Metadata/02-1 ANMP Policy.md" + - kind: "page" + title: "Blockchain Commands" + match_path: "/docs/08-blockchain-and-metadata/03-blockchain-commands/" + slug: "08-blockchain-and-metadata/03-blockchain-commands" + url: "/docs/08-blockchain-and-metadata/03-blockchain-commands/" + file: "08-blockchain-and-metadata/03-blockchain-commands.md" + source_path: "08- Blockchain & Metadata/03- Blockchain Commands.md" + - kind: "page" + title: "Blockchain Full Circle" + match_path: "/docs/08-blockchain-and-metadata/03-1-blockchain-full-circle/" + slug: "08-blockchain-and-metadata/03-1-blockchain-full-circle" + url: "/docs/08-blockchain-and-metadata/03-1-blockchain-full-circle/" + file: "08-blockchain-and-metadata/03-1-blockchain-full-circle.md" + source_path: "08- Blockchain & Metadata/03-1 Blockchain Full Circle.md" + - kind: "page" + title: "Mapping Policy" + match_path: "/docs/08-blockchain-and-metadata/04-mapping-policy/" + slug: "08-blockchain-and-metadata/04-mapping-policy" + url: "/docs/08-blockchain-and-metadata/04-mapping-policy/" + file: "08-blockchain-and-metadata/04-mapping-policy.md" + source_path: "08- Blockchain & Metadata/04- Mapping Policy.md" + - kind: "page" + title: "Unitfied Namespace" + match_path: "/docs/08-blockchain-and-metadata/05-unitfied-namespace/" + slug: "08-blockchain-and-metadata/05-unitfied-namespace" + url: "/docs/08-blockchain-and-metadata/05-unitfied-namespace/" + file: "08-blockchain-and-metadata/05-unitfied-namespace.md" + source_path: "08- Blockchain & Metadata/05- Unitfied Namespace.md" + - kind: "page" + title: "UNS Custom Dynamic Examples" + match_path: "/docs/08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples/" + slug: "08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples" + url: "/docs/08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples/" + file: "08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples.md" + source_path: "08- Blockchain & Metadata/05-1 UNS Custom Dynamic Examples.md" + - kind: "page" + title: "UNS Custom Examples" + match_path: "/docs/08-blockchain-and-metadata/05-2-uns-custom-examples/" + slug: "08-blockchain-and-metadata/05-2-uns-custom-examples" + url: "/docs/08-blockchain-and-metadata/05-2-uns-custom-examples/" + file: "08-blockchain-and-metadata/05-2-uns-custom-examples.md" + source_path: "08- Blockchain & Metadata/05-2 UNS Custom Examples.md" +- kind: "section" + title: "Data Management" + match_path: "/docs/09-data-management/" + children: + - kind: "page" + title: "Data Management" + match_path: "/docs/09-data-management/01-data-management/" + slug: "09-data-management/01-data-management" + url: "/docs/09-data-management/01-data-management/" + file: "09-data-management/01-data-management.md" + source_path: "09- Data Management/01- Data Management.md" + - kind: "page" + title: "Databases" + match_path: "/docs/09-data-management/02-databases/" + slug: "09-data-management/02-databases" + url: "/docs/09-data-management/02-databases/" + file: "09-data-management/02-databases.md" + source_path: "09- Data Management/02- Databases.md" + - kind: "section" + title: "Databases" + match_path: "/docs/09-data-management/02-1-databases/" + children: + - kind: "page" + title: "SQL Storage" + match_path: "/docs/09-data-management/02-1-databases/01-sql-storage/" + slug: "09-data-management/02-1-databases/01-sql-storage" + url: "/docs/09-data-management/02-1-databases/01-sql-storage/" + file: "09-data-management/02-1-databases/01-sql-storage.md" + source_path: "09- Data Management/02-1 Databases/01- SQL Storage.md" + - kind: "page" + title: "Blob Storage" + match_path: "/docs/09-data-management/02-1-databases/02-blob-storage/" + slug: "09-data-management/02-1-databases/02-blob-storage" + url: "/docs/09-data-management/02-1-databases/02-blob-storage/" + file: "09-data-management/02-1-databases/02-blob-storage.md" + source_path: "09- Data Management/02-1 Databases/02- Blob Storage.md" + - kind: "page" + title: "NoSQL (MongoDB)" + match_path: "/docs/09-data-management/02-1-databases/03-nosql-mongodb/" + slug: "09-data-management/02-1-databases/03-nosql-mongodb" + url: "/docs/09-data-management/02-1-databases/03-nosql-mongodb/" + file: "09-data-management/02-1-databases/03-nosql-mongodb.md" + source_path: "09- Data Management/02-1 Databases/03- NoSQL (MongoDB).md" + - kind: "page" + title: "Bucket Storage" + match_path: "/docs/09-data-management/02-1-databases/04-bucket-storage/" + slug: "09-data-management/02-1-databases/04-bucket-storage" + url: "/docs/09-data-management/02-1-databases/04-bucket-storage/" + file: "09-data-management/02-1-databases/04-bucket-storage.md" + source_path: "09- Data Management/02-1 Databases/04- Bucket Storage.md" + - kind: "page" + title: "MilvusDB" + match_path: "/docs/09-data-management/02-1-databases/05-milvusdb/" + slug: "09-data-management/02-1-databases/05-milvusdb" + url: "/docs/09-data-management/02-1-databases/05-milvusdb/" + file: "09-data-management/02-1-databases/05-milvusdb.md" + source_path: "09- Data Management/02-1 Databases/05- MilvusDB.md" + - kind: "page" + title: "Data Aggregations" + match_path: "/docs/09-data-management/02-2-data-aggregations/" + slug: "09-data-management/02-2-data-aggregations" + url: "/docs/09-data-management/02-2-data-aggregations/" + file: "09-data-management/02-2-data-aggregations.md" + source_path: "09- Data Management/02-2 Data Aggregations.md" + - kind: "page" + title: "High Availability" + match_path: "/docs/09-data-management/03-high-availability/" + slug: "09-data-management/03-high-availability" + url: "/docs/09-data-management/03-high-availability/" + file: "09-data-management/03-high-availability.md" + source_path: "09- Data Management/03- High Availability.md" + - kind: "page" + title: "HA Support" + match_path: "/docs/09-data-management/03-1-ha-support/" + slug: "09-data-management/03-1-ha-support" + url: "/docs/09-data-management/03-1-ha-support/" + file: "09-data-management/03-1-ha-support.md" + source_path: "09- Data Management/03-1 HA Support.md" + - kind: "page" + title: "File Processing" + match_path: "/docs/09-data-management/04-file-processing/" + slug: "09-data-management/04-file-processing" + url: "/docs/09-data-management/04-file-processing/" + file: "09-data-management/04-file-processing.md" + source_path: "09- Data Management/04- File Processing.md" + - kind: "page" + title: "Query Profiling" + match_path: "/docs/09-data-management/06-query-profiling/" + slug: "09-data-management/06-query-profiling" + url: "/docs/09-data-management/06-query-profiling/" + file: "09-data-management/06-query-profiling.md" + source_path: "09- Data Management/06- Query Profiling.md" +- kind: "section" + title: "Edge Data Manager" + match_path: "/docs/10-edge-data-manager/" + children: + - kind: "page" + title: "EDM" + match_path: "/docs/10-edge-data-manager/01-edm/" + slug: "10-edge-data-manager/01-edm" + url: "/docs/10-edge-data-manager/01-edm/" + file: "10-edge-data-manager/01-edm.md" + source_path: "10- Edge Data Manager/01- EDM.md" +- kind: "section" + title: "Extended Services" + match_path: "/docs/11-extended-services/" + children: + - kind: "page" + title: "LLM Dashboard Generation" + match_path: "/docs/11-extended-services/01-llm-dashboard-generation/" + slug: "11-extended-services/01-llm-dashboard-generation" + url: "/docs/11-extended-services/01-llm-dashboard-generation/" + file: "11-extended-services/01-llm-dashboard-generation.md" + source_path: "11- Extended Services/01- LLM Dashboard Generation.md" + - kind: "page" + title: "mcpAI" + match_path: "/docs/11-extended-services/02-mcpai/" + slug: "11-extended-services/02-mcpai" + url: "/docs/11-extended-services/02-mcpai/" + file: "11-extended-services/02-mcpai.md" + source_path: "11- Extended Services/02- mcpAI.md" + - kind: "page" + title: "federated learning (demo)" + match_path: "/docs/11-extended-services/03-federated-learning-demo/" + slug: "11-extended-services/03-federated-learning-demo" + url: "/docs/11-extended-services/03-federated-learning-demo/" + file: "11-extended-services/03-federated-learning-demo.md" + source_path: "11- Extended Services/03- federated learning (demo).md" +- kind: "section" + title: "Examples & Use Cases" + match_path: "/docs/12-examples-and-use-cases/" + children: + - kind: "page" + title: "Examples & Use Cases" + match_path: "/docs/12-examples-and-use-cases/01-examples-and-use-cases/" + slug: "12-examples-and-use-cases/01-examples-and-use-cases" + url: "/docs/12-examples-and-use-cases/01-examples-and-use-cases/" + file: "12-examples-and-use-cases/01-examples-and-use-cases.md" + source_path: "12- Examples & Use Cases/01- Examples & Use Cases.md" +- kind: "section" + title: "Support & Troubleshooting" + match_path: "/docs/13-support-and-troubleshooting/" + children: + - kind: "page" + title: "FAQ" + match_path: "/docs/13-support-and-troubleshooting/01-faq/" + slug: "13-support-and-troubleshooting/01-faq" + url: "/docs/13-support-and-troubleshooting/01-faq/" + file: "13-support-and-troubleshooting/01-faq.md" + source_path: "13- Support & Troubleshooting/01- FAQ.md" + - kind: "page" + title: "Troubleshooting" + match_path: "/docs/13-support-and-troubleshooting/02-troubleshooting/" + slug: "13-support-and-troubleshooting/02-troubleshooting" + url: "/docs/13-support-and-troubleshooting/02-troubleshooting/" + file: "13-support-and-troubleshooting/02-troubleshooting.md" + source_path: "13- Support & Troubleshooting/02- Troubleshooting.md" + - kind: "page" + title: "MTU Network Issue" + match_path: "/docs/13-support-and-troubleshooting/03-mtu-network-issue/" + slug: "13-support-and-troubleshooting/03-mtu-network-issue" + url: "/docs/13-support-and-troubleshooting/03-mtu-network-issue/" + file: "13-support-and-troubleshooting/03-mtu-network-issue.md" + source_path: "13- Support & Troubleshooting/03- MTU Network Issue.md" + - kind: "section" + title: "Third-Party Support" + match_path: "/docs/13-support-and-troubleshooting/04-third-party-support/" + children: + - kind: "page" + title: "Docker & K8s Commands" + match_path: "/docs/13-support-and-troubleshooting/04-third-party-support/01-docker-and-k8s-commands/" + slug: "13-support-and-troubleshooting/04-third-party-support/01-docker-and-k8s-commands" + url: "/docs/13-support-and-troubleshooting/04-third-party-support/01-docker-and-k8s-commands/" + file: "13-support-and-troubleshooting/04-third-party-support/01-docker-and-k8s-commands.md" + source_path: "13- Support & Troubleshooting/04- Third-Party Support/01- Docker & K8s Commands.md" + - kind: "page" + title: "MinIO" + match_path: "/docs/13-support-and-troubleshooting/04-third-party-support/02-minio/" + slug: "13-support-and-troubleshooting/04-third-party-support/02-minio" + url: "/docs/13-support-and-troubleshooting/04-third-party-support/02-minio/" + file: "13-support-and-troubleshooting/04-third-party-support/02-minio.md" + source_path: "13- Support & Troubleshooting/04- Third-Party Support/02- MinIO.md" + - kind: "page" + title: "MilvusDB" + match_path: "/docs/13-support-and-troubleshooting/04-third-party-support/03-milvusdb/" + slug: "13-support-and-troubleshooting/04-third-party-support/03-milvusdb" + url: "/docs/13-support-and-troubleshooting/04-third-party-support/03-milvusdb/" + file: "13-support-and-troubleshooting/04-third-party-support/03-milvusdb.md" + source_path: "13- Support & Troubleshooting/04- Third-Party Support/03- MilvusDB.md" + - kind: "page" + title: "Data Generator" + match_path: "/docs/13-support-and-troubleshooting/05-data-generator/" + slug: "13-support-and-troubleshooting/05-data-generator" + url: "/docs/13-support-and-troubleshooting/05-data-generator/" + file: "13-support-and-troubleshooting/05-data-generator.md" + source_path: "13- Support & Troubleshooting/05- Data Generator.md" +- kind: "section" + title: "Releases Notes" + match_path: "/docs/14-releases-notes/" + children: + - kind: "page" + title: "AnylogEDF Releases Notes" + match_path: "/docs/14-releases-notes/01-anylogedf-releases-notes/" + slug: "14-releases-notes/01-anylogedf-releases-notes" + url: "/docs/14-releases-notes/01-anylogedf-releases-notes/" + file: "14-releases-notes/01-anylogedf-releases-notes.md" + source_path: "14- Releases Notes/01- AnylogEDF Releases Notes.md" + - kind: "page" + title: "AnylogEDF SOURCE-CHANGELOGS" + match_path: "/docs/14-releases-notes/02-anylogedf-source-changelogs/" + slug: "14-releases-notes/02-anylogedf-source-changelogs" + url: "/docs/14-releases-notes/02-anylogedf-source-changelogs/" + file: "14-releases-notes/02-anylogedf-source-changelogs.md" + source_path: "14- Releases Notes/02- AnylogEDF SOURCE-CHANGELOGS.md" + - kind: "page" + title: "AnylogEDF DEPLOYMENT_SCRIPTS-CHANGELOGS" + match_path: "/docs/14-releases-notes/03-anylogedf-deployment_scripts-changelogs/" + slug: "14-releases-notes/03-anylogedf-deployment_scripts-changelogs" + url: "/docs/14-releases-notes/03-anylogedf-deployment_scripts-changelogs/" + file: "14-releases-notes/03-anylogedf-deployment_scripts-changelogs.md" + source_path: "14- Releases Notes/03- AnylogEDF DEPLOYMENT_SCRIPTS-CHANGELOGS.md" + - kind: "page" + title: "AnylogEDF DOCKER_COMPOSE-CHANGELOG" + match_path: "/docs/14-releases-notes/04-anylogedf-docker_compose-changelog/" + slug: "14-releases-notes/04-anylogedf-docker_compose-changelog" + url: "/docs/14-releases-notes/04-anylogedf-docker_compose-changelog/" + file: "14-releases-notes/04-anylogedf-docker_compose-changelog.md" + source_path: "14- Releases Notes/04- AnylogEDF DOCKER_COMPOSE-CHANGELOG.md" +- kind: "section" + title: "Appendices" + match_path: "/docs/15-appendices/" + children: + - kind: "section" + title: "Legal & Licensing" + match_path: "/docs/15-appendices/01-legal-and-licensing/" + children: + - kind: "page" + title: "AnylogEDF Evaluation License Agreement" + match_path: "/docs/15-appendices/01-legal-and-licensing/01-anylogedf-evaluation-license-agreement/" + slug: "15-appendices/01-legal-and-licensing/01-anylogedf-evaluation-license-agreement" + url: "/docs/15-appendices/01-legal-and-licensing/01-anylogedf-evaluation-license-agreement/" + file: "15-appendices/01-legal-and-licensing/01-anylogedf-evaluation-license-agreement.md" + source_path: "15- Appendices/01- Legal & Licensing/01- AnylogEDF Evaluation License Agreement.md" + - kind: "page" + title: "Privacy Policy" + match_path: "/docs/15-appendices/01-legal-and-licensing/02-privacy-policy/" + slug: "15-appendices/01-legal-and-licensing/02-privacy-policy" + url: "/docs/15-appendices/01-legal-and-licensing/02-privacy-policy/" + file: "15-appendices/01-legal-and-licensing/02-privacy-policy.md" + source_path: "15- Appendices/01- Legal & Licensing/02- Privacy Policy.md" + - kind: "page" + title: "Notice of Open Source Usage" + match_path: "/docs/15-appendices/01-legal-and-licensing/03-notice-of-open-source-usage/" + slug: "15-appendices/01-legal-and-licensing/03-notice-of-open-source-usage" + url: "/docs/15-appendices/01-legal-and-licensing/03-notice-of-open-source-usage/" + file: "15-appendices/01-legal-and-licensing/03-notice-of-open-source-usage.md" + source_path: "15- Appendices/01- Legal & Licensing/03- Notice of Open Source Usage.md" + - kind: "page" + title: "AnylogEDF used OPENSOURCE-NOTICE" + match_path: "/docs/15-appendices/01-legal-and-licensing/04-anylogedf-used-opensource-notice/" + slug: "15-appendices/01-legal-and-licensing/04-anylogedf-used-opensource-notice" + url: "/docs/15-appendices/01-legal-and-licensing/04-anylogedf-used-opensource-notice/" + file: "15-appendices/01-legal-and-licensing/04-anylogedf-used-opensource-notice.md" + source_path: "15- Appendices/01- Legal & Licensing/04- AnylogEDF used OPENSOURCE-NOTICE.md" diff --git a/_layouts/default.html b/_layouts/default.html index 259c8f6..13846a3 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -12,7 +12,6 @@ {% seo %} - {% include header.html %}
diff --git a/assets/css/main.css b/assets/css/main.css index b818050..c78fbaa 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -11,6 +11,7 @@ --gray-50: #f8f9fb; --gray-100: #f1f3f6; --gray-200: #e4e9f0; + --gray-300: #d4dce7; --gray-400: #a0aab8; --gray-600: #64748b; --gray-800: #2d3748; @@ -39,6 +40,7 @@ --gray-50: #161b22; --gray-100: #1c2128; --gray-200: #2d333b; + --gray-300: #38414b; --gray-400: #6e7681; --gray-600: #8b949e; --gray-800: #cdd9e5; @@ -68,6 +70,17 @@ body { line-height: 1.75; -webkit-font-smoothing: antialiased; } +.visually-hidden { + position: absolute !important; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} a { color: var(--teal-mid); text-decoration: none; } a:hover { color: var(--teal); text-decoration: underline; } img { max-width: 100%; height: auto; display: block; } @@ -171,7 +184,7 @@ img { max-width: 100%; height: auto; display: block; } margin-left: auto; display: flex; align-items: center; - gap: 1.25rem; + gap: .55rem; } .header-nav a { font-size: 13.5px; @@ -180,21 +193,24 @@ img { max-width: 100%; height: auto; display: block; } transition: color .15s; text-decoration: none; } -.header-nav a:hover, -.header-nav a.active { color: var(--white); } -.btn-github { +.header-nav a:hover { color: var(--white); } +.btn-github, +.btn-header { display: flex; align-items: center; gap: 6px; - padding: 5px 12px; + padding: 5px 10px; border: 1px solid rgba(255,255,255,.18); border-radius: var(--radius); background: rgba(255,255,255,.07); color: rgba(255,255,255,.75) !important; font-size: 13px !important; + line-height: 1.2; + white-space: nowrap; transition: background .15s, border-color .15s; } -.btn-github:hover { +.btn-github:hover, +.btn-header:hover { background: rgba(255,255,255,.14) !important; border-color: rgba(255,255,255,.28) !important; text-decoration: none; @@ -255,7 +271,7 @@ img { max-width: 100%; height: auto; display: block; } left: 0; bottom: 0; width: var(--sidebar-w); - background: var(--gray-50); + background: linear-gradient(180deg, var(--gray-50) 0%, var(--surface) 100%); border-right: 1px solid var(--border); overflow-y: auto; z-index: 150; @@ -263,20 +279,22 @@ img { max-width: 100%; height: auto; display: block; } flex-direction: column; } .sidebar-inner { - padding: 1rem 0 2rem; + padding: 1rem 0 1.5rem; display: flex; flex-direction: column; flex: 1; } .sidebar-search { - position: relative; padding: 0 .875rem .75rem; border-bottom: 1px solid var(--border); - margin-bottom: .5rem; + margin-bottom: .65rem; +} +.sidebar-search-box { + position: relative; } .search-icon { position: absolute; - left: 1.375rem; + left: .75rem; top: 50%; transform: translateY(-60%); color: var(--gray-400); @@ -284,45 +302,212 @@ img { max-width: 100%; height: auto; display: block; } } .sidebar-search input { width: 100%; - padding: 7px 10px 7px 30px; + padding: 8px 10px 8px 36px; font-size: 13px; font-family: inherit; border: 1px solid var(--border); + border-radius: 999px; + background: var(--surface-raised); + color: var(--text); + outline: none; + transition: border-color .15s, box-shadow .15s, background .15s; +} +.sidebar-search input:focus { + border-color: var(--teal-mid); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--teal-mid) 14%, transparent); +} +.sidebar-search-results { + margin-top: .5rem; + max-height: 56vh; + overflow-y: auto; + border: 1px solid var(--border); border-radius: var(--radius); background: var(--white); + box-shadow: 0 12px 28px rgba(15, 23, 42, .12); +} +.sidebar-search-results a, +.header-search-results a { + display: block; + text-decoration: none; +} +.sidebar-search-results a { + padding: .65rem .7rem; + border-bottom: 1px solid var(--border); color: var(--text); - outline: none; - transition: border-color .15s; } -.sidebar-search input:focus { border-color: var(--teal-mid); } -.sidebar-nav { padding: 0 .75rem; } -.nav-section { margin-bottom: .25rem; } -.nav-section-title { - font-size: 10.5px; - font-weight: 600; - letter-spacing: .07em; - text-transform: uppercase; - color: var(--gray-400); - padding: .75rem .375rem .3rem; +.sidebar-search-results a:last-child { border-bottom: none; } +.sidebar-search-results a:hover { background: var(--gray-100); } +.result-title { + display: block; + font-size: 13px; + font-weight: 650; + color: var(--text); } -.nav-section ul { list-style: none; } -.nav-section ul li a { +.result-path { display: block; - padding: 5px 10px; + margin-top: .15rem; + font-size: 11px; + color: var(--teal-mid); + overflow-wrap: anywhere; +} +.result-snippet { + display: block; + margin-top: .3rem; + font-size: 12px; + line-height: 1.45; + color: var(--gray-500); +} +.search-empty { + padding: .75rem; + font-size: 12.5px; + color: var(--gray-500); +} +.sidebar-nav { + padding: 0 .75rem; font-size: 13.5px; - color: var(--gray-800); +} +.sidebar-home-link { + margin: 0 0 .55rem; + border-bottom: 1px solid var(--border); + border-radius: 0; + font-weight: 620; +} +.nav-tree { + list-style: none; +} +.nav-tree-depth-0 { + display: flex; + flex-direction: column; + gap: .2rem; +} +.nav-item { + min-width: 0; +} +.nav-item-depth-0.nav-item-section { + margin-top: .35rem; +} +.nav-folder { + border-radius: var(--radius); +} +.nav-tree-depth-0 > .nav-item > .nav-folder { + padding: .2rem; + border: 1px solid transparent; +} +.nav-folder[open] { + background: color-mix(in srgb, var(--surface-raised) 88%, transparent); + border-color: var(--border); + box-shadow: 0 10px 24px rgba(15, 23, 42, .04); +} +[data-theme="dark"] .nav-folder[open] { + box-shadow: none; +} +.nav-folder-summary { + list-style: none; + display: flex; + align-items: flex-start; + gap: .55rem; + width: 100%; + padding: .48rem .62rem; border-radius: var(--radius); + cursor: pointer; + color: var(--gray-800); + font-weight: 620; + line-height: 1.35; transition: background .1s, color .1s; +} +.nav-folder-summary::-webkit-details-marker { + display: none; +} +.nav-folder-summary::before { + content: "▸"; + color: var(--gray-400); + font-size: 10px; + line-height: 1.4; + margin-top: .18rem; + transition: transform .15s ease, color .1s ease; +} +.nav-folder[open] > .nav-folder-summary::before { + transform: rotate(90deg); +} +.nav-folder-summary:hover { + background: color-mix(in srgb, var(--gray-100) 82%, transparent); + color: var(--text); +} +.nav-folder-summary.active { + color: var(--teal); + background: color-mix(in srgb, var(--teal-faint) 78%, transparent); +} +.nav-folder-label { + min-width: 0; + overflow-wrap: anywhere; +} +.nav-tree-depth-0 > .nav-item > .nav-folder > .nav-folder-summary { + font-size: 13px; + text-transform: none; + letter-spacing: 0; + color: var(--text-muted); + padding-top: .42rem; + padding-bottom: .42rem; +} +.nav-tree-depth-0 > .nav-item > .nav-folder > .nav-folder-summary:hover { + color: var(--text); +} +.nav-tree-depth-0 > .nav-item.is-ancestor > .nav-folder > .nav-folder-summary { + color: var(--teal); + background: color-mix(in srgb, var(--teal-faint) 82%, transparent); +} +.nav-tree-depth-1, +.nav-tree-depth-2, +.nav-tree-depth-3, +.nav-tree-depth-4 { + padding-left: .7rem; + margin: .16rem 0 .28rem .35rem; + border-left: 1px solid color-mix(in srgb, var(--gray-300) 70%, transparent); +} +.nav-page-link { + display: block; + padding: .42rem .68rem; + border-radius: var(--radius); + color: var(--gray-800); + line-height: 1.42; text-decoration: none; + overflow-wrap: anywhere; + transition: background .1s, color .1s; } -.nav-section ul li a:hover { - background: var(--gray-200); +.nav-page-link:hover { + background: color-mix(in srgb, var(--gray-100) 84%, transparent); color: var(--text); } -.nav-section ul li a.active { +.nav-page-link.active { background: var(--teal-faint); color: var(--teal); - font-weight: 500; + font-weight: 600; + box-shadow: inset 3px 0 0 var(--teal); +} +.nav-item.is-active > .nav-page-link { + position: relative; +} +.nav-item.is-active > .nav-page-link::after { + content: ""; + position: absolute; + top: 50%; + right: .6rem; + width: 7px; + height: 7px; + border-radius: 999px; + background: currentColor; + transform: translateY(-50%); + opacity: .9; +} +[data-theme="dark"] .nav-page-link.active, +[data-theme="dark"] .nav-folder-summary.active, +[data-theme="dark"] .nav-tree-depth-0 > .nav-item.is-ancestor > .nav-folder > .nav-folder-summary { + box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--teal-mid) 24%, transparent); +} +.nav-item-depth-0 > .nav-page-link { + margin-bottom: .45rem; + padding: .58rem .8rem; + font-weight: 600; } .sidebar-footer { margin-top: auto; @@ -348,21 +533,38 @@ img { max-width: 100%; height: auto; display: block; } .main-content { margin-left: var(--sidebar-w); flex: 1; - padding: 3rem 2.5rem 4rem; + padding: 2.5rem 3rem 4rem; min-width: 0; } /* ── Doc article ─────────────────────────────────────── */ -.doc-content { max-width: var(--content-max); } +.doc-content { + max-width: 860px; + margin: 0 auto; +} .doc-header { margin-bottom: 1.5rem; } +.doc-header-top { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 1.5rem; +} .doc-header h1 { - font-size: 2rem; + font-size: 2.2rem; font-weight: 600; line-height: 1.25; color: var(--text); letter-spacing: -.02em; } +.doc-last-updated { + flex: 0 0 auto; + margin-top: .45rem; + color: var(--text-muted); + font-size: .78rem; + font-weight: 500; + white-space: nowrap; +} .doc-description { margin-top: .5rem; font-size: 1.05rem; @@ -399,13 +601,50 @@ img { max-width: 100%; height: auto; display: block; } color: var(--text-muted); margin: 1.75rem 0 .5rem; } -.doc-content p { margin-bottom: 1rem; } +.doc-content p { + margin-bottom: 1rem; + max-width: 72ch; + font-size: 1.02rem; + line-height: 1.85; + color: var(--text); +} .doc-content ul, .doc-content ol { padding-left: 1.5rem; margin-bottom: 1rem; + max-width: 72ch; +} +.doc-content li { + margin-bottom: .38rem; + line-height: 1.75; } -.doc-content li { margin-bottom: .3rem; } .doc-content strong { font-weight: 600; } +.doc-content img { + max-width: 100%; + height: auto; + margin: 1.6rem auto; + border-radius: var(--radius); + border: 1px solid var(--border); + background: var(--surface-subtle); + box-shadow: 0 14px 34px rgba(15, 23, 42, .06); +} +.doc-content figure { + margin: 1.6rem auto; +} +.doc-content figure img { + margin: 0; +} +.doc-image-fallback { + margin: 1.4rem 0; + padding: .85rem 1rem; + border: 1px dashed var(--border); + border-radius: var(--radius); + background: var(--surface-subtle); + color: var(--text-muted); + font-size: .92rem; +} +.doc-image-fallback strong { + color: var(--text); +} /* ── Code ────────────────────────────────────────────── */ .doc-content code { @@ -434,7 +673,86 @@ img { max-width: 100%; height: auto; display: block; } color: #c9d8ed; line-height: 1.7; } - +.doc-code-block { + position: relative; + margin: 1.25rem 0; +} +.doc-code-block pre { + margin: 0; + padding-top: 3.2rem; + padding-right: 3.9rem; +} +.doc-code-toolbar { + position: absolute; + top: .7rem; + right: .75rem; + display: inline-flex; + align-items: center; + z-index: 2; +} +.doc-code-button { + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border: 1px solid rgba(255,255,255,.16); + border-radius: 10px; + background: rgba(255,255,255,.12); + color: rgba(255,255,255,.82); + cursor: pointer; + transition: background .15s, border-color .15s, color .15s, transform .15s ease; +} +.doc-code-button:hover, +.doc-code-button:focus-visible { + background: rgba(255,255,255,.2); + border-color: rgba(255,255,255,.24); + color: #ffffff; + outline: none; +} +.doc-code-button img { + width: 16px; + height: 16px; + pointer-events: none; +} +.doc-code-button .theme-icon-dark { + display: none; +} +[data-theme="dark"] .doc-code-button .theme-icon-light { + display: none; +} +[data-theme="dark"] .doc-code-button .theme-icon-dark { + display: block; +} +.doc-code-button.copied { + background: rgba(63, 212, 160, .18); + border-color: rgba(63, 212, 160, .32); + color: #8ff0cb; +} +.doc-code-button.copied::after, +.doc-code-button.failed::after { + position: absolute; + top: calc(100% + .45rem); + right: 0; + padding: .26rem .48rem; + border-radius: 999px; + font-size: 11px; + font-weight: 600; + line-height: 1; + white-space: nowrap; + box-shadow: 0 10px 24px rgba(15, 23, 42, .18); +} +.doc-code-button.copied::after { + content: "Copied"; + background: #0f6e56; + color: #ffffff; +} +.doc-code-button.failed::after { + content: "Failed"; + background: #7f1d1d; + color: #ffffff; +} /* Rouge syntax */ .highlight .k, .highlight .kd, .highlight .kn { color: #79c0ff; } .highlight .s, .highlight .s1, .highlight .s2 { color: #a5d6ff; } @@ -525,46 +843,54 @@ img { max-width: 100%; height: auto; display: block; } /* ── Homepage ────────────────────────────────────────── */ .home-hero { - max-width: var(--content-max); - padding: 1.5rem 0 .25rem; + max-width: 900px; + padding: 2rem 0 3.5rem; + margin: 0 auto; + text-align: center; } .home-hero h1 { - font-size: 2rem; + font-size: 2.25rem; font-weight: 600; letter-spacing: -.025em; line-height: 1.2; - margin-bottom: .5rem; + margin-bottom: .75rem; } .home-hero p { - font-size: 1.05rem; + font-size: 1.1rem; color: var(--text-muted); - max-width: 560px; - margin-bottom: 0; + max-width: 680px; + margin: 0 auto 2rem; } .home-diagram { - text-align: center; - margin: 0 0 .75rem; + width: min(100%, 1120px); + margin: -1.5rem auto 3.25rem; } .home-diagram svg { - display: inline-block; + display: block; width: 100%; - max-width: 650px; height: auto; - max-height: 260px; + max-height: 500px; } .home-cards { display: grid; - grid-template-columns: repeat(auto-fit, minmax(165px, 1fr)); - gap: 1rem; - margin-top: .5rem; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 1.25rem; + width: min(100%, 1120px); + margin: 1rem auto 0; } .home-card { border: 1px solid var(--border); border-radius: var(--radius-lg); - padding: .95rem; + padding: 1.25rem; text-decoration: none; transition: border-color .15s, box-shadow .15s; background: var(--surface); + min-height: 188px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; } .home-card:hover { border-color: var(--teal-mid); @@ -572,44 +898,163 @@ img { max-width: 100%; height: auto; display: block; } text-decoration: none; } .home-card-icon { - width: 27px; height: 27px; + width: 36px; height: 36px; background: var(--teal-faint); border-radius: var(--radius); display: flex; align-items: center; justify-content: center; - margin-bottom: .65rem; + margin-bottom: .875rem; color: var(--teal); - font-size: 14px; + font-size: 18px; } .home-card h3 { - font-size: .72rem; + font-size: .95rem; font-weight: 600; color: var(--text); - margin-bottom: .27rem; + margin-bottom: .35rem; } .home-card p { - font-size: .68rem; + font-size: .85rem; color: var(--text-muted); - line-height: 1.45; + line-height: 1.5; margin: 0; } +.home-contact { + margin: 1.4rem auto 0; + max-width: 720px; + color: var(--text-muted); + font-size: .95rem; + line-height: 1.6; + text-align: center; +} +.home-contact a { + color: var(--teal); + font-weight: 600; + text-decoration: none; +} +.home-contact a:hover { + text-decoration: underline; +} +.not-found-shell { + max-width: 980px; + margin: 0 auto 2.25rem; +} +.not-found-hero { + padding: 1.5rem 1.6rem; + border: 1px solid var(--border); + border-radius: 18px; + background: linear-gradient(180deg, color-mix(in srgb, var(--surface-raised) 94%, transparent), color-mix(in srgb, var(--surface-subtle) 88%, transparent)); + box-shadow: 0 16px 36px rgba(15, 23, 42, .06); +} +[data-theme="dark"] .not-found-hero { + box-shadow: none; +} +.not-found-eyebrow { + margin: 0 0 .45rem; + font-size: .8rem; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + color: var(--teal); +} +.not-found-hero h1 { + margin: 0; + font-size: clamp(2rem, 4vw, 2.7rem); + line-height: 1.08; +} +.not-found-copy { + margin: .85rem 0 0; + max-width: 68ch; + color: var(--text-muted); + line-height: 1.8; +} +.not-found-actions { + display: flex; + flex-wrap: wrap; + gap: .8rem; + margin-top: 1.2rem; +} +.not-found-button { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 42px; + padding: 0 .95rem; + border: 1px solid var(--border); + border-radius: 999px; + background: var(--surface); + color: var(--text); + font-weight: 600; + text-decoration: none; + transition: border-color .15s, background .15s, color .15s; +} +.not-found-button:hover { + border-color: color-mix(in srgb, var(--teal-mid) 30%, var(--border)); + background: color-mix(in srgb, var(--teal-faint) 70%, var(--surface)); + color: var(--teal); + text-decoration: none; +} +.not-found-button.primary { + border-color: transparent; + background: var(--teal); + color: #ffffff; +} +.not-found-button.primary:hover { + background: var(--teal-mid); + color: #ffffff; +} +.not-found-suggestion { + margin-top: 1rem; + padding: .9rem 1rem; + border: 1px solid color-mix(in srgb, var(--teal-mid) 22%, var(--border)); + border-radius: 14px; + background: color-mix(in srgb, var(--teal-faint) 70%, var(--surface)); +} +.not-found-suggestion-label { + display: block; + margin-bottom: .2rem; + font-size: .8rem; + font-weight: 700; + letter-spacing: .03em; + color: var(--teal); +} +.not-found-suggestion-link { + display: inline-block; + font-size: 1.02rem; + font-weight: 650; + color: var(--text); +} +.not-found-suggestion-link:hover { + color: var(--teal); +} +.not-found-suggestion-path { + display: block; + margin-top: .22rem; + color: var(--text-muted); + font-size: .88rem; + overflow-wrap: anywhere; +} +.not-found-home { + margin-top: 2rem; + padding-top: 1.4rem; + border-top: 1px solid var(--border); +} +.not-found-home .home-hero { + padding-top: .2rem; +} /* ── Footer ──────────────────────────────────────────── */ .site-footer { background: var(--navy); color: rgba(255,255,255,.6); margin-left: var(--sidebar-w); - padding: 1rem 2rem; -} -.site-footer img { - height: 28px; - width: auto; + padding: 2rem 2.5rem; } .footer-inner { max-width: calc(var(--content-max) + var(--sidebar-w)); display: flex; align-items: center; flex-wrap: wrap; - gap: 1rem; + gap: 1.25rem; } .footer-brand { display: flex; @@ -618,15 +1063,12 @@ img { max-width: 100%; height: auto; display: block; } font-size: 13.5px; font-weight: 500; color: rgba(255,255,255,.75); - line-height: 1.2; } .footer-links { display: flex; gap: 1.25rem; flex-wrap: wrap; margin-left: auto; - line-height: 1.2; - } .footer-links a { font-size: 13px; @@ -639,8 +1081,7 @@ img { max-width: 100%; height: auto; display: block; } width: 100%; font-size: 12px; color: rgba(255,255,255,.3); - margin-top: .15rem; - line-height: 1.2; + margin-top: .25rem; } /* ── Responsive ──────────────────────────────────────── */ @@ -657,10 +1098,22 @@ img { max-width: 100%; height: auto; display: block; } .header-nav { display: none; } .sidebar-toggle { display: flex; } .header-search { max-width: 160px; } + .home-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (max-width: 560px) { - .doc-header h1 { font-size: 1.6rem; } + .doc-header h1 { font-size: 1.75rem; } + .doc-header-top { display: block; } + .doc-last-updated { + display: block; + margin-top: .5rem; + } .home-hero h1 { font-size: 1.75rem; } + .home-hero { padding-top: 1rem; } + .home-diagram { margin: -1rem auto 1.5rem; } + .home-diagram svg { max-height: none; } + .home-cards { grid-template-columns: 1fr; } + .not-found-hero { padding: 1.2rem 1.15rem; } + .not-found-actions { flex-direction: column; align-items: stretch; } .doc-pagination { flex-direction: column; } .header-search { display: none; } } @@ -734,4 +1187,4 @@ img { max-width: 100%; height: auto; display: block; } #search-results li:last-child a { border-bottom: none; } #search-results li a:hover { background: var(--hover-bg, #f8fafc); } #search-results li a strong { display: block; font-weight: 600; } -#search-results li a span { color: var(--text-muted, #64748b); } \ No newline at end of file +#search-results li a span { color: var(--text-muted, #64748b); } diff --git a/assets/js/main.js b/assets/js/main.js index ad5046e..c94c44e 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -19,21 +19,27 @@ if (toggle) toggle.addEventListener('click', () => ); if (overlay) overlay.addEventListener('click', closeSidebar); -// ── Sidebar nav filter ──────────────────────────────────────────────────────── -const sidebarSearch = document.getElementById('doc-search'); -if (sidebarSearch) { - sidebarSearch.addEventListener('input', () => { - const q = sidebarSearch.value.toLowerCase().trim(); - document.querySelectorAll('.nav-section ul li').forEach(li => { - const text = li.textContent.toLowerCase(); - li.style.display = (!q || text.includes(q)) ? '' : 'none'; - }); - document.querySelectorAll('.nav-section').forEach(section => { - const visible = [...section.querySelectorAll('li')].some(li => li.style.display !== 'none'); - section.style.display = visible ? '' : 'none'; - }); +// ── Keep the current page visible in the sidebar ──────────────────────────── +(function () { + if (!sidebar) return; + + const activeLink = sidebar.querySelector('.nav-page-link.active[aria-current="page"]'); + if (!activeLink) return; + + window.requestAnimationFrame(() => { + const sidebarRect = sidebar.getBoundingClientRect(); + const activeRect = activeLink.getBoundingClientRect(); + const isAbove = activeRect.top < sidebarRect.top + 72; + const isBelow = activeRect.bottom > sidebarRect.bottom - 24; + + if (isAbove || isBelow) { + activeLink.scrollIntoView({ + block: 'center', + inline: 'nearest', + }); + } }); -} +})(); // ── Dark / light mode ───────────────────────────────────────────────────────── const themeToggle = document.getElementById('theme-toggle'); @@ -51,119 +57,327 @@ if (themeToggle) { }); } -// ── Full-text search (Lunr.js) ──────────────────────────────────────────────── -let lunrIndex = null; -let searchDocs = []; +// ── Documentation images ───────────────────────────────────────────────────── +(function () { + const content = document.querySelector('.doc-content'); + if (!content) return; + + function replaceBrokenImage(img) { + if (!img || img.dataset.fallbackApplied === 'true') return; + img.dataset.fallbackApplied = 'true'; + + const fallback = document.createElement('div'); + fallback.className = 'doc-image-fallback'; + + const label = document.createElement('strong'); + label.textContent = img.alt || 'Image unavailable'; + fallback.appendChild(label); + + const src = img.getAttribute('src'); + if (src) { + const path = document.createElement('div'); + path.textContent = src; + fallback.appendChild(path); + } + + img.replaceWith(fallback); + } + + content.querySelectorAll('img').forEach(img => { + img.loading = img.loading || 'lazy'; + img.decoding = 'async'; + img.addEventListener('error', () => replaceBrokenImage(img), { once: true }); + + if (img.complete && img.naturalWidth === 0) { + replaceBrokenImage(img); + } + }); +})(); + +// ── Copy buttons for code blocks ──────────────────────────────────────────── +(function () { + const content = document.querySelector('.doc-content'); + if (!content) return; + const baseUrl = (window.siteBaseUrl || '').replace(/\/$/, ''); + + function iconUrl(path) { + return `${baseUrl}${path}`; + } + + async function copyText(text) { + if (navigator.clipboard && window.isSecureContext) { + await navigator.clipboard.writeText(text); + return; + } + + const helper = document.createElement('textarea'); + helper.value = text; + helper.setAttribute('readonly', ''); + helper.style.position = 'absolute'; + helper.style.left = '-9999px'; + document.body.appendChild(helper); + helper.select(); + document.execCommand('copy'); + helper.remove(); + } + + function codeTextFor(pre) { + const code = pre.querySelector('code'); + return (code ? code.textContent : pre.textContent || '').replace(/\s+$/, ''); + } + + function blockContainerFor(pre) { + const highlighted = pre.closest('.highlighter-rouge, .highlight'); + return highlighted || pre; + } + + content.querySelectorAll('pre').forEach(pre => { + if (pre.id === 'env-content') return; + + const container = blockContainerFor(pre); + if (!container || container.querySelector('.doc-code-toolbar')) return; + + container.classList.add('doc-code-block'); + + const toolbar = document.createElement('div'); + toolbar.className = 'doc-code-toolbar'; + + const copyButton = document.createElement('button'); + copyButton.type = 'button'; + copyButton.className = 'doc-code-button copy-code-button'; + copyButton.setAttribute('aria-label', 'Copy code'); + copyButton.setAttribute('title', 'Copy code'); + copyButton.innerHTML = ` + + + `; + + copyButton.addEventListener('click', async () => { + const text = codeTextFor(pre); + if (!text) return; + + copyButton.classList.remove('failed'); + copyButton.classList.remove('copied'); + try { + await copyText(text); + copyButton.classList.add('copied'); + } catch (_) { + copyButton.classList.add('failed'); + } + + window.setTimeout(() => { + copyButton.classList.remove('copied'); + copyButton.classList.remove('failed'); + }, 1800); + }); + + toolbar.appendChild(copyButton); + container.appendChild(toolbar); + }); +})(); + +// ── Full-text search ────────────────────────────────────────────────────────── +(function () { + const searchTargets = [ + { + input: document.getElementById('doc-search'), + results: document.getElementById('doc-search-results'), + itemTag: 'a', + limit: 10, + }, + { + input: document.getElementById('header-search-input'), + results: document.getElementById('header-search-results'), + itemTag: 'a', + limit: 8, + }, + { + input: document.getElementById('search-input'), + results: document.getElementById('search-results'), + itemTag: 'li', + limit: 8, + activeClass: 'active', + }, + ].filter(target => target.input && target.results); -const headerSearchInput = document.getElementById('header-search-input'); -const headerSearchResults = document.getElementById('header-search-results'); + if (!searchTargets.length || typeof lunr === 'undefined') return; -// only load the index if the search input exists on this page -if (headerSearchInput) { - fetch('/search-index.json') - .then(r => r.json()) + let docs = []; + let docsByUrl = new Map(); + let idx = null; + let loadError = false; + const baseUrl = (window.siteBaseUrl || '').replace(/\/$/, ''); + const indexReady = fetch(`${baseUrl}/search-index.json`) + .then(response => response.json()) .then(data => { - searchDocs = data; - lunrIndex = lunr(function () { + docs = data.map(doc => ({ + ...doc, + content: doc.content || '', + })); + docsByUrl = new Map(docs.map(doc => [doc.url, doc])); + idx = lunr(function () { this.ref('url'); - this.field('title', { boost: 10 }); + this.field('title', { boost: 12 }); + this.field('url', { boost: 3 }); this.field('content'); - data.forEach(doc => this.add(doc)); + docs.forEach(doc => this.add(doc)); }); }) .catch(() => { - // search-index.json not yet built — fail silently + loadError = true; }); - headerSearchInput.addEventListener('input', () => { - const q = headerSearchInput.value.trim(); + function escapeHtml(value) { + return String(value).replace(/[&<>"']/g, char => ({ + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + }[char])); + } - if (!q || !lunrIndex) { - headerSearchResults.hidden = true; - return; - } + function queryTerms(query) { + return query + .toLowerCase() + .replace(/[^a-z0-9_]+/g, ' ') + .split(/\s+/) + .filter(Boolean); + } + + function searchQuery(terms) { + return terms.map(term => `${term}*`).join(' '); + } + + function manualMatches(terms) { + if (!terms.length) return []; + + return docs + .map(doc => { + const haystack = `${doc.title} ${doc.url} ${doc.content}`.toLowerCase(); + const matched = terms.filter(term => haystack.includes(term)); + if (!matched.length) return null; + + const title = doc.title.toLowerCase(); + const score = matched.length * 2 + matched.filter(term => title.includes(term)).length * 3; + return { ref: doc.url, score }; + }) + .filter(Boolean) + .sort((a, b) => b.score - a.score); + } + + function searchDocs(query) { + const terms = queryTerms(query); + if (!terms.length || !idx) return []; - let hits = []; try { - hits = lunrIndex.search(q + '*').slice(0, 8); + const hits = idx.search(searchQuery(terms)); + if (hits.length) return hits; } catch (_) { - // lunr throws on some partial queries — ignore + // Lunr can throw while the user is typing partial syntax-like input. + } + + return manualMatches(terms); + } + + function snippetFor(doc, terms) { + const content = doc.content || ''; + const lowerContent = content.toLowerCase(); + const index = terms.reduce((best, term) => { + const found = lowerContent.indexOf(term); + return found === -1 || (best !== -1 && found >= best) ? best : found; + }, -1); + + if (index === -1) { + return content.slice(0, 140).trim(); + } + + const start = Math.max(0, index - 55); + const end = Math.min(content.length, index + 120); + const prefix = start > 0 ? '...' : ''; + const suffix = end < content.length ? '...' : ''; + return `${prefix}${content.slice(start, end).trim()}${suffix}`; + } + + function resultHtml(doc, query) { + const terms = queryTerms(query); + const title = escapeHtml(doc.title || doc.url); + const url = escapeHtml(doc.url); + const snippet = escapeHtml(snippetFor(doc, terms)); + + return ` + + ${title} + ${url} + ${snippet} + + `; + } + + function setResultsVisible(target, visible) { + if (target.activeClass) { + target.results.classList.toggle(target.activeClass, visible); + } else { + target.results.hidden = !visible; } + } + function renderResults(target, hits, query) { if (!hits.length) { - headerSearchResults.hidden = true; + target.results.innerHTML = '
No results
'; + setResultsVisible(target, true); return; } - headerSearchResults.innerHTML = hits.map(({ ref }) => { - const doc = searchDocs.find(d => d.url === ref); + target.results.innerHTML = hits.slice(0, target.limit).map(hit => { + const doc = docsByUrl.get(hit.ref); if (!doc) return ''; - return `${doc.title}`; + const html = resultHtml(doc, query); + return target.itemTag === 'li' ? `
  • ${html}
  • ` : html; }).join(''); + setResultsVisible(target, true); + } - headerSearchResults.hidden = false; - }); + searchTargets.forEach(target => { + target.input.addEventListener('input', () => { + const query = target.input.value.trim(); - // close results when clicking outside the search widget - document.addEventListener('click', e => { - if (!e.target.closest('.header-search')) { - headerSearchResults.hidden = true; - } - }); + if (!query) { + target.results.innerHTML = ''; + setResultsVisible(target, false); + return; + } - // close on Escape - headerSearchInput.addEventListener('keydown', e => { - if (e.key === 'Escape') { - headerSearchResults.hidden = true; - headerSearchInput.blur(); - } - }); -} -// ── Search ──────────────────────────────────────────────── -(function () { - const input = document.getElementById('search-input'); - const results = document.getElementById('search-results'); - if (!input || !results) return; + if (loadError) { + target.results.innerHTML = '
    Search index unavailable
    '; + setResultsVisible(target, true); + return; + } - let idx, docs; + if (!idx) { + target.results.innerHTML = '
    Loading search...
    '; + setResultsVisible(target, true); + indexReady.then(() => renderResults(target, searchDocs(query), query)); + return; + } - // Fetch and build the lunr index once - fetch('/search-index.json') - .then(r => r.json()) - .then(data => { - docs = data; - idx = lunr(function () { - this.ref('url'); - this.field('title', { boost: 10 }); - this.field('content'); - data.forEach(d => this.add(d)); - }); + renderResults(target, searchDocs(query), query); }); - input.addEventListener('input', function () { - const q = this.value.trim(); - results.innerHTML = ''; - if (!q || !idx) { results.classList.remove('active'); return; } - - const hits = idx.search(q + '*'); // trailing wildcard for partial match - if (!hits.length) { - results.innerHTML = '
  • No results
  • '; - } else { - hits.slice(0, 8).forEach(hit => { - const doc = docs.find(d => d.url === hit.ref); - if (!doc) return; - const li = document.createElement('li'); - li.innerHTML = `${doc.title}${doc.content.slice(0, 80)}…`; - results.appendChild(li); - }); - } - results.classList.add('active'); + target.input.addEventListener('keydown', event => { + if (event.key === 'Escape') { + target.input.value = ''; + target.input.dispatchEvent(new Event('input')); + target.input.blur(); + } + }); }); - // Close results when clicking outside - document.addEventListener('click', e => { - if (!input.contains(e.target) && !results.contains(e.target)) { - results.classList.remove('active'); - } + document.addEventListener('click', event => { + searchTargets.forEach(target => { + if (!target.input.contains(event.target) && !target.results.contains(event.target)) { + setResultsVisible(target, false); + } + }); }); -})(); \ No newline at end of file +})(); diff --git a/index.md b/index.md index 893bc89..e5120bf 100644 --- a/index.md +++ b/index.md @@ -6,37 +6,6 @@ title: AnyLog Documentation ## Changelog - 2026-04-20 | Created document - 2026-04-24 | updated document with new image + proper links -- 2026-06-21 | update image sizing --> -
    -

    AnyLog Documentation

    -

    AnyLog — Enable independent (industrial) databases to function as a single logical data network.

    -
    - -
    - {% include anylog_network_fabric_animated.svg %} -
    - - \ No newline at end of file +{% include home_content.html %} From a15b06d55a9aeea5726565b5878cf52653a26545 Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Sat, 8 Aug 2026 16:09:58 -0700 Subject: [PATCH 08/12] missing build Signed-off-by: Ori Shadmon --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 10d2c36..1ad27db 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ check-dir: fi up: check-dir - LOCAL_DOCS=$(LOCAL_DOCS) docker compose -f $(COMPOSE_FILE) up -d + LOCAL_DOCS=$(LOCAL_DOCS) docker compose -f $(COMPOSE_FILE) up --build -d logs: docker logs -f $(CONTAINER) From f589072bee323ff23bf285cfcf663536ef74ba5b Mon Sep 17 00:00:00 2001 From: royshadmon <16313057+royshadmon@users.noreply.github.com> Date: Tue, 11 Aug 2026 11:30:01 -0500 Subject: [PATCH 09/12] removing todo from being displayed on website (#40) --- .github/scripts/sync_external_docs.py | 3 +++ .github/scripts/validate_docs.py | 3 +++ _config.yml | 36 +++++++++++++-------------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.github/scripts/sync_external_docs.py b/.github/scripts/sync_external_docs.py index 3e5ba41..0f93ad1 100644 --- a/.github/scripts/sync_external_docs.py +++ b/.github/scripts/sync_external_docs.py @@ -147,6 +147,9 @@ def should_skip_rel(rel): if any(part.startswith(".") for part in parts): return True + if len(parts) == 1 and rel.name.lower() != "readme.md": + return True + if has_hidden_path_part(rel): return True top_level = parts[0] if parts else "" diff --git a/.github/scripts/validate_docs.py b/.github/scripts/validate_docs.py index f8797f7..5f59548 100644 --- a/.github/scripts/validate_docs.py +++ b/.github/scripts/validate_docs.py @@ -60,6 +60,9 @@ def should_include_source_path(source_path): if any(part.startswith(".") for part in parts): return False + if len(parts) == 1 and source_path.name.lower() != "readme.md": + return False + if any(re.match(r"^99(?:\b|[^A-Za-z0-9].*)", part) for part in parts): return False top_level = parts[0] if parts else "" diff --git a/_config.yml b/_config.yml index 4945985..c8aedf7 100644 --- a/_config.yml +++ b/_config.yml @@ -530,20 +530,20 @@ nav: title: "Trusted Platform Module (TPM)" match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/" children: - - kind: "page" - title: "TMP Configuration" - match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration/" - slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration" - url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration/" - file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-tmp-configuration.md" - source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/01- TMP Configuration.md" - kind: "page" title: "Software TPM" - match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm/" - slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm" - url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm/" - file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-software-tpm.md" - source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/02- Software TPM.md" + match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm/" + slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm" + url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm/" + file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/01-software-tpm.md" + source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/01- Software TPM.md" + - kind: "page" + title: "TMP Configuration" + match_path: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration/" + slug: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration" + url: "/docs/06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration/" + file: "06-networking-and-security/07-security/02-trusted-platform-module-tpm/02-tmp-configuration.md" + source_path: "06- Networking & Security/07- Security/02- Trusted Platform Module (TPM)/02- TMP Configuration.md" - kind: "section" title: "CLI" match_path: "/docs/07-cli/" @@ -832,12 +832,12 @@ nav: file: "11-extended-services/02-mcpai.md" source_path: "11- Extended Services/02- mcpAI.md" - kind: "page" - title: "federated learning (demo)" - match_path: "/docs/11-extended-services/03-federated-learning-demo/" - slug: "11-extended-services/03-federated-learning-demo" - url: "/docs/11-extended-services/03-federated-learning-demo/" - file: "11-extended-services/03-federated-learning-demo.md" - source_path: "11- Extended Services/03- federated learning (demo).md" + title: "Federated Learning" + match_path: "/docs/11-extended-services/03-federated-learning/" + slug: "11-extended-services/03-federated-learning" + url: "/docs/11-extended-services/03-federated-learning/" + file: "11-extended-services/03-federated-learning.md" + source_path: "11- Extended Services/03- Federated Learning.md" - kind: "section" title: "Examples & Use Cases" match_path: "/docs/12-examples-and-use-cases/" From ada6338572efcb5a339ad1707e8618d41f619b69 Mon Sep 17 00:00:00 2001 From: royshadmon <16313057+royshadmon@users.noreply.github.com> Date: Wed, 12 Aug 2026 10:20:43 -0500 Subject: [PATCH 10/12] Pre develop (#42) * removing todo from being displayed on website * fix bug with auto syncing in github actions (#41) --- .github/scripts/sync_external_docs.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/scripts/sync_external_docs.py b/.github/scripts/sync_external_docs.py index 0f93ad1..f54496a 100644 --- a/.github/scripts/sync_external_docs.py +++ b/.github/scripts/sync_external_docs.py @@ -308,9 +308,10 @@ def liquid_relative_url(url): return liquid_relative_url(doc_map[rel_candidate]["url"] + fragment) if rel_candidate.suffix == "": - md_candidate = rel_candidate.with_suffix(".md") - if md_candidate in doc_map: - return liquid_relative_url(doc_map[md_candidate]["url"] + fragment) + if rel_candidate.name: + md_candidate = rel_candidate.with_suffix(".md") + if md_candidate in doc_map: + return liquid_relative_url(doc_map[md_candidate]["url"] + fragment) for index_name in ("README.md", "readme.md", "Overview.md", "overview.md"): index_candidate = rel_candidate / index_name From c00bac97d675052b04116a3fc04cd71f2faa4cbe Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Thu, 13 Aug 2026 11:50:47 -0700 Subject: [PATCH 11/12] reorg boxes Signed-off-by: Ori Shadmon --- _config.yml | 312 ++++++++++++++++++++---------------- _includes/home_content.html | 10 +- 2 files changed, 175 insertions(+), 147 deletions(-) diff --git a/_config.yml b/_config.yml index c8aedf7..b0e85d2 100644 --- a/_config.yml +++ b/_config.yml @@ -216,156 +216,170 @@ nav: url: "/docs/04-southbound-interfaces/01-southbound-interfaces/" file: "04-southbound-interfaces/01-southbound-interfaces.md" source_path: "04- Southbound Interfaces/01- Southbound Interfaces.md" + - kind: "page" + title: "Mapping Policy" + match_path: "/docs/04-southbound-interfaces/02-mapping-policy/" + slug: "04-southbound-interfaces/02-mapping-policy" + url: "/docs/04-southbound-interfaces/02-mapping-policy/" + file: "04-southbound-interfaces/02-mapping-policy.md" + source_path: "04- Southbound Interfaces/02- Mapping Policy.md" - kind: "section" title: "Direct Connectors" - match_path: "/docs/04-southbound-interfaces/02-direct-connectors/" + match_path: "/docs/04-southbound-interfaces/03-direct-connectors/" children: - kind: "page" title: "REST" - match_path: "/docs/04-southbound-interfaces/02-direct-connectors/01-rest/" - slug: "04-southbound-interfaces/02-direct-connectors/01-rest" - url: "/docs/04-southbound-interfaces/02-direct-connectors/01-rest/" - file: "04-southbound-interfaces/02-direct-connectors/01-rest.md" - source_path: "04- Southbound Interfaces/02- Direct Connectors/01- REST.md" + match_path: "/docs/04-southbound-interfaces/03-direct-connectors/01-rest/" + slug: "04-southbound-interfaces/03-direct-connectors/01-rest" + url: "/docs/04-southbound-interfaces/03-direct-connectors/01-rest/" + file: "04-southbound-interfaces/03-direct-connectors/01-rest.md" + source_path: "04- Southbound Interfaces/03- Direct Connectors/01- REST.md" - kind: "page" title: "Message Broker" - match_path: "/docs/04-southbound-interfaces/02-direct-connectors/02-message-broker/" - slug: "04-southbound-interfaces/02-direct-connectors/02-message-broker" - url: "/docs/04-southbound-interfaces/02-direct-connectors/02-message-broker/" - file: "04-southbound-interfaces/02-direct-connectors/02-message-broker.md" - source_path: "04- Southbound Interfaces/02- Direct Connectors/02- Message Broker.md" + match_path: "/docs/04-southbound-interfaces/03-direct-connectors/02-message-broker/" + slug: "04-southbound-interfaces/03-direct-connectors/02-message-broker" + url: "/docs/04-southbound-interfaces/03-direct-connectors/02-message-broker/" + file: "04-southbound-interfaces/03-direct-connectors/02-message-broker.md" + source_path: "04- Southbound Interfaces/03- Direct Connectors/02- Message Broker.md" - kind: "section" title: "Industrial Connectors" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/" children: + - kind: "page" + title: "PLC Mapping" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/01-plc-mapping/" + slug: "04-southbound-interfaces/04-industrial-connectors/01-plc-mapping" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/01-plc-mapping/" + file: "04-southbound-interfaces/04-industrial-connectors/01-plc-mapping.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/01- PLC Mapping.md" - kind: "page" title: "Modbus" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/01-modbus/" - slug: "04-southbound-interfaces/03-industrial-connectors/01-modbus" - url: "/docs/04-southbound-interfaces/03-industrial-connectors/01-modbus/" - file: "04-southbound-interfaces/03-industrial-connectors/01-modbus.md" - source_path: "04- Southbound Interfaces/03- Industrial Connectors/01- Modbus.md" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/02-modbus/" + slug: "04-southbound-interfaces/04-industrial-connectors/02-modbus" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/02-modbus/" + file: "04-southbound-interfaces/04-industrial-connectors/02-modbus.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/02- Modbus.md" - kind: "page" title: "OPC-UA" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/02-opc-ua/" - slug: "04-southbound-interfaces/03-industrial-connectors/02-opc-ua" - url: "/docs/04-southbound-interfaces/03-industrial-connectors/02-opc-ua/" - file: "04-southbound-interfaces/03-industrial-connectors/02-opc-ua.md" - source_path: "04- Southbound Interfaces/03- Industrial Connectors/02- OPC-UA.md" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/03-opc-ua/" + slug: "04-southbound-interfaces/04-industrial-connectors/03-opc-ua" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/03-opc-ua/" + file: "04-southbound-interfaces/04-industrial-connectors/03-opc-ua.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/03- OPC-UA.md" - kind: "page" title: "EtherIP" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/03-etherip/" - slug: "04-southbound-interfaces/03-industrial-connectors/03-etherip" - url: "/docs/04-southbound-interfaces/03-industrial-connectors/03-etherip/" - file: "04-southbound-interfaces/03-industrial-connectors/03-etherip.md" - source_path: "04- Southbound Interfaces/03- Industrial Connectors/03- EtherIP.md" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/04-etherip/" + slug: "04-southbound-interfaces/04-industrial-connectors/04-etherip" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/04-etherip/" + file: "04-southbound-interfaces/04-industrial-connectors/04-etherip.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/04- EtherIP.md" - kind: "page" title: "DNP3" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-dnp3/" - slug: "04-southbound-interfaces/03-industrial-connectors/04-dnp3" - url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-dnp3/" - file: "04-southbound-interfaces/03-industrial-connectors/04-dnp3.md" - source_path: "04- Southbound Interfaces/03- Industrial Connectors/04- DNP3.md" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/05-dnp3/" + slug: "04-southbound-interfaces/04-industrial-connectors/05-dnp3" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/05-dnp3/" + file: "04-southbound-interfaces/04-industrial-connectors/05-dnp3.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/05- DNP3.md" - kind: "section" title: "DNP3" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/" children: - kind: "page" title: "DNP3 - Deploying Connector via Script" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script/" - slug: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script" - url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script/" - file: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/01-dnp3-deploying-connector-via-script.md" - source_path: "04- Southbound Interfaces/03- Industrial Connectors/04-1 DNP3/01- DNP3 - Deploying Connector via Script.md" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/01-dnp3-deploying-connector-via-script/" + slug: "04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/01-dnp3-deploying-connector-via-script" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/01-dnp3-deploying-connector-via-script/" + file: "04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/01-dnp3-deploying-connector-via-script.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/05-1 DNP3/01- DNP3 - Deploying Connector via Script.md" - kind: "page" title: "DNP3 - Mapping-Policies" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies/" - slug: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies" - url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies/" - file: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/02-dnp3-mapping-policies.md" - source_path: "04- Southbound Interfaces/03- Industrial Connectors/04-1 DNP3/02- DNP3 - Mapping-Policies.md" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/02-dnp3-mapping-policies/" + slug: "04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/02-dnp3-mapping-policies" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/02-dnp3-mapping-policies/" + file: "04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/02-dnp3-mapping-policies.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/05-1 DNP3/02- DNP3 - Mapping-Policies.md" - kind: "page" title: "DNP3 - TLS test certificates" - match_path: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates/" - slug: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates" - url: "/docs/04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates/" - file: "04-southbound-interfaces/03-industrial-connectors/04-1-dnp3/03-dnp3-tls-test-certificates.md" - source_path: "04- Southbound Interfaces/03- Industrial Connectors/04-1 DNP3/03- DNP3 - TLS test certificates.md" + match_path: "/docs/04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/03-dnp3-tls-test-certificates/" + slug: "04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/03-dnp3-tls-test-certificates" + url: "/docs/04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/03-dnp3-tls-test-certificates/" + file: "04-southbound-interfaces/04-industrial-connectors/05-1-dnp3/03-dnp3-tls-test-certificates.md" + source_path: "04- Southbound Interfaces/04- Industrial Connectors/05-1 DNP3/03- DNP3 - TLS test certificates.md" - kind: "section" title: "Monitoring" - match_path: "/docs/04-southbound-interfaces/04-monitoring/" + match_path: "/docs/04-southbound-interfaces/05-monitoring/" children: - kind: "page" title: "Node Monitoring" - match_path: "/docs/04-southbound-interfaces/04-monitoring/01-node-monitoring/" - slug: "04-southbound-interfaces/04-monitoring/01-node-monitoring" - url: "/docs/04-southbound-interfaces/04-monitoring/01-node-monitoring/" - file: "04-southbound-interfaces/04-monitoring/01-node-monitoring.md" - source_path: "04- Southbound Interfaces/04- Monitoring/01- Node Monitoring.md" + match_path: "/docs/04-southbound-interfaces/05-monitoring/01-node-monitoring/" + slug: "04-southbound-interfaces/05-monitoring/01-node-monitoring" + url: "/docs/04-southbound-interfaces/05-monitoring/01-node-monitoring/" + file: "04-southbound-interfaces/05-monitoring/01-node-monitoring.md" + source_path: "04- Southbound Interfaces/05- Monitoring/01- Node Monitoring.md" - kind: "page" title: "Syslog" - match_path: "/docs/04-southbound-interfaces/04-monitoring/02-syslog/" - slug: "04-southbound-interfaces/04-monitoring/02-syslog" - url: "/docs/04-southbound-interfaces/04-monitoring/02-syslog/" - file: "04-southbound-interfaces/04-monitoring/02-syslog.md" - source_path: "04- Southbound Interfaces/04- Monitoring/02- Syslog.md" + match_path: "/docs/04-southbound-interfaces/05-monitoring/02-syslog/" + slug: "04-southbound-interfaces/05-monitoring/02-syslog" + url: "/docs/04-southbound-interfaces/05-monitoring/02-syslog/" + file: "04-southbound-interfaces/05-monitoring/02-syslog.md" + source_path: "04- Southbound Interfaces/05- Monitoring/02- Syslog.md" - kind: "section" title: "RPC & Media Streaming" - match_path: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/" + match_path: "/docs/04-southbound-interfaces/06-rpc-and-media-streaming/" children: - kind: "page" title: "gRPC" - match_path: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc/" - slug: "04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc" - url: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc/" - file: "04-southbound-interfaces/05-rpc-and-media-streaming/01-grpc.md" - source_path: "04- Southbound Interfaces/05- RPC & Media Streaming/01- gRPC.md" + match_path: "/docs/04-southbound-interfaces/06-rpc-and-media-streaming/01-grpc/" + slug: "04-southbound-interfaces/06-rpc-and-media-streaming/01-grpc" + url: "/docs/04-southbound-interfaces/06-rpc-and-media-streaming/01-grpc/" + file: "04-southbound-interfaces/06-rpc-and-media-streaming/01-grpc.md" + source_path: "04- Southbound Interfaces/06- RPC & Media Streaming/01- gRPC.md" - kind: "page" title: "Video Streaming" - match_path: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming/" - slug: "04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming" - url: "/docs/04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming/" - file: "04-southbound-interfaces/05-rpc-and-media-streaming/02-video-streaming.md" - source_path: "04- Southbound Interfaces/05- RPC & Media Streaming/02- Video Streaming.md" + match_path: "/docs/04-southbound-interfaces/06-rpc-and-media-streaming/02-video-streaming/" + slug: "04-southbound-interfaces/06-rpc-and-media-streaming/02-video-streaming" + url: "/docs/04-southbound-interfaces/06-rpc-and-media-streaming/02-video-streaming/" + file: "04-southbound-interfaces/06-rpc-and-media-streaming/02-video-streaming.md" + source_path: "04- Southbound Interfaces/06- RPC & Media Streaming/02- Video Streaming.md" - kind: "section" title: "Third-Party" - match_path: "/docs/04-southbound-interfaces/06-third-party/" + match_path: "/docs/04-southbound-interfaces/07-third-party/" children: - kind: "page" title: "node-RED" - match_path: "/docs/04-southbound-interfaces/06-third-party/01-node-red/" - slug: "04-southbound-interfaces/06-third-party/01-node-red" - url: "/docs/04-southbound-interfaces/06-third-party/01-node-red/" - file: "04-southbound-interfaces/06-third-party/01-node-red.md" - source_path: "04- Southbound Interfaces/06- Third-Party/01- node-RED.md" + match_path: "/docs/04-southbound-interfaces/07-third-party/01-node-red/" + slug: "04-southbound-interfaces/07-third-party/01-node-red" + url: "/docs/04-southbound-interfaces/07-third-party/01-node-red/" + file: "04-southbound-interfaces/07-third-party/01-node-red.md" + source_path: "04- Southbound Interfaces/07- Third-Party/01- node-RED.md" - kind: "page" title: "Telegraf" - match_path: "/docs/04-southbound-interfaces/06-third-party/02-telegraf/" - slug: "04-southbound-interfaces/06-third-party/02-telegraf" - url: "/docs/04-southbound-interfaces/06-third-party/02-telegraf/" - file: "04-southbound-interfaces/06-third-party/02-telegraf.md" - source_path: "04- Southbound Interfaces/06- Third-Party/02- Telegraf.md" + match_path: "/docs/04-southbound-interfaces/07-third-party/02-telegraf/" + slug: "04-southbound-interfaces/07-third-party/02-telegraf" + url: "/docs/04-southbound-interfaces/07-third-party/02-telegraf/" + file: "04-southbound-interfaces/07-third-party/02-telegraf.md" + source_path: "04- Southbound Interfaces/07- Third-Party/02- Telegraf.md" - kind: "page" title: "EdgeX" - match_path: "/docs/04-southbound-interfaces/06-third-party/03-edgex/" - slug: "04-southbound-interfaces/06-third-party/03-edgex" - url: "/docs/04-southbound-interfaces/06-third-party/03-edgex/" - file: "04-southbound-interfaces/06-third-party/03-edgex.md" - source_path: "04- Southbound Interfaces/06- Third-Party/03- EdgeX.md" + match_path: "/docs/04-southbound-interfaces/07-third-party/03-edgex/" + slug: "04-southbound-interfaces/07-third-party/03-edgex" + url: "/docs/04-southbound-interfaces/07-third-party/03-edgex/" + file: "04-southbound-interfaces/07-third-party/03-edgex.md" + source_path: "04- Southbound Interfaces/07- Third-Party/03- EdgeX.md" - kind: "page" title: "Kubearmor" - match_path: "/docs/04-southbound-interfaces/06-third-party/04-kubearmor/" - slug: "04-southbound-interfaces/06-third-party/04-kubearmor" - url: "/docs/04-southbound-interfaces/06-third-party/04-kubearmor/" - file: "04-southbound-interfaces/06-third-party/04-kubearmor.md" - source_path: "04- Southbound Interfaces/06- Third-Party/04- Kubearmor.md" + match_path: "/docs/04-southbound-interfaces/07-third-party/04-kubearmor/" + slug: "04-southbound-interfaces/07-third-party/04-kubearmor" + url: "/docs/04-southbound-interfaces/07-third-party/04-kubearmor/" + file: "04-southbound-interfaces/07-third-party/04-kubearmor.md" + source_path: "04- Southbound Interfaces/07- Third-Party/04- Kubearmor.md" - kind: "page" title: "Data Ingestion" - match_path: "/docs/04-southbound-interfaces/07-data-ingestion/" - slug: "04-southbound-interfaces/07-data-ingestion" - url: "/docs/04-southbound-interfaces/07-data-ingestion/" - file: "04-southbound-interfaces/07-data-ingestion.md" - source_path: "04- Southbound Interfaces/07- Data Ingestion.md" + match_path: "/docs/04-southbound-interfaces/08-data-ingestion/" + slug: "04-southbound-interfaces/08-data-ingestion" + url: "/docs/04-southbound-interfaces/08-data-ingestion/" + file: "04-southbound-interfaces/08-data-ingestion.md" + source_path: "04- Southbound Interfaces/08- Data Ingestion.md" - kind: "section" title: "Northbound Connectors" match_path: "/docs/05-northbound-connectors/" @@ -459,19 +473,26 @@ nav: file: "06-networking-and-security/04-using-rest.md" source_path: "06- Networking & Security/04- Using REST.md" - kind: "page" - title: "Message Broker" - match_path: "/docs/06-networking-and-security/05-message-broker/" - slug: "06-networking-and-security/05-message-broker" - url: "/docs/06-networking-and-security/05-message-broker/" - file: "06-networking-and-security/05-message-broker.md" - source_path: "06- Networking & Security/05- Message Broker.md" + title: "MQTT Message Broker" + match_path: "/docs/06-networking-and-security/05-mqtt-message-broker/" + slug: "06-networking-and-security/05-mqtt-message-broker" + url: "/docs/06-networking-and-security/05-mqtt-message-broker/" + file: "06-networking-and-security/05-mqtt-message-broker.md" + source_path: "06- Networking & Security/05- MQTT Message Broker.md" + - kind: "page" + title: "Kafka Message Client" + match_path: "/docs/06-networking-and-security/05-1-kafka-message-client/" + slug: "06-networking-and-security/05-1-kafka-message-client" + url: "/docs/06-networking-and-security/05-1-kafka-message-client/" + file: "06-networking-and-security/05-1-kafka-message-client.md" + source_path: "06- Networking & Security/05-1 Kafka Message Client.md" - kind: "page" title: "Connectors To Data Sources" - match_path: "/docs/06-networking-and-security/05-1-connectors-to-data-sources/" - slug: "06-networking-and-security/05-1-connectors-to-data-sources" - url: "/docs/06-networking-and-security/05-1-connectors-to-data-sources/" - file: "06-networking-and-security/05-1-connectors-to-data-sources.md" - source_path: "06- Networking & Security/05-1 Connectors To Data Sources.md" + match_path: "/docs/06-networking-and-security/05-2-connectors-to-data-sources/" + slug: "06-networking-and-security/05-2-connectors-to-data-sources" + url: "/docs/06-networking-and-security/05-2-connectors-to-data-sources/" + file: "06-networking-and-security/05-2-connectors-to-data-sources.md" + source_path: "06- Networking & Security/05-2 Connectors To Data Sources.md" - kind: "section" title: "Network" match_path: "/docs/06-networking-and-security/06-network/" @@ -683,33 +704,26 @@ nav: file: "08-blockchain-and-metadata/03-1-blockchain-full-circle.md" source_path: "08- Blockchain & Metadata/03-1 Blockchain Full Circle.md" - kind: "page" - title: "Mapping Policy" - match_path: "/docs/08-blockchain-and-metadata/04-mapping-policy/" - slug: "08-blockchain-and-metadata/04-mapping-policy" - url: "/docs/08-blockchain-and-metadata/04-mapping-policy/" - file: "08-blockchain-and-metadata/04-mapping-policy.md" - source_path: "08- Blockchain & Metadata/04- Mapping Policy.md" - - kind: "page" - title: "Unitfied Namespace" - match_path: "/docs/08-blockchain-and-metadata/05-unitfied-namespace/" - slug: "08-blockchain-and-metadata/05-unitfied-namespace" - url: "/docs/08-blockchain-and-metadata/05-unitfied-namespace/" - file: "08-blockchain-and-metadata/05-unitfied-namespace.md" - source_path: "08- Blockchain & Metadata/05- Unitfied Namespace.md" + title: "Unified Namespace" + match_path: "/docs/08-blockchain-and-metadata/04-unified-namespace/" + slug: "08-blockchain-and-metadata/04-unified-namespace" + url: "/docs/08-blockchain-and-metadata/04-unified-namespace/" + file: "08-blockchain-and-metadata/04-unified-namespace.md" + source_path: "08- Blockchain & Metadata/04- Unified Namespace.md" - kind: "page" title: "UNS Custom Dynamic Examples" - match_path: "/docs/08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples/" - slug: "08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples" - url: "/docs/08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples/" - file: "08-blockchain-and-metadata/05-1-uns-custom-dynamic-examples.md" - source_path: "08- Blockchain & Metadata/05-1 UNS Custom Dynamic Examples.md" + match_path: "/docs/08-blockchain-and-metadata/04-1-uns-custom-dynamic-examples/" + slug: "08-blockchain-and-metadata/04-1-uns-custom-dynamic-examples" + url: "/docs/08-blockchain-and-metadata/04-1-uns-custom-dynamic-examples/" + file: "08-blockchain-and-metadata/04-1-uns-custom-dynamic-examples.md" + source_path: "08- Blockchain & Metadata/04-1 UNS Custom Dynamic Examples.md" - kind: "page" title: "UNS Custom Examples" - match_path: "/docs/08-blockchain-and-metadata/05-2-uns-custom-examples/" - slug: "08-blockchain-and-metadata/05-2-uns-custom-examples" - url: "/docs/08-blockchain-and-metadata/05-2-uns-custom-examples/" - file: "08-blockchain-and-metadata/05-2-uns-custom-examples.md" - source_path: "08- Blockchain & Metadata/05-2 UNS Custom Examples.md" + match_path: "/docs/08-blockchain-and-metadata/04-2-uns-custom-examples/" + slug: "08-blockchain-and-metadata/04-2-uns-custom-examples" + url: "/docs/08-blockchain-and-metadata/04-2-uns-custom-examples/" + file: "08-blockchain-and-metadata/04-2-uns-custom-examples.md" + source_path: "08- Blockchain & Metadata/04-2 UNS Custom Examples.md" - kind: "section" title: "Data Management" match_path: "/docs/09-data-management/" @@ -802,6 +816,13 @@ nav: url: "/docs/09-data-management/06-query-profiling/" file: "09-data-management/06-query-profiling.md" source_path: "09- Data Management/06- Query Profiling.md" + - kind: "page" + title: "Creating and Managing a Non-Time-Series Table" + match_path: "/docs/09-data-management/07-creating-and-managing-a-non-time-series-table/" + slug: "09-data-management/07-creating-and-managing-a-non-time-series-table" + url: "/docs/09-data-management/07-creating-and-managing-a-non-time-series-table/" + file: "09-data-management/07-creating-and-managing-a-non-time-series-table.md" + source_path: "09- Data Management/07- Creating and Managing a Non-Time-Series Table.md" - kind: "section" title: "Edge Data Manager" match_path: "/docs/10-edge-data-manager/" @@ -818,19 +839,19 @@ nav: match_path: "/docs/11-extended-services/" children: - kind: "page" - title: "LLM Dashboard Generation" - match_path: "/docs/11-extended-services/01-llm-dashboard-generation/" - slug: "11-extended-services/01-llm-dashboard-generation" - url: "/docs/11-extended-services/01-llm-dashboard-generation/" - file: "11-extended-services/01-llm-dashboard-generation.md" - source_path: "11- Extended Services/01- LLM Dashboard Generation.md" + title: "Performance" + match_path: "/docs/11-extended-services/01-performance/" + slug: "11-extended-services/01-performance" + url: "/docs/11-extended-services/01-performance/" + file: "11-extended-services/01-performance.md" + source_path: "11- Extended Services/01- Performance.md" - kind: "page" - title: "mcpAI" - match_path: "/docs/11-extended-services/02-mcpai/" - slug: "11-extended-services/02-mcpai" - url: "/docs/11-extended-services/02-mcpai/" - file: "11-extended-services/02-mcpai.md" - source_path: "11- Extended Services/02- mcpAI.md" + title: "LLM Dashboard Generation" + match_path: "/docs/11-extended-services/02-llm-dashboard-generation/" + slug: "11-extended-services/02-llm-dashboard-generation" + url: "/docs/11-extended-services/02-llm-dashboard-generation/" + file: "11-extended-services/02-llm-dashboard-generation.md" + source_path: "11- Extended Services/02- LLM Dashboard Generation.md" - kind: "page" title: "Federated Learning" match_path: "/docs/11-extended-services/03-federated-learning/" @@ -838,6 +859,13 @@ nav: url: "/docs/11-extended-services/03-federated-learning/" file: "11-extended-services/03-federated-learning.md" source_path: "11- Extended Services/03- Federated Learning.md" + - kind: "page" + title: "mcpAI" + match_path: "/docs/11-extended-services/04-mcpai/" + slug: "11-extended-services/04-mcpai" + url: "/docs/11-extended-services/04-mcpai/" + file: "11-extended-services/04-mcpai.md" + source_path: "11- Extended Services/04- mcpAI.md" - kind: "section" title: "Examples & Use Cases" match_path: "/docs/12-examples-and-use-cases/" diff --git a/_includes/home_content.html b/_includes/home_content.html index 4727df3..fd205ab 100644 --- a/_includes/home_content.html +++ b/_includes/home_content.html @@ -8,6 +8,11 @@

    AnyLog Documentation

    From 4a29a98e85eb70b676bb30978d5f2d4d4a8a5e22 Mon Sep 17 00:00:00 2001 From: Ori Shadmon Date: Thu, 13 Aug 2026 12:22:48 -0700 Subject: [PATCH 12/12] improved README Signed-off-by: Ori Shadmon --- README.md | 312 +++++++++++++++++++++--------------------------------- 1 file changed, 122 insertions(+), 190 deletions(-) diff --git a/README.md b/README.md index 66c02b6..9a665b2 100644 --- a/README.md +++ b/README.md @@ -1,119 +1,82 @@ # AnyLog Docs -This is the technical documentation for [AnyLog Edge Data Fabric](https://www.anylog.network/), built with Jekyll and hosted on GitHub Pages. +This is the technical documentation for [AnyLog Edge Data Fabric](https://www.anylog.network/), built with Jekyll and +hosted on GitHub Pages. ---- - -## How to deploy +This repository is the **backend** — it builds and serves the documentation site. The actual documentation content lives +in a separate repository; see [Documentation Source](#documentation-source) below. -1. Make sure you have `make`, `docker`, and `docker compose` installed -2. Clone the [Frontend](https://github.com/AnyLog-co/anylog-docs.github.io) & [Content](https://github.com/AnyLog-co/documentation) repositories -3. Start the docs locally: -```shell -make up LOCAL_DOCS=${PATH to documentation} +**Goal**: We decided to provide the documentation via a website at **https://anylog.network/docs** using Jekyll (same +theme as OpenHorizon), replacing raw GitHub repo access with a structured, navigable site comparable to EdgeX or +ReadTheDocs. -# Example +**Reference**: Source Repositories -make up LOCAL_DOCS=/mnt/c/Users/oshad/AnyLog-docs/documentation -``` +| Repo | Default Branch | Purpose | +|---|---|---| +| [AnyLog-co/documentation](https://github.com/AnyLog-co/documentation) | main | Documentation content — source of truth, synced into this site | +| [AnyLog-co/anylog-docs.github.io](https://github.com/AnyLog-co/anylog-docs.github.io) | main | This repo — the Jekyll backend that builds and serves the site | --- -## Goal - -We decided to Provide the documentation via a website at **https://anylog.network/docs** using Jekyll (same theme as OpenHorizon), replacing raw GitHub repo access with a structured, navigable site comparable to EdgeX or ReadTheDocs. - ---- +## Quick Start (Local Deployment) -## Documentation Source +1. Make sure you have `make`, `docker`, and `docker compose` installed. +2. Clone this repo (the backend) and the [content repository](https://github.com/AnyLog-co/documentation). +3. From this repo, start the docs locally, pointing `LOCAL_DOCS` at your local clone of the content repo: -Documentation content is sourced from the public -AnyLog-co/documentation -repository on the `main` branch. - -Do not edit generated Markdown files in `_docs/` in this repository. The Jekyll build runs -`.github/scripts/sync_external_docs.py`, which clones `AnyLog-co/documentation`, converts every upstream `.md` -file into a Jekyll collection page, copies supporting assets into `assets/external-docs/`, and regenerates the sidebar -navigation. - -The GitHub Pages workflow rebuilds on pushes and pull requests in this repository, manual workflow dispatch, an hourly -schedule, and `repository_dispatch` events of type `documentation-updated`. - -For immediate publishing when `AnyLog-co/documentation` changes, add a workflow in that repository that sends a -`repository_dispatch` event to this repository after pushes to `main`. Without that dispatch, the scheduled rebuild -will still pick up upstream changes within the next hourly run. - ---- - -## Contributing +```shell +make up LOCAL_DOCS=${PATH to documentation} -This documentation is implementing a change control process. Therefore the repository follows a **PR-based workflow** -Documentation changes are managed through pull requests against the `main` branch, which is the branch viewed when accessing the documentation URL (see above). +# Example +make up LOCAL_DOCS=/mnt/c/Users/oshad/AnyLog-docs/documentation +``` -**Required actions :** -- Find the file you want to update and fork it from `main` (or create a new file) -- IF you work locally - 1. Make sure your local copy is in sync with `main`: - ```bash - git fetch origin - git rebase origin/main - ``` - 2. Create a feature branch or fork the file, make your changes, then open a pull request **against `main`** +4. Open **http://localhost:4000** in your browser. Edits to files under `LOCAL_DOCS` are picked up live — no restart +needed. -- once edited, create a **pull request** for review and inclusion at the next update cycle +5. When you're done: -*note:* direct pushes to `main` are blocked -*note2:* GitHub Pages builds and publishes automatically once the PR is merged +```shell +make down +``` ---- - -## Reference : Source repositories - -| Repo | Purpose | Status | -|---|---|---| -| **https://github.com/AnyLog-co/documentation** | Old docs — ~279 files, comprehensive but unorganised, not a website | Source of truth for migration | -| **EdgeLake documentation site** | Ori's first Jekyll attempt — limited, semi-organised | To be deprecated | -| **https://github.com/AnyLog-co/anylog-docs.github.io** (branch: `main`) | New Jekyll site — active development | Work in progress | +> If `LOCAL_DOCS` is omitted, it defaults to `.` (this repo itself) — you almost always want to point it at your content +> repo clone instead. --- -## Adding or Updating Content +## Maintaining the Backend -### 1. Create or edit a page +This repo wraps a small Docker setup with a `Makefile` for convenience. The three pieces: -Documentation pages live in the upstream `AnyLog-co/documentation` repository. Create a new Markdown file or edit an existing one there: +**`Makefile`** — the entry point for local development. -``` -/.md -``` +| Target | What it does | +|---|---| +| `up` | `docker compose up --build -d` — builds and starts the container | +| `down` | `docker compose down` — stops the container | +| `logs` | `docker logs -f anylog-docs` — follows the container's logs | +| `clean` | `docker compose down -v --rmi all` — stops the container and removes its volumes and images | +| `help` | Prints usage (also the default target if you just run `make`) | -The sync script adds Jekyll front matter automatically. Page titles can still come from upstream front matter or headings, but the left sidebar label is always the Markdown filename without the `.md` extension. +All targets accept `LOCAL_DOCS=`. `up`, `down`, and `clean` validate that the path exists before doing anything (unless it's left at the default `.`). -If you do add front matter upstream, this site recognizes the `title` and `description` fields: +**`docker-compose.yaml`** — defines a single `docs` service, built from the local `Dockerfile`: +- Exposes port `4000` (the Jekyll site) and `35729` (LiveReload). +- Runs `.github/scripts/dev-start.sh` as its startup command. +- Mounts `${LOCAL_DOCS:-.}` to `/srv/documentation` (the content source) and this repo to `/srv/content` (the Jekyll site itself), both `cached` for performance. +- Persists Bundler's gem cache in a named volume (`bundle-cache`) mounted at `/srv/bundle`, so `bundle install` doesn't rerun from scratch on every rebuild. -```yaml ---- -title: Introduction to AnyLog -description: Understanding AnyLog's architecture, node types, and core concepts. -layout: page ---- - -``` -Evey file **must** contain a header change log so when reading it one knows when changed / who did it / what date and Anylog version, use this table format -| Date of change | Relevant Anylog code version | Author | Description | -|---|---|---|---| -| - | - | - | Documentation Copyright Anylog.co 2026 | -| 2026-04-19 | All | Eric Aquaronne | update readme for Anylog | +**`Dockerfile`** — built on `jekyll/jekyll:4`, with `python3` and `bash` installed for the repo's helper scripts. It +runs as `root` to avoid gem-install and bundle permission issues; `BUNDLE_PATH` is set to `/srv/bundle` to match +the compose volume above. +### Navigation / Sidebar Generation -### 2. Register it in the navigation - -Navigation is generated from the synced upstream files. The left sidebar section title is the folder that contains the Markdown file; root-level Markdown files are grouped under `Documentation`. +Navigation is generated from the synced upstream files. The left sidebar section title is the folder that contains the +Markdown file; root-level Markdown files are grouped under `Documentation`. `.github/scripts/navigation.py` is now only used for optional ordering overrides for known slugs: @@ -128,121 +91,36 @@ ITEM_ORDER = { } ``` -The slug is the synced path without the `.md` extension after the sync script normalizes spaces and punctuation. The sidebar display name is the synced filename without `.md`. The order of slugs within each section controls the order they appear in the sidebar. - -`navigation.py` is consumed by `validate_docs.py`, which scans the generated `_docs/` directory and writes the `nav` block in `_config.yml`. This runs automatically on `docker compose up` and in GitHub Actions — you do not need to invoke it manually. - ---- - -## Editing/Writing Guidelines +The slug is the synced path without the `.md` extension after the sync script normalizes spaces and punctuation. The +sidebar display name is the synced filename without `.md`. The order of slugs within each section controls the order +they appear in the sidebar. -- **Use absolute permalink paths** for links between doc pages — Jekyll builds each page at `/docs/

    //` regardless of which folder the source file is in, so relative paths will break: -```markdown - [Install](/docs/getting-started/installing-anylog/) - [Background Services](/docs/network-services/background-services/#rest-service) -``` - The slug is always the filename without `.md`, lowercased, under its section directory name (also lowercased with hyphens). -- **External links** must open in a new tab: -```html - Link text -``` -- Keep front matter `description` to a single sentence — it appears as the subtitle under the page title -- Keep to short sentences, add drawings/pics (PNG files) to make it easy to understand for readers that probably will be more OT than IT skills base +`navigation.py` is consumed by `validate_docs.py`, which scans the generated `_docs/` directory and writes the `nav` +block in `_config.yml`. This runs automatically on `docker compose up` and in GitHub Actions — you do not need to +invoke it manually. ---- +### Running Without Make -- The title at the top is also used as the page title, there's no need for double title -**Example**: How not to define the Makefile -```markdown ---- -title: Introduction to AnyLog -description: Understanding AnyLog's architecture, node types, and core concepts. -layout: page ---- - -# Introduction to AnyLog -[content] -``` - ---- - -## Leveraging Claude LLM to Update a Doc Page - -A reliable pattern for getting Claude to rewrite or update a page while keeping it consistent with the rest of the docs: - -1. Provide the **raw GitHub URL** of the file to update — in GitHub, open the file and click **Raw**, then copy the address bar URL -2. Provide the **raw GitHub URL** of an existing page whose layout you want the output to match -3. Include the required front matter block in your prompt -4. Ask Claude to rewrite the first file to match the structure and style of the second - -Keep the prompt substantive — include at least a short paragraph describing the intent and audience for each major section you want changed, not just bullet points. The more context you give about tone, audience, and structure, the better the result. - -### Sample prompt - -The following is a real example using `remote-gui.md`. Copy and adapt it for any page you want to update. - ---- - -> I need you to update the AnyLog documentation page for the Remote GUI. -> -> **File to update (raw URL):** -> `https://raw.githubusercontent.com/AnyLog-co/anylog-docs.github.io/refs/heads/main/_docs/Tools-UI/remote-gui.md` -> -> **Example file to match in style and structure (raw URL):** -> `https://raw.githubusercontent.com/AnyLog-co/anylog-docs.github.io/refs/heads/main/_docs/Getting-Started/getting-started.md` -> -> **Required front matter — keep this exactly at the top of the file:** -> ```yaml -> --- -> title: Remote GUI -> description: Architecture and developer reference for the AnyLog Remote GUI. -> layout: page -> --- -> ``` -> -> **What to change:** -> -> The current page reads like internal notes — it's dense and assumes the reader already knows the codebase. Rewrite it so a new developer joining the project can follow it from top to bottom. The architecture diagram and key terminology table are good and should stay, but the surrounding prose needs more context. -> -> The "Running locally" section currently has two terminal blocks with commands that aren't explained — add a sentence before each block describing what it does and why. The `uvicorn` command in particular looks like it may have a path issue (`CLI.local-cli-backend.main:app` uses dots but the `cd` above already entered the subdirectory); please flag that or correct it. -> -> The "Plugin system" section is the most important part for contributors — expand the intro paragraph to explain *when* someone would want to build a plugin versus modifying a core feature. Keep the code examples as-is. -> -> Use absolute permalink paths for links to other pages in `_docs/` — e.g. `/docs/network-services/background-services/`. Any link to an external repo or external site should use `` format. Do not change any section headings — the navigation relies on them. - ---- - -Adjust the URLs, front matter, and the description of changes to match whatever page you are working on. - ---- - - - -## Local Development with Docker - -The easiest way to preview the docs locally is via Docker — no Ruby or Jekyll installation required. - -**Prerequisites:** [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) +You can drive Docker Compose directly instead of going through `make`: ```bash git clone https://github.com/AnyLog-co/anylog-docs.github.io.git cd anylog-docs.github.io -docker compose up -d -``` -Once running, open your browser to **http://localhost:4000**. +LOCAL_DOCS=/path/to/AnyLog-co/documentation docker compose up --build -d +``` -The container mounts your local `_docs/` directory, so edits are reflected live — no restart needed. To stop: +Open **http://localhost:4000**. To stop: ```bash docker compose down ``` -**Troubleshooting:** If the container exits immediately with a bundle write permissions error (`There was an error while trying to write to /srv/bundle`), run: +> Don't skip `LOCAL_DOCS` here — without it, the compose file falls back to mounting the current directory (this repo) +> as the documentation source, which has no content to render. + +**Troubleshooting:** If the container exits immediately with a bundle write-permissions error (`There was an error +while trying to write to /srv/bundle`), clear the cached volume and retry: ```bash docker compose down -v @@ -251,7 +129,7 @@ docker compose up -d The `-v` flag removes the cached volume so it gets recreated with the correct permissions. -## Local Mac Development +### Local Mac Development Use the local launcher when you want to run Jekyll directly on macOS without Docker: @@ -275,3 +153,57 @@ Or let the launcher install Homebrew Ruby 3.3: ```bash python3 scripts/dev.py --install-ruby ``` + +--- + +## Documentation Source + +Documentation content is sourced from the public +AnyLog-co/documentation +repository on the `main` branch. + +Do not edit generated Markdown files in `_docs/` in this repository. The Jekyll build runs +`.github/scripts/sync_external_docs.py`, which clones `AnyLog-co/documentation`, converts every upstream `.md` +file into a Jekyll collection page, copies supporting assets into `assets/external-docs/`, and regenerates the sidebar +navigation. + +The GitHub Pages workflow rebuilds on pushes and pull requests in this repository, manual workflow dispatch, an hourly +schedule, and `repository_dispatch` events of type `documentation-updated`. + +For immediate publishing when `AnyLog-co/documentation` changes, add a workflow in that repository that sends a +`repository_dispatch` event to this repository after pushes to `main`. Without that dispatch, the scheduled rebuild +will still pick up upstream changes within the next hourly run. + +**Editing documentation content itself — creating or updating pages, front matter, page IDs, and formatting +conventions — happens in the content repo, not here:** +- Content repo: [AnyLog-co/documentation](https://github.com/AnyLog-co/documentation) +- How to update documentation: [HOWTO.md](https://github.com/AnyLog-co/documentation/blob/os-dev/HOWTO.md) + +--- + +## Contributing + +Changes to **this repository** (the Jekyll backend itself — templates, build scripts, `Makefile`, CI config, etc.) +follow the same staged workflow as the content repo: this repository is implementing a change control process, so it +follows a **PR-based workflow** against the **`pre-develop`** branch, not `main`. `main` is the published branch +backing the live documentation URL (see [Documentation Source](#documentation-source)); changes land there once +`pre-develop` is promoted to `main`. + +**Required actions:** +- Find the file you want to update and branch/fork it from `pre-develop` (or create a new file) +- If you work locally: + 1. Make sure your local copy is in sync with `pre-develop`: + ```bash + git fetch origin + git rebase origin/pre-develop + ``` + 2. Create a feature branch or fork the file, make your changes, then open a pull request **against `pre-develop`** + +- Once edited, create a **pull request** for review and inclusion at the next update cycle + +*Note:* direct pushes to `pre-develop` are blocked. +*Note 2:* merging into `pre-develop` does not publish immediately — the live site rebuilds once `pre-develop` is +promoted to `main`. + +> Content authoring conventions (page creation, front matter, permalinks, image paths) live in the content repo's +> [HOWTO.md](https://github.com/AnyLog-co/documentation/blob/os-dev/HOWTO.md), not in this repository. \ No newline at end of file