aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/_summary.md1
-rw-r--r--docs/configurator_architecture.md61
-rw-r--r--docs/configurator_diagram.drawio1
-rw-r--r--docs/configurator_diagram.svg3
4 files changed, 66 insertions, 0 deletions
diff --git a/docs/_summary.md b/docs/_summary.md
index 9798ef512..8347805a2 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -19,6 +19,7 @@
19 * [Overview](newbs_building_firmware_configurator.md) 19 * [Overview](newbs_building_firmware_configurator.md)
20 * [Step by Step](configurator_step_by_step.md) 20 * [Step by Step](configurator_step_by_step.md)
21 * [Troubleshooting](configurator_troubleshooting.md) 21 * [Troubleshooting](configurator_troubleshooting.md)
22 * [Architecture](configurator_architecture.md)
22 * QMK API 23 * QMK API
23 * [Overview](api_overview.md) 24 * [Overview](api_overview.md)
24 * [API Documentation](api_docs.md) 25 * [API Documentation](api_docs.md)
diff --git a/docs/configurator_architecture.md b/docs/configurator_architecture.md
new file mode 100644
index 000000000..0d7fc8a73
--- /dev/null
+++ b/docs/configurator_architecture.md
@@ -0,0 +1,61 @@
1# QMK Configurator Architecture
2
3This page describes the web architecture behind QMK Configurator at a high level. If you are interested in the architecture of the QMK Configurator code itself you should start at the [qmk_configurator](https://github.com/qmk/qmk_configurator) repository.
4
5# Overview
6
7![QMK Configurator Architecture Diagram](configurator_diagram.svg)
8
9# Detailed Description
10
11QMK Configurator is a [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) that allows users to create custom keymaps for their QMK-compatible keyboard. They can export JSON representation of their keymaps and compile firmware binaries that can be flashed to their keyboard using a tool like [QMK Toolbox](https://github.com/qmk/qmk_toolbox).
12
13Configurator gets metadata about keyboards from the Keyboard Metadata store and submits compile requests to the QMK API. The results of those compile requests will be made available on [Digital Ocean Spaces](https://www.digitalocean.com/products/spaces/), an S3-compatible data store.
14
15## Configurator Frontend
16
17Address: <https://config.qmk.fm>
18
19The [Configurator Frontend](https://config.qmk.fm) is compiled into a set of static files that are served by Github Pages. This action happens every time a commit is pushed to the [qmk_configurator `master`](https://github.com/qmk/qmk_configurator) branch. You can view the status of these jobs on the [qmk_configurator actions tab](https://github.com/qmk/qmk_configurator/actions/workflows/build.yml).
20
21## Keyboard Metadata
22
23Address: <https://keyboards.qmk.fm>
24
25The Keyboard Metadata is generated every time a keyboard in [qmk_firmware](https://github.com/qmk/qmk_firmware) changes. The resulting JSON files are uploaded to Spaces and used by Configurator to generate UI for each keyboard. You can view the status of this job on the [qmk_firmware actions tab](https://github.com/qmk/qmk_firmware/actions/workflows/api.yml). If you are a QMK Collaborator you can manually run this job using the `workflow_dispatch` event trigger.
26
27## QMK API
28
29Address: <http://api.qmk.fm>
30
31The QMK API accepts `keymap.json` files for compilation. These are the same files you can use directly with `qmk compile` and `qmk flash`. When a `keymap.json` is submitted the browser will poll the status of the job periodically (every 2 seconds or longer, preferably) until the job has completed. The final status JSON will contain pointers to source and binary downloads for the keymap.
32
33QMK API always presents the source and binary downloads side-by-side to comply with the GPL.
34
35There are 3 non-error status responses from the API-
36
371. Compile Job Queued
382. Compile Job Running
393. Compile Job Finished
40
41### Compile Job Queued
42
43This status indicates that the job has not yet been picked up by a [QMK Compiler](#qmk-compiler) node. Configurator shows this status as "Waiting for an oven".
44
45### Compile Job Running
46
47This status indicates that the job has started compiling. Configurator shows this status as "Baking".
48
49### Compile Job Finished
50
51This status indicates that the job has completed. There will be keys in the status JSON for source and binary downloads.
52
53## Redis/RQ
54
55QMK API uses RQ to distribute jobs to the available [QMK Compiler](#qmk-compiler) nodes. When a `keymap.json` is received it's put into the RQ queue, where a `qmk_compiler` node will pick it up from.
56
57## QMK Compiler
58
59[QMK Compiler](https://github.com/qmk/qmk_compiler) is what actually performs the compilation of the `keymap.json`. It does so by checking out the requested `qmk_firmware` branch, running `qmk compile keymap.json`, and then uploading the resulting source and binary to Digital Ocean Spaces.
60
61When users download their source/binary, API will redirect them to the authenticated Spaces download URL.
diff --git a/docs/configurator_diagram.drawio b/docs/configurator_diagram.drawio
new file mode 100644
index 000000000..091a3a76b
--- /dev/null
+++ b/docs/configurator_diagram.drawio
@@ -0,0 +1 @@
<mxfile host="Electron" modified="2021-08-09T19:46:29.036Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="PQ2r34UrZa0TfW4Fw0EV" version="14.6.13" type="device"><diagram id="NEtccoSKIy4HskWlhJpu" name="Page-1">5VvbcqM4EP2a1O4+hOLqy2Ni5zKX1CTxzszOU0oG2dZEIBZEYu/XbwuEDQg7csZ2vFlXjQca0RLdR+eohXPiDML5VYLi2Q0LMD2xzWB+4gxPbNvqezb8JywLaTFtr7BMExJI28owIv/gsqG0ZiTAaa0hZ4xyEteNPosi7POaDSUJe643mzBa7zVGU6wYRj6iqvU7CfissPY8c2W/xmQ6K3u2THklRGVjaUhnKGDPFZNzceIMEsZ4cRTOB5iK6JVxKe67XHN1ObAER1znhgfT76Zzxxp3Z49j5+7zjw/z+NSS+XlCNJNPLEfLF2UIcAARkacs4TM2ZRGiFyvrecKyKMCiHxPOVm0+MxaD0QLjT8z5QqYXZZyBacZDKq/iKDgTyYLTiEW4sFwSSqXLAKWz3L9orD64jEXKssTHG57WlQBCyRTzTVGRDsWTV3qQcb3CLMQ8WUCDBFPEyVMdK0hCbrpst8oKHMjEbJEk9+UckTDHcTWm0jQk4RR6pWQM3z4l8QNKuDhkYZxxnKRw/J0ljymHJ2HRg2X35vDPiKPp2kA/4YTj+cbIyKunjmv0zMpHeljSQXH6XJla0jSrzKrStvPIei9Hdgm9HNoZpyTCgyXZmPWYI0qmERz7EDGcgIGiMaa3LCUittULIoQEaOZzo8GYcc7CSoMz6ZKLqXQOJBKLgYXzqSBc4xmPKcy11JgSPsvG0GLCIn6JQkJFiK8xfcLCjbwgJyDM+uJ8wChL8ud0ivSILnjCHnHblQlMyIp9kn/ADkMJCK55G14OL4YXmybrFhhyOzXQtKEGdMVwVeBUzDvHTjmKjdS54jWfojQlfpP3YCR/CRwZXnn6o3ptOJcgK84W8gwma8JVz7lZ0qZVI9Ff401PkzddTdqsJM5rme6lTZtdZQ+3jMCTLXFjlRkqyaZJI8Vzy7uqytl01Gk4chqOisAojnJYLR/7F5BWTpkV0gZUTDjgbnOUxTEorqCosxO7QyGG5+MEjqbiaDBLoPsTGzo2L0mCJ2yuNhri9FHQi21+iehCAfHzjHA8ilEOkWegnTqGm0QVkiDIVwU5950j/3Garw9Kdsjd7YYZlmurkhlUYrDNFoB19qUnltPCCUW40xhFZcBnnIvl65noTChxNCFT4+/w0ZiEZXOwV+9Qk9bmd0SiKYTeNm+F9AM2RKTX3tno4iN6QiM/IbFYHXz7eqHeOJI8AeM2YbTQDL4fiuFnCeIs0RvmNUt54eWqUK1iwOnaZ28Asr7cfC0894E/q2PYehDs7w2CGqtFdbndqklVRaoI1BpN2tEaXVdryql2JGKzTKiEgvdasXHchqNDi01XAz/vpiK0tOHW0YTbYUpC6/1ULj9TuH0XlWZ93riOuhjotsz/rmf09pWkjpKkuvI/4sWYoSRIG+K/ks9PsgV4ucEcBYgjXV2ekCR8hoiq7a+uoeGZX+RN3PQ1BsdiwXB2+wG+h629rFR7SKDaRPSLj4VIm7n2ptsuG2voPKRIu7Zt9N9apHtbiXRr7VirASVHVgtAc4cFoDZNekclypZnWK5p9Tp9y+v1up1y73nRQMbWBWHdz3LP90ASbav14HuW6L4m9spsHotE95Us3d18Kkm2mS5KSZziik76lGXBy+XNLpTTq8O5Y6rKadkts3Rv27JlZ2uFE8VkrWTeX4z+nGS0DLSeWILDTYp3jyJ/Bqsf2xRrFXP4Bb6+3fy2tegdUuc6pqenct29pVFjkfryDulhtzDLWXskCnbarCtd75WadaoUlpqqBelBi0qzWDRINwzZanTkOObmkTVv8Pq1G+CgGMNuRVSl53csonZXV0R7RyWitrobIasPMMoCRGF4WY807b+PnD+OS3idXh347fuHrdrbt8qWu4+5WpzU1RcE81QocLTwHcMPIiMoUsJEPtI8+obPWqRZRlNK7+kLoqskejut3UWCeg1msh3L6PYrn54qsf2WbO3thYOjrpTeTGK1Oea4ikSQ/EaSX7t1qwiZfeC9W6ft9dO71TSn/D3YS3hz7KPSNEct3+/vlDyVciS2/FLOEnwYSWpskXS7ai3YOSjB2WqwcEDEm+9cjEwRuqaGfGTineJdhrOW3c/2AjApnO6/BNxBkpqVXrfz1pWes91Lx73KkPZ+UTkP31qHyiw26zFt2fEacGiWiPtWHXWNXvwuIIwpETNmDbPhuZhhAcvG+RWrJj3Wm2x99Vt+QXLYrS9XXdAVu4YDCCehIpztbHefRVH+a07dX22sc/efoLy+/daU5+pswh+I8vRXQt3joDyZVbeW015ztaxLgHU3/eZbnT3Tn6uuULYGwoF/z+lo7wYdF16AHes00GuuO/V3Qxui2bP0ULP1bqjTYK5yS2Gvm5vu/6sQ1IVzKa67KwTXEJK3GVu6KLWd14H0ZRjB6eovj4rmqz/gci7+BQ==</diagram></mxfile> \ No newline at end of file
diff --git a/docs/configurator_diagram.svg b/docs/configurator_diagram.svg
new file mode 100644
index 000000000..bcf0bf76d
--- /dev/null
+++ b/docs/configurator_diagram.svg
@@ -0,0 +1,3 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1261px" height="991px" viewBox="-0.5 -0.5 1261 991" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 885.2 40 L 1060 40" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><image x="804.7" y="-0.5" width="80" height="80" xlink:href="data:image/png;base64,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"/><path d="M 845.33 302.4 C 815.12 302.4 794 277.79 794 251.59 C 794 220.27 819.22 200 845.71 200 C 871.22 200 896.4 220.93 896.4 251.18 C 896.4 278.28 874.84 302.4 845.33 302.4 Z" fill="#0d2636" stroke="none" pointer-events="all"/><path d="M 834.25 291.19 C 834.25 293.4 832.57 294.32 830.06 293.46 C 814.91 288.15 800.34 271.75 800.34 251.27 C 800.34 223.57 824.03 206.1 844.57 206.1 C 871.22 206.1 890.18 227.94 890.18 251 C 890.18 270.03 877.94 287.54 859.59 293.69 C 857.52 294.24 856.23 293.13 856.23 291.31 L 856.23 277.98 C 856.23 275.4 855.18 272.65 853.24 270.74 C 860.69 269.89 865.21 268.02 868.67 264.46 C 872.07 261.08 873.6 256.13 873.88 250.01 C 874.07 245.15 872.77 240.41 869.25 236.8 C 870.48 233.82 870.69 229.86 868.83 224.97 C 865.14 224.69 860.94 226.9 856.64 229.56 C 849.08 227.59 841.52 227.33 833.96 229.67 C 830.58 227.47 827.51 225 821.65 224.97 C 820.1 229.29 819.86 233.23 821.19 236.72 C 817 241.37 816.52 245.93 816.6 250.47 C 817.06 259.25 820.27 263.68 823.83 266.33 C 826.79 268.52 830.94 269.9 837.27 270.83 C 835.57 272.51 834.62 274.51 834.46 276.86 C 830.74 278.56 825.42 279.41 821.78 274.25 C 820.15 271.66 817.93 268.73 813.72 268.74 C 813.03 268.72 812.35 268.98 812.25 269.28 C 812.15 269.61 812.54 270.3 813.01 270.57 C 816.7 272.92 817.29 274.23 818.8 277.44 C 820.2 281.19 822.62 282.63 825.24 283.64 C 827.92 284.59 832.25 284.32 834.25 283.64 Z" fill="#ffffff" stroke="none" pointer-events="all"/><path d="M 845.2 193.63 L 845.2 86.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 845.2 198.88 L 841.7 191.88 L 845.2 193.63 L 848.7 191.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 845.2 81.12 L 848.7 88.12 L 845.2 86.37 L 841.7 88.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="1060" y="10" width="200" height="60" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 40px; margin-left: 1061px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: white; white-space: normal; word-wrap: normal; ">Clients Supported:<br />Chrome, Firefox<br />Desktop Only</div></div></div></foreignObject><text x="1160" y="44" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Clients Supported:...</text></switch></g><rect x="1060" y="206.2" width="200" height="90" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 251px; margin-left: 1061px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><span>https://config.qmk.fm</span><br /><span>Single Page Site<br /></span>JavaScript/VUE<br />Source: qmk/qmk_configurator<br /><span>Host: Github Pages</span></div></div></div></foreignObject><text x="1160" y="255" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">https://config.qmk.fm...</text></switch></g><path d="M 896.4 251.2 L 1060 251.2" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 880 457.9 L 1060 457.9" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 833.22 495.8 C 828.16 495.8 821.72 491.64 821.72 483.75 L 821.72 475.34 L 813.15 475.34 C 811.65 475.34 810 474.49 810.03 471.92 L 810.03 455.36 C 810.03 453.81 810.93 452.17 812.91 452.12 L 821.72 452.12 L 821.72 431.37 C 821.72 425.69 826.62 420 833.69 420 L 856.49 420 C 858.53 420 861.18 421.45 863.72 423.93 L 876.39 436.67 C 879.49 440.04 880 441.77 880 443.93 L 880 484.09 C 880 490.1 875.34 495.8 867.72 495.8 Z" fill="#000000" stroke="none" pointer-events="all"/><path d="M 850.47 469.58 L 850.47 457.06 L 854.43 457.06 L 858.82 463.99 L 858.82 457.06 L 861.89 457.06 L 861.89 469.58 L 858.67 469.58 L 853.58 461.29 L 853.58 469.58 Z M 844.7 463.4 C 844.69 461.89 844.28 459.4 841.65 459.33 C 839.7 459.3 838.71 461.33 838.71 463.26 C 838.77 466.2 840.13 467.37 841.74 467.37 C 843.53 467.33 844.68 465.87 844.7 463.4 Z M 835.26 462.55 C 835.34 459.28 837.91 457.1 840.4 456.87 C 843.13 456.63 844.5 457.13 845.74 457.91 C 847.41 459.11 848.53 461.32 848.06 464.79 C 847.61 467.23 846.07 469.6 842.36 469.85 C 841 469.92 838.36 469.99 836.56 467.58 C 835.73 466.38 835.22 465.51 835.26 462.55 Z M 823.19 465.77 L 823.65 465.72 C 825.75 467.29 827.29 467.4 828.78 467.35 C 829.66 467.23 830.41 467.01 830.47 466.24 C 830.51 465.69 829.93 465.31 829.36 465.17 C 827.6 464.71 826.16 464.86 824.34 463.46 C 822.89 462.1 822.96 460.46 823.66 459.16 C 824.9 457.24 827.05 456.94 828.36 456.83 C 830.57 456.81 832.33 457.19 833.44 457.73 L 833.43 460.67 L 832.94 460.71 C 831.93 459.92 830.82 459.41 829.27 459.32 C 828.41 459.31 827.38 459.3 826.76 460 C 826.43 461.17 827.29 461.25 828.04 461.42 C 830.02 461.87 831.13 461.99 832.65 462.95 C 834.58 464.43 833.97 466.96 832.96 468.1 C 831.63 469.39 830.35 469.86 827.92 469.85 C 826.52 469.83 824.81 469.63 823.17 468.83 Z M 813.29 466.83 C 814.07 467.09 814.63 467.45 816.44 467.23 C 817.09 467.05 817.76 466.56 817.76 465.57 L 817.76 459.51 L 814.91 459.51 L 814.91 457.06 L 821.13 457.06 L 821.13 466.31 C 820.87 468.24 819.78 469.26 818.09 469.59 C 816.91 469.84 815.53 469.98 813.29 469.57 Z M 827.52 475.34 L 862.48 475.34 C 864.3 475.34 865.44 473.93 865.44 472.17 L 865.44 455.09 C 865.44 453.39 864.22 452.12 862.32 452.12 L 827.52 452.12 L 827.52 431.76 C 827.52 427.61 830.96 425.79 833.33 425.79 L 854.21 425.79 C 856.33 425.79 856.7 428.23 856.7 429.52 L 856.71 440.31 C 856.71 442.3 858.38 443.31 859.64 443.31 L 870.53 443.31 C 872.02 443.31 874.24 443.77 874.24 446.39 L 874.24 483.83 C 874.24 487.16 872.07 489.95 868.16 489.95 L 833.53 489.95 C 830.7 489.95 827.52 487.95 827.52 483.92 Z" fill="#ffffff" stroke="none" pointer-events="all"/><rect x="1060" y="412.9" width="200" height="90" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 458px; margin-left: 1061px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">https://keyboards.qmk.fm<br />Keyboard Metadata<br />Source: qmk/qmk_firmware<br />GH Action: Update API Data<br />Host: DigitalOcean Spaces</div></div></div></foreignObject><text x="1160" y="462" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">https://keyboards.qmk.fm...</text></switch></g><path d="M 845.04 420 L 845.14 308.77" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 845.15 303.52 L 848.64 310.52 L 845.14 308.77 L 841.64 310.51 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 905 630 L 1060 630" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 815 610 C 791 610 785 630 804.2 634 C 785 642.8 806.6 662 822.2 654 C 833 670 869 670 881 654 C 905 654 905 638 890 630 C 905 614 881 598 860 606 C 845 594 821 594 815 610 Z" fill="#ffffff" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 630px; margin-left: 786px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">QMK API</div></div></div></foreignObject><text x="845" y="634" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">QMK API</text></switch></g><rect x="1060" y="595" width="200" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 630px; margin-left: 1061px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">https://api.qmk.fm<br />RESTful API<br />Source: qmk/qmk_api<br />Host: Rancher on DO VM's</div></div></div></foreignObject><text x="1160" y="634" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">https://api.qmk.fm...</text></switch></g><path d="M 794 275.46 L 709.04 315.72 Q 700 320 700 330 L 700 570 Q 700 580 709.45 583.26 L 785.69 609.55" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 790.65 611.26 L 782.89 612.29 L 785.69 609.55 L 785.17 605.67 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 460 251.8 L 290 251.8" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 490 229 C 466 229 460 251.8 479.2 256.36 C 460 266.39 481.6 288.28 497.2 279.16 C 508 297.4 544 297.4 556 279.16 C 580 279.16 580 260.92 565 251.8 C 580 233.56 556 215.32 535 224.44 C 520 210.76 496 210.76 490 229 Z" fill="#ffffff" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 252px; margin-left: 461px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Digital Ocean<br />Spaces<br />(S3)</div></div></div></foreignObject><text x="520" y="255" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Digital Ocean...</text></switch></g><rect x="0" y="221.8" width="290" height="60" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 288px; height: 1px; padding-top: 252px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">https://qmk-api.nyc3.cdn.digitaloceanspaces.com<br />Space: qmk-api<br />Host: Digital Ocean</div></div></div></foreignObject><text x="145" y="255" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">https://qmk-api.nyc3.cdn.digitaloceanspaces.com...</text></switch></g><path d="M 580 251.8 L 787.63 251.31" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 792.88 251.3 L 785.89 254.81 L 787.63 251.31 L 785.87 247.81 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 875 790 L 1060 790" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 815 768 C 815 757.33 875 757.33 875 768 L 875 812 C 875 822.67 815 822.67 815 812 Z" fill="#ffffff" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 815 768 C 815 776 875 776 875 768 M 815 772 C 815 780 875 780 875 772 M 815 776 C 815 784 875 784 875 776" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 800px; margin-left: 816px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">RQ</div></div></div></foreignObject><text x="845" y="804" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">RQ</text></switch></g><rect x="1060" y="755" width="200" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 790px; margin-left: 1061px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Redis / RQ<br />Job Queue<br />Source: qmk/qmk_redis<br />Host: Rancher on DO VM's</div></div></div></foreignObject><text x="1160" y="794" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Redis / RQ...</text></switch></g><path d="M 845 670 L 845 753.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 845 758.88 L 841.5 751.88 L 845 753.63 L 848.5 751.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="785" y="910" width="120" height="80" rx="12" ry="12" fill="#ffffff" stroke="#000000" pointer-events="all"/><rect x="787" y="912" width="116" height="76" rx="11.4" ry="11.4" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 114px; height: 1px; padding-top: 950px; margin-left: 788px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">qmk_complier</div></div></div></foreignObject><text x="845" y="954" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">qmk_complier</text></switch></g><rect x="1060" y="915" width="200" height="70" fill="#ffffff" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 950px; margin-left: 1061px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">QMK Compiler<br />Job Runners<br />Source: qmk/qmk_compiler<br />Host: Rancher on DO VM's</div></div></div></foreignObject><text x="1160" y="954" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">QMK Compiler...</text></switch></g><path d="M 845 820 L 845 903.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 845 908.88 L 841.5 901.88 L 845 903.63 L 848.5 901.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 779.03 925.64 L 529.38 833.46 Q 520 830 520 820 L 520 303.77" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 783.95 927.46 L 776.17 928.32 L 779.03 925.64 L 778.6 921.75 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 520 298.52 L 523.5 305.52 L 520 303.77 L 516.5 305.52 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 905 950 L 1060 950" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg> \ No newline at end of file